CVE-2021-28169源码分析与漏洞复现(Jetty信息泄露)

article/2025/6/30 21:05:18

漏洞概述

漏洞名称:Jetty ConcatServlet 多重解码导致 WEB-INF 敏感信息泄露
漏洞编号:CVE-2021-28169
CVSS 评分:7.5
影响版本

  • Jetty 9.4.0 - 9.4.39
  • Jetty 10.0.0 - 10.0.1
  • Jetty 11.0.0 - 11.0.1
    修复版本
  • Jetty ≥ 9.4.40
  • Jetty ≥ 10.0.2
  • Jetty ≥ 11.0.2
    漏洞类型:路径遍历/信息泄露

CVE-2021-28169 是 Eclipse Jetty 的 Servlets 组件ConcatServletWelcomeFilter)中的安全漏洞。当开发者主动使用这些组件时,攻击者通过构造双重URL编码的路径(如 /%2557EB-INF/web.xml),利用多重解码逻辑缺陷绕过路径安全校验,直接访问 WEB-INFMETA-INF 目录下的敏感文件(如 web.xmlclasses 等),导致应用配置、源码和凭证信息泄露。


技术细节与源码分析

漏洞成因
  • 多重解码缺陷
    ConcatServlet 在处理请求参数时执行多次 URL 解码:
    1. 容器层自动解码(如 %25%
    2. ConcatServlet 自身再次解码(如 %57W
  • 安全校验滞后:路径校验在首次解码后执行,未考虑二次解码结果。
关键源码分析

(1)请求处理入口ConcatServlet.doGet()
代码定位org.eclipse.jetty.servlets.ConcatServlet#doGet

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String query = request.getQueryString();//  获取原始查询字符串(未解码)if (query == null) {response.sendError(204);return;} List<RequestDispatcher> dispatchers = new ArrayList<>();String[] parts = query.split("\\&");String type = null;for (String part : parts) {String path = URIUtil.canonicalPath(URIUtil.decodePath(part));// 漏洞点:第一次解码if (path == null) {response.sendError(404);return;} // 安全校验(易被绕过)if (startsWith(path, "/WEB-INF/") || startsWith(path, "/META-INF/")) {//response.sendError(404);return;} String t = getServletContext().getMimeType(path);if (t != null){if (type == null) {type = t;}else if (!type.equals(t)) {response.sendError(415);return;} }RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(path);if (dispatcher != null) {dispatchers.add(dispatcher);}} if (type != null) {response.setContentType(type);}for (RequestDispatcher dispatcher : dispatchers){//容器自动二次解码dispatcher.include((ServletRequest)request, (ServletResponse)response);}}
String path = URIUtil.canonicalPath(URIUtil.decodePath(part));

问题分析

  1. URIUtil.decodePath(part):对参数执行首次 URL 解码(如 %2557%57
  2. URIUtil.canonicalPath():路径规范化(但无法处理编码字符)
  3. 容器自动二次解码:当 RequestDispatcher 处理路径时,对 %57 再次解码为 W

安全校验缺陷

if (startsWith(path, "/WEB-INF/") || ... )  

问题分析

  • 校验时路径为首次解码结果(如 /%57EB-INF/web.xml
  • 未匹配 /WEB-INF/ 规则 → 错误放行
  • 未考虑二次解码后的真实路径(/WEB-INF/web.xml

漏洞利用原理

攻击请求

GET /static?/%2557EB-INF/web.xml HTTP/1.1

解码流程

步骤操作路径变化安全校验结果
1. 容器自动解码%2557%57/%57EB-INF/web.xml绕过(不匹配 /WEB-INF
2. URIUtil.decodePath()%57W/WEB-INF/web.xml未校验
3. RequestDispatcher实际访问文件/WEB-INF/web.xml敏感文件泄露

漏洞复现

环境搭建
1.使用 Vulhub 环境启动漏洞靶机
 docker-compose up -d 

在这里插入图片描述

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

在这里插入图片描述

攻击步骤
1.正常通过/static?/WEB-INF/web.xml无法访问到敏感文件web.xml:

在这里插入图片描述

2.对字母W进行双URL编码,即可绕过限制访问web.xml:
http://your-ip:8080/static?/%2557EB-INF/web.xml

在这里插入图片描述


修复方案

方案1:移除二次解码(官方修复)
// 修改前(漏洞代码)
String path = URIUtil.canonicalPath(URIUtil.decodePath(part));// 修改后(修复代码)
String path = URIUtil.canonicalPath(part); // 仅规范化,不额外解码

修复效果

  • 保持路径为单次解码状态(如 /%57EB-INF
  • 安全校验可正确拦截非常规路径
方案2:增强安全校验
// 增加双重解码后校验
String decodedPath = URIUtil.decodePath(URIUtil.decodePath(part));
String canonicalPath = URIUtil.canonicalPath(decodedPath);if (startsWith(canonicalPath, "/WEB-INF/") || startsWith(canonicalPath, "/META-INF/")) {response.sendError(404);return;
}

优势:兼容旧版,但性能较低

方案3:输入过滤
// 拦截包含双重编码的请求
if (part.contains("%25")) { // 检测 % 的编码形式 %25response.sendError(400, "Malicious path detected");return;
}

修复验证对比
请求修复前结果修复后结果
/?/css/style.css正常返回正常返回
/?/%57EB-INF/web.xml绕过校验,文件泄露拦截(路径未规范化)
/?/%2557EB-INF/web.xml文件泄露拦截(检测到 %25

漏洞启示

  1. 解码一致性原则:各层组件应统一解码策略,避免多重解码产生语义差异。
  2. 深度防御实践:敏感目录访问需在解码后、规范化后、业务逻辑前多层校验。
  3. 组件最小化:未使用的功能组件(如 ConcatServlet)应及时禁用。

参考链接

  1. CVE-2021-28169 官方通告(GitHub Advisory)
  2. Vulhub 漏洞复现环境指南
  3. 企业级防御实践(Tenable 报告)

附:多重解码漏洞模式对比

漏洞触发方式防护关键点
CVE-2021-28164单次编码绕过(%2e先解码后规范化
CVE-2021-28169双重编码绕过%2557避免多次解码

http://www.hkcw.cn/article/pyFsWuswYm.shtml

相关文章

CLion调试无法触发断点

CLion 调试时执行的是cmake-build-release目录中的exe&#xff0c;无法触发断点 这里配置要选择Debug&#xff0c;不要选择Release

2024年数维杯国际大学生数学建模挑战赛C题时间信号脉冲定时噪声抑制与大气时延抑制模型解题全过程论文及程序

2024年数维杯国际大学生数学建模挑战赛 C题 时间信号脉冲定时噪声抑制与大气时延抑制模型 原题再现&#xff1a; 脉冲星是一种快速旋转的中子星&#xff0c;具有连续稳定的旋转&#xff0c;因此被称为“宇宙灯塔”。脉冲星的空间观测在深空航天器导航和时间标准维护中发挥着至…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Sound Board(音响控制面板)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— SoundBoard 组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ &#x1f3af; 组件目标 实现一个响应式按钮面板&#xff0c;点…

【目标检测数据集】电动车驾驶员戴头盔相关数据集

一、TWHD 数据集 介绍 随着国家惩治行车不戴头盔违法行为的力度不断加大&#xff0c;双轮车&#xff08;电动车与摩托车&#xff09;头盔检测任务也越来越重要。双轮车佩戴头盔检测数据集&#xff08;two wheeler helmet dataset&#xff0c;TWHD&#xff09;收集了来自开源数…

【机器学习基础】机器学习入门核心:数学基础与Python科学计算库

机器学习入门核心&#xff1a;数学基础与Python科学计算库 一、核心数学基础回顾1. 函数与导数2. Taylor公式3. 概率论基础4. 统计量5. 重要定理6. 最大似然估计&#xff08;MLE&#xff09;7. 线性代数 二、Python科学计算库精要1. NumPy&#xff1a;数值计算核心2. SciPy&…

【存储基础】SAN存储基础知识

文章目录 1. 什么是SAN存储&#xff1f;2. SAN存储组网架构3. SAN存储的主要协议SCSI光纤通道&#xff08;FC&#xff09;协议iSCSIFCoENVMe-oFIB 4. SAN存储的关键技术Thin Provision&#xff1a;LUN空间按需分配Tier&#xff1a;分级存储Cache&#xff1a;缓存机制QoS&#x…

缓解颈部不适的营养补给之道

对于颈部常有不适的人群而言&#xff0c;合理的营养补充是维持身体良好状态的重要方式。日常饮食中&#xff0c;蛋白质是不容小觑的营养元素。瘦肉、蛋类、奶类以及豆制品都是优质蛋白质的来源&#xff0c;它们能够帮助增强肌肉力量&#xff0c;为颈部提供更好的支撑。​ 维生…

ck-editor5的研究 (6):进一步优化页面刷新时,保存提示的逻辑

文章目录 一、前言二、实现步骤1. 第一步: 引入 PendingActions 插件2. 第二步&#xff1a;注册事件3. 第三步&#xff1a;点击保存按钮时&#xff0c;控制状态变化 三、测试效果和细节四、总结 一、前言 在上一篇文章中 ck-editor5的研究 (5)&#xff1a;优化-页面离开时提醒…

手机归属地查询接口如何用Java调用?

一、什么是手机归属地查询接口&#xff1f; 是一种便捷、高效的工具&#xff0c;操作简单&#xff0c;请求速度快。它不仅能够提高用户填写地址的效率&#xff0c;还能帮助企业更好地了解客户需求&#xff0c;制定个性化的营销策略&#xff0c;降低风险。随着移动互联网的发展…

列表推导式(Python)

[表达式 for 变量 in 列表] 注意&#xff1a;in后面不仅可以放列表&#xff0c;还可以放range ()可迭代对象 [表达式 for 变量 in 列表 if 条件]

【机器学习|评价指标4】正预测值(PPV)、负预测值(NPV)、假阴性率(FNR)、假阳性率(FPR)详解,附代码。

【机器学习|评价指标4】正预测值&#xff08;PPV&#xff09;、负预测值&#xff08;NPV&#xff09;、假阴性率&#xff08;FNR&#xff09;、假阳性率&#xff08;FPR&#xff09;详解&#xff0c;附代码。 【机器学习|评价指标4】正预测值&#xff08;PPV&#xff09;、负预…

【Delphi】实现在多显示器时指定程序运行在某个显示器上

在多显示器时代&#xff0c;经常会出现期望将程序运行在某个指定的显示器上&#xff0c;特别是在调试程序的时候&#xff0c;期望切换分辨率&#xff0c;单步调试时&#xff0c;此时容易导致互相卡住&#xff0c;非常不方便&#xff0c;但是通过指定程序运行在不同的显示器上就…

渗透实战PortSwigger Labs AngularJS DOM XSS利用详解

本Lab学习到关于AngularJS的 xss 漏洞利用 直接输入回显页面&#xff0c;但是把<>进了 html 编码了 当我们输入{{11}}&#xff0c;没有当作字符处理&#xff0c;而是执行了 {{}} 是多种前端框架&#xff08;如 Vue、Angular、Django 模板等&#xff09;中常见的模板插值语…

配置刷新技术

FPGA 片上三模冗余( TMR) 设计结合配置刷新( Scrubbing) 的防护方法能够有效地提高系统的抗单粒子翻转性能。 三模冗余的方法利用模块三冗余及三取二自动表决来掩蔽错误&#xff0c;但是如果错误积累到一定程度&#xff0c;导致同时有两个或两个以上模块发生翻转错误&#xff0…

计算机科技笔记: 容错计算机设计05 n模冗余系统 其他复杂结构

目录 NMR变体动态冗余系统混合冗余系统筛除新系统 NMR变体 V是表决器 动态冗余系统 优点像N模并行系统&#xff0c;后边加一个故障检测和系统重构百分之90以上的故障都是瞬时故障&#xff0c;检测到故障重新运行即可如果出现老化&#xff0c;可以用Spare-1替代 混合冗余系…

HealthBench医疗AI评估基准:技术路径与核心价值深度分析(上)

引言:医疗AI评估的新范式 在人工智能技术迅猛发展的当下,医疗AI系统已逐渐从实验室走向临床应用。然而,医疗领域的特殊性要求这些系统不仅需要在技术指标上表现出色,更需要在实际临床场景中展现出可靠、安全且有效的性能。长期以来,医疗AI评估领域面临着三个核心挑战:评…

中国就业人口现状分析与未来趋势预测

目录 1、核心摘要 2、就业人口总量与趋势 就业人口规模 产业结构变化 3、未来就业趋势 2030年就业变革 人口结构影响 技能需求变化 4、年龄结构与老龄化影响 老龄化现状 抚养比变化 6、老龄化经济影响 消费结构变化 创新活力 7、行业分布与数字经济 行业就业结…

三种经典算法优化无线传感器网络(WSN)覆盖(SSA-WSN、PSO-WSN、GWO-WSN),MATLAB代码实现

三种经典算法优化无线传感器网络(WSN)覆盖&#xff08;SSA-WSN、PSO-WSN、GWO-WSN&#xff09;&#xff0c;MATLAB代码实现 目录 三种经典算法优化无线传感器网络(WSN)覆盖&#xff08;SSA-WSN、PSO-WSN、GWO-WSN&#xff09;&#xff0c;MATLAB代码实现效果一览基本介绍程序设…

SQL Transactions(事务)、隔离机制

目录 Why Transactions? Example: Bad Interaction Transactions ACID Transactions COMMIT ROLLBACK How the Transaction Log Works How Data Is Stored Example: Interacting Processes Interleaving of Statements Example: Strange Interleaving Fixing the…

Linux(10)——第二个小程序(自制shell)

目录 ​编辑 一、引言与动机 &#x1f4dd;背景 &#x1f4dd;主要内容概括 二、全局数据 三、环境变量的初始化 ✅ 代码实现 四、构造动态提示符 ✅ 打印提示符函数 ✅ 提示符生成函数 ✅获取用户名函数 ✅获取主机名函数 ✅获取当前目录名函数 五、命令的读取与…