Tomcat Ghostcat - AJP协议文件读取/文件包含漏洞(CVE-2020-1938 / CNVD-2020-10487)
字数 2110 2025-08-25 22:58:35
Tomcat Ghostcat漏洞(CVE-2020-1938/CNVD-2020-10487)深入分析与教学文档
0x00 漏洞概述
Tomcat Ghostcat漏洞是Apache Tomcat服务器中AJP协议实现的一个高危漏洞,包含文件读取和文件包含两种攻击方式,可能导致敏感信息泄露和远程代码执行(RCE)。该漏洞编号为CVE-2020-1938和CNVD-2020-10487。
0x01 环境搭建
所需工具与环境
- Tomcat 8.5.46源码:http://archive.apache.org/dist/tomcat/tomcat-8/v8.5.46/src/apache-tomcat-8.5.46-src.zip
- IDEA开发环境
搭建步骤
- 下载并解压Tomcat源码
- 在IDEA中导入项目
- 解决500错误:
- 找到
org.apache.catalina.startup.ContextConfig - 增加代码:
context.addServletContainerInitializer(new JasperInitializer(), null);
- 找到
- 启动Tomcat后,默认会开放8009(AJP)和8080(HTTP)端口
0x02 基础知识
1. Tomcat Connector(连接器)
- 功能:负责接收客户端连接和请求处理加工
- 类比:如同城堡的城门,提供进出通道
- 默认配置:
- HTTP Connector:监听8080端口
- AJP Connector:监听8009端口
2. Servlet(服务程序)
- 定义:处理网络请求的规范
- 生命周期:实例化、初始化、调用、销毁受控于Tomcat容器
- 默认Servlet:
DefaultServlet:处理静态资源请求JspServlet:处理JSP页面请求
3. Tomcat请求处理流程
- Connector接收请求并封装为Request对象
- Engine匹配虚拟主机Host
- Host匹配Context
- Context匹配Servlet
- Wrapper管理Servlet执行
- 返回响应
0x03 漏洞分析
漏洞触发条件
- 通过AJP协议(8009端口)发送特制请求
- 两种攻击方式:
- 文件读取(走DefaultServlet)
- 文件包含(走JspServlet)
1. 文件读取漏洞
关键参数
req_uri = '/asdf' # 请求URL
javax.servlet.include.request_uri = '/' # AJP属性
javax.servlet.include.path_info = 'WEB-INF/web.xml' # AJP属性
javax.servlet.include.servlet_path = '/' # AJP属性
漏洞流程
-
AjpProcessor处理:
service()→prepareRequest()- 解析请求并将属性设置到request对象
-
DefaultServlet处理:
service()→doGet()→serveResource()getRelativePath()拼接路径:'/WEB-INF/web.xml'getResource()→validate()→normalize()进行路径校验
-
路径限制:
normalize()方法会检查/../,因此只能读取webapps目录下的文件
-
文件读取:
- 通过
ServletOutputStream.write()返回文件内容
- 通过
-
目录控制:
- 修改
req_uri可读取webapps下不同目录的文件 - 如
/manager/asdf可读取manager应用下的文件
- 修改
漏洞复现
修改POC中的请求URL为/manager/asdf,可读取webapps/manager/status.xsd
2. 文件包含漏洞(RCE)
关键参数
req_uri = '/manager/ddd.jsp' # 必须以".jsp"结尾
javax.servlet.include.request_uri = '/'
javax.servlet.include.path_info = 'test.txt' # 包含的文件
javax.servlet.include.servlet_path = '/'
漏洞流程
-
JspServlet处理:
service()→serviceJspFile()- 将
servlet_path和path_info拼接为jspUri
-
JSP处理流程:
- 将包含的文件(test.txt)当作JSP处理
- 编译为Servlet源代码(.java)
- 编译为Servlet类(.class)
- 执行Servlet
-
RCE条件:
- 需要在webapps目录下上传恶意文件
- 通过文件包含漏洞执行该文件
漏洞复现
- 在
webapps/manager下创建test.txt:<% Runtime.getRuntime().exec("calc.exe");%> - 修改POC请求URL为
/manager/ddd.jsp - 执行
test.txt中的代码
0x04 漏洞修复
官方在Tomcat 9.0.31版本中修复了该漏洞,主要措施包括:
- 限制AJP请求中的特殊属性
- 加强路径校验
- 默认禁用AJP Connector
0x05 防御建议
- 升级Tomcat到安全版本
- 如不使用AJP协议,关闭8009端口
- 在
conf/server.xml中注释或删除AJP Connector配置 - 加强文件上传限制
- 设置适当的文件权限
附录:参考资源
- 官方漏洞公告
- POC代码:https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
- 趋势科技分析报告:Busting Ghostcat: An Analysis of the Apache Tomcat Vulnerability