@Author: Patrilic
@Time: 2020-3-25 19:16:24

0x00 前言

CVE-2020-1938 又名GhostCat, 之前引起了一场风雨,由长亭科技安全研究员发现的存在于 Tomcat 中的安全漏洞,由于 Tomcat AJP 协议设计上存在缺陷,攻击者通过 Tomcat AJP Connector 可以读取或包含 Tomcat 上所有 webapp 目录下的任意文件,例如可以读取 webapp 配置文件或源代码。此外在目标应用有文件上传功能的情况下,配合文件包含的利用还可以达到远程代码执行的危害。

0x01 Build

Mac下的MxSrvs预装了Tomcat 8.5.16版本,可以直接使用

3607445bc52ecdd4057ef904486ecadd

开放了8005|8009|8080端口

/Applications/MxSrvs/bin/tomcat/bin/catalina.sh第一行export一个变量

1
export JPDA_ADDRESS=9001

然后将/Applications/MxSrvs/bin/tomcat/bin/startup.sh最后一行修改为

1
exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"

可以看到已经开启了9001端口
f1f7da80f2efd200c84f45a5e42453ae

然后我们导入Tomcat源码包:
直接用maven,一步到位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>Tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-coyote -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>8.5.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>8.5.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jasper -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.16</version>
</dependency>


</dependencies>


</project>

设置一个Remote Debug的配置
1be5bb0aaf28c983ba3fb724202bbd8e

0x02 Poc

利用 https://github.com/threedr3am/learnjavabug

文件读取
05e3a873d645296b07adbb972dbf4fb8

文件包含
f27c24c0952108f232076a4a2f62c1b7

0X03 Tomcat AJP Connector

在具体分析漏洞之前,先来了解一下Tomcat-Ajp是个什么东西
f27c24c0952108f232076a4a2f62c1b7

在tomcat目录的/conf/server.xml下配置了Connector
b61a0e70e7a0d26073aa2d0fe5dcb402

在默认情况下,会开启8080 HTTP协议端口和8009 Ajp协议端口

9b345b3f4cce9c0b1f835d972a9ccc77

简单来说,Tomcat提供Servlet容器,与其他静态资源HTTP服务器(IIS,Nginx等)集成,Tomcat和其他HTTP服务器之间需要通过专门的插件来通信,这就是Connector存在的意义

0x04 漏洞分析

DefaultServlet 实现任意文件读取

tomcat在处理AJP请求的时候,主要是通过
/tomcat-coyote-8.5.16.jar!/org/apache/coyote/ajp/AjpProcessor.class#prepareRequest()

所以我们在AjpProcessor.class的第232行处打断点,开启Debug
6a8b3adcca83195befc643a3392c1790

利用poc发送请求
bbc0da7e3954f284c117d644c17c2b10

前面通过一系列getXXX()方法,收集请求的协议,uri,ip,host,MIME等信息
b0f40bb3268ca77624dccedff3917b46

然后通过一个switch()语句, 到request.setAttribute()方法,设置了request的三个属性
4e0492de670614f7be25ad25348554cf

1
2
3
javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path

进入this.getAdapter().service(this.request, this.response);
497059d25d1991783848867fcc68df0c

/org/apache/catalina/connector/CoyoteAdapter.class:330反射处理了request,response
53e13cacce6fe164f3c80a34069745dd

org/apache/catalina/servlets/DefaultServlet.class:
service() -> doGet() -> serveResource()
7f97fd07dd91365ddf99edd534ac3320

调用getRelativePath()获取相对路径
22a68b3ce61392d4c2dcad32d9739d3b

1c909083047e8acdd5ecd3acc55cf433

往下走经过一个else判断,进入this.resources.getResource(path)
250ed69f892dca8efb9c5319e4182613

bc0f18a692524274b8806f3e8256a8eb

跟到/org/apache/tomcat/util/http/RequestUtil.class#normalize函数的时候,发现对穿越字符进行了过滤
4f2fa281bdfba9d49c719e7be1899ec0

所以不能逃脱webapp目录

之后利用File类进行文件读取,并经过一系列检查
5b3e886235a957d809d46f374579a4f6

部分调用栈
d7758aba4a97a6b5098c35fc49fa4b03

jspservlet 文件包含

调用方式和上面的大体相同,直到service()函数
50d5fa52e3541c9308c9fc6194c69dce

调用了
org/apache/jasper/servlet/JspServlet.class#service

b6ca5f6121c0f2e6610fc29df7bb4aed

拼接后,直接到serviceJspFile方法
66cdee9873c78cc6142a3a79c138d26e

102d1049bfc3e8ae94ba9736cf02ac72

部分调用栈
c2eb005ef5c082377c5be726963a321a

0x05 相关链接

https://www.chaitin.cn/zh/ghostcat
https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
https://www.anquanke.com/post/id/199448
https://github.com/threedr3am/learnjavabug/tree/master/tomcat/ajp-bug
https://my.oschina.net/czg/blog/142616
https://www.linuxprobe.com/tomcat-http-ajp.html
https://zhzhdoai.github.io/2020/02/26/Tomcat-Ajp%E5%8D%8F%E8%AE%AE%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E5%88%A9%E7%94%A8-CVE-2020-1938/