【POP链PartⅠ】PHP应用程序Symfony的POP链利用过程
字数 1599 2025-08-23 18:31:08
Symfony PHP应用程序POP链利用分析
1. 概述
本文详细分析了Symfony框架中doctrine/doctrine-bundle依赖包的POP(Property-Oriented Programming)反序列化链利用过程。该依赖包已被下载超过1.44亿次,是PHP反序列化漏洞研究的理想目标。
2. 核心概念
2.1 反序列化漏洞基础
PHP反序列化漏洞利用的关键点在于:
__wakeup(): 反序列化时自动调用__destruct(): 对象销毁时自动调用__call(): 调用不可访问方法时触发__toString(): 对象被当作字符串使用时调用
2.2 研究目标
- 任意文件写入
- 任意文件包含
- PHP特性利用
- 弱类型安全问题
3. 研究方法
3.1 入口点定位
查找POP链的步骤:
- 搜索
__wakeup、__unserialize和__destruct方法 - 排除抛出
BadMethodCallException的类 - 分析可到达的危险函数调用链
3.2 关键类分析
3.2.1 Doctrine\Common\Cache\Psr6\CacheAdapter
final class CacheAdapter implements CacheItemPoolInterface {
public function __destruct() {
$this->commit();
}
public function commit(): bool {
// 关键逻辑
}
}
3.2.2 Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage
class MockFileSessionStorage extends MockArraySessionStorage {
public function save() {
file_put_contents($tmp, serialize($data));
rename($tmp, $path);
}
}
3.2.3 Symfony\Component\Cache\Adapter\PhpArrayAdapter
class PhpArrayAdapter {
private function initialize() {
$values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []];
}
}
4. POP链构建过程
4.1 第一阶段:从__destruct到commit
- 通过
CacheAdapter的__destruct方法触发commit调用 commit方法中关键路径:$item->getExpiry()调用$item->get()调用$this->cache->save()调用$this->cache->delete()调用
4.2 第二阶段:文件写入利用
通过MockFileSessionStorage的save方法实现文件写入:
- 控制
$data内容写入临时文件 - 文件路径格式为
$savePath/$id.mocksess - 虽然扩展名固定为
.mocksess,但可以写入PHP代码
4.3 第三阶段:文件包含利用
通过PhpArrayAdapter的deleteItem触发文件包含:
deleteItem调用initialize方法initialize方法使用include包含指定文件- 结合前阶段的文件写入实现代码执行
5. 完整利用链
CacheAdapter::__destruct()→commit()- 根据条件选择路径:
- 过期项:
delete()→deleteItem()→initialize()→include - 未过期项:
save()→ 文件写入
- 过期项:
- 通过文件写入+文件包含实现代码执行
6. 技术难点与解决方案
6.1 类型限制绕过
虽然PHP是弱类型语言,但某些接口限制可通过:
- Traits特性继承
- 中间代理类
- 方法调用链跳转
6.2 文件扩展名限制
虽然无法直接创建.php文件,但:
- 写入的序列化数据可包含PHP代码
- 通过
include执行序列化文件中的代码
7. 防御建议
- 避免反序列化用户可控数据
- 实现
__wakeup()或__unserialize()时抛出异常 - 对敏感操作进行严格类型检查
- 及时更新依赖包版本
8. 总结
该POP链利用展示了:
- PHP反序列化的危险性
- 弱类型语言的潜在安全问题
- 复杂依赖关系中隐藏的攻击面
- 通过方法调用链实现权限提升的技巧
通过深入分析此类漏洞,可以更好地理解PHP应用程序的安全机制和防御策略。