CVE-2016-1000340: Bouncy Castle 反序列化漏洞分析

0x00 漏洞背景与详情

  • CVE ID: CVE-2016-1000340
  • 影响组件: Bouncy Castle Java (bcprov-jdk15on)
  • 受影响版本: < 1.56
  • 漏洞类型: 不安全的反序列化 (CWE-502)
  • 危险等级: 高危 (CVSS 评分 9.8)

Bouncy Castle 是一个广泛使用的开源密码学库。CVE-2016-1000340 是其在处理特定对象反序列化时的一个经典安全缺陷。由于受影响版本中的某些类(如 org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAParameters)在反序列化过程中缺乏类检查,攻击者可以通过构造恶意的序列化数据,利用 Classpath 中已有的 Gadget Chain 实现远程代码执行(RCE)。

0x01 漏洞原理分析

该漏洞的核心在于 Gadget 链的引导能力

  1. 缺陷点: 在 1.56 之前的版本中,Bouncy Castle 的某些提供者类在反序列化时(readObject)会根据序列化数据流中的信息动态加载并实例化类。
  2. 利用机制: 当应用程序暴露了反序列化入口(如 RMI、JMX、或接收 Java 序列化对象的 Web 接口)且包含受影响的 BC 库时,攻击者可以将 BC 库中的类作为“跳板”。
  3. 组合拳: BC 库通常不是 RCE 的直接执行者,但它能作为一个可靠的 Gadget 引导程序。通过 BC 库的类引导到如 Apache Commons Collections 等已知的 RCE 链条上,即可完成攻击。

0x02 POC (Proof of Concept) 与高级利用姿势

POC 构造思路

利用 ysoserial 工具,结合 BC 库的特性进行载荷构造:

# 示例:利用 Bouncy Castle 作为入口引导到 CommonsCollections 链
java -jar ysoserial.jar CommonsCollections5 "touch /tmp/bouncy_castle_pwned" > payload.bin

高级实战姿势

  1. 无文件内存马 (Memory Shell) 注入: 在成功触发 RCE 后,通过 Java 动态代理或自定义类加载器(defineClass),直接在 JVM 内存中注入 Spring 控制器内存马或 Servlet 过滤器内存马。这种姿势不产生文件落地,重启即消失,极难被传统的 EDR 扫描发现。
  2. WAF 绕过技术:
    • 多层嵌套序列化: 利用 ObjectOutputStream 的自定义头部或将恶意对象嵌套在合法的复杂对象中,规避 WAF 对 AC ED 00 05 魔数的简单过滤。
    • 协议混淆: 如果目标使用特定的 RPC 协议承载 Java 序列化,可以利用协议头部的字段填充来干扰 WAF 的解析深度。
  3. 不出网环境下的数据外带 (Echo): 若目标服务器无法访问互联网,利用反序列化获取当前请求的 HttpServletResponse 对象,将命令执行结果直接写入 Response Body 返回,实现“所见即所得”的回显效果。

0x03 应急排查与日志痕迹分析

1. 组件版本审计

在 Java 项目根目录下运行依赖树检查命令:

mvn dependency:tree | grep bcprov

若版本号低于 1.56,则判定存在漏洞风险。

2. 日志特征匹配

  • 应用报错: 重点检索包含 java.io.InvalidClassExceptionjava.lang.ClassCastException 且调用栈中包含 org.bouncycastle 关键字的报错信息。
  • 流量监测: 在 WAF 或 IDS 中检查请求体起始位置是否包含十六进制 AC ED 00 05(Base64 为 rO0AB)的 Java 序列化特征。

0x04 修复方案与建议

  1. 直接升级 (推荐): 将 Bouncy Castle 升级至 1.56 或更高版本。
  2. 安全补丁: 在代码中引入 ObjectInputFilter(Java 9+)实施反序列化类白名单机制,仅允许业务必需的类参与反序列化。
  3. 隔离策略: 将所有涉及 Java 序列化传输的管理接口(如 JMX)严格限制在内网受控网段访问,禁止对公网开放。

0x05 参考材料