当前位置: 首页 > news >正文

DVWA靶场保姆级通关教程---02命令注入

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 目录

    文章目录

    前言

    基本的命令注入原理

    简单的注入技巧与命令连接符的使用

    Linux中的 : (冒号)

    简单绕过手法

    一、low级别

    low级别源码分析

    二、medium级别

    代码分析:

    注入方法

    三、high级别 

    源码分析

    四、impossible级别

    源码分析


前言

基本的命令注入原理

  • 理解服务器在后台执行系统命令时,如何把用户输入拼接到命令字符串中。

  • 如果输入没有正确过滤,攻击者可以注入额外的系统命令并执行,比如:

127.0.0.1; whoami

简单的注入技巧与命令连接符的使用

  • 熟练掌握各种操作系统的命令连接符:

    • Linux/Unix下常用:;, &&, |, ||

    • Windows下也可以使用:&, |

    • 在 Windows cmd 中,| 也是管道符(pipe),把前一个命令的输出作为后一个命令的输入和Linux一致

    • 在 Windows cmd 中,&顺序执行(不论前一个命令是否成功,都会继续执行后一个命令)。相当于Linux的 ;(分号)。

Linux中的 : (冒号)

Linux(Shell里),冒号 : 是一个非常特别的内置命令,叫做 "空命令"(null command)。

👉 它的特点是:

  • 什么也不做,但返回成功(退出码0)

  • 常用于占位、写流程时需要一个“啥也不做但要占个位置”的情况。

127.0.0.1 && cat /etc/passwd

简单绕过手法

  • 比如,直接用替代连接符 && 或用 URL 编码 %26%26

  • 或者注入拼接无害内容使得原命令完成后继续执行新的命令。


提示:以下是本篇文章正文内容,下面案例可供参考

一、low级别

输入127.0.0.1点击提交出现乱码

在phpstudy中打开网站根目录,找到DVWA中对应的文件 然后把编码形式进行修改,把utf-8改为gb2312

文件路径在dvwa/includes/dvwapage.inc.php

修改完成之后,再点击提交或者刷新页面即可

那么可以尝试用管道符(|)将ping的结果交给管道后面的命令处理,查看可以查看当前用户是谁

尝试用分号去拼接两个命令报错,分号拼接前后两个命令之间没有逻辑关系

在Linux里,命令行中的 && 是用来串联两个命令的执行关系的,具体来说:

  • 只有当前一个命令执行成功(返回值是0),后一个命令才会执行

  • 如果前一个命令执行失败(返回非0退出码),后面的命令就不会执行

所以,&& 在Shell中体现的逻辑是:“如果前面的命令成功了,那么继续执行后面的命令”。

这里&&后面除了用ipconfig查看ip,也可以whoami查看用户、systeminfo查看系统信息,dir查看目录,可以自己尝试

也可以将上面的两个&&替换成winds中一个&表示顺序执行,无论前面的地址是否能够ping通,后面的命令都会执行,但是输入一个ping不通的地址,等待返回超时,需要多等会儿。而这时候如果这个地址ping不通,是不能用&&的,两个&&链接的命令是有逻辑关系的,前面命令成功才会执行后面的命令,前面地址ping不通,那么&&后面的命令也不执行。

那么如果前面地址ping不通的情况下,使用||表示逻辑或

Linux (比如 bash/zsh 这些Shell)中,
||逻辑或(OR)操作符,意思是:

如果前一个命令失败(退出状态码非0),那么就执行后一个命令;
如果前一个命令成功(退出码是0),那么后一个命令不会执行

以下情况由于地址192.168.10.1ping不通(执行失败),那么执行||后的命令whoami

low级别源码分析

<?phpif( isset( $_POST[ 'Submit' ]  ) ) {  // 如果用户提交了表单(点击了Submit按钮)// Get input$target = $_REQUEST[ 'ip' ];  // 从请求中获取ip参数(可能来自GET或POST)// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {  // 判断服务器操作系统是不是Windows// Windows$cmd = shell_exec( 'ping  ' . $target );  // Windows系统下执行 ping 命令}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );  // Linux/Unix系统下执行 ping 命令,加上参数-c 4表示只发送4次}// Feedback for the end userecho "<pre>{$cmd}</pre>";  // 把ping命令的执行结果输出到页面上,并用<pre>标签保留格式
}?>

这里隐藏的漏洞点

  • $target 直接拿用户输入,没有经过任何过滤(比如禁止特殊字符 &|; 之类的)。

  • shell_exec() 是直接调用操作系统的Shell命令执行函数

  • 所以如果用户在 ip 参数里不仅传IP,还加了 | whoami,那么整个Shell执行的命令就变成了:

    • Windows:ping 127.0.0.1 | whoami

    • Linux:ping -c 4 127.0.0.1 | whoami

结果就可以直接命令注入执行了!

二、medium级别

有了前面low级别的基础,直接来分析源码

<?phpif( isset( $_POST[ 'Submit' ]  ) ) {  // 如果用户提交了表单(点击了Submit按钮)// Get input$target = $_REQUEST[ 'ip' ];  // 从请求中获取 'ip' 参数的值,可能来自 GET 或 POST 请求// Set blacklist$substitutions = array(  // 设置一个黑名单,列出了不允许出现的字符'&&' => '',  // 删除 '&&',防止命令链的注入';'  => '',  // 删除 ';',防止多命令执行的注入);// Remove any of the characters in the array (blacklist).$target = str_replace( array_keys( $substitutions ), $substitutions, $target );  // 将用户输入中的黑名单字符替换为空字符串,起到过滤作用// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {  // 判断操作系统是否为 Windows// Windows$cmd = shell_exec( 'ping  ' . $target );  // 如果是Windows,执行 ping 命令,ping目标是用户提供的IP地址}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );  // 如果是 Linux 或 Unix 系统,执行带有 -c 4 参数的 ping 命令,指定只发送4个包}// Feedback for the end userecho "<pre>{$cmd}</pre>";  // 将命令执行结果输出到页面,保留格式输出(<pre>标签保持换行和空格)
}?>

代码分析:

  1. 黑名单过滤

    • 通过创建一个 $substitutions 数组,代码尝试过滤掉可能导致命令注入的字符,比如 &&(命令链)和 ;(命令分隔符)。这是为了防止用户在输入中注入多个命令。

    • 但是,这个方法并不完全安全,因为还有其他特殊字符或者更复杂的注入方式(如管道符 |)没有被拦截。

  2. 操作系统判断

    • 使用 php_uname('s') 判断操作系统是 Windows 还是类 Unix 系统,然后分别执行不同的 ping 命令。

    • 这个判断是根据操作系统不同选择不同的命令格式,这本身是合理的。

  3. 命令执行

    • shell_exec() 函数用来执行拼接出来的命令,并返回命令的输出。

    • 如果用户输入的 ip 包含不安全的字符,str_replace() 可能可以在一定程度上避免注入,但是这并不是一个完整的安全解决方案,因为它只过滤了少数几个字符。

  4. 用户反馈

    • 命令执行结果会被输出到网页上,使用 <pre> 标签进行格式化显示。这使得用户能够看到 ping 命令的执行结果。

注入方法

使用不在黑名单里面的命令连接符,比如 | 或者 || 或者 & ,同样可以拼接前面的命令

三、high级别 

源码分析

<?phpif( isset( $_POST[ 'Submit' ]  ) ) { // 如果用户提交了表单(点击了Submit按钮)// Get input$target = trim($_REQUEST[ 'ip' ]); // 获取用户提交的IP地址,并用trim去除前后空格// Set blacklist$substitutions = array( // 定义一个黑名单,把一些危险字符列出来'&'  => '',   // 单个&,用于连接命令,清除';'  => '',   // 分号,能分隔多个命令,清除'| ' => '',   // 管道符后带空格的,清除'-'  => '',   // 减号,可能用来传参数,如ping命令参数,清除'$'  => '',   // 美元符号,能用来执行如$(命令)或环境变量,清除'('  => '',   // 左括号,配合$用于子命令执行,清除')'  => '',   // 右括号,配合$用于子命令执行,清除'`'  => '',   // 反引号,可执行反引号内的命令,清除'||' => '',   // 双竖线,逻辑或连接符,可分开执行命令,清除);// Remove any of the characters in the array (blacklist).$target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // 把用户输入中的黑名单字符全部替换为空(相当于删掉)// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // 检查服务器系统是不是Windows(根据系统名中是否有"Windows NT"判断)// Windows系统下执行ping命令$cmd = shell_exec( 'ping  ' . $target );}else {// *nix系统(比如Linux)下执行ping命令,加参数-c 4,表示ping 4次$cmd = shell_exec( 'ping  -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>"; // 把命令执行结果用pre标签包裹,格式化输出到网页上
}?>

仔细看这里的 '| '后面有一个空格,所以依然可以用 | 这个注入。我们之前在注入的时候

127.0.0.1 | whoami #|后面是有个空格的,是可以成功的

这次high级别写的时候|后面不要加空格,加上空格会被黑名单过滤

简单总结一下:

  • 这一版比medium.php更加严格了,过滤了更多危险字符

  • 尤其是把单独的 &|、反引号 `、美元符号 $()等都清除了。

  • 但它依然是基于黑名单过滤,理论上还是可能被绕过(比如编码、空格变形、双写等手法)。

四、impossible级别

源码分析

<?phpif( isset( $_POST[ 'Submit' ]  ) ) { // 如果点击了提交按钮// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // 检查CSRF防护令牌,防止跨站请求伪造攻击// Get input$target = $_REQUEST[ 'ip' ]; // 获取用户提交的IP地址$target = stripslashes( $target ); // 去除字符串中的反斜杠(如果有)// Split the IP into 4 octects$octet = explode( ".", $target ); // 按点号"."分割成4段(四个8位字节)// Check IF each octet is an integerif( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {// 如果每一段都是数字,且总共有4段,说明输入的是合法IP格式// If all 4 octets are int's put the IP back together.$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3]; // 将IP重新组合成标准格式// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // 如果服务器是Windows系统$cmd = shell_exec( 'ping  ' . $target ); // 执行ping命令}else {// 否则认为是Linux或Unix系统$cmd = shell_exec( 'ping  -c 4 ' . $target ); // 执行ping命令并指定4次}// Feedback for the end userecho "<pre>{$cmd}</pre>"; // 把ping结果输出给用户}else {// 如果输入的IP不合法echo '<pre>ERROR: You have entered an invalid IP.</pre>'; // 提示错误信息}
}// Generate Anti-CSRF token
generateSessionToken(); // 重新生成新的CSRF防护令牌?>
🛡️ 过滤方式只允许格式正确的IP地址(四段数字,用"."分隔),其他任何输入直接拒绝。
🛡️ CSRF防护使用了token机制防止跨站请求伪造。
🛡️ 命令执行点只有经过严格校验的纯数字IP才能进入执行流程,避免了注入。
🔥 注入可能性理论上基本没法注入(除非PHP本身或服务器存在其他漏洞,比如某些超老版本PHP漏洞)
http://www.xdnf.cn/news/220483.html

相关文章:

  • 5.4.2 MVVM例2-用户控件的使用(水在水管中流动的实例)
  • 路径规划算法总结:从 Dijkstra 到 A* 与 Hybrid A
  • GUI_DrawPixel 函数详解
  • BalenaEtcher 2.1镜像烧录工具软件下载及安装教程
  • Vite性能优化指南 ✅
  • 强化学习(二)马尔科夫决策过程(MDP)
  • java AsyncTool
  • ACTF2025 - WEB Excellent-Site
  • 第十章:CrewAI - 面向流程的多 Agent 结构化协作
  • Andorid车机UI适配,AndroidUI图px的单位,如何适配1920x720,PPI100的屏幕设备
  • 【GESP】C++三级练习 luogu-B2117 整理药名
  • Rockchip Android平台打开GKI无法开机问题
  • 应用服务器-IIS
  • 推荐系统中 Label 回收机制之【时间窗口设计】
  • 基于Lucene的多场景检索系统开发指南
  • [按键安卓ios脚本辅助插件开发]数组排序函数例子
  • 明远智睿SSD2351开发板:开启嵌入式开发新篇程
  • C#实现对达索(Dassault)SolidWorks中3D图纸转化为手机可直接查看预览图纸格式
  • 高级项目管理
  • 巧记英语四级单词 Unit6-下【晓艳老师版】
  • C++程序退出时的对象析构陷阱:深度解析与避坑指南
  • mysql 事务中如果有sql语句出错,会导致自动回滚吗?
  • 力扣刷题总表
  • 【Vue】 实现TodoList案例(待办事项)
  • Java高频面试之并发编程-10
  • C++之string
  • 如何在本地部署小智服务器:从源码到全模块运行的详细步骤
  • CA校验主辅小区配置及UE能力
  • 首发记忆行车方案与座舱智能管家,佑驾创新“抢跑”驾舱融合市场
  • 恒流恒压直流充电测试负载设计:构建精准化检测体系