PHP文件包含新思路:除了php://filter,别忘了phar://这个隐藏BOSS
PHP文件包含进阶:揭秘phar伪协议的隐藏攻击面
在PHP安全研究领域,文件包含漏洞一直是攻击者最青睐的攻击向量之一。大多数开发者对常见的php://filter伪协议有所了解,却往往忽视了phar://这个同样强大但鲜为人知的协议。本文将带您深入探索phar协议的工作原理、攻击手法以及防御策略,帮助您在安全测试和代码审计中占据先机。
1. PHP文件包含漏洞与伪协议家族
文件包含漏洞在PHP应用中屡见不鲜,它允许攻击者通过参数动态包含恶意文件。常见的伪协议包括:
php://filter:最广为人知的协议,常用于读取文件内容和进行编码转换zip://:用于读取zip压缩包内的文件data://:直接包含base64编码的数据phar://:本文重点,可操作PHP归档文件
为什么phar协议容易被忽视?
- 文档资料相对较少,社区讨论热度低
- 许多开发者认为它"只是用来处理压缩文件"
- 实际攻击面比表面看起来要广泛得多
注意:所有伪协议攻击都需要文件包含漏洞存在,且allow_url_include配置开启
2. phar协议深度解析
phar(PHP Archive)是PHP 5.3+引入的一种打包格式,类似于Java的JAR。一个标准的phar文件包含四个部分:
| 组成部分 | 描述 | 安全意义 |
|---|---|---|
| Stub | 文件头标识,必须包含__HALT_COMPILER() | 可伪装成其他文件类型 |
| Manifest | 元数据,存储序列化信息 | 反序列化攻击入口 |
| 文件内容 | 实际压缩的内容 | 可隐藏恶意代码 |
| 签名 | 可选的文件签名 | 完整性校验 |
关键特性分析:
// 典型phar文件生成代码 $phar = new Phar('test.phar'); $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $phar->addFromString('test.txt', '恶意内容'); $phar->setMetadata(['key' => '可序列化数据']); $phar->stopBuffering();- 文件伪装能力:phar文件可以完全伪装成图片、PDF等格式,只需保持有效的stub结构
- 无需特定后缀:虽然.phar是标准后缀,但任意后缀均可被phar协议解析
- 元数据反序列化:当phar文件被操作时,元数据会自动反序列化
3. 实战攻击场景剖析
让我们通过一个模拟CTF题目来演示phar协议的实际利用。假设存在以下条件:
- 网站允许上传zip格式文件
- 存在文件包含漏洞,且自动补全.php后缀
- 上传文件后缀检查不严格
攻击步骤:
创建恶意phar文件:
php -d phar.readonly=0 generate.phar将phar文件重命名为无害后缀:
mv malicious.phar harmless.zip上传文件并获取存储路径,如
/uploads/harmless.zip通过文件包含触发:
/vuln.php?file=phar:///uploads/harmless.zip/internal_file
为什么phar比zip协议更有优势?
- 更灵活的文件伪装能力
- 支持元数据反序列化
- 对文件结构要求更低
- 在自动补全后缀的场景下更可靠
4. 高级攻击技巧与变种
除了基本的文件包含,phar协议还能用于更复杂的攻击场景:
1. 反序列化攻击链
// 精心构造的元数据 $phar->setMetadata(new DangerousClass());当phar文件被包含时,元数据会自动反序列化,可能触发POP链。
2. 结合文件上传限制绕过
- 上传检查通常只验证文件头几个字节
- phar stub可以设计为合法的图片头:
"\xFF\xD8\xFF\xE0" . "<?php __HALT_COMPILER(); ?>"
3. 无文件包含的直接利用
某些PHP函数如file_exists()、is_file()也会触发phar解析:
file_exists('phar://malicious.zip');5. 防御策略与最佳实践
针对phar协议攻击,开发者可以采取多层防御措施:
1. 输入验证与过滤
- 严格检查用户输入的文件路径
- 禁用不必要的伪协议:
allow_url_include=Off
2. 服务器配置加固
| 配置项 | 推荐值 | 作用 |
|---|---|---|
| phar.readonly | On | 禁止生成phar文件 |
| disable_functions | Phar::__construct | 禁用phar类 |
3. 代码层防护
- 使用白名单限制包含文件路径
- 对动态包含参数进行严格校验:
$allowed = ['safe.php', 'config.php']; if(!in_array($input, $allowed)) { die('Invalid file'); }
4. 监控与日志
- 记录所有文件包含操作
- 监控可疑的文件操作序列
在实际项目中,我曾遇到一个案例:攻击者通过精心构造的phar文件,不仅绕过了上传限制,还利用元数据反序列化获取了服务器权限。这提醒我们,安全防护需要全面考虑各种可能的攻击向量。
