phar反序列化漏洞
基本概念
phar (PHP Archive)
是PHP里类似于Java中jar的一种打包文件,用于归档。当PHP 版本>=5.3时默认开启支持PHAR文件的。
phar文件默认状态是只读,使用phar文件不需要任何的配置。
而phar://伪协议即PHP归档,用来解析phar文件内容。
phar文件结构
1、stub
一个供phar扩展用于识别的标志,格式为xxx<?php xxx; __HALT_COMPILER();?>
,前面内容不限,但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。
2、manifest
phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data
,这是上述攻击手法最核心的地方。
被压缩文件的内容。
4. [optional] a signature for verifying Phar integrity (phar file format only)
签名,放在文件末尾,格式如下:
测试
根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类来处理相关操作。
注意:要将php.ini
中的phar.readonly选项设置为Off,否则无法生成phar文件。
[Phar]
; http://php.net/phar.readonly
phar.readonly = Off
phar.php
<?php
class User{
var $name;
}
@unlink("phar.phar");
$phar = new Phar("phar.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");//设置stub
$o = new User();
$o->name = "Kobe";
$phar->setMetadata($o);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
运行之后生成phar.phar
用winhex打开
有序列化数据必然会有反序列化操作,php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data
进行反序列化,测试后受影响的函数如下:
来看一下php底层代码是如何处理的:
phar_parse.php
<?php
class User{
var $name;
function __destruct(){
echo $this->name;
}
}
$filename = 'phar://phar.phar/test.txt';
file_exists($filename);
?>
结果:
其他函数当然也是可行的:
<?php
class User{
//var $name;
function __destruct(){
echo "hello world";
}
}
$filename = 'phar://1.phar/test.txt';
file_get_contents($filename);
//......
?>
参考文章:
https://paper.seebug.org/680/
https://blog.csdn.net/SKI_12/article/details/85551194
下一篇: PHP常用转义字符函数
推荐阅读