H2 Database Web Console 未授权 JNDI 注入 RCE 漏洞 CVE-2021-42392¶
漏洞描述¶
H2 Database 是一个快速、开源的基于 Java 的关系型数据库管理系统(RDBMS),可用于嵌入式(集成在 Java 应用中)和客户端-服务器模式。
当 Spring Boot 集成 H2 Database 时,如果设置如下选项,将会启用 Web 管理页面:
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
H2 Database 管理页面支持通过 JNDI 加载 JDBC 驱动,攻击者可以利用 JNDI 注入实现远程代码执行。
参考链接:
- https://jfrog.com/blog/the-jndi-strikes-back-unauthenticated-rce-in-h2-database-console/
- https://www.leavesongs.com/PENETRATION/talk-about-h2database-rce.html
- https://mp.weixin.qq.com/s?__biz=MzI2NTM1MjQ3OA==&mid=2247483658&idx=1&sn=584710da0fbe56c1246755147bcec48e
- https://github.com/h2database/h2database/commit/b24aa46f48904ce64443f8f4353d70a2eed09037
- https://github.com/h2database/h2database/security/advisories/GHSA-h376-j262-vhq6
漏洞影响¶
1.1.100<= H2 Console <=2.0.204
环境搭建¶
Vulhub 执行如下命令启动一个集成了 H2 Database 2.0.204 版本的 Spring Boot:
docker compose up -d
容器启动后,Spring Boot 服务监听在 http://your-ip:8080
,H2 管理页面默认地址为 http://your-ip:8080/h2-console/
。
漏洞复现¶
在复现本漏洞前,可以先确认 CVE-2018-10054 中的 payload 已无法利用,因为 1.4.198 版本及以后,内存数据库被禁用,报错 Database “mem:test” not found, either pre-create it or allow remote database creation (not recommended in secure environments)
:
jdbc:h2:mem:test
1.4.198 版本及以后的 H2 控制台中,添加了新的 -ifNotExists
选项,默认禁用远程数据库创建,这将导致攻击者必须找到一个已存在的 H2 数据库才能执行上述 JDBC 攻击。但 H2 控制台依然支持 JNDI注入,可用于执行任意代码。
直到官方在 2.1.210 中修复了 CVE-2022-23221 漏洞,才彻底解决 Web console 登陆页面的 RCE 问题。
我们可以直接使用 Java-Chains 来利用该漏洞。首先,使用 JNDI/JNDIResourceRefPayload
模块生成恶意 JNDI URL(记得填写你想执行的命令):
然后,访问 H2 Web 控制台登录页,将 Driver class 填写为 javax.naming.InitialContext
,JDBC URL 填写为 Java-Chains 生成的 JNDI URL:
如图所示,命令已被成功执行:
漏洞修复¶
升级至最新版本: https://github.com/h2database/h2database/releases/
对于暂时无法升级 H2 的用户,可以采取以下措施进行缓解:
- 与 Log4Shell 漏洞类似,较新版本的 Java 包含 trustURLCodebase,不允许通过 JNDI 加载远程代码库。用户可以通过升级 Java (JRE/JDK) 版本进行缓解该漏洞。在以下 Java 版本(或任何更高版本)上默认启用此缓解措施(该方法可能会被绕过):6u211、7u201、8u191、11.0.1。
- 当 H2 控制台 Servlet 部署在 Web 服务器上(不使用独立的 H2 Web 服务器)时,可以使用设置白名单方法,仅允许特定用户访问控制台页面。