Tomcat Ajp协议文件包含漏洞分析
字数 2113 2025-08-26 22:12:03

Tomcat AJP协议文件包含漏洞(CVE-2020-1938)深入分析与防御指南

漏洞概述

漏洞编号: CVE-2020-1938 / CNVD-2020-10487
漏洞类型: 文件包含漏洞
影响范围:

  • Apache Tomcat 6
  • Apache Tomcat 7 < 7.0.100
  • Apache Tomcat 8 < 8.5.51
  • Apache Tomcat 9 < 9.0.31

漏洞描述: 攻击者可以利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件,包括webapp配置文件或源代码等敏感信息。在特定条件下,还可实现远程代码执行(RCE)。

漏洞背景知识

Tomcat架构简介

Tomcat的整体架构包含以下关键组件:

  • Server: 一个Tomcat实例就是一个Server
  • Service: 每个Server可以包含多个Service(逻辑层)
  • Connector: 处理客户端请求的组件
  • Container: 包含多个Host(虚拟主机)
    • 每个Host对应一个域名
    • 每个Host可包含多个Context(Web应用)
      • 每个Context包含多个Wrapper(封装Servlet)

关键配置文件

  1. conf/server.xml: 定义Tomcat启动时的组件属性

    • 包含两个重要的Connector:
      <!-- HTTP Connector -->
      <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
      
      <!-- AJP Connector -->
      <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
      
    • Tomcat启动后会监听8080(HTTP)和8009(AJP)端口
  2. conf/web.xml: 定义Servlet配置

    • 包含两个关键的内建Servlet:
      • DefaultServlet: 处理所有未被匹配到其他servlet的URI请求
      • JspServlet: 处理以.jsp/.jspx为后缀的URI请求

AJP协议简介

AJP(Apache JServ Protocol)是建立在TCP之上的二进制协议,主要用于Tomcat与前端的Web服务器(如Apache HTTP Server)通信。相比HTTP协议,AJP协议效率更高。

漏洞详细分析

漏洞成因

漏洞主要存在于Tomcat处理AJP协议的代码中,攻击者可以通过构造特殊的AJP请求控制request对象的某些属性,进而实现文件包含。

关键代码分析

  1. AJP请求处理(org.apache.coyote.ajp.AjpProcessor)

    • service()方法调用prepareRequest()解析请求头
    • 当AJP数据包头设置为SC_REQ_ATTRIBUTE时,Connector会读取属性名(n)和值(v)
    • 当n不是SC_A_REQ_LOCAL_ADDRSC_A_REQ_REMOTE_PORTSC_A_SSL_PROTOCOL时,会用v来赋值属性n
  2. DefaultServlet处理流程

    • 当请求URI无法匹配其他servlet时,由DefaultServlet处理
    • 调用链: service()doGet()serveResource()
    • getRelativePath()方法从request对象获取以下属性控制路径:
      javax.servlet.include.request_uri
      javax.servlet.include.path_info
      javax.servlet.include.servlet_path
      
    • 攻击者可通过AJP协议控制这些属性来读取任意文件
  3. JspServlet处理流程

    • 对于.jsp/.jspx请求,由JspServlet处理
    • service()方法通过可控属性构造jspUri:
      String jspUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
      if (jspUri == null) {
          jspUri = request.getServletPath();
      }
      
    • 后续会编译jsp文件生成servlet,实现文件包含

漏洞利用方式

  1. 任意文件读取

    • 通过控制DefaultServlet处理的路径,读取webapp目录下的任意文件
    • 包括配置文件、源代码等敏感信息
  2. 远程代码执行(RCE)

    • 前提: 能上传可控内容到webapp目录(如头像上传功能)
    • 步骤:
      1. 上传包含恶意JSP代码的文件(如evilman.png)
      2. 通过AJP协议包含该文件
      3. Tomcat会将其作为JSP编译执行

漏洞复现

环境准备

  • 受影响Tomcat版本(如8.5.40)
  • 内网测试环境(IP: 10.0.12.93)

复现步骤

  1. 任意文件下载测试

    • 使用公开POC工具
    • 成功读取webapp目录下的文件
  2. 文件包含到RCE

    • webapps/examples/下创建evilman.png,内容为:
      <% out.println(new java.io.BufferedReader(new java.io.InputStreamReader(Runtime.getRuntime().exec("whoami").getInputStream())).readLine()); %>
      
    • 通过AJP协议包含该文件
    • 成功执行系统命令,验证漏洞
  3. 查看编译结果

    • 编译后的jsp代码位于:
      work/Catalina/localhost/examples/org/apache/jsp/
      
    • 可查看生成的servlet代码

防御措施

  1. 升级Tomcat

    • 升级到安全版本:
      • Tomcat 7 ≥ 7.0.100
      • Tomcat 8 ≥ 8.5.51
      • Tomcat 9 ≥ 9.0.31
  2. 临时解决方案

    • 禁用AJP协议:
      修改conf/server.xml,注释掉8009端口的Connector:
      <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
      
  3. 其他防护建议

    • 限制AJP端口的访问(如防火墙规则)
    • 定期检查服务器上的可疑文件
    • 加强文件上传功能的安全检查

参考资源

  1. Tomcat AJP协议漏洞分析 - CSDN
  2. Tomcat架构解析 - CSDN
  3. Tomcat连接器详解 - CSDN
  4. AJP协议官方文档
  5. 漏洞深度分析 - 安全客
  6. 漏洞利用分析 - 安全客
Tomcat AJP协议文件包含漏洞(CVE-2020-1938)深入分析与防御指南 漏洞概述 漏洞编号 : CVE-2020-1938 / CNVD-2020-10487 漏洞类型 : 文件包含漏洞 影响范围 : Apache Tomcat 6 Apache Tomcat 7 < 7.0.100 Apache Tomcat 8 < 8.5.51 Apache Tomcat 9 < 9.0.31 漏洞描述 : 攻击者可以利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件,包括webapp配置文件或源代码等敏感信息。在特定条件下,还可实现远程代码执行(RCE)。 漏洞背景知识 Tomcat架构简介 Tomcat的整体架构包含以下关键组件: Server : 一个Tomcat实例就是一个Server Service : 每个Server可以包含多个Service(逻辑层) Connector : 处理客户端请求的组件 Container : 包含多个Host(虚拟主机) 每个Host对应一个域名 每个Host可包含多个Context(Web应用) 每个Context包含多个Wrapper(封装Servlet) 关键配置文件 conf/server.xml : 定义Tomcat启动时的组件属性 包含两个重要的Connector: Tomcat启动后会监听8080(HTTP)和8009(AJP)端口 conf/web.xml : 定义Servlet配置 包含两个关键的内建Servlet: DefaultServlet : 处理所有未被匹配到其他servlet的URI请求 JspServlet : 处理以.jsp/.jspx为后缀的URI请求 AJP协议简介 AJP(Apache JServ Protocol)是建立在TCP之上的二进制协议,主要用于Tomcat与前端的Web服务器(如Apache HTTP Server)通信。相比HTTP协议,AJP协议效率更高。 漏洞详细分析 漏洞成因 漏洞主要存在于Tomcat处理AJP协议的代码中,攻击者可以通过构造特殊的AJP请求控制request对象的某些属性,进而实现文件包含。 关键代码分析 AJP请求处理(org.apache.coyote.ajp.AjpProcessor) service() 方法调用 prepareRequest() 解析请求头 当AJP数据包头设置为 SC_REQ_ATTRIBUTE 时,Connector会读取属性名(n)和值(v) 当n不是 SC_A_REQ_LOCAL_ADDR 、 SC_A_REQ_REMOTE_PORT 或 SC_A_SSL_PROTOCOL 时,会用v来赋值属性n DefaultServlet处理流程 当请求URI无法匹配其他servlet时,由 DefaultServlet 处理 调用链: service() → doGet() → serveResource() getRelativePath() 方法从request对象获取以下属性控制路径: 攻击者可通过AJP协议控制这些属性来读取任意文件 JspServlet处理流程 对于.jsp/.jspx请求,由 JspServlet 处理 service() 方法通过可控属性构造jspUri: 后续会编译jsp文件生成servlet,实现文件包含 漏洞利用方式 任意文件读取 通过控制 DefaultServlet 处理的路径,读取webapp目录下的任意文件 包括配置文件、源代码等敏感信息 远程代码执行(RCE) 前提: 能上传可控内容到webapp目录(如头像上传功能) 步骤: 上传包含恶意JSP代码的文件(如evilman.png) 通过AJP协议包含该文件 Tomcat会将其作为JSP编译执行 漏洞复现 环境准备 受影响Tomcat版本(如8.5.40) 内网测试环境(IP: 10.0.12.93) 复现步骤 任意文件下载测试 使用公开POC工具 成功读取webapp目录下的文件 文件包含到RCE 在 webapps/examples/ 下创建evilman.png,内容为: 通过AJP协议包含该文件 成功执行系统命令,验证漏洞 查看编译结果 编译后的jsp代码位于: 可查看生成的servlet代码 防御措施 升级Tomcat 升级到安全版本: Tomcat 7 ≥ 7.0.100 Tomcat 8 ≥ 8.5.51 Tomcat 9 ≥ 9.0.31 临时解决方案 禁用AJP协议: 修改 conf/server.xml ,注释掉8009端口的Connector: 其他防护建议 限制AJP端口的访问(如防火墙规则) 定期检查服务器上的可疑文件 加强文件上传功能的安全检查 参考资源 Tomcat AJP协议漏洞分析 - CSDN Tomcat架构解析 - CSDN Tomcat连接器详解 - CSDN AJP协议官方文档 漏洞深度分析 - 安全客 漏洞利用分析 - 安全客