利用phar实行php反序列化命令执行(测试环境复现)
前言
一般说到反序列化漏洞,第一反应都是unserialize()函数。然而安全研究员Sam Thomas分享了议题”It’s a PHP unserialization vulnerability Jim, but not as we know it”,利用phar伪协议会将用户自定义的meta-data序列化的形式存储这一特性,扩展php反序列化的攻击面。
phar介绍
简单来说phar就是php压缩文档。它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file:// php://等类似,也是一种流包装器。
phar结构由 4 部分组成
stub phar 文件标识,格式为xxx<?php xxx; __HALT_COMPILER();?>;
manifest 压缩文件的属性等信息,以序列化存储;
contents 压缩文件的内容;
signature 签名,放在文件末尾;
这里有两个关键点,一是文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制;二是反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化,而这样的文件操作函数有很多。
以上内容摘自:由 PHPGGC 理解 PHP 反序列化漏洞 。
https://kylingit.com/blog/%E7%94%B1phpggc%E7%90%86%E8%A7%A3php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
复现过程
Phar文件生成
根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类。
phar_gen.php
Evil.class.php
直接运行的时候会报错
原因是:需要将php.ini中的phar.readonly设置成off。(我在这浪费了很多时间,配置文件一定要改完后保存,然后重启服务器)
执行之后生成一个vul.phar,用二进制编辑器打开,如图所示
由图可以发现,meta-data已经以序列化的形式存在phar文件中。
说明一下:其实就是把要执行的命令序列化保存在phar的压缩文件里
反序列化
对应序列化,肯定存在着反序列化的操作。php
文件系统中很大一部分的函数在通过phar://
解析时,存在着对meta-data
反序列化的操作。
测试环境如下: test.php
访问test.php, http://127.0.0.1/test.php?url=phar://vul.phar,得图
执行成功。
防御
- 在文件系统函数的参数可控时,对参数进行严格的过滤。
- 严格检查上传文件的内容,而不是只检查文件头。
- 在条件允许的情况下禁用可执行系统命令、代码的危险函数。