介绍
与普通反序列化利用有什么区别?
在 PHP 下利用反序列化漏洞的时候,通常走这样的一条路线:
反序列化点 => 可利用函数 => 构造反序列化 POP 链
但在 2018 年的 Black Hat 上,安全研究员 Sam Thomas 指出了一条新思路:
在文件系统函数 ( file_get_contents 、 unlink 等)参数可控的情况下,配合 phar:// 伪协议 ,可以不依赖反序列化函数 unserialize()
直接进行反序列化的操作。
phar 是什么?
官方文档 给出了详细的解释。概括来说,有如下特点:
Phar 存档在概念上类似于 Java JAR 存档,但是根据 PHP 应用程序的需求和灵活性进行了定制。
Phar 可以把多个文件归档到同一个文件中,不经过解压就能被 PHP 访问并执行。
Meta-data can be any PHP variable that can be serialized.
最后一点尤其重要,有序列化就有反序列。
This meta-data is unserialized when a Phar archive is first accessed by any(!) file operation.
This opens the door to unserialization attacks whenever a file operation occurs on a path whose
beginning is controlled by an attacker.
再看一下 phar 的文件结构。
The phar file format is literally laid out as stub / manifest / contents / signature, and stores the crucial information of what is included in the phar archive in its manifest.
也就是说分为四个部分:
stub
Phar::mapPhar();
include 'phar://myphar.phar/index.php';
__HALT_COMPILER();可以当做一个标志来理解,正如上面写的这样,必须以
_HALT_COMPILER();
结尾。所以在设置stub
时,也要有__HALT_COMPILER();
,这里的设置就相当灵活了,你可以随便插数据 。比如:xxx;__HALT_COMPILER();
// 需要提醒的是 <?php ?> 并不是必须的,以 ; 隔开即可,可避开检测 <? 的情况manifest
phar 文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的 meta-data,这是上述攻击手法最核心的地方。
contents:被压缩文件的内容。
signature:签名,放在文件末尾。
Demo
用个小 Demo 来测试一下反序列化(注意要将 php.ini 中的 phar.readonly 选项设置为 0,否则无法生成)
// phar_gen.php |
可以看到 meta-data 在 phar 中的存在形式
// dese_phar.php |
可以看到析构函数被成功调用
seaii 师傅给出了函数列表
应用场景
这里不得不提 orange 在 hitcon 2017 出的 baby^h-master-php-2017
,本题可以通过 i 春秋平台复现。
|
另外还有:
护网杯 easy laravel
code-breaking lumenserial
相关绕过
TODO
php://filter/resource=phar://phar.phar |
原理分析
来看一下源码 php-src/ext/phar/phar.c:618,调用了 php_var_unserialize
。
if (!php_var_unserialize(metadata, &p, p + zip_metadata_len, &var_hash)) { |
太忙了,有时间深入分析一下。