Shiro安全(五):Shiro权限绕过之Shiro-682&CVE-2020-13933
- 0x00 前言
- 0x01 Shiro-682
- 利用条件
- 漏洞环境
- 漏洞分析
- 漏洞修复
- 0x02 CVE-2020-13933
- 利用条件
- 漏洞环境
- 漏洞分析
- 漏洞修复
- 0x03 总结
- 0x04 参考文章
0x00 前言
上一篇文章大概讲述了一下shiro以及spring获取uri的流程,总的来说shiro权限绕过是因为shiro与spring在对同一个请求获取uri时的处理步骤不同导致的,下面讲的两个权限绕过漏洞也是基于该原因
0x01 Shiro-682
利用条件
shiro < 1.5.2
漏洞环境
漏洞分析
利用的是 shiro 和 spring 对 url 中的 “;” 处理差别来绕过校验。
uri获取逻辑
shiro:具体方法WebUtils#getRequestUri
,方法先调用 decodeAndCleanUriString
方法处理请求路径,再调用 normalize 方法标准化路径。当uri中存在封号时,删除掉封号后面所有内容
spring:方法是 UrlPathHelper#decodeAndCleanUriString
,方法名也叫 decodeAndCleanUriString
,但是呢操作完全不同。对于spring来说,对于封号的处理规则是其会删除掉两个反斜线中封号后面的内容,然后解码然后将//转换为/
所以说当payload为/admin/;/nice来说
在shiro眼里就是:/admin
PS:shiro在geturi后会将最后一个斜线删去,而/admin不匹配/admin/*
在spring眼里就是:/admin/nice
所以绕过了shiro认证
还有其他payload比如,但是无法在高版本使用,因为在高版本上不处理跨目录
就只能借助 shiro 一些配置问题尝试绕过:比如应用程序配置了访问路径 “/admin/**” 为 anon,但是指定了其中的一个 “/admin/nice” 为 authc。这时在不跳目录的情况下,可以使用如下请求绕过:
http://127.0.0.1:8080/admin/;/nice
漏洞修复
shiro 不再使用 request.getRequestURI()
来获取用户随意输入的请求路径,而是使用 request.getContextPath()
、request.getServletPath()
、request.getPathInfo()
进行拼接,直接获取中间件处理后的内容。
这种获取方式会对uri进行解码,shiro-782就是利用该特性绕过的
0x02 CVE-2020-13933
利用条件
shiro < 1.6.0
漏洞环境
漏洞分析
在shiro 1.5.3中利用servletPath + pathInfo 的加法思路获取uri
方法逻辑如下,里面均用request.getxxx,而request.getXX
方法,会进行 URL 解码操作。
uri获取逻辑
Shiro:先 URL 解码,再处理分号,然后标准化路径
Spring:先处理分号,再 URL 解码,然后标准化路径。下面图就是spring获取uri逻辑
当payload为/admin/%3baaa时
在shiro眼里uri就是:/admin
在spring眼里uri就是:/admin/;aaa
所以绕过了shiro认证
漏洞修复
shiro 没有改动现有的处理逻辑,而是选择了使用全局过滤和处理的方式
Shiro 创建了一个 global 的 filter:InvalidRequestFilter
,用来过滤和阻断有危害的请求,会返回 400 状态码,其中包括:
- 带有分号的请求;
- 带有反斜线的请求;
- 非 ASCII 字符。
0x03 总结
总的来说就是shiro与spring在对同一个请求获取uri时的处理步骤不同,导致攻击者构造特殊的uri既可以绕过shiro认证且能够访问controller
0x04 参考文章
https://www.yuque.com/tianxiadamutou/zcfd4v/emcdeq