1. 命令执行绕过的底层逻辑在CTF比赛中命令执行绕过就像一场黑客与防御系统的猫鼠游戏。想象你面前有个严格的门卫他只允许特定格式的指令通过。这时候你需要做的不是硬闯而是找到他检查规则的漏洞。命令执行漏洞通常出现在Web应用调用系统命令时未做好过滤的场景。比如一个简单的PHP代码片段system(ping -c 3 . $_GET[ip]);当攻击者输入127.0.0.1; ls时系统会先执行ping命令接着执行ls命令。防御方通常会采用黑名单过滤危险字符这就引出了我们的核心命题——如何用非常规方式表达相同语义。我曾遇到一个真实案例某次比赛中过滤了所有空格和分号但允许使用${IFS}。更妙的是当$IFS被加入黑名单后使用{cat,flag.txt}这样的花括号扩展依然有效。这就像用摩斯密码代替口语交流虽然形式不同但传达的信息相同。2. 基础绕过技巧全解析2.1 空格的七十二变当空格被过滤时Linux系统提供了多种替代方案。最经典的是使用$IFS环境变量这个特殊变量在bash中默认为空格、制表符和换行符。实际测试时要注意几个变种cat${IFS}flag.txt cat$IFS$9flag.txt # $9指向空参数 catflag.txt # 重定向符号替代有个容易踩的坑直接使用cat$IFSa.txt会报错因为bash会把IFSa整体当作变量名。这时候就需要用花括号明确变量边界或者用$9进行隔离。2.2 截断符号的妙用截断符号相当于命令中的句子分隔符。在一次内部赛中我发现目标系统过滤了|和;但漏掉了%0aURL编码的换行符。测试payload如下GET /ping.php?ip127.0.0.1%0aid HTTP/1.1常用截断符号效果对比符号适用场景备注;顺序执行最基础管道传递逻辑与前命令需成功%0aHTTP场景换行符URL编码3. 命令构造的艺术3.1 命令拆解重组当关键命令被过滤时可以像拼积木一样重组命令。某次遇到过滤cat的情况我用了三种解法# 反斜杠分割 c\at fl\ag.txt # base64编码 echo Y2F0Cg | base64 -d flag.txt # 变量拼接 ac;bat;$a$b flag.txt更隐蔽的方式是利用环境变量继承。在bash中可以通过${PATH:0:1}提取斜杠配合${#PATH}获取数字最终拼接出完整命令。3.2 通配符的魔法Linux通配符是绕过关键词过滤的神器。记得某次比赛过滤了flag关键词但允许使用通配符cat fla? cat fl* cat f[a-z][a-z][a-z].txt特别要注意大括号扩展的特性{a,b}会展开为a和b两个参数即使文件不存在也会展开。而[a-z]在匹配不到文件时会退化为普通字符。4. 实战Fuzz方法论4.1 黑盒Fuzz测试流程搭建自己的Fuzz字典很重要。我的常用方法是用Python生成测试用例import itertools base [cat, ca\t, c\\at] conn [ , ${IFS}, ] target [flag, fl?g, fla*] print(list(itertools.product(base, conn, target)))实际测试时要关注三个关键点错误回显差异过滤和未过滤的报错通常不同响应时间执行成功的命令可能有延迟间接验证通过DNS或HTTP请求外带数据4.2 经典赛题复盘以[GXYCTF2019]PingPingPing为例突破过程堪称教科书先用|ls确认命令注入点发现空格过滤后改用$IFS$9遭遇flag关键词过滤时组合使用cat$IFS$9fla? ag;cat$IFS$9fla$a最终通过base64编码绕过完整检测另一个典型案例是某次比赛过滤了所有字母最终通过$(printf \154\163)这样的八进制编码实现了ls命令。5. 防御视角的思考作为防守方我建议采用多层过滤策略白名单优于黑名单只允许已知安全的字符命令参数静态分析检测异常参数组合沙箱环境执行限制命令权限和资源最根本的解决方案是避免直接调用系统命令。比如用PHP的file_get_contents()代替cat用scandir()代替ls。在最近的一次渗透测试中我发现即使严格过滤了所有特殊字符攻击者仍可能通过环境变量注入实现绕过。这提醒我们安全防护需要不断迭代更新。