shiro 在 1.11.0版本之前,当与spring boot 2.6以上版本组合使用的时候,在默认配置下,配合特定的路由规则,攻击者可以通过发送特殊的请求造成shiro中的鉴权绕过。
大致原理为/admin/..会被Shiro识别为/,大多数Shiro配置对/是允许匿名访问,Spring的controller通过**或者{path}识别到了..,从而导致被绕过。
环境配置
Shiro:1.10.1
Spring-boot:2.6.1
漏洞分析
在shiro过滤器PathMatchingFilterChainResolver#getChainget方法下断
PathWithinApplication用于获取请求 URI
跟进getPathWithinApplication
继续跟getPathWithinApplication
这个方法从请求中提取应用程序内的相对路径,移除路径中的分号,并对路径进行标准化处理。
现在传递的路径为/admin/..
normalize方法加工后变成了/
一般shiro配置针对根目录、js、css等目录会放行,这里shiro处理后的目录为/,很多情况下是会放行的。
进入到Spring的路径处理中
ServletRequestPathUtils#parseAndCache这个方法用于解析 HTTP 请求路径并将其缓存。
跟进ServletRequestPath.parse
这个方法会解析HttpServletRequest 对象中的请求路径,并返回一个 RequestPath 对象
返回到parseAndCache方法后requestPath和HttpServletRequest对象进行绑定,这样可以在同一个请求处理链中可以共享和访问路径信息。
然后根据路径去匹配对应的controller
initLookupPath方法获取了传递的url(admin/..)
返回一直往下跟到AbstractHandlerMethodMapping#addMatchingMappings
这个方法从给定的映射集合中查找与当前请求匹配的映射,并将这些匹配的信息(包括映射和相关的注册信息)添加到一个列表中。
这里根据传递的LookupPath匹配到一个controller(/admin/{*path})
然后寻找对应的Bean执行对应的方法
漏洞利用条件比较苛刻,路由需要为:
“/admin/{*path}”
“/admin/**”
漏洞复现
正常请求admin会重定向首页
加上/..成功绕过限制
/image-20240908202040507.png)
/image-20240908202217309.png)
/image-20240908203947665.png)
/image-20240908204858198.png)
/image-20240908205007875.png)
/image-20240908215011685.png)
/image-20240908215402683.png)
/image-20240908215731213.png)
/image-20240908221247171.png)
/image-20240908222305699.png)
/image-20240908222732059.png)
/image-20240908223318037.png)
/image-20240908224033982.png)
/image-20240908223859410.png)