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

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    4

    主题

    7

    帖子

    118

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

    i春秋签约作者春秋文阁

    发表于 2021-3-12 18:20:38 417835
    本帖最后由 xiaoleung 于 2021-3-18 08:10 编辑

    【代码审计】某CMS代码审计一次疯狂的Bypass

    在看这个Thinkphp5.1写cms时候发现在application/task/controller/UtilController.php处存在一个file_put_contents.

    WX20210312-090026@2x

    可以很明显地看到这个方法是在public在控制器里面可以直接通过路由来访问到。同时$img是可控的。

    WX20210312-090353@2x

    咱们从正常的思路来看咱们先看一下$img可控能不能完全可控或者能不能部分可控如控制文件后缀。回到代码第32行,可以看到该方法对咱们传入的$img变量进行分割,也就是通过.来分割为数组并赋值给$path,若$path的元素数量正好为三的时候就进入第一个分支,否则将会重定向到一张系统系统默认的图片。

    WX20210312-090026@2x

    也就是说咱们传入的$img必须且有三个点(.)组成。否则将会被重定向,这个正则可以暂时不看对后续有影响在看。跳到代码第42行,调用了crop_image个函数,并且将path[0]拼接path[2]$args

    WX20210312-090026@2x

    找到这个函数原型,可以看到实例化了ImageCrop类并调用了crop方法。咱们直接跳到ImageCrop来看。可以看到,咱们传入的参数被赋值给属性file,并在crop中赋值给$img变量同时,将$img作为getImgData参数传入,咱们继续跟进。

    WX20210312-090026@2x

    可以看到getImgData会对传入的参数进行匹配看是否存在http://若存在则调用file_get_contents来读取远程文件。那么问题来了,这个$img咱么能不能直接控制为咱们服务器地址呢。但是前面又限制死了只能有三个(.)点这该怎么办呢?

    WX20210312-090026@2x

    其实这里是可以Bypass的。在linux情况下,file_get_content是可以识别十六进制或者八进制的IP地址的。使用16进制不就没有点了吗。那么$img就可以完全可控。那么咱么在自己服务器下存放一个shell.php,将服务器IP转换为16进制注意要加上0x。IP转换脚本如下:

    <?php
    $ip = '127.0.0.1';
    $ip = explode('.',$ip);
    $r = ($ip[0] << 24) | ($ip[1] << 16) | ($ip[2] << 8) | $ip[3] ;
    if($r < 0) {
        $r += 4294967296;
    }
    echo "十进制:";
    echo $r;
    echo "八进制:";
    echo decoct($r);
    echo "十六进制:";
    echo dechex($r);
    ?>

    可以看到存放在远程服务器的内容<?php phpinfo();?>被读取出来,并且当做参数传入给getimagesize

    WX20210312-101624@2x

    getimagesize要怎么才能bypass呢。咱们可以使用图片马,进行绕过。咱们在远程shell.php写一个远程的图片马地址。但是传入file_put_contnets时候出问题了。

    WX20210312-103025@2x

    file_put_contents在遇到//指都会将其当做wrapper处理,在windows下可以使用NTFS Stream技巧file_put_contents('php://filter/write=convert.base64-decode/resource=C:/path/to/testphp::$INDEX_ALLOCATION', '');创建文件夹C:/path/to/testphp但是这里伪协议.已经写死了无法使用.难道这条路已经封死了吗?回过头来咱么前面getimagesize的参数咱么是完全可控的。

    在回想一下咱么这个CMS是Thinkphp5.1开发的,而getimagesize是可以触发Phar反序列化的。那么现在思路再次转变,我们能否远程控制一个文件写phar文件的地址,在file_get_contents读取远程文件,将这个文件的内容传给getimagesize而这个文件内容确实我再后台上传的phar文件的地址,进而触发thinkphp的反序列化。

    WX20210312-090026@2x

    那么传入phar伪协议进行反序列化,可以看到在最后成功触发反序列化。

    WX20210312-104940@2x

    WX20210312-105115@2x

    EXP:

    个人博客:https://www.plasf.cn
    表哥tql,yyds
    使用道具 举报 回复
    发表于 2021-3-16 11:30:59
    表哥yyds
    使用道具 举报 回复
    发表于 2021-3-17 16:40:11

    表哥yyds
    使用道具 举报 回复
    提升空间很大。
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册