利用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,得图

 

 

 

执行成功。

防御

  1.  在文件系统函数的参数可控时,对参数进行严格的过滤。
  2.  严格检查上传文件的内容,而不是只检查文件头。
  3. 在条件允许的情况下禁用可执行系统命令、代码的危险函数。