春节前夕,我在渗透测试的过程中遇到了TeamCity这款CI/CD工具,搜索到了一个历史漏洞CVE-2023-42793,并稍微分析了一下这个漏洞的成因。并进行了简单的漏洞挖掘,于是就挖掘到了这个CVSS 9.8分的CVE-2024-23917
CVE-2023-42793
下面是这个漏洞的补丁
可以看到这个漏洞主要是由于/**/
这个通配符,导致的权限绕过。这个关键代码在RequestInterceptors
当中,在其构造函数当中添加了这个绕过路径。
CVE-2024-23917
现在,我们回到这个类当中,可以看到处理这个绕过的关键函数:requestPreHandlingAllowed
requestPreHandlingAllowed
private boolean requestPreHandlingAllowed(@NotNull HttpServletRequest request) {
if (WebUtil.isJspPrecompilationRequest(request)) {
return false;
} else {
return !this.myPreHandlingDisabled.matches(WebUtil.getPathWithoutContext(request));
}
}
当这个函数返回false的时候,TeamCity的处理逻辑会跳过身份认证,直接进入对应的Controller当中。
isJspPrecompilationRequest
public static boolean isJspPrecompilationRequest(@NotNull HttpServletRequest request) {
String uri = StringUtil.notNullize(request.getRequestURI());
return (uri.endsWith(".jsp") || uri.endsWith(".jspf")) && request.getParameter("jsp_precompile") != null;
}
我们可以看到,只需要满足两个条件即可:
后缀名是.jsp 或者 .jspf
jsp_precompile参数不为空
这两个条件很简单,我们只需要利用Java的一个小feature即可完成,就是分号(这个方法已经出现了很多很多次了)。
POST /app/rest/users/id:1/tokens/test;1.jsp?jsp_precompile=1 HTTP/1.1
于是我们构造对应的Payload就可以获得Admin的Token了。
CVE-2024-24942
这个漏洞,也是一个很Java的漏洞(x)。在/app/rest/swagger**
路由之下, 是不需要进行鉴权的,对应的Handler为SwaggerUI 。
serveSwaggerResource
从路径中获取了path的遍历,然后丢到getFileFromResources
当中,其实就是一个简单的目录拼接,然后用classLoader.getResource
获取内容。
这样的话,直接路径里面../../
就可以了。不过影响有限,只能读读WEB-INF的文件。
Timeline
2024-01-19 向TeamCity团队提交了漏洞
2024-02-06 TeamCity团队修复了漏洞并发布博客
2024-04 TeamCity向我们支付了赏金