检测方法与修复实战指南
目录导读
什么是序列化漏洞?核心危害与攻击原理
1 漏洞本质
序列化(Serialization)是将对象转换为可传输的字节流或字符串格式的过程;反序列化(Deserialization)则是逆向还原过程,当应用程序未经安全验证直接反序列化外部输入数据时,攻击者能够构造恶意序列化数据,触发服务器上的任意代码执行、远程命令执行或拒绝服务攻击。

2 攻击流程示意图
攻击者构造恶意Payload → 注入到HTTP请求参数/Cookie/Session →
服务器调用readObject() → 触发构造函数和魔术方法 → 执行系统命令
以Java为例,攻击者利用ObjectInputStream.readObject()方法,通过修改序列化数据中的类的属性值,触发Runtime.getRuntime().exec()等危险方法。
3 典型危害场景
- Java反序列化:Apache Commons Collections、Fastjson、Jackson等库的已知漏洞(如CVE-2015-7501)
- PHP反序列化:利用
unserialize()函数配合__wakeup()或__destruct()魔术方法 - Python反序列化:
pickle模块的代码执行风险 - .NET反序列化:BinaryFormatter、NetDataContractSerializer等
问答1
Q: 为什么序列化漏洞被称为“无文件攻击”?
A: 因为攻击载荷完全存在于网络传输的数据流中,不依赖上传恶意文件,因此传统杀毒软件和文件监控难以检测。
序列化漏洞检测:5大关键技术手段
1 静态代码扫描(SAST)
- 工具推荐:Fortify、Checkmarx、SonarQube(配合规则库)
- 检测重点:
- 查找
readObject()、unserialize()、pickle.loads()等函数调用 - 识别未进行类型过滤的
ObjectInputStream重写
- 查找
- 局限性:对动态反射调用链的误报率较高
2 动态行为分析(DAST)
- 工具:Burp Suite Pro(配合反序列化插件)、Acunetix
- 操作步骤:
- 拦截HTTP请求,寻找序列化数据格式(如Java的
aced0005十六进制头、PHP的a:1:{s:4:”test”}) - 使用ysoserial(Java)、PHPGGC(PHP)等工具生成测试Payload
- 观察响应耗时(差异化响应)或错误信息判断是否存在漏洞
- 拦截HTTP请求,寻找序列化数据格式(如Java的
- 技巧:针对Fastjson,尝试发送
@type字段探测
3 依赖库版本审计
- 检测命令(以Maven为例):
mvn dependency-check:check -DfailBuildOnCVSS=7
- 关键库版本要求:
- Apache Commons Collections:升级至3.2.2+ 或使用4.1+
- Jackson:2.10.0以上版本
- Fastjson:1.2.83以上版本(并启用
safeMode) - .NET BinaryFormatter:已被标记为不安全,建议替换
4 安全测试框架自动化
- OWASP ZAP:其反序列化扫描器可检测多种语言
- Nikto:内置部分常见Payload测试
- 自定义POC脚本:使用Python编写自动化检测工具,结合ysoserial动态生成Payload
5 流量异常监控
- 检测特征:
- Base64编码中的
rO0ABX(Java序列化标记) - 数据包含
@type字段(Fastjson) - 参数包含
O:8:(PHP对象标记)
- Base64编码中的
- 工具:WAF规则(ModSecurity)、ELK实时分析
问答2
Q: 生产环境中无法直接发送攻击Pay load怎么办?
A: 采用“白盒审计”策略:重点审查第三方依赖库版本是否在CVE列表内,并使用“黑盒+白盒”组合检测:先通过SAST锁定可疑函数,再用DAST对指定接口进行精准测试。
序列化漏洞修复:从代码到架构的完整方案
1 首选方案:禁止反序列化不可信数据
-
代码示例(Java):
// 错误做法 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(request.getParam("data"))); // 修复后:仅接受JSON格式并做结构校验 String jsonStr = request.getParam("data"); MyObj obj = JSON.parseObject(jsonStr, MyObj.class, MyFilter.class); -
哲学:不信任任何外部序列化输入,转而使用安全的序列化格式(如JSON、Protocol Buffers)
2 强类型过滤与白名单机制
-
实现方式:
// Java自定义ObjectInputStream class SafeObjectInputStream extends ObjectInputStream { private static final Set<String> ALLOWED_CLASSES = Set.of("com.example.User", "java.lang.String"); @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { if (!ALLOWED_CLASSES.contains(desc.getName())) { throw new InvalidClassException("Unexpected class: " + desc.getName()); } return super.resolveClass(desc); } } -
注意:白名单必须非常严格,仅包含业务必需的类
3 升级依赖库与启用安全配置
| 组件 | 最低安全版本 | 额外配置 |
|---|---|---|
| Fastjson | 2.83 | ParserConfig.getGlobalInstance().setSafeMode(true); |
| Jackson | 10.0 | 禁用default typing:mapper.enableDefaultTyping(DefaultTyping.NON_FINAL) |
| Pickle (Python) | 不升级 | 完全避免使用;改用json或msgpack |
4 纵深防御:WAF与运行时防护
- Web应用防火墙:编写规则拦截序列化特征
(ModSecurity规则示例):
SecRule REQUEST_BODY "@contains rO0ABX" "id:12345,phase:2,deny,status:403" - RASP(运行时应用自保护):如Contrast Security、Sqreen,可在运行时拦截反序列化操作
5 框架层面解决方案
- Spring Boot:启用
spring.autoconfigure.exclude排除风险组件 - Fastjson:使用
2.83版本并配置AutoType白名单 - Java 17+:使用
Record类型减少序列化风险(默认不可序列化)
问答3
Q: 使用了白名单后,业务需要新增类怎么办?
A: 实施“审批+自动化”流程:开发提交PR时,强制检查是否涉及反序列化类修改;管理员审核并在ALLOWED_CLASSES中添加,测试环境验证无误后上线。
常见问题解答(FAQ)
Q1: 为什么我的序列化数据经过了加密,还需要修复?
A: 端口嗅探不是唯一威胁,攻击者若获得加密密钥(如通过SSRF、日志泄露),密文仍可被解密并反序列化,加密仅保护传输机密性,不解决反序列化本身的逻辑漏洞。
Q2: 使用Gson代替Fastjson是否安全?
A: Gson默认不会调用对象的构造函数自动触发危险方法,但若使用了RuntimeTypeAdapterFactory或自定义反序列化器,仍然存在风险,建议:Gson默认比Fastjson更安全,但最佳实践仍是避免使用任何自动反序列化机制。
Q3: 如何修复遗留系统的序列化代码?
A: 采用“重写优于修补”策略:
- 识别所有反序列化入口(通常集中在Session、Cookie、RPC调用)
- 逐步替换为JSON格式,并添加严格的数据校验schema(如JSON Schema)
- 在替换完成前,启用WAF绕过特征拦截 + 白名单ObjectInputStream
Q4: PHP反序列化漏洞修复有什么特殊点?
A: 禁用unserialize()函数,使用json_decode()并配合类属性验证,若必须使用,设置allowed_classes参数:
$obj = unserialize($data, ['allowed_classes' => ['MySafeClass']]);
并将'allowed_classes'设置为false阻止所有对象反序列化。
核心行动清单:
- 立即扫描所有第三方依赖库版本,更新至安全版本
- 审计所有
readObject、unserialize、pickle.loads调用,添加白名单 - 部署WAF规则拦截序列化特征流量
- 针对遗留系统制定“分阶段替换”计划,优先替换Session存储
最终建议:将序列化漏洞纳入CI/CD门禁,使用maven dependency-check或npm audit等工具自动阻断风险引入,并定期进行红蓝对抗检验修复效果。