PHP 7.3.28已停止维护且存在高危反序列化风险,需通过静态分析(RIPS)、动态探测(PHPGGC+Burp)和依赖扫描(Security Checker)三步结合识别;其不支持allowed_classes语法,凡可控输入调用unserialize()即视为高危。

PHP 7.3.28 属于已停止维护的版本(官方自2021年12月起终止支持),该版本存在多个已知反序列化相关风险,如未校验输入时调用 unserialize()、配合危险类(如 Monolog, SwiftMailer, Laravel 旧组件)可能触发 POP 链执行。扫描它不能只靠“一键工具”,而要结合静态分析 + 动态探测 + 框架特征识别三步走。
? 一、确认是否真在用 PHP 7.3.28 并暴露反序列化入口
先别急着扫,先人工验证风险面:
- 检查 Cookie、POST 参数、HTTP Header 中是否存在形如
O:,a:开头的 Base64 或明文序列化字符串(例如Cookie: prefs=OTp7czozOiJuYW1lIjtzOjM6ImFkbSI7fQ==解码后是a:1:{s:3:"name";s:3:"adm";}) - 查看代码中是否有类似
unserialize($_COOKIE['data'])、unserialize(file_get_contents($cache))等调用,且未限制allowed_classes或未做输入过滤 - 注意:即使加了
allowed_classes => false,若类中__wakeup/__destruct含文件写入、日志记录、命令拼接等逻辑,仍可能被链式利用
✅ 小提示:PHP 7.3.28 不支持
unserialize()的allowed_classes数组语法(该语法从 7.4+ 引入),所以旧版只要调用unserialize()且输入可控,基本就等于高危。
?️ 二、推荐组合使用三类扫描工具
1. 静态扫描:RIPS(专为 PHP 设计)
适用于源码可得场景(如内部审计、CI 流程):
- 下载 RIPS 3.x(支持 PHP 7.3 兼容语法解析)
- 上传项目目录,启用「反序列化函数调用」+「魔术方法敏感操作」规则集
- 关键检测项包括:
-
unserialize(出现在用户输入路径上(如$_GET,$_POST,$_COOKIE,$_REQUEST) - 类中定义了
__wakeup,__destruct,__toString且内部调用system,file_put_contents,include,call_user_func -
unserialize()调用前无preg_match('/^[a-zA-Z0-9\+\=\/\{\}\[\]\:\;]+$/')类型白名单校验
-
2. 动态探测:PHPGGC + Burp Suite 协同
适用于黑盒测试(如渗透测试、上线前验收):
- 安装 PHPGGC(支持 PHP 7.3 兼容链):
git clone https://github.com/ambionics/phpggc.git cd phpggc && php phpggc -l | grep -i "7.3" # 查看是否含适配链
- 常用命令示例(以 ThinkPHP 5.0.23 为例,该版本常见于 PHP 7.3 环境):
php phpggc ThinkPHP/RCE7 system "id" --base64
- 将生成的 Base64 字符串,替换到疑似入口参数中(如
?data=xxx或Cookie: data=xxx),用 Burp Repeater 发送,观察响应是否含uid=或报错回显 - ⚠️ 注意:部分链在 PHP 7.3 下因 ZVAL 结构差异会失败,优先试
Monolog/RCE1,SwiftMailer/RCE1,Guzzle/RCE1
3. 依赖成分扫描:Security Checker + Composer Audit
很多反序列化漏洞不在你写的代码里,而在老旧第三方包中:
- 运行:
wget https://security.symfony.com/check_lock php check_lock composer.lock
- 重点盯这些高危组件的旧版:
-
monolog/monolog -
swiftmailer/swiftmailer -
laravel/framework -
phpunit/phpunit
-
? 三、绕过常见“假安全”陷阱
有些团队以为加了防护就没事,其实不然:
- ❌
unserialize(base64_decode($input))不等于安全 —— Base64 只是编码,不是校验 - ❌
if (strpos($input, 'O:') === false)可被a:或C:绕过,且现代 POP 链大量使用数组和资源类型 - ❌ 把序列化数据存数据库再读取 ≠ 可信 —— 若写入接口未鉴权(如低权限后台导出配置),照样算外部输入
- ❌ 用
json_decode()替换但没设JSON_THROW_ON_ERROR—— 静默失败后可能 fallback 到unserialize(),反而更危险
✅ 最终建议动作
立即执行以下三项(不依赖工具也能见效):
- 搜索全项目:
grep -r "unserialize(" . --include="*.php",对每个结果人工判断输入来源是否可控 - 将所有
unserialize()调用,按「不可信输入 → JSON 替代」路径迁移(参考 DeepSeek 提供的字段白名单 JSON 方案) - 升级 PHP 至受支持版本(至少 8.1+),并启用
unserialize()的allowed_classes => []严格模式
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











