最近在suctf的招新赛中遇到了这个比较新的知识点,记录一下,本文参考https://paper.seebug.org/680/

phar文件结构

stub

一个标志,格式为xxx<?php xxx; __HALT_COMPILER();?>,必须以__HALT_COMPILER();?>结尾

manifest

被压缩文件的权限,属性等信息都放在这部分。同时这部分会以序列化的形式存储用户自定义的meta-data,这里便是反序列化利用的关键。

contents

被压缩文件的内容

signature

文件的签名,在文件末尾

phar文件测试

自己 构建一个phar文件,这里需要修改php.ini中的配置,把php.ini 中的phar.readonly设置为Off,这里测试一个小demo。

<?php
class test
{
    private $message;
    
    public function __construct()
    {
        echo "被反序列化了";
    }
}
<?php
include "test.php";
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub, 增加gif文件头,伪造文件类型
$o = new test();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
在metadata.bin中可以很清楚的看到test的信息以序列化的方式存入O:4:"test":1:{s:13:" test message";N;}

有序列化肯定就有反序列化,这里可以利用一些文件读取函数来达到反序列化的目的:

include 'test.php';
$file_name='phar://phar.phar/test.txt';
file_get_contents($file_name);
//可以看到输出call destruct

php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化,这里给出知道创宇404实验室给出的测试结果

img

phar文件的伪装

系统识别phar文件是通过头部的 stub模块识别,与其的后缀无关,所以上传这个可以通过修改后缀和stub前面的文件头伪装来达到绕过上传的目的。

phar反序列化运用场景

需要可以操控文件操作函数,上面举出的系统file函数的参数可控

需要可以上传phar文件

需要有反序列化可以利用的魔术方法