一、学习序列化漏洞
(一)基础概念
1. 什么是序列化 / 反序列化
- 序列化(serialize):将程序中的对象、数组、类实例转换成字符串 / 字节流,用于存储、传输(存文件、Cookie、接口传参)。
- 反序列化(unserialize):把序列化字符串还原成程序对象,漏洞根源:反序列化时会自动执行对象的魔术方法,可控序列化字符串可触发恶意代码。
2. 漏洞核心原理
用户可控输入直接传入反序列化函数,攻击者构造恶意序列化字符串,程序解析时自动调用 __wakeup、__destruct、__toString 等魔术方法,触发命令执行、文件读写、SQL 注入、SSRF 等危害。
3. 常见存在语言
PHP(最主流)、Java、Python、.NET、Node.js
(二)PHP 反序列化漏洞
1. 基础语法
// 序列化
$a = array("user"=>"admin");
echo serialize($a);
// 输出:a:1:{s:4:"user";s:5:"admin";}
// 反序列化
$str = $_GET['data'];
unserialize($str); // 危险函数,输入可控即存在漏洞
类型标识
- a 数组、s 字符串、i 数字、O 对象、C 自定义类、N null
2. 魔术方法(漏洞触发关键)
表格
| __wakeup() | 反序列化完成瞬间自动调用 | 最常用入口,构造恶意逻辑 |
| __destruct() | 对象销毁、脚本结束时调用 | 收尾执行恶意代码 |
| __toString() | 对象被当作字符串输出 | 文件读取、拼接命令 |
| __call() | 调用不存在方法 | 方法链调用 |
| __get() | 读取不存在属性 | 访问敏感成员 |
3. 简单漏洞 Demo
脆弱代码:
<?php
class Test{
public $cmd;
function __wakeup(){
system($this->cmd); // 危险函数
}
}
$str = $_GET['input'];
unserialize($str);
?>
构造恶意序列化字符串:
$obj = new Test();
$obj->cmd = "whoami";
echo serialize($obj);
输出:O:4:"Test":1:{s:3:"cmd";s:6:"whoami";}传入 URL:?input=O:4:"Test":1:{s:3:"cmd";s:6:"whoami";} 直接执行系统命令。
4. 常见绕过技巧
5. PHP 工具
- phpggc:一键生成各版本框架 POP 链(Laravel/ThinkPHP/WordPress)
- serchal:序列化字符串解析、修改工具
- 在线工具:serialize 解析、编码转换
6. 常见框架漏洞
- ThinkPHP 5.x 反序列化 RCE
- Laravel 框架 POP 链命令执行
- WordPress 历史反序列化漏洞
(三)Java 反序列化漏洞
1. 核心原理
Java ObjectInputStream.readObject() 反序列化可控对象,触发重写的 readObject() 方法,通过原生类(CC 链、CB 链、JRMP)实现远程代码执行。
2. 关键链
- CC1~CC7:CommonsCollections 利用链(最经典)
- CB:CommonsBeanutils
- JRMP、URLDNS(DNS 探测,无回显)
3. 触发入口
- 表单参数、Cookie、HTTP Header、RMI、JMX、Shiro Cookie(RememberMe)
4. 工具
ysoserial:生成 Java 恶意序列化 payload
经典漏洞:Shiro 反序列化、WebLogic、JBoss 反序列化 RCE
(四)Python 反序列化漏洞(pickle)
1. 函数
危险模块:pickle、cPickle、dill
- pickle.dumps() 序列化
- pickle.loads() 反序列化(可控输入直接 RCE)
2. Payload 原理
pickle 序列化支持执行任意函数,构造 payload 调用 os.system简易 payload:
import pickle,os
payload = b'cos\\nsystem\\n(S"calc")\\ntR.'
pickle.loads(payload) # 弹出计算器
3. 防护
使用 json 替代 pickle;反序列化前校验来源;使用安全序列化库。
(五)漏洞挖掘思路
- PHP:unserialize()
- Java:ObjectInputStream.readObject
- Python:pickle.load/loads
- .NET:BinaryFormatter.Deserialize
(六)漏洞危害分级
(七)防御方案
- PHP:unserialize($str, ["allowed_classes"=>["SafeClass"]])
- Java:自定义 ObjectInputStream 过滤类



