深入分析 ImmutableSetMultimap 反序列化利用链
字数 1889 2025-12-26 12:10:39
ImmutableSetMultimap 反序列化利用链深入分析
概述
本文深入分析 Guava 库中 ImmutableSetMultimap 类的反序列化利用链。该漏洞利用 Guava 不可变集合在反序列化过程中的空值检查机制,结合特定对象触发恶意代码执行。
漏洞背景
核心组件
- ImmutableSetMultimap: Guava 库中的不可变多重映射集合
- JSONArray: Jackson 库中的 JSON 数组实现
- DruidXADataSource: 阿里 Druid 连接池的 XA 数据源实现
关键技术点
- Jackson 的
JSONArray.toString()方法会自动调用类的 getter 方法 - Guava 的不可变集合在反序列化时具有严格的空值检查机制
- 利用异常处理过程中的字符串转换触发恶意代码
利用链构造过程
调用链分析
ImmutableSetMultimap.readObject()
→ SingletonImmutableBiMap.readResolve()
→ SerializedForm.createMap()
→ Builder.put()
→ ImmutableMap.entryOf()
→ checkEntryNotNull()
→ String.valueOf()
→ JSONArray.toString()
→ DruidXADataSource.getValidationQuery()
→ SQL CALL 语句执行
→ SerializationUtils.deserialize()
详细技术分析
第一步:ImmutableSetMultimap 反序列化
当 ImmutableSetMultimap 的 readObject 方法被调用时:
- 读取序列化数据,包括内部的 map 结构
- 在利用链中,这个 map 是
SingletonImmutableBiMap实例
第二步:SingletonImmutableBiMap 的 readResolve
SingletonImmutableBiMap 在反序列化时的行为:
- 调用
readResolve方法 - 通过
SerializedForm.createMap重新构建 map 对象 - 在构建过程中,调用
Builder.put来添加键值对
第三步:Builder.put 和 entryOf
Builder.put 方法的执行流程:
- 调用
ImmutableMap.entryOf创建 entry 对象 - 该方法会检查 key 和 value 是否为 null
第四步:关键的空值检查
checkEntryNotNull 方法的作用:
- 检查 entry 的 key 和 value 是否为 null
- 在检查过程中,由于抛出异常,Guava 会调用
String.valueOf()将对象转换为字符串 - 这是整个利用链的关键转折点
第五步:触发 JSONArray.toString
字符串转换的触发机制:
- 当
String.valueOf()被调用时,如果对象是JSONArray,就会调用JSONArray.toString()方法 - Jackson 的
JSONArray.toString()方法会自动调用类中定义的 getter 方法
恶意对象构造
DruidXADataSource 利用
恶意对象选择:使用 DruidXADataSource 作为攻击载体
攻击原理:
validationQuery字段会在连接池验证连接时被执行- 在该字段中嵌入 SQL CALL 语句
- 调用 Spring 的反序列化工具类执行构造好的 payload
具体实现:
DruidXADataSource ds = new DruidXADataSource();
// 设置恶意 validationQuery,包含 SQL CALL 语句
ds.setValidationQuery("CALL malicious_procedure()");
攻击执行流程
DruidXADataSource.getXAConnection()执行 SQL 语句- 调用
com.fr.third.springframework.util.SerializationUtils.deserialize方法 - 进行反序列化操作,执行恶意 payload
完整利用条件
环境要求
- 目标系统使用 Guava 库(包含漏洞版本)
- 存在 Jackson 库的
JSONArray类 - 系统中包含 Druid 连接池相关类
- 存在 Spring 框架的序列化工具类
技术前提
- 攻击者能够控制反序列化数据源
- 目标系统存在相应的类路径依赖
- 安全防护机制未阻止该特定利用链
防护建议
代码层面防护
- 对反序列化操作进行严格的白名单控制
- 更新 Guava 库到已修复漏洞的版本
- 对输入数据进行严格的验证和过滤
系统层面防护
- 使用安全管理器限制反序列化操作
- 实施最小权限原则,减少攻击面
- 定期进行安全审计和漏洞扫描
总结
该利用链巧妙地结合了多个流行框架的特性:
- 利用 Guava 不可变集合的空值检查机制
- 通过 Jackson 的字符串转换触发 getter 方法
- 借助 Druid 连接池的 SQL 执行能力
- 最终通过 Spring 的反序列化工具完成攻击
这种复杂的利用链表明,现代 Java 应用安全需要综合考虑各种组件之间的交互影响,实施纵深防御策略。