0x00 前言
最近总是写JS的东西,快写吐了,所以这次写点PHP。其实是之前学过的,但是自己早就忘得差不多了,所以就写一下;虽然前几天写过的东西,现在也忘得差不多了,但是写了总是有机会看的。
0x01 Phar文件
在软件中,PHAR文件是一种打包格式,通过将许多PHP代码文件和其他资源捆绑到一个归档文件中来实现应用程序和库的分发。 PHAR文件可以是三种格式之一:tar和ZIP,以及自定义的PHAR格式。无论使用何种格式,所有PHAR文件都使用.phar作为文件扩展名。 – 维基百科
可以看到phar文件是一种类似于Jar的文件,但根据官方文档的介绍,Tar和Zip格式都需要安装额外的拓展,所以这里就主要介绍第三种Phar格式。
格式
可以看到Phar文件由四部分组成,下文将对这四部分进行详细的阐述。
stub
stub是一个php文件,一个最小的形式如下:
<?php __HALT_COMPILER();
你也可以自己随便加点什么(include之类的)在__HALT_COMPILER
的前面, 但是__HALT_COMPILER();
是不能省略的;并且这里省略了闭合标签,不过最好带上。
a manifest describing the contents
可以看到这里存放的是数据的各种信息,并且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.readonly
为off
,然后我们可以运行以下代码,来在当前文件夹生成一个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();
生成的文件内容具体如下:
可以看到,确实是以序列化的形式存入了我们的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://
伪协议的读取,所以这些相关的关键字不能被过滤
具体攻击实例,可以自己做题感受,或者看参考文章(以下三篇都很好),我是个懒狗,只是写下笔记