phar反序列化解析及phar文件生成
[TOC]
Phar相关基础
Phar是将php文件打包而成的一种压缩文档,类似于Java中的jar包。它有一个特性就是phar文件会以序列化的形式储存用户自定义的meta-data
。以扩展反序列化漏洞的攻击面,配合phar://
协议使用。
Phar是PHP的归档格式,类似Java的JAR或是.NET的ZIP。Phar文件可以在不需要解压的情况下在PHP中运行。Phar文件可以用于分发PHP代码,就像你分发Python代码时使用的是.pyc或.whl文件。
Phar伪协议是PHP的一个特性,它允许直接从Phar归档中读取文件,而不需要将Phar文件解压。这样可以直接从Phar文件运行PHP脚本,而无需在服务器上物理地提取文件。
Phar文件结构
a stub
是一个文件标志,格式为 :xxx
。manifest
是被压缩的文件的属性等放在这里,这部分是以序列化存储的,是主要的攻击点。contents
是被压缩的内容。signature
签名,放在文件末尾。
就是这个文件由四部分组成,每种文件都是有它独特的一种文件格式的,有首有尾。而__HALT_COMPILER();
就是相当于图片中的文件头的功能,没有它,图片无法解析,同样的,没有文件头,php识别不出来它是phar文件,也就无法起作用。
生成phar文件
这里测试一下~
前提:生成phar文件需要修改php.ini中的配置,将phar.readonly
设置为Off
1 | <?php |
生成phar文件命令:php -d phar.readonly=0 脚本.php
生成的phar文件,打开该文件可以看到文件头是``以及中间的部分内容是序列化的形式存在于这个文件中。
该方法在文件系统函数(file_exists()
、is_dir()
等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()
直接进行反序列化操作。
https://paper.seebug.org/680/得知:有序列化数据必然会有反序列化操作,php一大部分的文件系统函数在通过phar://
伪协议解析phar文件时,都会将meta-data
进行反序列化,测试后受影响的函数如下:(仿照大佬的图)
这里使用file_get_contents()
函数来进行实验。
1 | <?php |
__HALT_COMPILER();
必须大写,小写不会被识别出来。导致无法进行反序列化操作。
因为考虑到在上传的时候,可能只会允许上传图片(jpg/png/gif
),上传时将test.phar修改文件扩展名为jpg也可以进行反序列化,不会影响解析。
如果对文件头有识别的,也可以使用GIF文件头GIF89a
来绕过检测,具体操作与文件上传部分细节类似,不再赘述。