PHP反序列化漏洞触发需同时满足三点:可控输入传入unserialize()、存在可利用的POP链及魔术方法(如__wakeup/__destruct)、运行环境未启用allowed_classes白名单或disable_functions等基础防护。

可控的反序列化入口
攻击者必须能向程序传入自己构造的序列化字符串,并被代码实际调用 unserialize()(或等效逻辑,如某些框架的隐式反序列化)。常见入口包括:
- URL 参数(如
?s=O%3A3%3A%22ABC%22%3A0%3A%7B%7D) - Cookie 值(如
PHPSESSID或自定义键如user_data) - POST Body 或 JSON 中的字段(尤其在未严格校验类型时)
- Session 数据(当 session 存储方式为 files 且 key 可控时)
- 缓存内容(如 Redis、Memcached 中存储的序列化值被直接反序列化)
存在可利用的 POP 链与魔术方法
光有 unserialize() 不够,还得有类和方法构成一条“通路”,让恶意数据最终走到危险操作。关键依赖:
- 目标环境中已加载(或可通过自动加载机制引入)的类
- 至少一个魔术方法(如 __wakeup、__destruct、__toString)被触发,且其中包含危险操作(如
file_put_contents、call_user_func、system) - POP 链中各属性可被攻击者控制(例如通过序列化字符串设定
$this->filename = '/etc/passwd')
运行环境未做基础防护
即使上述两点都满足,若服务端做了限制,漏洞也可能无法利用:
-
unserialize()未被禁用(PHP 7.4+ 默认仍启用,但部分框架会封装或拦截) - 未启用
allowed_classes参数(PHP 7.0+ 支持白名单模式,设为false可禁止反序列化对象) - 危险函数未被
disable_functions屏蔽(如system、exec) - 错误信息未关闭(
display_errors=Off),否则可能泄露类名、路径等关键线索
版本与配置相关细节不能忽略
很多链只在特定 PHP 版本或 ThinkPHP/Laravel 等框架版本中有效:
立即学习“PHP免费学习笔记(深入)”;
- PHP 7.2+ 对
__wakeup()的调用更严格,部分旧链失效 - ThinkPHP 5.1.23 之前存在
Windows类 POP 链;5.2.0 以下存在Model类__toString触发点 - PHP 5.4–8.3 所有版本均受底层 PHP2Shell(CVE-2026-109618/19)影响——该漏洞绕过所有应用层反序列化防护,直接在引擎层触发 RCE



















