沉铝汤的破站

IS LIFE ALWAYS THIS HARD, OR IS IT JUST WHEN YOU'RE A KID

通过Phar文件进行的反序列化攻击

0x00 前言


最近总是写JS的东西,快写吐了,所以这次写点PHP。其实是之前学过的,但是自己早就忘得差不多了,所以就写一下;虽然前几天写过的东西,现在也忘得差不多了,但是写了总是有机会看的

0x01 Phar文件


在软件中,PHAR文件是一种打包格式,通过将许多PHP代码文件和其他资源捆绑到一个归档文件中来实现应用程序和库的分发。 PHAR文件可以是三种格式之一:tar和ZIP,以及自定义的PHAR格式。无论使用何种格式,所有PHAR文件都使用.phar作为文件扩展名。 – 维基百科

可以看到phar文件是一种类似于Jar的文件,但根据官方文档的介绍,Tar和Zip格式都需要安装额外的拓展,所以这里就主要介绍第三种Phar格式。

格式

image-20210320220728332

可以看到Phar文件由四部分组成,下文将对这四部分进行详细的阐述。

stub

stub是一个php文件,一个最小的形式如下:

<?php __HALT_COMPILER();

你也可以自己随便加点什么(include之类的)在__HALT_COMPILER的前面, 但是__HALT_COMPILER();是不能省略的;并且这里省略了闭合标签,不过最好带上。

a manifest describing the contents

image-20210323195859510

可以看到这里存放的是数据的各种信息,并且Meta-data以序列化的形式储存。

the file contents

顾名思义,存放的是文件的内容

signature

签名,是可选的,“The signature formats supported at this time are MD5, SHA1, SHA256, SHA512, and OPENSSL”,这是目前所支持的几种加密算法。

0x02 创建一个Phar文件


要创建一个Phar文件,首先要修改php.ini种的phar.readonlyoff,然后我们可以运行以下代码,来在当前文件夹生成一个phar文件。

<?php
    class myTest{
        var $bar;

        function __construct($foo)
        {
            $this->bar=$foo;
        }
    }

    $phar = new Phar("myPhar.phar");
    $phar->startBuffering();
    $phar->setStub("<?foobar __HALT_COMPILER(); ?>");//stub
    $my_meta = new myTest('chenlvtang');
    $phar->setMetadata($my_meta);
    $phar->addFromString("foobar.txt", 'this is the text content');//添加要压缩的文件,后面的参数是文件的内容
    $phar->stopBuffering();

生成的文件内容具体如下:

image-20210328203629554

可以看到,确实是以序列化的形式存入了我们的meta。既然phar文件是类似于jar的文件打包,这里进行了序列化,后面在进行phar文件操作时,应该也有相应的反序列化操作,而这就是我们的利用点了。经过师傅们的测试,大部分(或者是全部?可自行看师傅们的文章)的php文件操作都会进行phar文件的meta反序列化。

0x03 利用点


可以把phar文件成功上传

多亏了上文提到的stub,php进行phar文件识别的时候,都是通过,这个stub进行,而对文件后缀和stub之前的数据没什么要求,所以我们可以利用这个进行文件类型的伪造。

$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); 

然后我们还可以把phar文件改为gif,来绕过文件上传的限制。

可控的文件操作函数参数

上文说到,很多文件操作函数都会进行meta的反序列化,所以这就大大提高了我们的攻击面,此时,我们不需要unserialize函数便可以进行反序列化攻击。但我们需要一个可控的文件操作函数的参数来供我们读取文件。

有魔法函数作为跳板

正如以往普通的反序列化攻击一样,既然任然是反序列化攻击,就离不开以魔法函数作为跳板来进行攻击。

关键字没有被过滤

因为phar文件的读取,要用到phar://伪协议的读取,所以这些相关的关键字不能被过滤

具体攻击实例,可以自己做题感受,或者看参考文章(以下三篇都很好),我是个懒狗,只是写下笔记

0x04 参考文章


初探phar:// - 先知社区 (aliyun.com)

利用 phar 拓展 php 反序列化漏洞攻击面 (seebug.org)

重新认识反序列化-Phar (lmxspace.com)