Ywc's blog

CVE-2020-1938:Tomcat AJP文件包含漏洞分析

Word count: 1.2kReading time: 4 min
2020/03/01

漏洞概述

由于Tomcat在处理AJP请求时,未对请求做任何验证,通过设置AJP连接器封装的request对象的属性, 导致产生任意文件读取漏洞和代码执行漏洞

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

影响范围:

Apache Tomcat 9.x < 9.0.31

Apache Tomcat 8.x < 8.5.51

Apache Tomcat 7.x < 7.0.100

Apache Tomcat 6.x

本次漏洞与三个include属性有关

  • javax.servlet.include.request_uri
  • javax.servlet.include.path_info
  • javax.servlet.include.servlet_path

任意文件读取

任意文件读取问题出现在org.apache.catalina.servlets.DefaultServlet这个Servlet

构造一个AJP请求,请求会走默认的DefaultServlet并交给DefaultServletdoGet方法处理。
doGet会调用ServeResource方法获取资源文件,调用getRelativePath方法获取要读取资源的相对路径,通过getResources方法就可以获取到了对应路径的Web资源对象。
然后再通过控制ajp控制的上述三个include属性来读取文件,通过操控上述三个属性从而可以读取到/WEB-INF下面的所有敏感文件,不限于class、xml、jar等文件。

任意代码执行

任意代码执行问题出现在org.apache.jasper.servlet.JspServlet这个servlet

构造一个如下的AJP请求,让Tomcat执行/docs/test.jsp,但实际上它会将code.txt当成jsp来解析执行。

1
2
3
4
RequestUri:/docs/test.jsp
javax.servlet.include.request_uri: /
javax.servlet.include.path_info: code.txt
javax.servlet.include.servlet_path: /

code.txt内容如下:

1
2
3
4
5
6
7
8
<%
java.util.List<String> commands = new java.util.ArrayList<String>();
commands.add("/bin/bash");
commands.add("-c");
commands.add("/Applications/Calculator.app/Contents/MacOS/Calculator");
java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder(commands);
pb.start();
%>

发送AJP请求,请求的是/docs/test.jsp这个jsp,但是由于那三个include属性可控,可以将test.jsp对应的服务器脚本文件改为code.txt,导致tomcat把我们的code.txt当jsp文件编译运行,导致代码执行。

Tomcat AJP Connector以及AJP协议

Tomcat Connector 是 Tomcat 与外部连接的通道,它使得 Catalina 能够接收来自外部的请求,传递给对应的 Web 应用程序处理,并返回请求的响应结果。

默认情况下,Tomcat 配置了两个 Connector,它们分别是 HTTP ConnectorAJP Connector:

1
2
3
HTTP Connector:用于处理 HTTP 协议的请求(HTTP/1.1),默认监听地址为 0.0.0.0:8080

AJP Connector:用于处理 AJP 协议的请求(AJP/1.3),默认监听地址为 0.0.0.0:8009

HTTP Connector 就是用来提供我们经常用到的 HTTP Web 服务。而 AJP Connector,它使用的是 AJP 协议(Apache Jserv Protocol),AJP 协议可以理解为 HTTP 协议的二进制性能优化版本,它能降低 HTTP 请求的处理成本,因此主要在需要集群、反向代理的场景被使用。

AJP是Apache Tomcat web服务器用来与servlet容器通信的一个二进制协议。主要用于集群或逆向代理场景,其中web服务器与应用服务器或servelet容器进行通信。

简单来说,就是HTTP Connector暴露给客户端了,AJP是webserver (如Apache HTTPD)和Apache Tomcat服务器之间内部使用的,如下图所示。AJP在Apache HTTP服务器中是以模块的形式实现的,表示为mod_jk或mod_proxy_ajp。AJP本身并不会暴露到外部,这也是下一部分要讨论的RCE场景的先决条件之一。

CVE-2020-1938-Tomcat-AJP文件包含漏洞分析

漏洞修复

1.将Tomcat立即升级到9.0.31、8.5.51或7.0.100版本进行修复。
2.禁用AJP协议

  • 具体方法:编辑 /conf/server.xml,找到如下行:

    1
    <Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />

3.配置secret来设置AJP协议的认证凭证。

  • 例如(注意必须将YOUR_TOMCAT_AJP_SECRET更改为一个安全性高、无法被轻易猜解的值):

    1
    <Connector port="8009"protocol="AJP/1.3" redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS" secret="YOUR_TOMCAT_AJP_SECRET"/>

Reference

http://gv7.me/articles/2020/cve-2020-1938-tomcat-ajp-lfi/#2-2-%E4%BB%BB%E6%84%8F%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C

https://www.chaitin.cn/zh/ghostcat

https://mp.weixin.qq.com/s/Y05EOzMhyztogNtL41MNNw

CATALOG
  1. 1. 漏洞概述
  2. 2. 任意文件读取
  3. 3. 任意代码执行
  4. 4. Tomcat AJP Connector以及AJP协议
  5. 5. 漏洞修复
  6. 6. Reference