Command Injection 命令注入漏洞:系统命令拼接缺陷与执行利用技术 Command Injection 命令注入漏洞系统命令拼接缺陷与执行利用技术前言1. Command Injection 核心理论基础1.1 漏洞本质与定义1.2 漏洞成立的三大必要条件1.3 完整攻击链路1.4 命令注入与代码注入的核心区别1.5 常见攻击场景与业务危害1.6 漏洞在安全榜单中的定位2. DVWA Command InjectionLow2.1 页面黑盒探测2.2 黑盒漏洞利用实操2.2.1 分号分隔符注入最经典2.2.2 常用分隔符与 Payload 汇总2.3 源码审计无过滤直接拼接3. DVWA Command InjectionMedium3.1 页面黑盒探测3.2 黑盒漏洞利用实操3.2.1 单个分隔符绕过Windows最优3.2.2 全环境可用Payload汇总Windows靶场专用3.3 源码审计4. DVWA Command InjectionHigh4.1 页面黑盒探测4.2 黑盒漏洞利用实操4.3 源码审计5. DVWA Command InjectionImpossible5.1 源码审计5.2 源码安全总结免责声明前言上一篇我们详细拆解了 Open HTTP Redirect 开放重定向漏洞的校验缺陷与各类绕过技巧相信大家对URL 参数未校验导致的信任滥用攻击思路已经有了清晰的认识。今天我们继续 Web 漏洞系列来聊一个危害等级直接拉满、入门 Web 安全必须掌握的经典注入类漏洞——Command Injection命令注入。如果说 SQL 注入是操作数据库XSS 是操作用户浏览器那命令注入就是直接操作服务器的操作系统。攻击者只要找到一个命令注入点就能在服务器上执行任意系统命令读文件、写 Shell、提权、内网横向移动……相当于直接拿到了服务器的控制权属于RCE远程代码执行级别的高危漏洞。命令注入的核心原理非常简单本质就是用户可控的输入被直接拼接到系统命令中执行和 SQL 注入是同一个路子——凡是字符串拼接 解释执行的地方都可能出现注入漏洞。1. Command Injection 核心理论基础1.1 漏洞本质与定义命令注入漏洞Command Injection又称 OS 命令注入对应的标准漏洞编号为CWE-78: OS Command Injection。漏洞的本质一句话就能说清Web 应用程序将用户可控的输入直接拼接到系统命令中执行没有做任何过滤或转义导致攻击者可以注入额外的命令在服务器上执行任意系统指令。用最直白的话讲后端代码要执行一条系统命令比如ping 目标IP其中目标IP是用户传进来的。结果用户传的不是 IP而是127.0.0.1; cat /etc/passwd后端直接拼进去变成了ping 127.0.0.1; cat /etc/passwd两条命令一起执行服务器的敏感文件就被读出来了。典型的漏洞代码长这样PHP 为例$ip$_GET[ip];system(ping .$ip);// 用户输入直接拼进命令里用户传什么命令里就有什么完全不设防。1.2 漏洞成立的三大必要条件不是所有带参数的地方都有命令注入必须同时满足以下三个条件条件一用户可控的输入被拼接到系统命令中后端调用了执行系统命令的函数PHP 的system()、exec()、shell_exec()Java 的Runtime.getRuntime().exec()Python 的os.system()等命令的某一部分参数、选项等完全由用户输入控制条件二没有对用户输入做严格的过滤和转义完全没过滤Low 级别过滤了但能被绕过Medium/High 级别用了黑名单、关键字替换等不靠谱的过滤方式条件三命令执行函数的输出能被回显或利用有回显命令执行结果直接显示在页面上最理想情况无回显可以通过 DNS 外带、时间盲注等方式判断命令是否执行成功1.3 完整攻击链路命令注入的攻击链路非常直接分四步走第一步寻找命令注入点在目标网站上找那些看起来会调用系统功能的地方比如ping 功能、traceroute 功能文件解压、格式转换功能DNS 查询、WHOIS 查询功能系统信息展示、日志查看功能第二步判断是否存在注入先传正常参数看功能是否正常。然后尝试在参数后面加分号、管道符等命令分隔符看是否能执行额外命令。比如正常输入127.0.0.1能 ping 通输入127.0.0.1; whoami后如果页面返回了当前用户名说明存在命令注入。第三步信息收集与权限判断确认有注入后先摸清楚服务器的基本情况什么操作系统Windows/Linux当前用户是谁、有什么权限网站根目录在哪、能不能写文件有哪些有用的系统命令可以用第四步进一步利用根据权限和环境逐步扩大战果读敏感文件/etc/passwd、配置文件、源码等写 WebShell 拿到持久化控制提权拿到 root/管理员权限内网横向移动渗透整个内网1.4 命令注入与代码注入的核心区别很多人容易把命令注入和代码注入搞混其实两者不是一回事类型执行层面典型函数危害范围命令注入操作系统层面system()、exec()、os.system()整个服务器系统代码注入应用程序语言层面eval()、assert()、exec()Python应用程序权限范围内简单说命令注入 直接调用系统 Shell 执行命令代码注入 在当前编程语言的解释器里执行代码命令注入的危害通常更大因为它直接操作的是操作系统不受应用层权限的限制当然也看运行用户是谁。1.5 常见攻击场景与业务危害命令注入属于高危甚至严重级别的漏洞危害极大。主要攻击场景网络工具类功能最常见ping、traceroute、nslookup、whois 等网络诊断功能几乎都是直接调用系统命令实现的是命令注入的重灾区。文件处理类功能文件压缩/解压、格式转换、图片处理、PDF 生成等功能很多是调用 ImageMagick、ffmpeg 等外部命令实现的参数过滤不严就会被注入。系统管理类功能一些后台管理功能会提供查看系统日志、“重启服务”、备份数据等功能本质都是执行系统命令一旦被越权访问就是灾难。第三方组件/插件很多 CMS、框架、插件自带的功能里可能藏着命令注入不需要登录就能打危害极大。业务危害直接 RCE攻击者可以在服务器上执行任意命令完全控制服务器数据泄露读取数据库配置、用户数据、源码等敏感信息网页篡改修改网站文件挂黑页、挂马内网渗透以服务器为跳板横向攻击内网其他机器勒索挖矿植入勒索病毒、挖矿木马造成直接经济损失1.6 漏洞在安全榜单中的定位CWE 编号CWE-78— OS Command Injection操作系统命令注入的标准定义OWASP Top 10属于A03:2021 - Injection注入类漏洞的一种和 SQL 注入、XSS 同属注入大家族常年位居 OWASP Top 10 前列CTF 定位Web 方向的核心考点入门必学几乎每场 CTF 都有命令注入的题从简单的直接注入到复杂的各种绕过花样百出漏洞评级一般直接评高危如果无需登录且能直接 getshell直接严重级别实战地位在真实渗透测试中命令注入是含金量极高的漏洞找到一个往往就能直接拿下服务器属于 P1/P0 级别的高危漏洞一句话总结命令注入是注入类漏洞里最爽的一种——找到就是 RCE直接拿到服务器权限是 Web 安全入门必须吃透的核心漏洞。2. DVWA Command InjectionLow2.1 页面黑盒探测先不看源码我们以渗透测试者的视角先摸清楚这个页面的功能。进入 DVWA 的 Command Injection 模块看到一个输入框提示Enter an IP address to ping输入一个 IP 地址来 ping旁边有个 Submit 按钮。看起来是个 ping 功能我们先正常用一下输入127.0.0.1点提交。正常返回结果注Windows 环境下 ping 输出的中文提示可能会显示菱形问号乱码这是 GBK 和 UTF-8 编码冲突导致的不影响漏洞测试数字和英文输出都是正常的。页面直接把 ping 命令的输出结果显示出来了说明后端确实调用了系统的 ping 命令而且有回显。黑盒初步结论功能调用系统 ping 命令测试网络连通性输入参数IP 地址用户完全可控输出命令执行结果直接回显在页面上那问题来了如果我在 IP 后面加点别的东西比如分号加另一条命令会怎么样这就是命令注入的核心测试思路。2.2 黑盒漏洞利用实操2.2.1 分号分隔符注入最经典命令注入最经典的分隔符就是分号;在 Linux Shell 里分号用来分隔多条命令按顺序执行。测试思路在正常 IP 后面加分号再加一条我们想执行的命令看能不能一起执行。构造 Payload127.0.0.1 whoami把这个输入到框里提交。结果页面先输出了 ping 的结果然后紧接着输出了当前用户名Linux 下通常是www-dataWindows 下是系统用户名。说明whoami命令被成功执行了命令注入漏洞实锤。2.2.2 常用分隔符与 Payload 汇总除了分号还有很多种命令分隔符都可以用不同场景用不同的分隔符作用示例 Payload适用场景;顺序执行多条命令127.0.0.1; whoamiLinux 专用Windows CMD 不识别前置命令执行成功才执行后置命令127.0.0.1 dirLinux / Windows 通用||前置命令执行失败才执行后置命令127.0.0.1|| verLinux / Windows 通用|管道符将前命令输出传给后命令127.0.0.1 | ipconfigLinux / Windows 通用并行同时执行两条命令127.0.0.1 dirWindows 首选Linux 也兼容%0aURL换行符换行分割两条独立命令绕过字符过滤127.0.0.1%0adir存在符号黑名单过滤的绕过场景实战常用 Payload 清单# 查看当前用户127.0.0.1;whoami# 查看操作系统信息127.0.0.1;uname-a# Linux127.0.0.1ver# Windows# 查看当前目录127.0.0.1;pwd# Linux127.0.0.1cd# Windows# 列出当前目录文件127.0.0.1;ls-la# Linux127.0.0.1dir# Windows# 读取敏感文件127.0.0.1;cat/etc/passwd# Linux127.0.0.1typeC:\Windows\System32\drivers\etc\hosts# Windows# 查看网络配置127.0.0.1;ifconfig# Linux127.0.0.1ipconfig# WindowsLow 级别没有任何过滤这些 Payload 全都可以直接用。2.3 源码审计无过滤直接拼接黑盒测完了我们来看看源码确认一下是不是真的什么防护都没有。Low 级别的源码路径/vulnerabilities/exec/source/low.php?phpif(isset($_POST[Submit])){// Get input$target$_REQUEST[ip];// Determine OS and execute the ping command.if(stristr(php_uname(s),Windows NT)){// Windows$cmdshell_exec(ping .$target);}else{// *nix$cmdshell_exec(ping -c 4 .$target);}// Feedback for the end user$html.pre{$cmd}/pre;}?源码逐行分析获取用户输入第 5 行$target$_REQUEST[ip];直接接收前端传入的ip参数没有任何过滤、转义、校验用户输入的所有特殊字符; | || 等全部原样保留。判断操作系统并拼接命令第 8-14 行if(stristr(php_uname(s),Windows NT)){$cmdshell_exec(ping .$target);// Windows}else{$cmdshell_exec(ping -c 4 .$target);// Linux}用php_uname(s)判断当前是 Windows 还是 Linux 系统根据系统不同拼接不同的 ping 命令参数核心漏洞点用户输入$target直接拼接到命令字符串里没有任何处理正常输入127.0.0.1→ 执行ping -c 4 127.0.0.1注入输入127.0.0.1; whoami→ 执行ping -c 4 127.0.0.1; whoami执行结果回显第 17 行$html.pre{$cmd}/pre;命令执行结果直接输出到页面属于有回显命令注入可以直接看到命令执行的输出。一句话总结 Low 级别完全没有任何安全防护用户输入直接拼进系统命令执行属于开发者根本没想过有人会在 IP 里塞命令的典型反面教材是最基础的命令注入形态。3. DVWA Command InjectionMedium3.1 页面黑盒探测切换靶场难度为Medium进入Ping功能页面页面结构与Low一致仅IP输入框与提交按钮。输入正常IP127.0.0.1提交ping正常返回数据基础功能无异常复用Low核心Payload127.0.0.1; dir测试页面仅展示ping输出无dir目录信息判定分号;被后端过滤尝试双与号Payload127.0.0.1 dir页面提示找不到主机被整体清空注入失效。黑盒初步结论后端启用黑名单过滤拦截了;、两类常用分隔符但未对全部命令符号做处理存在绕过空间。3.2 黑盒漏洞利用实操3.2.1 单个分隔符绕过Windows最优测试Payload127.0.0.1 dir提交后页面同时输出ping反馈、当前目录文件列表注入成功。原理黑名单仅清除与;单个不在过滤数组内Windows CMD可识别分割多条命令。3.2.2 全环境可用Payload汇总Windows靶场专用分隔符Payload示例执行效果127.0.0.1 dir并行执行ping、列出目录|127.0.0.1 | ver管道符输出系统版本||127.0.0.1 || ipconfigping失败后执行查看网卡信息3.3 源码审计完整Medium源码?phpif(isset($_POST[Submit])){// Get input$target$_REQUEST[ip];// 黑名单数组过滤 和 ;$substitutionsarray(,;,);// 单次替换删除匹配到的 、;$targetstr_replace(array_keys($substitutions),$substitutions,$target);// Determine OS and execute the ping command.if(stristr(php_uname(s),Windows NT)){// Windows$cmdshell_exec(ping .$target);// 新增编码转换解决Windows ping中文乱码$cmdiconv(GBK,UTF-8//IGNORE,$cmd);}else{// *nix$cmdshell_exec(ping -c 4 .$target);}// Feedback for the end user$html.pre{$cmd}/pre;}?漏洞核心拆解过滤逻辑缺陷仅删除、;、|、||完全放行str_replace仅单次匹配无法覆盖全部命令分隔符高危拼接执行过滤后的变量直接拼接进shell_exec()无IP格式白名单校验可控符号可带入系统命令编码修复说明Windows分支添加iconv编码转换解决CMD中文GBK与网页UTF-8冲突的菱形问号乱码。4. DVWA Command InjectionHigh4.1 页面黑盒探测正常输入127.0.0.1提交ping 正常返回数据基础功能正常。测试 Medium 可用Payload127.0.0.1 dir仅输出ping结果被过滤。测试127.0.0.1 || ver、127.0.0.1; dir全部失效||、;被清空。测试带空格管道127.0.0.1 | dir无第二条命令输出|管道空格被过滤。测试无空格管道127.0.0.1|dir同时输出ping与目录列表注入成功。测试URL换行127.0.0.1%0aver成功执行ver查看系统版本可绕过。黑盒结论后端扩充黑名单拦截绝大多数分隔符但过滤存在两处漏洞只拦截带空格的管道|、未拦截URL换行符%0a存在绕过手段。4.2 黑盒漏洞利用实操无空格管道符绕过Payload127.0.0.1|dir利用原理黑名单匹配规则是|管道后带空格输入|dir无空格无法命中过滤规则管道符完整保留CMD识别管道执行多条命令。4.3 源码审计?phpif(isset($_POST[Submit])){// 获取输入trim去除首尾空格$targettrim($_REQUEST[ip]);// 扩容黑名单过滤大量命令特殊符号$substitutionsarray(||,,;,| ,-,$,(,),,);// 单次替换删除黑名单内所有匹配字符$targetstr_replace(array_keys($substitutions),$substitutions,$target);// 判断系统执行ping命令直接拼接过滤后的输入if(stristr(php_uname(s),Windows NT)){// Windows$cmdshell_exec(ping .$target);// Windows GBK编码转UTF-8修复中文乱码$cmdiconv(GBK,UTF-8//IGNORE,$cmd);}else{// Linux$cmdshell_exec(ping -c 4 .$target);}// 执行结果回显页面echopre{$cmd}/pre;}?逐行漏洞拆解输入预处理trim()清除输入首尾空格防止用首尾空格构造过滤绕过。核心黑名单过滤缺陷$substitutionsarray(||,,;,| ,// 仅过滤【管道空格】单独|不处理-,$,(,),,);$targetstr_replace(array_keys($substitutions),$substitutions,$target);只匹配|管道后带空格连续无空格|不会被删除未收录换行符\nURL编码%0a无法拦截换行分割命令str_replace仅做简单字符替换无循环过滤、无IP格式白名单校验。高危命令拼接过滤后的$target直接拼接进shell_exec()用户可控特殊字符仍能带入系统命令执行。编码转换代码Windows分支增加iconv(GBK, UTF-8//IGNORE)将CMD输出的GBK中文转为UTF-8解决页面乱码方块。输出修改使用echo直接打印结果不再使用$html拼接和Low/Medium源码输出逻辑区分。High级别总结相比Medium大幅扩充黑名单覆盖更多危险符号但本质仍是黑名单防御无法穷尽所有命令分隔手段依靠无空格管道、URL换行符即可绕过依然存在完整命令注入漏洞。5. DVWA Command InjectionImpossible5.1 源码审计?phpif(isset($_POST[Submit])){// 1. CSRF令牌校验防止跨站伪造请求checkToken($_REQUEST[user_token],$_SESSION[session_token],index.php);// 获取用户输入$target$_REQUEST[ip];// 去除转义反斜杠$targetstripslashes($target);// 用点号.把输入拆分成四段数组$octetexplode(.,$target);// 核心白名单校验必须是4段且每一段都只能是纯数字if((is_numeric($octet[0]))(is_numeric($octet[1]))(is_numeric($octet[2]))(is_numeric($octet[3]))(sizeof($octet)4)){// 校验通过后手动用四段数字重新拼接IP完全丢弃用户输入里的所有特殊字符$target$octet[0]...$octet[1]...$octet[2]...$octet[3];// 判断操作系统执行ping命令if(stristr(php_uname(s),Windows NT)){// Windows$cmdshell_exec(ping .$target);// Windows GBK编码转UTF-8修复中文乱码$cmdiconv(GBK,UTF-8//IGNORE,$cmd);}else{// Linux/Unix$cmdshell_exec(ping -c 4 .$target);}// 回显执行结果echopre{$cmd}/pre;}else{// 格式不合法 → 直接报错不执行任何命令echopreERROR: You have entered an invalid IP./pre;}}// 生成新的CSRF令牌generateSessionToken();?分层源码安全分析CSRF防护层checkToken()校验会话绑定的随机token外部不能直接构造POST发包必须从当前页面获取合法user_token拦截跨站伪造请求阻断脱离页面的自动化注入发包。转义符清理stripslashes($target)清除输入中所有转义反斜杠\杜绝通过转义字符变形特殊符号绕过校验。核心白名单校验根治命令注入的关键$octetexplode(.,$target);if(is_numeric四段全部通过数组长度等于4)逻辑输入必须严格是标准IPv4格式拆分为4段每一段只能是数字注入阻断逻辑只要输入包含;\|\|\|%0a任意符号拆分后某一段会包含非数字字符is_numeric()返回false直接进入else分支。纯净IP重拼接彻底销毁用户可控恶意字符$target$octet[0]...$octet[1]...$octet[2]...$octet[3];不使用原始用户输入仅提取四段数字重新拼接IP原始输入里所有特殊符号全部被丢弃没有任何恶意字符能进入shell_exec。命令执行与编码处理只有白名单校验通过才会调用shell_exec()执行ping校验失败完全不调用系统命令Windows分支增加iconv(GBK, UTF-8//IGNORE)将CMD的GBK输出转为网页UTF-8编码消除中文乱码方块不影响安全逻辑。会话令牌刷新页面底部generateSessionToken()每次提交后刷新token防止令牌复用。5.2 源码安全总结抛弃Low/Medium/High的黑名单思路采用输入格式白名单从根源阻断所有命令分隔符多层防护叠加CSRF校验 转义符清理 IP格式强校验不存在任何可绕过方式无命令注入漏洞是DVWA标准安全写法。免责声明本文所有内容仅用于网络安全技术研究与教学演示所有测试均在本地授权搭建的 DVWA 靶场环境中进行旨在帮助读者理解漏洞原理与防御机制。请勿将本文涉及的技术与方法用于任何未经授权的真实系统测试。任何利用本文内容进行的非法攻击行为均与作者无关由使用者自行承担相应法律责任。网络安全学习请严格遵守《中华人民共和国网络安全法》及相关法律法规仅在获得明确书面授权的前提下开展安全测试。

本周精选

本月热点