MySQL JDBC中detectCustomCollations触发点不同版本的差异
字数 1589 2025-08-29 08:31:35
MySQL JDBC中detectCustomCollations触发点不同版本的差异分析
概述
本文详细分析MySQL JDBC驱动中detectCustomCollations触发点在不同版本中的差异,以及如何利用该特性进行反序列化攻击。该技术是JDBC Attack中对MySQL利用的两种主要方式之一(另一种是通过queryInterceptors)。
背景知识
在MySQL JDBC攻击中,通过detectCustomCollations触发反序列化的原理是:当JDBC客户端连接恶意MySQL服务器时,服务器可以返回特制的序列化数据,在某些版本的JDBC驱动中会触发反序列化操作,从而导致RCE。
版本差异分析
1. 5.1.18及以下版本
- 行为:对
SHOW COLLATION返回的结果未使用getObject() - 结论:无法触发反序列化
2. 5.1.19-5.1.39版本
- 处理逻辑:
- 对
SHOW COLLATION返回结果调用Util.resultSetToMap进行处理 resultSetToMap与ServerStatusDiffInterceptor相同- 最终走到
ResultSetImpl#getObject触发反序列化
- 对
- 调用链:
detectCustomCollations -> Util.resultSetToMap -> ResultSetImpl#getObject - 结论:可以触发反序列化
3. 5.1.40-5.1.48版本
-
处理变化:
- 不再直接调用
ResultSetImpl#getObject - 但对
SHOW COLLATION结果的第三列直接调用results.getObject() - 最终仍进入
ResultSetImpl#getObject
- 不再直接调用
-
关键点:
- 当字段类型为-4(blob)、-3(bit)、-2(binary)时,会进入
getObjectDeserializingIfNeeded方法 - 需要修改恶意MySQL服务器代码,将第三个字段填充为序列化数据
- 当字段类型为-4(blob)、-3(bit)、-2(binary)时,会进入
-
触发条件:
- 需要在连接URL中设置
autoDeserialize=true
- 需要在连接URL中设置
-
结论:可以触发反序列化
4. 5.1.49版本
- 行为:真正没有调用
getObject() - 结论:无法触发反序列化
5. 6.0.2-6.0.6版本
-
处理变化:
- 又直接调用
ResultSetUtil.resultSetToMap - 回到
ServerStatusDiffInterceptor那条链
- 又直接调用
-
结论:可以触发反序列化
6. 8.x版本
- 行为:获取
SHOW COLLATION时处理方式改变 - 结论:无法利用该点触发反序列化
利用方法总结
-
可触发版本范围:
- 5.1.18 < version ≤ 6.0.6(不包括5.1.49)
-
恶意服务器配置:
- 需要修改代码将第三个字段填充为yso序列化的数据
- 对于5.1.40+版本,需要确保第三列数据类型为blob/bit/binary
-
客户端配置:
- 在连接URL中设置
autoDeserialize=true
- 在连接URL中设置
防御建议
- 升级到不受影响的JDBC驱动版本(8.x或5.1.49)
- 避免使用不受信任的MySQL服务器
- 检查连接URL中是否设置了
autoDeserialize=true
参考实现
恶意MySQL服务器需要实现以下功能:
- 响应
SHOW COLLATION命令 - 在返回结果中:
- 对于5.1.19-5.1.39:填充序列化数据到适当字段
- 对于5.1.40+:确保第三列是blob/bit/binary类型并包含序列化数据
总结
了解MySQL JDBC驱动在不同版本中对detectCustomCollations的处理差异对于安全研究和防御都至关重要。攻击者可以利用这些差异构造特定的攻击载荷,而防御者则需要根据这些信息选择合适的防御策略。