用户
搜索
  • TA的每日心情
    慵懒
    2021-3-16 11:41
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    5

    主题

    8

    帖子

    144

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2018-11-4

    i春秋签约作者春秋文阁

    发表于 2021-8-6 16:27:12 01870
    本帖最后由 xiaoleung 于 2021-8-6 08:30 编辑

    [md]# 从一道CTF题学习无字母RCE的极限利用

    最近有培训过的学院发给我一道题目,虽然一开始就知道使用通配符来做,但由于对无参数RCE的细枝末节没有很好的理解和深入的学习,导致做题时间过长。也发现了之前学习的状态一直处于蜻蜓点水,并未有很细致的学习。在此记录一下如何对代码进行Fuzz分析以及文件上传和命令执行之间的利用Trick.

    题目源码

    <?php
    if(isset($_GET['evil'])){
        if(strlen($_GET['evil'])>25||preg_match("/[\w$=()<>'\"]/", $_GET['evil'])){
            die("danger!!");
        }
        @eval($_GET['evil']);
    }
    highlight_file(__FILE__);
    ?>

    题目分析

    单个字符的正则FUZZ技巧

    题目代码非常简单,题目规定了传入的参数长度不得大于25并且存在一个正则表达式来过滤咱们的传入参数,对于正则表达式如果我们没有能够很好的学习了理解那么很难快速得知过滤了那些内容,也很难知道有哪些字符能够用。这就需要引入咱们的fuzz思想,既然看不懂,倒不如我们采用“黑盒”的思想来爆破这个正则,由于过滤的都是单个字符,并没有单词的组合所以我们可以直接爆破0-255的AIISC码,这样我们就能快速得知正则过滤了什么内容,我们可以写个脚本进行FUZZ:

    <?php
    for ($ascii = 0; $ascii < 256; $ascii++) {
        if (!preg_match("/[\w$=()<>'\"]/", chr($ascii))) {
            echo (chr($ascii));
        }
    }
    ?>
    //运行结果
    // !#%&*+,-./:;?@[\]^`{|}~��������������������������������������������������������������������������������������������������������������������������������[Finished in 0.3s]
    

    这样我们就能够得出上面正则我们能够正常使用的只有!#%&*+,-./:;?@[]^``{|}~,取反、异或、或运算、位运算都是通过动态拼接函数来实现执行任意代码的.这里已经过滤掉了括弧基本上无法实现上述典型的无字符RCE。这里还不能使用可见的字符,使用require来包含flag也是不可能实现的。这里还能用的就是反引号了。我们知道反引号能执行shell,它本质就是调用shell_exec,这个函数执行的shell是不会有回显的,就算cat flag也不会显示出来。那么要怎么才能RCE呢?

    有趣的Linux通配符

    P神的《无字母数字webshell之提高篇》 ,可以 知道这么两个有趣的shell知识点:

    • shell下可以利用.来执行任意脚本
    • Linux文件名支持用glob通配符代替:

    ​                但是我们用通配符来执行这个SB脚本的时候却会报错:

    ​                这说明我们能够匹配上??的文件或者目录很多,我们直接列出来看看

    ​                这说明两个字符的文件还是有很多的,我们必须匹配上我们唯一的文件才有可能直线我们想要直接的代码。

    • 我们都认识*?这两个通配符,其实在glob语法里面还支持类似于正则表达式的语法。例如[^S]就是排除掉S字母,我们可以排除掉S字母然后再列目录看看,就会发现SB这个文件被排除在外。

    • 但是这里我们的要求是不能有字母数字,我们刚才说了glob是支持类似正则表达式的用法,如[0-9],是支持的,那么我们在aiisc表中找出两个包含大写字母之间的字符就行了这样我们就能够成功获取到SB文件。

    • 从AIISC表中我们可以知道,@-[是在大写字母之间的,那么我构造[@-[]?是不是能够匹配到SB了呢?答案是肯定的。

    PHP文件上传和命令执行的组合拳

    在PHP中上传文件,只需在表单中加入*enctype="multipart/form-data",*不需要编写额外的代码,文件就能上传到服务器缓冲区中。PHP在接受上传表单的文件流后会将文件保存到/tmp文件夹中,而这个文件类似于这样的命名方式:/tmp/phpXXXXXX.

    7

    和上面讨论的一样,这样匹配出来的回匹配到很多文件,我们可以看到后面两位或者一位可能是大写这样我们就可以用.+/???/????????[@-[]来匹配执行文件。那么我们就可以构造一个上传表单同时传入该参数来进行RCE如下:

    最终文件写入到网站根目录的SB文件,可以看到ls命令的执行结果已经写入该文件:

    9

    总结

    通过上述案例我们可以知道即便在条件如此苛刻的情况下,仍然可以通过PHP文件上传和Linux通配符来执行任意远程命令。命令执行和文件上传两个看似关系不大的利用条件,在作为组合拳使用下却有如此神奇的效果。因此在实际解决安全问题过程中,我们不能仅仅关注一个漏洞能够引发的典型安全问题,还需要结合已有的知识储备创新地发掘漏洞利用的极限。同时我们要善于利用黑盒方法,来协助白盒的审计工作,上面编写脚本来FUZZ正则就是很好的例子。

    [/md]
    个人博客:https://www.plasf.cn
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册