PHP反序列化漏洞这么学(细)!
字数 1623 2025-08-09 22:00:40
PHP反序列化漏洞深入解析
一、PHP序列化与反序列化基础
1.1 序列化概念
序列化是将对象转换为可存储或传输的字符串的过程,反序列化则是将字符串重新转换为对象。
1.2 PHP序列化函数
serialize()- 将对象序列化为字符串unserialize()- 将字符串反序列化为对象
1.3 序列化格式
PHP序列化字符串格式示例:
O:4:"User":2:{s:4:"name";s:5:"admin";s:6:"isAdmin";b:1;}
解释:
O:4:"User"- 对象,类名长度为4,类名为"User"2- 对象有2个属性s:4:"name"- 字符串属性,长度4,名称为"name"s:5:"admin"- 字符串值,长度5,值为"admin"s:6:"isAdmin"- 字符串属性,长度6,名称为"isAdmin"b:1- 布尔值,值为true
二、PHP反序列化漏洞原理
2.1 漏洞产生条件
- 应用程序接收用户可控的反序列化数据
- 目标类中存在"魔法方法"
- 类属性可用于危险操作
2.2 危险魔法方法
__wakeup()- 反序列化时自动调用__destruct()- 对象销毁时调用__toString()- 对象被当作字符串使用时调用__call()- 调用不可访问方法时触发
2.3 攻击面
攻击者可以:
- 控制反序列化的类
- 控制类属性值
- 触发危险方法执行恶意代码
三、漏洞利用技术
3.1 基本利用流程
- 寻找包含魔法方法的类
- 分析类中危险操作
- 构造恶意序列化字符串
- 触发反序列化操作
3.2 实例分析
class Example {
public $file;
public $data;
public function __destruct() {
file_put_contents($this->file, $this->data);
}
}
// 恶意序列化数据
$payload = serialize(new Example());
$payload = str_replace(
'O:7:"Example":2:{s:4:"file";N;s:4:"data";N;}',
'O:7:"Example":2:{s:4:"file";s:8:"test.php";s:4:"data";s:18:"<?php phpinfo(); ?>";}',
$payload
);
// 触发漏洞
unserialize($payload);
3.3 属性数量不一致攻击
PHP 5.6.30之前存在CVE-2016-7124漏洞,当序列化字符串中表示对象属性个数的值与实际属性个数不一致时,可以绕过__wakeup()的执行。
利用方式:
O:4:"User":1:{s:4:"name";s:5:"admin";}
改为
O:4:"User":100:{s:4:"name";s:5:"admin";}
四、POP链构造
4.1 概念
Property-Oriented Programming(面向属性编程),通过组合多个类的魔法方法形成攻击链。
4.2 构造步骤
- 寻找起点(如
__destruct()) - 寻找数据传输点(类属性)
- 寻找危险函数调用点
- 连接各点形成完整利用链
4.3 实例分析
class FileClass {
public $filename;
public function __toString() {
return file_get_contents($this->filename);
}
}
class User {
public $obj;
public function __destruct() {
echo $this->obj;
}
}
// 构造POP链
$file = new FileClass();
$file->filename = '/etc/passwd';
$user = new User();
$user->obj = $file;
$payload = serialize($user);
unserialize($payload);
五、防御措施
5.1 输入验证
- 不要反序列化不可信数据
- 使用JSON等更安全的数据交换格式
5.2 安全配置
- 升级PHP版本(修复已知漏洞)
- 禁用危险函数(如
unserialize())
5.3 代码层面
- 限制魔法方法的敏感操作
- 对反序列化类进行白名单控制
- 使用
__wakeup()重置对象状态
5.4 加密签名
对序列化数据进行签名,确保数据未被篡改
六、实战案例分析
6.1 Typecho反序列化漏洞
- 漏洞点:
install.php中的反序列化操作 - 利用链:通过
__get()方法触发文件包含 - 最终实现远程代码执行
6.2 ThinkPHP反序列化漏洞
- 利用
__destruct()方法 - 通过
__toString()触发文件操作 - 结合其他功能实现完整利用
七、工具与资源
7.1 工具推荐
- PHPGGC - PHP反序列化payload生成工具
- php-serialize - PHP序列化分析工具
- Burp Suite - 用于拦截和修改序列化数据
7.2 学习资源
- PHP官方文档(序列化部分)
- OWASP反序列化备忘单
- 已知PHP反序列化漏洞CVE分析
八、高级技巧
8.1 字符逃逸
利用序列化字符串的格式特点,通过精心构造数据改变解析逻辑
8.2 引用攻击
利用PHP对象引用特性,修改已序列化对象的属性
8.3 Phar反序列化
通过Phar文件的元数据触发反序列化操作,扩展攻击面
九、总结
PHP反序列化漏洞危害严重,开发人员应:
- 避免反序列化用户输入
- 谨慎实现魔法方法
- 保持PHP环境更新
- 实施深度防御策略
安全研究人员应:
- 深入理解序列化机制
- 掌握POP链构造方法
- 关注新型利用技术
- 负责任地披露漏洞