从JDBC attack到detectCustomCollations利用范围扩展
字数 1830 2025-08-26 22:11:15

MySQL JDBC 反序列化漏洞分析与利用

漏洞概述

MySQL JDBC 驱动存在反序列化漏洞,攻击者可以通过构造恶意的 JDBC 连接字符串,利用 MySQL 驱动的某些特性触发 Java 反序列化操作,从而执行任意代码。

关键利用点

1. JDBC 连接字符串关键属性

String url = "jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections4_calc";
  • autoDeserialize: 自动检测与反序列化存在 BLOB 字段中的对象
  • statementInterceptors: 实现了 com.mysql.jdbc.StatementInterceptor 接口的拦截器类
  • queryInterceptors: 高版本中替代 statementInterceptors 的属性

2. 反序列化触发点 - getObject 方法

ResultSetImpl.getObject() 方法中:

  1. 判断字段类型是否为 BIT 类型
  2. 调用 getObjectDeserializingIfNeeded 方法
  3. 检查字段是否为 Binary 或 Blob 类型
  4. 检查是否开启 autoDeserialize
  5. 检查前两个字节是否为序列化标志 (0xACED)
  6. 调用 readObject 进行反序列化

3. ServerStatusDiffInterceptor 拦截器利用

com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor 类中的调用链:

  1. populateMapWithSessionStatusValues 方法执行 SHOW SESSION STATUS 查询
  2. 调用 Util.resultSetToMap(toPopulate, rs)
  3. resultSetToMap 中调用 rs.getObject(1)rs.getObject(2)
  4. 最终触发反序列化

4. detectCustomCollations 利用 (5.1.29+)

ConnectionImpl#buildCollationMapping 方法中:

  1. 执行 SHOW COLLATION 查询
  2. 调用 Util.resultSetToMap 处理结果
  3. 触发 getObject 方法调用

触发条件

  • 服务端版本 > 4.1.0
  • detectCustomCollations=true
  • 对于 5.1.28 以下版本,还需要版本 > 5.0.0

版本差异与利用

1. ServerStatusDiffInterceptor 利用版本

  • 5.1.11-6.0.6: 使用 statementInterceptors 属性
  • 8.0+: 使用 queryInterceptors 属性
  • 5.1.10 及以下: 不可用,因为 Interceptors 初始化在利用过程之后

2. detectCustomCollations 利用版本

  • 5.1.29-5.1.48: 可用
  • 5.1.49+: 不可用(代码修改)
  • 6.x: 可用(使用 ResultSetUtil.resultSetToMap
  • 8.0.x: 不可用(没有 getObject 方法调用)

3. 版本关键变更

  • 5.1.41: 不再调用 Util.resultSetToMap,改为直接调用 getObject
  • 5.1.49: 修改导致 detectCustomCollations 不可用
  • 5.1.28→5.1.29: 添加 detectCustomCollations 属性判断

利用工具修改

对于 detectCustomCollations 利用,需要修改恶意 MySQL 服务端:

  1. handle_server 方法中修改返回结果
  2. 确保第3列包含序列化数据(5.1.41+版本)
  3. 对于 config.json 配置方式,将某个233改为 yso_dict[username]

防御措施

  1. 升级到最新版本 MySQL Connector/J
  2. 避免使用 autoDeserialize=true
  3. 限制 JDBC 连接字符串中的拦截器配置
  4. 使用网络隔离限制数据库连接

参考链接

MySQL JDBC 反序列化漏洞分析与利用 漏洞概述 MySQL JDBC 驱动存在反序列化漏洞,攻击者可以通过构造恶意的 JDBC 连接字符串,利用 MySQL 驱动的某些特性触发 Java 反序列化操作,从而执行任意代码。 关键利用点 1. JDBC 连接字符串关键属性 autoDeserialize : 自动检测与反序列化存在 BLOB 字段中的对象 statementInterceptors : 实现了 com.mysql.jdbc.StatementInterceptor 接口的拦截器类 queryInterceptors : 高版本中替代 statementInterceptors 的属性 2. 反序列化触发点 - getObject 方法 在 ResultSetImpl.getObject() 方法中: 判断字段类型是否为 BIT 类型 调用 getObjectDeserializingIfNeeded 方法 检查字段是否为 Binary 或 Blob 类型 检查是否开启 autoDeserialize 检查前两个字节是否为序列化标志 (0xACED) 调用 readObject 进行反序列化 3. ServerStatusDiffInterceptor 拦截器利用 com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor 类中的调用链: populateMapWithSessionStatusValues 方法执行 SHOW SESSION STATUS 查询 调用 Util.resultSetToMap(toPopulate, rs) 在 resultSetToMap 中调用 rs.getObject(1) 和 rs.getObject(2) 最终触发反序列化 4. detectCustomCollations 利用 (5.1.29+) 在 ConnectionImpl#buildCollationMapping 方法中: 执行 SHOW COLLATION 查询 调用 Util.resultSetToMap 处理结果 触发 getObject 方法调用 触发条件 : 服务端版本 > 4.1.0 detectCustomCollations=true 对于 5.1.28 以下版本,还需要版本 > 5.0.0 版本差异与利用 1. ServerStatusDiffInterceptor 利用版本 5.1.11-6.0.6 : 使用 statementInterceptors 属性 8.0+ : 使用 queryInterceptors 属性 5.1.10 及以下 : 不可用,因为 Interceptors 初始化在利用过程之后 2. detectCustomCollations 利用版本 5.1.29-5.1.48 : 可用 5.1.49+ : 不可用(代码修改) 6.x : 可用(使用 ResultSetUtil.resultSetToMap ) 8.0.x : 不可用(没有 getObject 方法调用) 3. 版本关键变更 5.1.41 : 不再调用 Util.resultSetToMap ,改为直接调用 getObject 5.1.49 : 修改导致 detectCustomCollations 不可用 5.1.28→5.1.29 : 添加 detectCustomCollations 属性判断 利用工具修改 对于 detectCustomCollations 利用,需要修改恶意 MySQL 服务端: 在 handle_server 方法中修改返回结果 确保第3列包含序列化数据(5.1.41+版本) 对于 config.json 配置方式,将某个233改为 yso_dict[username] 防御措施 升级到最新版本 MySQL Connector/J 避免使用 autoDeserialize=true 限制 JDBC 连接字符串中的拦截器配置 使用网络隔离限制数据库连接 参考链接 New Exploit Technique In Java Deserialization Attack MySQL Connector/J GitHub 仓库版本对比