Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

渗透技巧 6个月前 admin
156 0 0

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Overview 概述

In an effort to safeguard our customers, we perform proactive vulnerability research with the goal of identifying zero-day vulnerabilities that are likely to impact the security of leading organizations.  We decided to focus on the F5 BIG-IP suite, as F5 products are fairly ubiquitous among large corporations. We targeted the F5 BIG-IP Virtual Edition with the goal of finding an unauthenticated vulnerability that would result in complete compromise of the target server.
为了保护我们的客户,我们执行了主动的漏洞研究,目的是识别可能影响领先组织安全的零日漏洞。 我们决定专注于 F5 BIG-IP 套件,因为 F5 产品在大公司中相当普遍。我们以 F5 BIG-IP 虚拟版为目标,目标是找到一个未经身份验证的漏洞,该漏洞会导致目标服务器完全受损。

As a result of our research we were able to identify an authentication bypass issue that led to complete compromise of an F5 system with the Traffic Management User Interface (TMUI) exposed. The bypass was assigned CVE-2023-46747, and is closely related to CVE-2022-26377. Like our recently reported Qlik RCE, the F5 vulnerability was also a request smuggling issue. In this blog we will discuss our methodology for identifying the vulnerability, walk through the underlying issues that caused the bug, and explain the steps we took to turn the request smuggling into a critical risk issue. We will conclude with remediation steps and our thoughts on the overall process.
作为我们的研究的结果,我们能够识别出身份验证绕过问题,该问题导致暴露了流量管理用户界面 (TMUI) 的 F5 系统完全受损。绕过被分配为 CVE-2023-46747,与 CVE-2022-26377 密切相关。就像我们最近报道的 Qlik RCE 一样,F5 漏洞也是一个请求走私问题。在这篇博客中,我们将讨论识别漏洞的方法,演练导致错误的潜在问题,并解释我们为将请求走私转变为关键风险问题而采取的步骤。最后,我们将介绍补救步骤和我们对整个过程的想法。

Recent F5 Vulnerabilities
最近的 F5 漏洞

Attackers recently exploited two major F5 CVEs in the wild. The first of these, released in 2020, was CVE-2020-5902. Briefly, this was an issue where the Apache httpd service interpreted the “/..;/” characters in a URL differently than the Apache Tomcat service on the backend. Orange Tsai conducted the original research that discovered the parser vulnerability class and presented it at BlackHat in 2018. Orange’s slide from the presentation explains the issue very well (see figure 1):
攻击者最近在野外利用了两个主要的 F5 CVE。其中第一个于 2020 年发布,是 CVE-2020-5902。简而言之,这是Apache httpd服务解释“/..;URL 中的 /“ 字符与后端的 Apache Tomcat 服务不同。Orange Tsai进行了发现解析器漏洞类的原始研究,并于2018年在BlackHat上进行了展示。Orange的演示幻灯片很好地解释了这个问题(见图1):

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 1: Orange Tsai’s Blackhat 2018 Presentation
图1:Orange Tsai的Blackhat 2018演示文稿

The proof of concept for CVE-2020-5902 was a simple HTTP request to bypass authentication requirements and send a request to the “tmshCmd.jsp” endpoint, which executed tmsh commands on the system. The following is an example curl request to bypass auth:
CVE-2020-5902 的概念验证是一个简单的 HTTP 请求,用于绕过身份验证要求并将请求发送到“tmshCmd.jsp”端点,该端点在系统上执行 tmsh 命令。以下是绕过身份验证的示例 curl 请求:

curl -k 'https://<host>:<port>/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin'

Attackers exploited the vulnerability in the wild and CISA released an advisory about the activity. The “/tmui” API contained the relevant handler code for this bug.
攻击者在野外利用了这个漏洞,CISA发布了有关该活动的公告。“/tmui”API 包含此错误的相关处理程序代码。

The second F5 vulnerability disclosure occurred in 2022 (CVE-2022-1388). At a very high level, due to how HTTP Hop by Hop headers are processed, setting the header “Connection: X-F5-Auth-Token” resulted in the “X-F5-Auth-Token” header not appearing in the request that the backend code processes. The backend code did not stop processing in the absence of the header, resulting in the request going through successfully as if it were authenticated.
第二次 F5 漏洞披露发生在 2022 年 ( CVE-2022-1388)。在非常高的级别上,由于 HTTP 逐跃点标头的处理方式,设置标头“连接:X-F5-身份验证令牌”会导致“X-F5-身份验证令牌”标头未显示在后端代码处理的请求中。在没有标头的情况下,后端代码不会停止处理,从而导致请求成功通过,就像它已经过身份验证一样。

The example request below (from this proof of concept) results in code execution. The “/mgmt/tm/util/bash” API is an endpoint that executes commands and returns the results.
下面的示例请求(来自此概念证明)导致代码执行。“/mgmt/tm/util/bash” API 是执行命令并返回结果的端点。

POST /mgmt/tm/util/bash HTTP/1.1

Host: <redacted>:8443

Authorization: Basic YWRtaW46

Connection: keep-alive, X-F5-Auth-Token

X-F5-Auth-Token: 0

{"command": "run" , "utilCmdArgs": " -c 'id' " }

This authentication vulnerability dealt with a different component of the F5 BIG-IP API, the “/mgmt” handler.
此身份验证漏洞涉及 F5 BIG-IP API 的不同组件,即“/mgmt”处理程序。

F5 has since patched both of these vulnerabilities, and further updated the relevant JSP handlers in the “/tmui” API to restrict their functionality. The “fileRead.jsp” handler will not read arbitrary files anymore (it is restricted to a very small subset) and the “tmshCmd.jsp” handler does not execute arbitrary tmsh commands (it is a small subset of “ilx” related functionality).
此后,F5 修补了这两个漏洞,并进一步更新了“/tmui”API 中的相关 JSP 处理程序以限制其功能。“fileRead.jsp”处理程序将不再读取任意文件(它仅限于非常小的子集),并且“tmshCmd.jsp”处理程序不会执行任意 tmsh 命令(它是“ilx”相关功能的一小部分)。

Mapping out the F5 BIG-IP Attack Surface
绘制 F5 BIG-IP 攻击面

While previous write-ups provided a rough idea of the F5 tech stack, the best source of information is the appliance itself. We deployed a default F5 installation using a cheap AWS Marketplace template and began identifying components on the server.
虽然之前的文章提供了F5技术堆栈的粗略概念,但最好的信息来源是设备本身。我们使用廉价的 AWS Marketplace 模板部署了默认的 F5 安装,并开始识别服务器上的组件。

[admin@localhost:Active:Standalone] ~ # cat /etc/os-release

NAME="CentOS Linux"

VERSION="7 (Core)"

ID="centos"

ID_LIKE="rhel fedora"

VERSION_ID="7"

PRETTY_NAME="CentOS Linux 7 (Core)"

ANSI_COLOR="0;31"

CPE_NAME="cpe:/o:centos:centos:7"

HOME_URL="https://www.centos.org/"

BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"

CENTOS_MANTISBT_PROJECT_VERSION="7"

REDHAT_SUPPORT_PRODUCT="centos"

REDHAT_SUPPORT_PRODUCT_VERSION="7"

[admin@localhost:Active:Standalone] ~ # uname -r

3.10.0-862.14.4.el7.ve.x86_64

A quick look at the OS banner and kernel version let us know that the appliance was running on CentOS 7.5-1804 which was released in 2018. While CentOS 7 had not aged beyond its end of life, the older kernel base gave us reason to examine the versions for other core software components on the machine. Several server components were on the older side but the version banner for one component in particular stood out:
快速浏览操作系统横幅和内核版本,让我们知道该设备是在 2018 年发布的 CentOS 7.5-1804 上运行的。虽然 CentOS 7 的寿命并没有超过其寿命,但较旧的内核基础让我们有理由检查机器上其他核心软件组件的版本。几个服务器组件位于较旧的一侧,但一个组件的版本横幅特别突出:

[admin@localhost:Active:Standalone] ~ # httpd -version

Server version: BIG-IP 67.el7.centos.5.0.0.5 (customized Apache/2.4.6) (CentOS)

Server built:   Jul 11 2023 09:24:58

Vulnerable Apache Version
易受攻击的阿帕奇版本

The version of Apache on the F5 appliance, while customized, was still based from 2.4.6, which meant the developers needed to maintain a sizable number of security patches in order to ensure a secure system. Coming off of our Qlik Sense Enterprise vulnerability research, we were particularly interested in potential vulnerabilities related to HTTP request smuggling. We knew from the previously discussed F5 vulnerabilities from 2020 and 2022 that a discrepancy in the way that frontend and backend systems interpreted a request was likely to result in an authentication bypass issue.
F5 设备上的 Apache 版本虽然是定制的,但仍基于 2.4.6,这意味着开发人员需要维护大量安全补丁以确保系统安全。从我们的 Qlik Sense Enterprise 漏洞研究中,我们对与 HTTP 请求走私相关的潜在漏洞特别感兴趣。我们从之前讨论的 2020 年和 2022 年的 F5 漏洞中知道,前端和后端系统解释请求的方式差异可能会导致身份验证绕过问题。

We identified one such request smuggling vulnerability, CVE-2022-26377, as potentially impacting the custom Apache 2.4.6 version. Interestingly, F5 had even acknowledged this vulnerability as an issue in a public KB article they published. While they identified all major supported versions of F5-BIG IP as “affected,” they did not release a fix to address the vulnerability. We hypothesized that maybe F5 believed that the issue could not be meaningfully exploited to cause a direct security impact beyond more hypothetical or theoretical risks.
我们发现了一个此类请求走私漏洞 CVE-2022-26377,它可能会影响自定义 Apache 2.4.6 版本。有趣的是,F5 甚至在他们发布的一篇公开知识库文章中承认了这个漏洞是一个问题。虽然他们将 F5-BIG IP 的所有主要受支持版本确定为“受影响”,但他们没有发布修复程序来解决该漏洞。我们假设,也许 F5 认为除了更多假设或理论风险之外,无法有意义地利用该问题来造成直接的安全影响。

One of CVE-2022-26377’s original reporters wrote an excellent blog post (note, this blog post no longer exists; please see the original hackerone report) describing the straightforward exploitation of the vulnerability. We decided to track down this request smuggling issue in the custom httpd software running on the server.
CVE-2022-26377 的一位原始报告者撰写了一篇出色的博客文章(注意,此博客文章已不复存在;请参阅原始 hackerone 报告),描述了对该漏洞的直接利用。我们决定在服务器上运行的自定义httpd软件中追踪此请求走私问题。

Apache JServ Protocol (AJP) and Tomcat
Apache JServ Protocol (AJP) 和 Tomcat

The next step was to identify whether the F5 appliance used Apache JServ Protocol (AJP). A look at `/usr/share/tomcat/conf/server.xml` confirmed the usage of an AJP connector on Tomcat, a prerequisite for the request smuggling vulnerability.
下一步是确定 F5 设备是否使用 Apache JServ 协议 (AJP)。查看“/usr/share/tomcat/conf/server.xml”确认了Tomcat上使用AJP连接器,这是请求走私漏洞的先决条件。

<Service name="Catalina">

<!-- Define an AJP 1.3 Connector on port 8009 -->

<Connector port="8009" protocol="AJP/1.3"

redirectPort="8443"

enableLookups="true"

address="127.0.0.1"

maxParameterCount="32500"

tomcatAuthentication="false" />

We also observed that the Apache httpd configuration (/etc/httpd/conf.d/proxy_ajp.conf) used AJP to route requests to the backend application running Apache Tomcat application (see Figure 2).
我们还观察到 Apache httpd 配置 (/etc/httpd/conf.d/proxy_ajp.conf) 使用 AJP 将请求路由到运行 Apache Tomcat 应用程序的后端应用程序(参见图 2)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 2: The httpd configuration for routing AJP requests.
图 2:用于路由 AJP 请求的 httpd 配置。

All AJP routing rules required that the initial request URI contain the “/tmui/” endpoints. Because of this requirement, the “/mgmt” API for running commands from CVE-2022-1388 would not be reachable via AJP request tunneling.
所有 AJP 路由规则都要求初始请求 URI 包含“/tmui/”端点。由于此要求,无法通过 AJP 请求隧道访问用于运行 CVE-2022-1388 命令的“/mgmt”API。

F5 Traffic Management User Interface (TMUI) Overview

The F5 Traffic Management User Interface (TMUI) routed all HTTP requests to different services on the backend using the ProxyPassMatch routing rules within Apache httpd. Requests to “/tmui” endpoints were ultimately forwarded to the AJP (Apache JServ Protocol) service listening on port 8009 (see figure 3). Checking the processes listening on that port led us to the relevant Java process, as figure 4 shows.

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 3: A java process listened on port 8009.

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 4: The java process listening on 8009 was Tomcat.
图 4:侦听 8009 的 Java 进程是 Tomcat。

Upon reviewing the Tomcat deployment directory, the “tmui.xml” file provided some more information on where to locate the relevant “/tmui” files (see figure 5).
在查看 Tomcat 部署目录后,“tmui.xml”文件提供了有关在何处查找相关“/tmui”文件的更多信息(参见图 5)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 5: The tomcat deployment XML file contained the base directory for the TMUI code.
图 5:tomcat 部署 XML 文件包含 TMUI 代码的基本目录。

Within the “/usr/local/www/tmui” directory, the servlet’s “web.xml” file contained all the mapping information for the relevant handlers, as figure 6 shows:
在 “/usr/local/www/tmui” 目录中,servlet 的 “web.xml” 文件包含相关处理程序的所有映射信息,如图 6 所示:

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 6: The Tomcat server’s web.xml mapping for the TMUI API.
图 6:TMUI API 的 Tomcat 服务器的 Web.xml 映射。

These files confirmed that Tomcat served the AJP process listening on port 8009 and that the “/usr/local/www/tmui” directory contained the relevant Java code and handlers.

Verifying AJP Smuggling

At a glance it appeared that hitting any `/tmui/` URL would be sufficient to trigger AJP smuggling. Before potentially going too deep into a research rabbit hole, we wanted to verify that AJP smuggling worked.

As a first step we took the example AJP payload implementation from RicterZ’s blog post (again, this blog post no longer is on the internet, please see the related hackerone report) and pointed it at a URL we knew would be publicly exposed–the login page.

$ xxd raw.dat

00000000: 0008 4854 5450 2f31 2e31 0000 012f 0000  ..HTTP/1.1.../..

00000010: 0931 3237 2e30 2e30 2e31 00ff ff00 0161  .127.0.0.1.....a

00000020: 0000 5000 0000 0a00 216a 6176 6178 2e73  ..P.....!javax.s

00000030: 6572 766c 6574 2e69 6e63 6c75 6465 2e72  ervlet.include.r

00000040: 6571 7565 7374 5f75 7269 0000 012f 000a  equest_uri.../..

00000050: 0022 6a61 7661 782e 7365 7276 6c65 742e  ."javax.servlet.

00000060: 696e 636c 7564 652e 7365 7276 6c65 745f  include.servlet_

00000070: 7061 7468 0001 532f 2f2f 2f2f 2f2f 2f2f  path..S/////////

00000080: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000090: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000a0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000b0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000c0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000d0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000e0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000000f0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000100: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000110: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000120: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000130: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000140: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000150: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000160: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000170: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000180: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

00000190: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000001a0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000001b0: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f  ////////////////

000001c0: 2f2f 2f2f 2f2f 2f2f 2f2f 000a 001f 6a61  //////////....ja

000001d0: 7661 782e 7365 7276 6c65 742e 696e 636c  vax.servlet.incl

000001e0: 7564 652e 7061 7468 5f69 6e66 6f00 0010  ude.path_info...

000001f0: 2f57 4542 2d49 4e46 2f77 6562 2e78 6d6c  /WEB-INF/web.xml

00000200: 00ff

$ curl -k -i http://our.f5.ami.ip:8443/tmui/login.jsp -H 'Transfer-Encoding: chunked, chunked' --data-binary @raw.dat

When we first sent this payload the server returned the login page, which is a normal and expected response. We then leveraged our advanced pentesting skills and re-ran the curl command several times, because sometimes vulnerability research is doing the same thing multiple times and somehow getting different results.
当我们第一次发送此有效负载时,服务器返回了登录页面,这是一个正常和预期的响应。然后,我们利用我们先进的渗透测试技能并多次重新运行curl命令,因为有时漏洞研究会多次做同样的事情,并以某种方式获得不同的结果。

Interestingly enough, after a few curl requests, we occasionally would receive 404 Not Found responses instead of the expected login page. This was the moment when we knew that our hunch about the AJP smuggling vulnerability was most likely correct. We also decompiled the relevant Apache .so modules and compared their implementation to the patched httpd source code.
有趣的是,在几个 curl 请求之后,我们偶尔会收到 404 未找到的响应,而不是预期的登录页面。这一刻,我们知道我们对AJP走私漏洞的预感很可能是正确的。我们还反编译了相关的 Apache .so 模块,并将它们的实现与修补后的 httpd 源代码进行了比较。

We’ll dig into how AJP packets work further into this blog post, but the example above is essentially the same as requesting to read the contents of /WEB-INF/web.xml from the ROOT webapp in Tomcat (the default PoC for 2020’s GhostCat vulnerability). By default the F5-BIGIP does not run a ROOT webapp, so the system returned a 404 instead. By explicitly creating a file at /usr/share/tomcat/webapps/ROOT/WEB-INF/web.xml, we were able to trigger the GhostCat LFI.
我们将在这篇博文中进一步深入探讨 AJP 数据包的工作原理,但上面的示例基本上与请求从 Tomcat 中的根 webapp 读取 /WEB-INF/web.xml 的内容相同(2020 年 GhostCat 漏洞的默认 PoC)。默认情况下,F5-BIGIP 不运行根 Web 应用,因此系统返回了 404。通过在 /usr/share/tomcat/webapps/ROOT/WEB-INF/web.xml 显式创建一个文件,我们能够触发 GhostCat LFI。

$ curl -k -i https://our.f5.ami.ip:8443/tmui/login.jsp -H 'Transfer-Encoding: chunked, chunked' --data-binary @raw.dat

HTTP/1.1 200 OK

Date: Fri, 08 Sep 2023 19:57:12 GMT

Server: Apache

X-Frame-Options: SAMEORIGIN

Strict-Transport-Security: max-age=16070400; includeSubDomains

Accept-Ranges: bytes

ETag: W/"60-1694202750000"

Last-Modified: Fri, 08 Sep 2023 19:52:30 GMT

Content-Type: application/xml

Content-Length: 60

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Content-Security-Policy: default-src 'self'  'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data:  http://127.4.1.1 http://127.4.2.1

Cache-Control: no-store

Pragma: no-cache

<Contents of File we wrote to /usr/share/tomcat/webapps/ROOT/WEB-INF/web.xml/>

At this point we knew that AJP smuggling was live on current versions of F5-BIGIP appliances; our next question was how to leverage it. This required understanding how the AJP smuggling CVE-2022-26377 actually worked.

AJP Smuggling and Server Interpretation

The Apache httpd description of CVE-2022-26377 states “Inconsistent Interpretation of HTTP Requests (‘HTTP Request Smuggling’) vulnerability in mod_proxy_ajp of Apache HTTP Server allows an attacker to smuggle requests to the AJP server it forwards requests to. This issue affects Apache HTTP Server 2.4 version 2.4.53 and prior versions.” We hoped that a request smuggling issue on the F5 httpd service would provide the authentication bypass that we needed to fully compromise the device.
Apache httpd 对 CVE-2022-26377 的描述指出“Apache HTTP 服务器mod_proxy_ajp中对 HTTP 请求的解释不一致(’HTTP 请求走私’)漏洞允许攻击者将请求偷运到它转发请求的 AJP 服务器。此问题会影响 Apache HTTP Server 2.4 版本 2.4.53 和更早版本。我们希望 F5 httpd 服务上的请求走私问题能够提供完全危害设备所需的身份验证绕过。

The blog post (unfortunately no longer online) partly described how the AJP smuggling occurred, but its explanation on “why” it occurred was not fully correct (keep in mind Google’s translation might not be exact). AJP is poorly documented and the best reference online is on the Apache site itself. We determined the best way to explain how and why the smuggling works is with an example walkthrough of the normal flow.
这篇博客文章(不幸的是不再在线)部分描述了AJP走私是如何发生的,但它对“为什么”发生的解释并不完全正确(请记住,谷歌的翻译可能并不准确)。AJP的记录很差,最好的在线参考是在Apache网站上。我们确定了解释走私如何以及为什么运作的最佳方式是通过正常流程的示例演练。

Normal AJP Message Processing
普通 AJP 消息处理

A binary AJP message sent from the httpd service to the backend AJP listener starts with the magic bytes “0x12” “0x34”, followed by a two byte message length, followed by the “data.” The 5th byte of the message contains the “Code,” a value that determines the type of AJP request. The Code for HTTP forward requests is the value “0x2”. The 6th byte of the HTTP forward request encodes the request’s HTTP verb. A GET request is 0x2, a POST request is 0x4, and so on. The rest of the message data encodes AJP attributes and HTTP request information.
从 httpd 服务发送到后端 AJP 侦听器的二进制 AJP 消息以魔术字节“0x12”“0x34”开头,后跟两个字节的消息长度,后跟“数据”。消息的第 5 个字节包含“Code”,该值确定 AJP 请求的类型。HTTP 转发请求的代码是值“0x2”。HTTP 转发请求的第 6 个字节对请求的 HTTP 谓词进行编码。0x2 GET 请求,0x4 POST 请求,依此类推。其余消息数据对 AJP 属性和 HTTP 请求信息进行编码。

A POST request might also contain body content. The AJP protocol encodes POST body content as its own special data message. The first bytes are the same magic bytes “0x1234,” and these are similarly followed by a two byte message length. The 5th and 6th bytes differ, these two bytes contain the data length. The rest of the message is the POST body data. A typical AJP POST message from the httpd service to the AJP listener will look like the following two packets sent back to back (see figures 7, 8 and 9).
POST 请求也可能包含正文内容。AJP 协议将 POST 正文内容编码为其自己的特殊数据消息。第一个字节是相同的魔术字节“0x1234”,这些字节后面同样跟着一个两个字节的消息长度。第 5 个和第 6 个字节不同,这两个字节包含数据长度。消息的其余部分是 POST 正文数据。从 httpd 服务到 AJP 侦听器的典型 AJP POST 消息类似于背靠背发送的以下两个数据包(参见图 7、8 和 9)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 7: A standard AJP Message to the server.
图 7:发往服务器的标准 AJP 消息。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 8: A AJP data message to the server (for sending POST body content).
图 8:发送到服务器的 AJP 数据消息(用于发送 POST 正文内容)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 9: The standard data flow between httpd and Tomcat.

Encoded in the “Data” packet of the first message is a “Content-Length” header that will match the length of the POST Body data. When the Tomcat AJP listener sees the “Content-Length” header, it reads another AJP packet from the input stream and interprets it as a data packet. Then a brief exchange occurs wherein it sends a message back to httpd and asks for more Body content, to which the httpd server replies with another data packet with zero length. Finally, the Tomcat AJP server sends back the expected HTTP response to the original request. Figure 10 shows what this looks like in Wireshark.

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 10: The two AJP messages sent to the server representing a HTTP Post request.

Note the “Content-Length” value in the message, as well as the Apache JServ Protocol Message at the bottom, which is the POST body content packet.

The code responsible for the AJP message processing lives in the AjpProcessor implementation, which we can see in figure 11.

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 11: The service method in the AJP Processor.
图 11:AJP 处理器中的服务方法。

The service method reads messages off a socket connection. When it sees a “Content-Length” header, it sets the “contentLengthSet” variable and notes that it needs to read a body later on in the process (see figure 12).
服务方法从套接字连接读取消息。当它看到“Content-Length”标头时,它会设置“contentLengthSet”变量,并注意到它需要在流程的稍后阶段读取正文(参见图 12)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 12: Checking the Content-Length header when processing an AJP message.
图 12:在处理 AJP 消息时检查内容长度标头。

The body is eventually read and processed, and it is pulled directly off the socket connection (as the second message from before, shown again in figure 13).
正文最终被读取和处理,并直接从套接字连接上拉出(如之前的第二条消息,如图 13 中再次显示)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 13: The expected POST Body data AJP message.
图 13:预期的开机自检正文数据 AJP 消息。

Smuggled AJP Processing 走私 AJP 加工

CVE-2022-26377 occurs when the original request to the Apache httpd service includes a “Transfer-Encoding” header with a value of “chunked, chunked”. The value “chunked, chunked” is a valid “Transfer-Encoding” header. When Apache receives both a “Transfer-Encoding” and “Content-Length” header, it removes the “Content-Length” header from the request it sends to the backend AJP server, as in figure 14.
当对 Apache httpd 服务的原始请求包含值为“分块,分块”的“传输编码”标头时,会发生 CVE-2022-26377。值“分块,分块”是有效的“传输编码”标头。当 Apache 同时收到“传输编码”和“内容长度”标头时,它会从发送到后端 AJP 服务器的请求中删除“Content-Length”标头,如图 14 所示。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 14: Apache when processing both a “Content-Length” and “Transfer-Encoding” header.

Because of this, the request sent to the Apache mod_proxy_ajp for forwarding does not contain a “Content-Length” header. First, the httpd AJP processor sends the request and its headers to the backend. Then mod_proxy_ajp checks if the “Transfer-Encoding” header is present and if it matches “chunked” exactly (see figure 15). Because the “chunked, chunked” value for the header it is processing does not match, it proceeds with the rest of the else branch and sends the POST body content directly to the backend server as an AJP data packet (see figure 16).

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 15: Apache httpd mod_proxy_ajp compared the “Transfer-Encoding” value to “chunked”.
图 15:Apache httpd mod_proxy_ajp将“传输编码”值与“分块”值进行了比较。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 16: A smuggled AJP message. Note the distinct request in the bottom left highlight, which is the BODY content.
图 16:走私的 AJP 邮件。请注意左下角突出显示的不同请求,即 BODY 内容。

After the httpd service encounters the “chunked, chunked” Transfer-Encoding, it sends the two messages in figures 17 and 18. Note that the Data Length is the length of the attacker controlled POST body, and the POST body IS the attacker controlled POST body.
在 httpd 服务遇到“分块、分块”传输编码后,它会发送图 17 和图 18 中的两条消息。请注意,数据长度是攻击者控制的 POST 正文的长度,而 POST 正文是攻击者控制的 POST 正文。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 17: The first AJP packet when sending a smuggled request. The data does not contain a “Content-Length” header. httpd removed it because of the “chunked, chunked” Transfer-Encoding.
图 17:发送走私请求时的第一个 AJP 数据包。数据不包含“内容长度”标头。httpd 删除了它,因为“分块,分块”传输编码。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 18: The second AJP packet when sending a smuggled request.
图 18:发送走私请求时的第二个 AJP 数据包。

The Tomcat AJP service processing the messages sees the first message come across, as we see in figure 19:
处理消息的 Tomcat AJP 服务会看到遇到的第一条消息,如图 19 所示:

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 19: The first received AJP packet message.
图 19:第一个收到的 AJP 数据包消息。

But, as in the Wireshark screenshot we referenced previously, the AJP message does not contain a “Content-Length” header. The Tomcat server does not read any post body data, and the second message sent by httpd is still sitting on the socket. After processing the first message, the whole loop continues, and another message is read from the socket (see figure 20).
但是,正如我们之前引用的Wireshark屏幕截图一样,AJP消息不包含“内容长度”标头。Tomcat服务器不读取任何帖子正文数据,httpd发送的第二条消息仍然位于套接字上。处理完第一条消息后,整个循环继续,并从套接字读取另一条消息(参见图 20)。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 20: The processing loop in the AJP handler.
图 20:AJP 处理程序中的处理循环。

The next (smuggled) message that the AJP handler reads looks like the following message to the httpd service that sent it along (see figure 21):
AJP 处理程序读取的下一条(走私)消息与发送它的 httpd 服务发送的以下消息类似(参见图 21):

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 21: What the httpd server thinks it is sending as an AJP message.
图 21:httpd 服务器认为它作为 AJP 消息发送的内容。

But the Tomcat AJP processor consumes the attacker controlled message as if it were what we see in figure 22.
但是Tomcat AJP处理器消耗攻击者控制的消息,就好像我们在图22中看到的那样。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 22: What the AJP processor interprets the smuggled AJP message as.
图 22:AJP 处理器将走私的 AJP 消息解释为什么。

This confusion is what causes CVE-2022-26377. If we submit a message with a POST body length of 0x204 (0x2 is the FORWARD_REQUEST Code, and 0x4 is the HTTP POST method), then the Tomcat AJP listener interprets corresponding data as an AJP POST request and sends it to wherever we want. The confusion results in request smuggling, with a constraint that the message length must be exactly 0x204 for it to be interpreted as a POST request. Figure 23 illustrates the new flow.
这种混乱是导致CVE-2022-26377的原因。如果我们提交一条 POST 正文长度为 0x204 的消息(0x2 是FORWARD_REQUEST代码,0x4是 HTTP POST 方法),那么 Tomcat AJP 侦听器会将相应的数据解释为 AJP POST 请求,并将其发送到我们想要的任何地方。这种混淆会导致请求走私,并限制消息长度必须完全0x204才能将其解释为 POST 请求。图 23 说明了新流程。

Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

Figure 23: The smuggled AJP request flow.
图 23:走私的 AJP 请求流。

But What To Do With the Smuggling?
但是走私怎么办?

REDACTED 已编辑

We bypassed authentication and executed commands as root on the target system.
我们绕过了身份验证,并以 root 用户身份在目标系统上执行命令。

REDACTED 已编辑

In the coming days we will post more information about the exploitation of this vulnerability, but given that there is no official patch for F5-BIGIP appliances yet, we believe that dropping all technical details would not be consistent with responsible disclosure.
在接下来的几天里,我们将发布有关利用此漏洞的更多信息,但鉴于目前还没有针对 F5-BIGIP 设备的官方补丁,我们认为删除所有技术细节与负责任的披露不一致。

Once F5 has dropped an official patch  and organizations have had time to apply it, we will post the remaining information about how to leverage AJP smuggling into compromising the device and executing commands as the root user.
一旦 F5 删除了官方补丁并且组织有时间应用它,我们将发布有关如何利用 AJP 走私来破坏设备并以 root 用户身份执行命令的剩余信息。

Remediation 修复

F5 released an advisory detailing the impacted versions and components. Follow the instructions outlined in the advisory and run the hotfix released by F5 on your systems. Additionally, restrict access to the TMUI portal entirely. The portal itself should not be accessible at all from the public internet. Including the issue described in this blog, there have been three unauthenticated remote code execution vulnerabilities in the TMUI portal within the past three years. If access to it is required, ensure the TMUI portal is only accessible from the internal network or from a VPN connection.
F5 发布了一份公告,详细说明了受影响的版本和组件。按照通报中概述的说明进行操作,并在您的系统上运行 F5 发布的修补程序。此外,完全限制对 TMUI 门户的访问。门户本身根本不应该从公共互联网访问。包括本博客中描述的问题在内,在过去三年中,TMUI 门户中存在三个未经身份验证的远程代码执行漏洞。如果需要访问它,请确保只能从内部网络或 VPN 连接访问 TMUI 门户。

Conclusion 结论

A seemingly low impact request smuggling bug can become a serious issue when two different services offload authentication responsibilities onto each other. Sending requests to the “backend” service that assumes the “frontend” handled authentication can lead to some interesting behavior. If you’re interested in these request smuggling vulnerabilities, take a look at our recent blog posts on Qlik: the first critical risk issue, and the patch bypass.
当两个不同的服务将身份验证责任相互卸载时,看似影响较小的请求走私错误可能会成为一个严重的问题。向假定“前端”处理的身份验证的“后端”服务发送请求可能会导致一些有趣的行为。如果您对这些请求走私漏洞感兴趣,请查看我们最近关于 Qlik 的博客文章:第一个关键风险问题和补丁绕过。

While the issue we highlighted in the F5 TMUI portal was a critical risk issue and an unknown vulnerability, you can still take steps to protect yourself. After the two previous RCEs in the TMUI service, the interface itself should not be exposed to the Internet in the first place. Our Chariot platform can help scan your attack surface to identify these risks proactively. Please don’t hesitate to contact us for a demo.
虽然我们在 F5 TMUI 门户中强调的问题是一个关键的风险问题和未知漏洞,但您仍然可以采取措施保护自己。在 TMUI 服务中的前两个 RCE 之后,接口本身首先不应该暴露在互联网上。我们的Chariot平台可以帮助扫描您的攻击面,以主动识别这些风险。请随时与我们联系进行演示。

Disclosure Timeline 披露时间表

October 4th, 2023 – Initial email to F5 sent (to [email protected]).
2023 年 10 月 4 日 – 发送给 F5 的初始电子邮件已发送(发送给 [email protected])。

October 5th, 2023 – Vulnerability report provided to the F5 SIRT team.
2023 年 10 月 5 日 – 向 F5 SIRT 团队提供漏洞报告。

October 12th, 2023 – Emailed F5 SIRT to ask for confirmation they received the report. F5 confirmed and also informed us that they were able to reproduce the vulnerability.
2023 年 10 月 12 日 – 通过电子邮件向 F5 SIRT 要求确认他们收到了报告。F5 确认并通知我们他们能够重现该漏洞。

October 16th, 2023 – Discussed potential disclosure timelines with F5 SIRT.
2023 年 10 月 16 日 – 与 F5 SIRT 讨论了潜在的披露时间表。

October 25th, 2023 – F5 SIRT informed us that their advisory would go live tomorrow (October 26th).
2023 年 10 月 25 日 – F5 SIRT 通知我们,他们的公告将于明天(10 月 26 日)上线。

October 26th, 2023 – Published initial advisory.
2023 年 10 月 26 日 – 发布初步公告。

 

原文始发于Michael Weber and Thomas Hendrickson:Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747

版权声明:admin 发表于 2023年10月27日 下午5:58。
转载请注明:Refresh: Compromising F5 BIG-IP With Request Smuggling | CVE-2023-46747 | CTF导航

相关文章

暂无评论

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