[CISCN2019 华北赛区 Day1 Web1]Dropbox(phar反序列化)
我们打开页面,注册登录
我们发现可以上传文件
但只能上传图片
我们点击下载,进行抓包,发现filename这个参数可控,我们想到任意文件读取
由题目信息可知页面存在upload.php,delete.php,index,php
我们一个一个读取
1 | filename=../../index.php |
index.php
1 | <?php |
upload.php
1 | <?php |
delete.php
1 | <?php |
我们可以看到delete.php和upload.php都包含了class.php这个文件,我们把它也读取出来
1 | <?php |
我们注意到在class.php,有个close方法可以进行文件包含
1 | public function close() { |
我们找触发条件,在class.php中,有User类,其中__destruct()魔术方法,可以调用close()方法
1 | public function __destruct() { |
但如果直接调用,不会回显,需要用到FileList类中的__call()魔术方法,将close()执行得到的信息放入生成test.phar的脚本
由于这里没有unserialize函数进行反序列化,我们可以用phar协议进行反序列化
1 | <?php |
运行之后,我们可以发现在同级目录下生成了phar文件
在执行生成phar文件的脚本时候,如果无法正常执行,生成不了新的phar文件,需要修改php.ini中的配置。
在php.ini中,phar.readonly
默认选项为On,无法生成phar文件要将php.ini中的phar.readonly
选项设置为Off
我们进行上传,注意要修改文件后缀和type
由于class.php的delete方法中有unlink(),可以触发phar反序列化,我们点击删除抓包,用phar协议读取,得到flag
知识点
phar反序列化条件
有文件上传条件,可以上传phar文件
可利用函数
有如
unlink、file_get_contents、isdir、file_exists
等函数文件操作函数的参数可控:upload.php中filename、delete.php中filename可控
题目对
:
、/
、phar
等特殊字符没有过滤。
phar结构由 4 部分组成
stub
phar 文件标识,格式为 xxx;
manifest
压缩文件的属性等信息,以序列化存储;
contents
压缩文件的内容;
signature
签名,放在文件末尾;
这里有两个关键点:
一是文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制;
二是反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化,而这样的文件操作函数有很多。