ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CTFHub RCE命令注入通关指南:从原理到绕过技巧

CTFHub RCE命令注入通关指南:从原理到绕过技巧 如果你在CTFHub技能树里刷到“RCE命令注入”这一节大概率会经历一个从“一脸懵”到“原来如此”的过程。命令注入这个考点说难不难说简单也不简单——它的核心逻辑很直白程序把用户输入拼进了系统命令里又没有做好过滤导致你能通过几个特殊符号让服务器执行自己的命令。但真正上手做题时各种过滤规则、绕过姿势、回显判定问题会一层层叠上来刷完整个模块你会发现自己对shell命令、Linux系统特性、PHP函数行为的理解都上了一个台阶。这篇文章就围绕CTFHub技能树的RCE命令注入题目来写从命令注入的基本原理讲起按“无过滤—单点过滤—综合过滤—无回显”这条主线展开把每类题目的判断思路和绕过技巧拆开揉碎最后分享一些我在刷题过程中踩过的坑和排错方法。不管你是刚开始接触CTF的新手还是刷了一半卡在某个过滤点的选手这篇文章都能给你一条相对完整的通关路径。1. 命令注入的本质先搞清楚我们在打什么很多人把命令注入、代码执行、文件包含这几个RCE相关考点混在一起实际上它们的触发点和利用方式完全不同。命令注入的核心前提是程序本身调用了系统命令而你输入的内容被当作命令的一部分拼接了进去。换句话说漏洞不在函数本身而在变量拼接这一段逻辑。1.1 命令注入与代码执行的分界线代码执行对应的是eval、assert这类函数你输入的是PHP代码本身程序把你输入的内容当代码来解析比如eval($_GET[code])。命令注入对应的则是system、exec、shell_exec、passthru、popen、proc_open这一类函数你输入的内容最终会传递到操作系统的shell里去执行。打个比方代码执行是你直接抢过厨师手里的锅铲自己炒菜而命令注入是你只能往菜单里加备注但厨师完全信任你的备注连“多加辣”和“把厨房点了”都分不清。在CTFHub这类平台里RCE模块通常把这两类题目都收进来但命令注入子模块专注的是后者。1.2 命令注入的高发拼接场景命令注入最容易出现在需要调用系统命令的业务场景里典型的包括ping功能ping -c 4 $ip用户传IP地址进去日志查看tail -f $logfile文件压缩/解压zip -r $filename.zip $dir网络诊断tracert $host、nslookup $domain执行脚本python $script_path在CTFHub的命令注入题目里最常见的是一个ping测试接口或者一个文件查看接口。输入IP/文件名后后台执行命令并把结果回显到页面上。这种场景的好处是回显直观适合教学缺点是想做成“完全无过滤”其实很难因为只要有一层过滤你就得开始琢磨绕过方案了。1.3 注入符号的语义差异为什么都往;上靠命令注入第一步是选分隔符让攻击命令和原有命令断开或者说并列执行。常见的符号有这些符号含义注入示例是否常用;顺序执行多条命令不管前一条是否成功127.0.0.1;whoami最常用前一条成功后才执行后一条127.0.0.1whoami常用|把前一条的输出作为后一条的输入127.0.0.1|whoami常用||前一条失败才执行后一条127.0.0.1||whoami偶尔用后台执行前一条同时执行后一条127.0.0.1whoami偶尔用换行符利用shell解析换行的特性%0awhoami特定场景拿CTFHub的ping题来说输入127.0.0.1后台执行的是ping -c 4 127.0.0.1如果你输入127.0.0.1;whoamishell会先执行ping -c 4 127.0.0.1再执行whoami最终输出里除了ping的结果还会带上当前用户名通常是无权用户www-data之类的。这个步骤是命令注入的第一个完整的验证链。实战中我一般优先用分号因为它对前置命令的成功与否没有要求也不依赖管道输出信息不容易丢。如果分号被过滤了再考虑、|这些替代。2. CTFHub技能树RCE命令注入的题目地图与通关策略CTFHub这类平台的技能树设计通常有明确的递进逻辑先让你用一个最简单的姿势打通关再逐步增加过滤条件逼着你学习各种绕过手段。RCE命令注入这一节也不例外整体是一条“由简到难、逐层加过滤”的主线。2.1 题目的递进逻辑从我刷题的经验来看命令注入子模块通常会安排这样一个顺序无过滤命令注入直接拼;ls就能看到目录再cat flag就出答案主要目的是让你把基本流程跑通过滤cat类命令cat关键字被过滤需要找替代命令或者拼接技巧过滤空格空格被过滤需要借助${IFS}等特殊变量绕过过滤目录分隔符/被过滤需要切换路径思考方式综合过滤练习多个关键字同时过滤组合前面的技巧无回显/盲注类输出被完全截断只能靠延迟或DNS请求判断命令是否执行每一关对应的是一个过滤维度刷完这个模块相当于把“命令注入的绕过武器库”完整过了一遍。2.2 每一关对应的能力点关卡类型考察的核心能力关键绕过思路无过滤最基本的注入点探测分号、管道符、and/or逻辑判断过滤catLinux命令替代方案tac、more、less、nl、sed等过滤空格对shell字段分隔符的理解${IFS}、重定向符重写命令过滤目录分隔符路径切换与通配符运用cd、通配符、变量拼接综合过滤多个技巧的组合运用编码绕过、变量拼接、命令替换无回显盲打技术的判断思路延迟注入、DNS外带练习环境可自行搭建验证2.3 环境与工具准备刷题前的工具准备其实不需要太多浏览器加一个HackBar插件就够起步。HackBar的优势在于可以直接在浏览器里改GET/POST参数不用来回切Burp Suite。到了后面调试复杂payload时用curl反而更高效因为它能精确控制URL编码和特殊字符。我个人习惯的组合是HackBar/FoxyProxy快速改参数适合前期摸索Burp Suite重放和观察响应适合分析过滤点也能配合Intruder做关键字fuzz本地Linux终端验证命令本身是否正确比如${IFS}在bash里的解析效果不确定的时候本地敲一遍最靠谱话虽如此真正决定刷题效率的不是工具而是对命令本身的熟悉度。很多绕过姿势在本地Shell里一试便知不需要在平台上反复试错。3. 无过滤命令注入第一关的正确打开方式无过滤题目是整个模块的“开胃菜”但千万别因为简单就跳过。这一关的意义在于帮你建立一个标准的命令注入操作流程判断注入点、确认命令执行、查看flag、回显处理。这个流程在后面对抗过滤规则时会被反复使用。3.1 先探测注入点与回显假设题目是一个ping功能输入框提示你输入IP地址。正常输入127.0.0.1会看到4个ping包的结果这是默认业务逻辑。接下来用payload探测是否存在命令注入127.0.0.1;ls 127.0.0.1whoami 127.0.0.1|id如果页面出现了ls列出的文件列表或者whoami/id的输出说明命令注入成立。通过不同符号的回显情况你还能顺便判断后台拼接代码是怎么写的——比如生效而;不生效说明输入可能经过了某种处理。这一步是重点不要只测一个符号就完事。不同的过滤规则会让你误判“这题不能注入”实际上只是符号选错了。我当时刷题时就用;测不出来换成|马上就通了。3.2 从ls到cat的完整流程确认注入点后查看当前目录127.0.0.1;ls通常能看到flag.php、index.php这类文件。下一步就是读取flag。这里需要注意CTF题目的flag可能藏在当前目录下的flag、flag.txt文件flag.php文件访问时会被当PHP执行直接访问URL看不到源码但用cat命令能直接读出原始PHP代码上级目录或系统临时目录所以如果当前目录没有可以试试127.0.0.1;ls / 127.0.0.1;ls /flag 127.0.0.1;cat /flag_xxx找到flag文件后用cat读取127.0.0.1;cat flag.php这时页面会把flag.php的源码连同ping的输出一起显示出来里面就是flag{...}的答案。3.3 一个很容易踩的坑命令输出与HTML渲染很多新手第一次看到cat flag.php的结果会以为自己失败了因为页面上显示的是一大段PHP代码flag并不显眼。原因很简单flag.php里除了flag还有一个PHP标签结构而cat输出的是纯文本源码没有经过PHP解析会直接出现在响应里。比如flag.php的内容可能是?php $flag flag{test_flag_123}; ?页面显示时?php这些标签会被浏览器当HTML注释或文本处理但中间的flag字符串一定会显示出来。所以用cat读源码是没问题的方式。如果输出的内容里出现了大量空白、换行错乱多数情况下不是命令失败而是PHP标签被当作HTML解析了。这时候按CtrlU查看页面源码或者用curl直接看原始响应会清晰很多。4. 过滤绕过实战cat、空格和目录分隔符三场硬仗刷过无过滤的入门题之后真正的挑战才开始。平台会在后台把某些关键字直接替换为空字符串或拦截你需要做的事只剩一件找到一种方式在绕过过滤的前提下让shell仍然能识别并执行你想用的命令。4.1 核心思路绕过不是魔法是换一种表达先说一个总原则shell本身是“按字符拆词按特殊字符解释”的解析器过滤规则通常只针对一串固定字符串。只要你能让最终交给shell的字符串在不包含禁用关键字的情况下被解释成相同的命令就算绕过成功。因此绕过方式本质上都是同一类思路对命令字符串做变形让过滤正则匹配不到但shell能正确识别。4.2 过滤cat时的替代命令与拼接技巧当后台过滤cat时最简单的方案是换一个功能等价命令。Linux里能查看文件内容的命令远不止cat一个tac反序输出效果几乎一样more、less分页显示head、tail显示头部或尾部nl带行号输出sed流编辑sed -n 1,100p flag.php效果等同catod、xxd十六进制转储虽然格式不友好但能看到内容sort排序输出strings提取可打印字符串在CTFHub的命令注入题里最常用的替代就是tac因为tac flag.php在输出文本内容上几乎和cat flag.php没差别。如果所有常见查看命令都被过滤了或者你懒得一个个试还有两个更细的绕法变量拼接cat flag.php cat flag.php在bash里cat会被解析成字符串cat。因为单引号和双引号里的内容会被合并到同一单词里最终传给execve的命令名是cat。而过滤规则通常只匹配cat这个连续字符串cat不在匹配范围里。反斜杠转义c\at flag.php反斜杠在shell里表示转义下一个字符\a就是字母a本身。过滤规则匹配的是原始输入字符串c\at也没有连续出现cat所以能绕过。这两种方法放在命令注入里尤其好用因为payload一般通过URL传递只要对方没有二次解码或更严格的过滤直接传入就能生效。4.3 过滤空格时的IFS变量与重定向思路空格被过滤是更常见的难题。命令行的核心结构是“命令 参数”参数之间需要分隔符空格就是最自然的分隔符。但shell里可作分隔符的不止空格还有制表符和换行符而${IFS}这个变量恰好就代表这三个字符。所以常见的绕过是这样cat${IFS}flag.php${IFS}会被shell展开成空格、制表符和换行的集合在命令解析时充当字段分隔符。实际效果等同于cat flag.php。如果${IFS}也被过滤还有两个替代思路$IFS的简化写法cat$IFS$9flag.php$IFS后面跟$9是为了把IFS和后面的文件名隔开。如果不加$9$IFSflag会被解析成变量名IFSflag因为shell里变量名以字母开头时后面连续的数字和字母都属于变量名的一部分。重定向符替代空格catflag.php是输入重定向符catflag.php的意思是“把flag.php作为cat的输入”效果等同于cat flag.php。这里根本不需要空格因为自身就是命令和文件名之间的分隔。花括号展开{cat,flag.php}在bash里花括号展开{a,b}会展开为用空格分隔的两个参数所以{cat,flag.php}等于cat flag.php。缺点是花括号展开对逗号两侧内容有限制不能有空格但简单的命令加文件名是可以用的。4.4 目录分隔符受限时的路径切换思路如果/被过滤你没法直接写cat /flag这种绝对路径。这时需要换个思路不是一定要用绝对路径。如果flag文件就在当前目录直接cat flag就行根本不需要斜杠。但如果flag在别处可以用cd命令先切目录cd /;ls等等/被过滤了连cd都写不了。再想一层cd不跟参数时默认回到$HOME目录但这个路径往往没有flag。更实用的思路是利用通配符和相对路径。Linux里*.php可以匹配任意以.php结尾的文件./flag里的.代表当前目录。如果题目环境下/确实被过滤可以尝试cat flag.php cat ./*.php但如果flag在根目录下的/flag这种位置没有斜杠确实很难处理。这时候可以依赖环境变量比如$PATH包含的路径通常以/开头但复杂场景下不一定可用。在CTFHub这套题目里目录分隔符过滤通常结合的是“相对路径通配符”就能解决如果配合空格过滤还要叠加${IFS}一题多滤的场景在综合练习题里很常见。5. 综合过滤与组合拳把零散技巧连成思路单点过滤练完之后平台的综合过滤题目会把cat、空格、目录分隔符等多个关键字同时卡住。这种题能筛掉一大批停留在一招一式的玩家因为单一技巧已经不够用必须把多个绕过方式组合成一条完整链路。5.1 先确认过滤了哪些字符综合过滤题的第一步不是猜而是探测。通过逐个尝试输入不同字符观察回显或者用一个比较长的payload观察哪一部分被“吃掉”了可以快速确定过滤名单。举个例子如果输入/;ls但输出里只剩下了ping的响应没有执行ls说明;或者/很可能被拦截。再输入;ls如果ls的输出出现了说明;没问题有问题的可能是/。继续用二分法缩小范围这种方法效率很高。有的题目会直接在你提交的payload里显示“检测到攻击字符”之类的提示并按过滤规则返回错误信息那么过滤名单就一目了然了。但更多的题目不会给你反馈只能靠行为判断。5.2 一条可复用的综合绕过payload构建公式当多个字符被过滤构建payload的有效路径是先写出目标命令的标准形式→替换被过滤的命令名→替换被过滤的分隔符→替换被过滤的路径符→逐段验证。比如目标命令是cat /flag假设cat和空格都被过滤标准形式cat /flag替换cat为tactac /flag替换空格为${IFS}tac${IFS}/flag如果/也被过滤考虑用cd切换目录或通配符tac ./*flag*假设当前目录可到达目标文件组合起来URL里的payload可能是;tac${IFS}./*flag*如果还有更多过滤还要在前面叠加变量拼接、反斜杠等方法。这里有个实操技巧在本地Shell里验证通配符和IFS展开后的真实命令。比如你怀疑通配符展开结果不对可以先在自己电脑上跑一下echo ./*flag*看看输出是不是你想要的路径。肉眼观察展开结果能省很多试错时间。5.3 无回显场景下的盲打思路刷到模块末段时有些题目会把回显完全切断页面只显示“命令已执行”或直接空白。这种题不能直接看到命令输出需要转换思路把“能不能看到结果”变成“命令有没有执行”。命令注入盲打的三种典型手段延迟注入利用sleep命令制造时间差。;sleep 5如果页面等5秒才返回说明命令确实被执行了。延迟时间的长短还能作为条件判断的依据比如用;sleep $(if [ -f /flag ];then echo 5;else echo 1;fi)这种方式做布尔盲注。逻辑判断输出差异让命令执行结果影响页面内容。比如输入;ls /tmp如果后台代码把命令输出渲染进页面即使没有明文回显也可能通过页面元素的变化判断结果。DNS外带在公网搭一个可控的DNS记录点这类做法在真实渗透中常用于绕过出网限制但在CTFHub这类商业平台上通常建议优先用延时和回显差异完成判断更简洁高效。对CTFHub这类平台的练习题而言盲注题目设计得一般比较基础延时注入基本够用。我刷题时最常用的就是sleep 5和ping -c 3 127.0.0.1这种“让时间说话”的方式既好写又不会触发额外限制。6. 刷题过程中的经验沉淀与日常排错命令注入题目刷多了以后我最大的体会是技巧背得再多不如自己踩一次坑记得牢。下面这几个经验是我在CTFHub技能树上反复吃过亏后总结出来的值得拿出来单独说一说。6.1 不确定过滤规则时用二分fuzz代替瞎猜很多人遇到过滤题就直接去找“万能payload”其实最高效的方法是先摸清过滤名单。我最常用的方式是先用Burp的Intruder跑一个常见字符集合;、|、、/、 、cat、flag、*、?、$、{、}、、。对每个字符单独提交一次请求观察哪些字符导致返回异常或没有执行命令过滤规则就出来了。整个过程五分钟不到比从网上找几百字的payload经验贴靠谱得多。6.2 善用本地Shell预验证别在平台上无限试错命令注入的payload是一长串字符串中间牵涉到shell解析、变量展开、通配符替换等多层逻辑。很多payload看起来没问题但实际在bash里执行时因为一个引号没闭合就完全失效。我的习惯是先把payload复制到本地终端的bash里跑一遍看真实展开和输出是什么。这样既能验证命令本身正确性也能发现变量名粘连这类细节问题。另外在本地测试时还能直接用set -x看shell的调试输出看清每一步是怎么解析的。6.3 Windows与Linux的命令差异一开始就要意识到CTFHub的题跑在Linux容器里所以注入用的是ls、cat、tac、${IFS}这些Linux shell自带的东西。但如果哪天你刷到Windows靶机环境的题命令就完全不一样了dir替代lstype替代cat分隔符虽然还有;和但没有${IFS}这么方便。做题前先判断目标操作系统是基本功。判断方式很简单看正常ping输出的TTL时间、看报错信息里的路径风格、看目录列表内容Linux几乎必然有/etc/passwd这类文件Windows则是C:\盘符风格。CTF平台里虽然以Linux为主但建立这个意识能帮你避免很多无效尝试。6.4 一个清单命令注入绕过的常用payload归纳最后整理一份我实际使用频率最高的payload清单覆盖常见过滤场景方便做题时直接查目标payload例子基础注入验证;whoami、|id、pwd当前目录文件枚举;ls、|ls -la、;find . -name flag*读取文件;cat flag.php、;tac flag.php过滤cat;cat flag.php、;c\at flag.php过滤空格;cat${IFS}flag.php、;catflag.php、;{cat,flag.php}过滤目录分隔符;cd ..;ls、;cat ./*flag*多字符过滤;tac${IFS}./*f*、;head${IFS}-n${IFS}5${IFS}index.php无回显探测;sleep 5、;ping -c 3 127.0.0.1这些payload都不是银弹要根据题目反馈调整但覆盖CTFHub命令注入这一节点到线到面的练习基本够了。刷完这一节内容回头看CTFHub技能树的RCE命令注入模块它给我的感觉更像一个“shell命令熟练度训练场”。每一道题都在逼你想清楚shell到底是怎么拆词的、变量是怎么展开的、通配符是怎么匹配的。这些知识在校招面试、真实渗透测试、甚至是日常写自动化脚本时都会用到。把无过滤到综合过滤这条线完整走一遍之后再去碰其他平台的命令注入题你会发现套路都大同小异难度差异只在于过滤条件的组合方式。最后分享一个小技巧刷这类题时把每次成功的payload记在一个本地笔记里标注清楚题目过滤了什么、你的绕过依据是什么。积累十几题以后再回看你自己就是命令注入的活字典。
返回列表