环境搭建
1 | docker run -itd --name teamcity-server-instance3 \ |
这个 11.2
随便改成 11.3
11.4
就好。
一些Spring的前置知识
(之前没系统学过不知道,知道的师傅们可以跳过了~)
首先是一些 Spring 的前置知识:
1 |
|
上面两个方法,当访问 test1
后,会重定向到 test2
函数
具体分析一下为什么:
首先会在这个函数选择解析器
1 | org.springframework.web.servlet.DispatcherServlet#resolveViewName |
由于没有配置,默认选择到了:InternalResourceView
。
然后就是如下的调用过程:
1 | org.springframework.web.servlet.view.AbstractView#render |
然后 Tomcat
就会根据路由去找对应的方法了~
那么延伸拓展一下,当返回 “index.html” 时是什么处理的呢?
1 |
|
经过调试发现,不管是上面 forward 到一个方法,还是返回一个 html,最终都会到这里:
1 | org.springframework.web.servlet.DispatcherServlet#doDispatch |
上面是返回一个模板,下面是跳转到一个方法:
其实这里说白了就是找路由的那一套了,从 mappingRegistry
啊或者别的属性找对应的。
CVE-2024-27198
这个漏洞网上有很多分析了
数据包:
1 | POST /xxxx?jsp=/app/rest/users%23.jsp HTTP/1.1 |
漏洞位置:
1 | jetbrains.buildServer.controllers.BaseController#updateViewIfRequestHasJspParameter |
只要以 .jsp
结尾并且不包含 admin/
,就能返回并且直接 set
进去
然后找到处理请求的地方:
1 | jetbrains.buildServer.controllers.BaseController#handleRequestInternal |
只要返回不是 RedirectView
就会进入到 updateViewIfRequestHasJspParameter
函数。
也就是只要请求一个 404 界面,就会进入到此处,然后传递 jsp
参数 /app/rest/users%23.jsp
,这里可以用 #
和 ?
,因为 tomcat
会在做请求处理之前对路由做一些处理,就会把后面的 .jsp
处理掉了。
这个漏洞的修复和下面是一样的地方~
CVE-2024-23917
找了半天网上也没找到分析,就寻思自己瞎看看
起初我并没有对比出版本差异在哪里,但是我看了下 chybeta
师傅的这张图:
我想应该不是什么很复杂的,毕竟 header
也没有,cookie
也没有的,我就觉得估计是路有问题,后来看到一篇文章:
https://attackerkb.com/topics/1XEEEkGHzt/cve-2023-42793/rapid7-analysis
这文章写得很好,让我锁定到了一个类:
1 | jetbrains.buildServer.controllers.interceptors.RequestInterceptors |
甚至连函数都是一样的:
1 | private boolean requestPreHandlingAllowed( { HttpServletRequest request) |
只不过上面的漏洞聚焦的是 else
语句块,而这个漏洞聚焦在这个函数:
1 | jetbrains.buildServer.web.util.WebUtil#isJspPrecompilationRequest |
1 | public static boolean isJspPrecompilationRequest(final HttpServletRequest request) { |
这里其实很简单,就是判断 uri
嘛,那就用最简单的 payload
试了一下:
1 | POST /app/rest/users;.jsp?jsp_precompile=1 HTTP/1.1 |
没想到还真成功了
漏洞修复
是怎么修复的呢,一开始我也找了好久没找到,然后看到 docker 中有 warning 报错:
搭建好11.3
的版本,在这下个断点:
1 | com.intellij.openapi.diagnostic.Logger#warn(String) |
发现是个代理过的 interceptor
,看看此时的 interceptorList
:
此时页面返回:
1 | HTTP/1.1 403 |
上面的 27198
也是这个返回,并且 warning
是一样的,所以应该是在同一个地方做的过滤。
只可惜我没找到他是在哪里定义的
上面 Proxy
中还提到了一个类
1 | jetbrains.buildServer.controllers.interceptors.AuthorizationInterceptorImpl#preHandle |
但是单看这个类的话并没有看出什么东西
并且新版应该做了什么混淆导致反编译会有一些问题,留给之后看看吧