PHP反序列化常见的是使用unserilize()进行反序列化,除此之外还有其它的反序列化方法,不需要用到unserilize()。就是用到phar反序列化。
Phar
phar文件
Phar是将php文件打包而成的一种压缩文档,类似于Java中的jar包。它有一个特性就是phar文件会以序列化的形式储存用户自定义的meta-data。以扩展反序列化漏洞的攻击面,配合phar://协议使用。
phar文件格式
- a stub:phar文件标志,格式为xxx<?php xxx;__HALT_COMPILER();?>,前面内不限,但多以__HALT_COMPILER()来结尾否则phar扩展将无法识别这个文件为phar文件,也就是说如果我们留下这个标志位,构进一个图片或者其他文件,那么可以绕过上传限制。并用被 phar 这函数利用
-  manifest是被压缩的文件的属性等放在这里,这部分是以序列化存储的,是主要的攻击点。
-  contents是被压缩的内容。
-  signature签名,放在文件末尾。
就是这个文件由四部分组成,每种文件都是有它独特的一种文件格式的,有首有尾。而__HALT_COMPILER();就是相当于图片中的文件头的功能,没有它,图片无法解析,同样的,没有文件头,php识别不出来它是phar文件,也就无法起作用。
为什么能进行反序列化?
phar文件本质上是一种压缩文件,会以序列化的形式存储用户自定义的meta-data。当受影响的文件操作函数调用phar文件时,会自动反序列化meta-data内的内容。(漏洞利用点)
phar://
phar://就是一个类似 file://协议的流包装器,它的作用可以使得多个文件归档到统一文件,并且在不经过解压的情况下被php所访问,并且执行。
利用条件
-  phar文件能够上传至服务器 
-  要有可利用的魔术方法 
-  文件操作函数的参数可控,且:、 /、phar等特殊字符没有被过滤
demo
<?php
//构造了一个类
    class TestObject {
    }
    @unlink("phar.phar");
    //实例化类
    $phar = new Phar("phar.phar"); //后缀名必须为phar,会生成一个phar.phar文件
    $phar->startBuffering();//开始缓冲,往里面写东西
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub,是phar文件的标志
    //新实例化一个类
    $o = new TestObject();
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件
所以先找到php.ini文件
通过
<?
phpinfo();
?> 找到php.ini,设置phar.readonly = Off
找到php.ini,设置phar.readonly = Off
并且!!!!
前面的分号要删掉!!!!
我一开始就是没删然后一直无法生成phar文件

好的,关掉后,访问一下127.0.0.1/phar.php
生成了phar文件

 用010打开
可以看到meta_data是以序列化的形式存储的
php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化,测试后受影响的函数如下

新建一个b.php
<?php 
    class TestObject {
        public function __destruct() {
            echo 'Destruct called';
        }
    }
    $filename = 'phar://phar.phar/test.txt';
    file_get_contents($filename); 
?>
发现析构方法被调用
这样就可以在不调用unserialize()的情况下进行反序列化操作




















