文章目录
反序列化漏洞的原理、利用方式与防范措施
一、原理
1. 定义与触发条件
反序列化漏洞 源于应用程序将用户可控的序列化数据还原为对象时,未校验数据合法性,导致恶意代码执行。其核心触发条件包括:
- 参数可控:用户能够控制传入
unserialize()
函数的参数(如$_GET['data']
)。 - 魔术方法滥用:类中定义了自动触发的魔术方法(如
__destruct()
、__wakeup()
),这些方法可能包含敏感操作(如文件写入、命令执行)。 - 敏感操作暴露:反序列化过程中调用危险函数(如
eval()
、system()
),或通过POP链间接触发敏感逻辑。
2. 攻击链流程图
二、利用方式
1. 利用手法与分类
(1) 直接代码执行
-
PHP示例:通过
__destruct()
或__wakeup()
直接调用危险函数。class Exploit { public $cmd = "system('whoami');"; public function __destruct() { eval($this->cmd); } } // 序列化payload:O:7:"Exploit":1:{s:3:"cmd";s:15:"system('whoami');";}
影响:攻击者可执行任意系统命令或写入Webshell。
(2) POP链构造
-
原理:通过链式调用多个类的魔术方法,间接触发敏感操作。例如:
class A { public $obj; public function __destruct() { $this->obj->trigger(); } } class B { public function trigger() { system($_GET['cmd']); } } // 序列化payload:O:1:"A":1:{s:3:"obj";O:1:"B":0:{}}
案例:SugarCRM反序列化漏洞(CVE-2016-1000001)利用POP链实现远程代码执行。
(3) 框架/中间件漏洞
- Java反序列化:
- Apache Commons Collections(CC链):通过
InvokerTransformer
等类构造恶意对象,触发命令执行。 - WebLogic CVE-2019-2725:利用XMLDecoder反序列化漏洞执行远程代码。
- Apache Commons Collections(CC链):通过
- PHP框架:如Laravel、ThinkPHP历史版本因反序列化链暴露风险。
2. 真实案例
-
Pikachu靶场漏洞演示
- 漏洞:未过滤用户输入的序列化数据,触发
__destruct()
执行XSS代码。 - 利用:构造
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
,实现弹窗。
- 漏洞:未过滤用户输入的序列化数据,触发
-
PHP对象注入RCE
-
漏洞:某CMS反序列化时调用
eval()
函数。 -
Payload:
class Payload { public $data = "system('rm -rf /');"; public function __wakeup() { eval($this->data); } }
-
效果:服务器执行任意命令,导致数据删除或系统沦陷。
-
-
JBoss反序列化漏洞(CVE-2017-12149)
- 原理:JBoss的
Invoker
接口未校验反序列化数据,攻击者注入恶意对象触发代码执行。 - 工具利用:使用
ysoserial
生成Payload,通过HTTP请求触发漏洞。
- 原理:JBoss的
-
PHP CTF例题绕过
__wakeup()
- 漏洞:通过修改序列化字符串中的属性数量(如
O:5:"SoFun":2:{...}
),绕过__wakeup()
方法重置逻辑,最终读取flag.php
。 - Payload:
O:5:"SoFun":2:{S:7:"\00*\00file";s:8:"flag.php";}
(Base64编码后提交)。
- 漏洞:通过修改序列化字符串中的属性数量(如
-
Hitachi Vantara Pentaho漏洞
- 漏洞:未限制JSON反序列化中的类,攻击者可上传恶意数据触发拒绝服务或代码执行。
- 修复:升级版本并限制解析器仅使用白名单类。
-
中国工商银行专利防护方法
- 技术:通过白名单机制筛选可信类,替换原反序列化方法,确保仅允许安全类执行。
三、防范措施
1. 输入校验与过滤
-
白名单机制:限制反序列化类名,仅允许预定义的安全类。
- Java:使用
ObjectInputFilter
设置全局或局部过滤器(Java 9+)。 - PHP:通过
allowed_classes
参数限制反序列化对象类型(unserialize($data, ['allowed_classes' => ['SafeClass']])
)。
- Java:使用
-
白名单控制:仅允许可信的序列化数据格式。
if (!preg_match('/^[a-zA-Z0-9_:]+$/', $_GET['data'])) { die("Invalid data!"); }
-
签名验证:对序列化数据进行签名,防止篡改。
2. 禁用危险函数与类
-
PHP配置:在
php.ini
中禁用unserialize()
或限制允许的类。disable_functions = unserialize allowed_classes = SafeClass1, SafeClass2
-
Java安全策略:扩展
SecurityManager
禁止敏感操作(如Runtime.exec()
)。
3. 安全开发
- 避免魔术方法中的敏感操作:不在
__wakeup()
、__destruct()
中执行高危代码。 - 使用安全序列化格式:优先选择JSON、XML等非原生序列化方案(如Java的
Jackson
、PHP的json_encode()
)。
4. 框架与中间件加固
- 升级与补丁:及时修复已知漏洞(如Fastjson、WebLogic补丁)。
- 最小化权限:运行服务的用户权限限制为仅必要目录读写。
5. 监控与应急响应
- 日志审计:记录所有反序列化操作,检测异常行为(如频繁调用
Runtime.exec()
)。 - 入侵检测系统(IDS):部署规则库监控反序列化攻击特征(如HTTP请求中的
aced0005
或rO0AB
标识)。
四、结语与拓展
漏洞本质与行业趋势
反序列化漏洞的本质是**“信任用户输入的序列化数据”**。随着自动化代码审计工具(如CodeQL)的普及,漏洞挖掘效率提升,但防御技术也在迭代(如工商银行白名单专利)。未来,结合AI的智能过滤和运行时沙箱隔离或成主流防护方案。
漏洞自查清单
- 是否存在未过滤的
unserialize()
参数? - 是否禁用或限制了敏感函数与类?
- 是否启用白名单校验和签名验证?
- 是否使用JSON等更安全的序列化方案?
思考题
- 为什么JSON序列化比PHP原生序列化更安全?
(提示:JSON不支持对象类型,无法触发魔术方法,且结构更易校验。)
参考资源
- OWASP反序列化指南:https://cheatsheetseries.owasp.org/ 。
- CVE数据库:https://cve.mitre.org/(搜索CVE-2017-12149、CVE-2019-2725等)。
- PHP安全编程规范:PHP官方文档 。