CTF靶场实战:当cat被ban,如何用/bin/base64和通配符绕过RCE的字符黑名单?
CTF靶场实战:当cat被禁用时如何用base64与通配符突破字符限制
在CTF竞赛中,命令注入类题目常常设置各种字符过滤规则来增加挑战难度。最近遇到一个有趣的场景:目标系统禁止了绝大多数字母和符号,仅允许使用数字、小写字母a和问号。这种情况下,传统的cat、ls等命令完全无法使用,需要寻找更巧妙的绕过方式。
1. 理解题目限制与突破口
首先我们需要明确题目给出的过滤条件:
- 允许字符:数字0-9、小写字母a、问号?
- 禁止字符:b-z的所有字母、A-Z大写字母以及大部分特殊符号
这种限制下,我们面临两个主要问题:
- 无法直接输入常见命令如cat、ls、head等
- 路径和参数传递也受到严格限制
但仔细观察会发现几个关键突破口:
- 问号(?)在Linux shell中可以作为通配符,匹配任意单个字符
- 系统路径分隔符(/)未被过滤
- 小写字母a可用,这是定位特定命令的关键
提示:在受限环境中,/bin目录下包含许多可能被忽略的实用程序,它们往往比常见命令有更复杂的名称。
2. 定位替代命令:从base64入手
当cat不可用时,我们需要寻找其他能够读取文件内容的系统命令。通过分析/bin目录下的程序,发现几个潜在候选:
| 命令路径 | 功能描述 |
|---|---|
| /bin/base64 | 对输入进行base64编码/解码 |
| /bin/od | 以八进制格式输出文件内容 |
| /bin/xxd | 十六进制转储工具 |
| /bin/rev | 反转文件内容 |
其中,/bin/base64特别适合我们的需求,因为:
- 名称中包含允许的字母a
- 可以将文件内容完整输出(虽然经过编码)
- 输出结果容易解码还原
3. 通配符精确匹配技巧
要使用base64命令,我们需要在不直接输入完整路径的情况下定位它。这时问号通配符就派上用场了。
/bin/base64的路径结构分析:
/ b i n / b a s e 6 4 1 2 3 4 5 6 7 8 9 10我们可以用问号代替每个不确定的字符:
/???/?a??64这样匹配的原理是:
- /???/ 匹配/bin/目录(因为/bin是4字符)
- ?a??64 匹配base64(b被过滤,只能用a定位)
在终端测试这个模式:
echo /???/?a??64典型输出会是:
/bin/base644. 构造完整Payload并解码
现在我们可以组合出完整的文件读取方案:
- 使用通配符定位base64命令
- 同样方法定位目标文件(假设为/flag)
- 将base64编码结果解码获取原始内容
具体Payload构造:
/???/?a??64 /??a?解释:
- 第一部分:/???/?a??64 → /bin/base64
- 第二部分:/??a? → /flag(假设flag文件名为4字符)
执行后输出是flag文件的base64编码内容,只需简单解码即可:
import base64 encoded = "VGhlIGZsYWcgaXM6IENURntiYXNlNjRfY2FuX3NhdmVfeW91fQo=" print(base64.b64decode(encoded).decode())5. 其他可能的变体与技巧
在实际CTF中,题目设置可能有变化,这里提供几个应对策略:
5.1 当文件名长度未知时
如果不知道flag文件的确切字符数,可以尝试:
/???/?a??64 /????? # 尝试5字符文件名 /???/?a??64 /?????? # 尝试6字符文件名5.2 使用od命令的替代方案
如果base64也被过滤,可以尝试od命令:
/???/?d /??a?5.3 目录遍历技巧
当flag不在根目录时,可以尝试:
/???/?a??64 /???/??a? # 匹配二级目录6. 防御视角:如何防止此类绕过
从安全开发角度,要完全防止命令注入,建议:
- 使用白名单而非黑名单进行输入验证
- 尽量避免将用户输入直接拼接为系统命令
- 使用专门的命令执行函数而非shell
- 对必须执行的命令进行完整路径限制
例如在PHP中更安全的做法:
$allowed_commands = ['/usr/bin/safe_command']; if (in_array($user_input, $allowed_commands)) { system($user_input . ' --safe-flag'); }在CTF比赛中遇到这类限制时,关键是要保持创造性思维,深入了解系统提供的各种工具及其路径命名规律。通过组合有限的可用字符和系统特性,往往能找到意想不到的解决方案。
