0x00 前言
前段时间Vulhub更新了Jetty相关的漏洞环境,之前没搞过,这次就学习学习。
0x01 漏洞原理
Jetty Servlets中的ConcatServlet、WelcomeFilter类存在多重解码问题,当应用到这两个类之一时,攻击者就可以利用双重URL编码绕过限制来访问WEB-INF目录下的敏感文件,造成敏感信息泄露。
0x02 影响版本
-
9.x系列 <= 9.4.40
-
10.x系列 <= 10.0.2
-
11.x系列 <= 11.0.2
0x03 环境搭建
参考Vulhub:https://github.com/vulhub/vulhub/tree/master/jetty/CVE-2021-28169
0x04 漏洞复现
正常访问是个Example页面:
查看页面源码,其中link标签的href属性值是使用到了ConcatServlet类来优化静态文件的加载:
<link rel="stylesheet" href="/static?/css/base.css&/css/app.css">
基于这种访问方式尝试直接访问WEB-INF下的文件是会返回404的:
/static?/WEB-INF/web.xml
对W进行双重URL编码则成功绕过限制访问得到敏感文件:
/static?/%2557EB-INF/web.xml
这里看到确实设置了ConcatServlet类来优化静态文件加载。
针对WelcomeFilter类的测试可以参考官网GitHub的代码:https://github.com/eclipse/jetty.project/pull/6261/commits/c704b8100a1ccc36f4bb8b80a96f3375dde8d182#diff-70d52a090f69fbcbb6fb9d0899c514474c25c4ea79263f81cbf0e87e3c103bd5
0x05 调试分析
在运行Jetty的命令中添加IDEA中远程调试的参数然后IDEA连接即可:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar start.jar
之前在关于CVE-2021-28164的文章中已经简单调试过Jetty的主要路由处理过程了,后面就只看本次漏洞的关键点。
直接在ConcatServlet类的doGet()函数中下断点。
访问/static?/WEB-INF/web.xml
在断点中看到,先获取请求查询内容即URI中?号之后/WEB-INF/web.xml
,接着根据&
即做参数切分,再逐个参数进行操作(URL解码和.
、..
等字符处理),最后判断处理后的path值是否以/WEB-INF/
或/META-INF/
开头,是的话直接返回404:
可以看到,还想用/./
和/../
等方式已经行不通了,但是URL解码那块代码逻辑还需要继续跟进分析。
访问/static?/%2557EB-INF/web.xml
调试到调用URIUtil.decodePath()函数进行解码的地方:
调试发现只进行了一次URL解码操作:
看下关键的处理逻辑,就是逐个获取请求参数的字符,当遇到%
时会对其后面两位字符进行URL解码并替换结果,但是可以看到仅仅替换了一次,这就是漏洞根源:
Utf8StringBuilder builder = null;
int end = offset + length;
for (int i = offset; i < end; i++)
{
char c = path.charAt(i);
switch (c)
{
case '%':
if (builder == null)
{
builder = new Utf8StringBuilder(path.length());
builder.append(path, offset, i - offset);
}
if ((i + 2) < end)
{
char u = path.charAt(i + 1);
if (u == 'u')
{
// TODO remove %u support in jetty-10
// this is wrong. This is a codepoint not a char
builder.append((char)(0xffff & TypeUtil.parseInt(path, i + 2, 4, 16)));
i += 5;
}
else
{
builder.append((byte)(0xff & (TypeUtil.convertHexDigit(u) * 16 + TypeUtil.convertHexDigit(path.charAt(i + 2)))));
i += 2;
}
}
else
{
throw new IllegalArgumentException("Bad URI % encoding");
}
break;
case ';':
...
default:
if (builder != null)
builder.append(c);
break;
}
}
0x06 补丁分析
参考官方在9.4.41版本的修复commit:https://github.com/eclipse/jetty.project/pull/6261/commits/c704b8100a1ccc36f4bb8b80a96f3375dde8d182
ConcatServlet类的修复方法就是将path替换为part,即使用原始路径字符串作为分发器就会再次进行URL解码:
0x07 防御方法
升级到9.4.41, 10.0.3, 11.0.3及以上版本。
0x08 参考
https://github.com/eclipse/jetty.project/security/advisories/GHSA-gwcr-j4wh-j3cq
原文始发于微信公众号(98KSec):浅析Jetty Servlets URI路径限制绕过漏洞(CVE-2021-28169)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论