命令注入漏洞及过滤绕过-漏洞解析9
前言
命令注入(Command Injection),是后端直接拼接用户可控参数至系统 shell 命令执行所引发的高危漏洞。区别于 SQL 注入针对数据库、XSS 针对浏览器,命令注入直接操控操作系统底层指令,危害直达服务器本体。
运维人员、安全工程师在护网巡检中经常碰到:接口入参看似做了关键词过滤,仍被攻击者利用特殊字符、编码变形绕过防护,成功执行系统命令。本文从漏洞原理、常见业务场景、全品类绕过技巧、运维落地防御、面试考点完整梳理,兼顾实战挖洞与应急加固。
一、命令注入基础原理
1. 漏洞成因
后端开发直接把用户可控输入拼接入系统命令语句,调用系统接口(Runtime.exec、ProcessBuilder、system ()、exec () 等)执行 shell 指令;未对特殊分隔符、系统关键字做过滤,攻击者插入拼接字符,在原有指令后追加自定义恶意命令。
2. 攻击执行链路
用户提交恶意参数 → 程序拼接至系统命令 → 操作系统 shell 解析复合命令 → 恶意指令被执行 → 读取文件、反弹 shell、篡改系统配置。
3. 高危开发函数
Java:Runtime.getRuntime().exec()、ProcessBuilder
PHP:system()、exec()、shell_exec()、passthru()
Python:os.popen、os.system、subprocess.call(shell=True)
错误示例
// 接收前端传入ip参数,直接拼接ping命令
String ip = request.getParameter("ip");
// 漏洞:可控参数直接拼接shell指令
Runtime.getRuntime().exec("ping -c 1 " + ip);
4. 高频出现业务场景
- 在线 IP 探测、域名 PING 测速功能;
- 后台文件压缩、解压、备份调度功能;
- 远程文件同步、服务器磁盘空间查询;
- 运维平台自定义脚本参数输入。
二、常用命令分隔符
| 符号 | 作用 | 示例 |
|---|---|---|
| ; | 顺序执行,前一条执行完毕执行后一条(Linux 通用) | ping 127.0.0.1;id |
| | | 管道符,前一条输出作为后一条输入 | ping 127.0.0.1|whoami |
| || | 逻辑或,前命令失败则执行后续 | ping xxx||cat /etc/passwd |
| && | 逻辑与,前命令执行成功才执行后续 | ping 127.0.0.1&&ls -l |
| & | 后台并发执行(Windows/Linux 通用) | ping 127.0.0.1 & calc |
三、关键字过滤绕过全方案
开发常采用黑名单过滤:拦截cat、ls、id、whoami、netstat等命令关键词、;|& 等符号,攻击者通过变形、编码、分隔、特殊语法绕过,也是护网应急溯源最常见的攻击手法。
1. 空格绕过
系统 shell 支持多种占位符替代空格:
cat${IFS}/etc/passwd
2. 关键词截断拼接绕过
(1)反斜杠 \ 分隔字符
c\at /etc/passwd
(2)单引号 / 双引号拆分字符
c'a't /etc/passwd
c"a"t /etc/passwd
(3)变量截取构造命令
a=c;b=at;$a$b /etc/passwd
3. 环境变量取值绕过
利用系统环境变量截取字符拼接指令,规避关键词黑名单:
# 利用PATH、PS1等内置变量切片取值
${PATH:5:1}${PATH:8:1} /etc/passwd
4. 编码绕过
(1)URL 编码
前端参数 URL 二次编码,后端解码后还原特殊字符与命令; 原始:;id → URL 编码:%3Bid
(2)八进制 / 十六进制编码
echo -e "\x63\x61\x74" /etc/passwd
5. 通配符模糊匹配绕过
利用*、?通配符模糊匹配文件路径,不用完整文件名:
cat /etc/pass?wd
ls /etc/pass*
6. 换行符 %0a 换行注入
部分过滤仅拦截同行分隔符,换行符可另起一行执行新命令:
127.0.0.1%0aid
7. 嵌套命令绕过 ` 反引号、$()
`id`
$(whoami)
ping 127.0.0.1$(cat /etc/passwd)
8. Windows 系统特殊绕过
利用 cmd 特殊语法:^换行转义、% 变量截取,适用于 Windows 服务器命令注入场景。
四、高阶无字母数字命令注入
当系统过滤全部英文字母、数字,仅保留符号,攻击者依托 Linux 内置运算符、环境变量构造命令,护网高危难点漏洞,多用于无过滤白名单场景。
五、企业和运维全维度防御方案
1. 最优方案:禁用字符串拼接,参数列表调用
Java 使用ProcessBuilder多参数构造,参数与指令分离,杜绝拼接,从底层阻断注入。
// 安全写法:指令、参数分开传入,不会拼接注入
List<String> cmd = Arrays.asList("ping","-c","1",ip);
ProcessBuilder pb = new ProcessBuilder(cmd);
禁止任何形式的字符串拼接系统命令。
2. 输入校验:采用白名单,摒弃黑名单
- 入参格式强校验:如 PING 功能仅允许 IPv4/IPv6 正则格式,不符合直接拒绝;
- 限制输入内容,只允许数字、小数点等业务必需字符,其余特殊符号直接拦截;
3. 特殊字符全局过滤
非业务必需的分隔符:; | & $ \ ' " 、换行符、IFS 相关字符统一拦截。
4. 运行权限最小化
应用运行进程使用低权限普通账号,禁止 root/Administrator 权限运行 Web 服务;即便触发命令注入,攻击者也无法高权限篡改系统、植入后门。
5. 运维兜底防护
- 系统启用 bash 审计日志,记录异常系统调用,护网期间快速溯源攻击行为;
- WAF 配置命令注入特征规则,拦截含各类绕过字符的异常请求;
- 定期代码审计,全局检索 Runtime、ProcessBuilder、system 等危险执行函数。
6. 沙箱隔离
高危运维功能单独部署在隔离沙箱服务器,与核心业务服务器内网隔离,避免漏洞横向扩散。
六、安全面试高频背诵考点
1. 命令注入和 SQL 注入的区别?
命令注入攻击操作系统 shell,执行系统指令;SQL 注入攻击数据库引擎,执行 SQL 语句;二者注入对象、利用函数、危害范围不同。
2. 黑名单过滤为什么防不住命令注入?
攻击者可通过空格替代符、引号拆分、环境变量截取、编码、通配符等几十种变形绕过关键词与符号黑名单,无法穷举所有绕过方式,白名单 + 参数分离才是安全方案。
3. 防止命令注入最有效的编码方案是什么?
不拼接字符串,采用数组形式拆分命令与参数,使用 ProcessBuilder 等参数化调用 API。
4. IFS 是什么,在注入中的作用?
Linux 内置环境变量,代表分隔空格,攻击者用 ${IFS} 替换空格绕过空格过滤,实现命令注入。
七、总结
- 命令注入核心根源:可控参数直接拼接系统 shell 命令,是护网蓝队应急处置 TOP 级漏洞;
- 绕过核心思路:替换空格、拆分关键词、编码变形、环境变量取值、换行另起指令;
- 安全三原则:优先参数化调用不拼接、入参使用白名单强校验、进程权限最小化;
- 运维侧记住:黑名单永远无法彻底防御注入,只能作为辅助兜底策略。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)