排查PHP反序列化漏洞的核心是确认unserialize()的调用者、输入来源及后续操作;需重点审计Cookie/Session、隐藏域、API参数、缓存数据等高危入口,结合PHPGGC验证POP链,严格限制allowed_classes并监控敏感函数调用。

排查PHP反序列化漏洞,核心不是找“有没有unserialize()”,而是确认“谁在用、从哪来、干了什么”。工具只是放大器,真正起作用的是对信任边界的判断和业务逻辑的梳理。
识别高危入口点
先锁定所有可能接收外部输入并调用unserialize()的位置:
- Cookie和Session数据:特别是以serialized=开头或包含O:、a:等特征字符串的字段
- 隐藏表单域(hidden input):常见于偏好设置、向导状态、多步提交缓存
- API请求体或查询参数:如?data=...、POST body中base64或URL编码的字符串
- 缓存键值对:Redis/Memcached中存储的value,若来源不可控,读取后直接unserialize就是风险点
- 日志或导入文件内容:某些系统会把用户上传的JSON/文本解析失败后,尝试fallback到unserialize
用PHPGGC快速验证POP链存在性
PHPGGC不是用来攻击生产环境的,而是帮你确认当前环境中是否存在可利用的反序列化链:
- 运行php phpggc -l列出当前支持的所有框架和类库链
- 用php phpggc -i Laravel/RCE4查看某条链依赖的类、版本范围和触发条件
- 生成一个无害payload测试是否能被解析:php phpggc Guzzle/FW1 print_r ['test'] --base64,再在代码中尝试unserialize(base64_decode($payload)),观察是否报错或输出
- 注意:仅在隔离环境运行,不传入真实业务对象,不连接数据库或文件系统
静态扫描与代码审计要点
人工检查比工具更可靠,重点关注三类信号:
- unserialize()调用附近是否有输入过滤:比如是否校验了字符串是否以a:、O:开头,是否限制长度或嵌套层级
- 是否设置了allowed_classes参数:但要明白,它只限制类名,不限制类内逻辑;若允许的类本身含危险__destruct,仍可能被利用
- 反序列化后是否触发敏感操作:如调用file_put_contents、system、include、PDO::query等——这些才是漏洞的“出口”
- 搜索__wakeup、__destruct、__toString定义,看内部是否使用了动态变量、反射、eval或外部资源操作
运行时检测与日志加固
在无法立即修复的过渡期,靠监控降低风险:
- 在unserialize()封装层加日志:记录调用栈、输入前20字符、$_SERVER['REQUEST_URI'],不记完整payload
- 用set_error_handler捕获反序列化失败异常,区分是格式错误还是类不存在,后者更可疑
- 在Web服务器层(如Nginx)拦截含O:、a:、s:且长度>500的GET参数或Cookie值
- 禁用unserialize的替代方案上线前,用json_last_error()配合严格schema校验兜底
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











