来源信息
- BUUCTF
- 题目名称:Dropbox
- 类型:Web
- 难度:★★★★☆
- 题目地址:链接
- 题目内容:
解题过程
打开链接就是登陆页面,第一反应就是sql注入,但是试了一会没有成功,看到了**注册**按钮,直接注册登陆。
注册用户,完成登陆,发现后台有登陆按钮,试试文件上传,看能不能传个🐎。
在上传图片的时候发现会调用upload.php,下载的时候会调用download.php。同时成功上传文件之后会发现下载的路径都是#,我们无法获取上传文件的绝对路径。
考虑修改文件名是否能下载到上层目录的网站源码,分别测试../index.php和../../index.php后下载到index.php的内容,同理下载delete.php,upload.php,download.php,再对剩下的网站文件进行下载后代码审计。
在login.php中,发现了上传文件之后的绝对路径。
但是再次尝试了传🐎,还是无用。到此可以确定不是文件上传了。
看到了提示说是phar反序列化漏洞。
phar
PHAR (“Php ARchive”) 是PHP里类似于JAR的一种打包文件。如果你使用的是 PHP 5.3 或更高版本,那么Phar后缀文件是默认开启支持的,你不需要任何其他的安装就可以使用它。**phar格式归档文件可以直接执行**,它的产生依赖于Phar扩展,由自己编写的php脚本产生
详情可以查看这篇文PHP开发常识:什么是Phar?
创建phar文件首先在php.ini中修改phar.readonly这个选项,将其修改为0:
1 | phar.readonly = 0 |
phar结构
stub
phar 文件标识,格式为 xxx;
manifest
压缩文件的属性等信息,以序列化存储;
contents
压缩文件的内容;
signature
签名,放在文件末尾;
这里有两个关键点:
- 是文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制;
- 是反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化,而这样的文件操作函数有很多。
经过代码审计发现delete.php可以利用.$file->detele();再看class.php里的file类的delete方法:
delete.php
1 | if (strlen($filename) < 40 && $file->open($filename)) { |
class.php
1 | public function detele() { |
unlink可以反序列化,而且delete.php文件include了class.php,也就可以利用FileList类的__destruct()方法,满足攻击的三个条件:
- phar文件要能够上传到服务器端。
- 要有可用的魔术方法作为“跳板”。
- 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。
然后分析class.php类的结构关系,构造脚本生成phar文件:
payload如下
1 | <?php |
先调用了User类,User类destruct的时候,调用了db.close方法,而这里的db是Filelist类的对象,所以调用了Filelist类的close()方法,但是Filelist又不存在这个方法,所以调用了call方法,
call方法会调用file的close方法,也就是/flag.txt调用close方法,也就是包含这个文件。最后,Filelist类调用destruct方法,打印出函数执行结果,也就是根目录下flag.txt文件的内容
_call方法
1 | 为了避免当调用的方法不存在时产生错误,而意外的导致程序中止,可以使用 __call() 方法来避免。 |
之后将生成的phar文件后缀改为jpg上传。
接下来再点击删除文件,将文件名改为phar://phar.jpg即可获得flag