Shiro权限绕过3
Shiro漏洞复盘系列--1.5.3版本以下的权限绕过复现分析。(CVE-2020-11989)
# 简介
漏洞影响范围:shiro < 1.5.3
利用条件:
- Spring 需要设置 ContextPath
- alwaysUseFullPath 必须设置为 false
# 配置
Spring的版本配置有坑点,主要与的alwaysUseFullPath
值有关。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- <version>2.4.3</version>-->
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- shiro dependence -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.2</version>
</dependency>
# 分析
设置 context-path
为 test
:
访问/test/admin
,被shiro拦截:
访问/;/test/admin
,绕过shiro鉴权:
# shiro
依然是在org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain
这个方法打下断点,调试shiro来处理URL请求的过程,跟进getPathWithinApplication
方法:
通过gerRequestUri
方法获得的结果是/
:
所以跟进到该方法内部调试,在1.5.2
的补丁版本中我们知道URL的获取规则变成了ContextPath
、ServletPath
、PathInfo
三者拼接而成:
问题就处在getContextPath
方法中,经过这个方法之后可以获得带;
号的ContextPath
:
三者拼接之后URL为/;/test//admin
,之后传入decodeAndCleanUriString
方法中,仅仅保留了;
号前面的部分:
那么由shiro处理完成之后的结果就是/
,从而绕过了shiro鉴权:
# Spring
Spring 是否调用 getPathWithinServletMapping
方法和 alwaysUseFullPath
的值有关,Spring官方称该值默认为 false,但是我在使用最新版Spring的时候却是默认为 true ,导致漏洞无法复现(待解决),下面两张图是不同版本的Spring的差异。
5.2.5版本的Spring:
5.3.4版本的Spring:
只有当alwaysUseFullPath
为false
的情况下才会进入getPathWithinServletMapping
中,经过getPathWithinServletMapping
处理之后可以正确获取到路径:
getPathWithinApplication
方法中的处理逻辑在上一篇中已经分析过,这里不再赘述,getServletPath
方法获取到的其实是Request
对象的某个属性值:
正确获取到路径之后,就可以匹配对应的Controller
了。
# 修复
漏洞的成因在于shiro和Spring对于;
的处理逻辑不一样:
- shiro会直接截断
;
号后面的部分 - Spring会截断
;
号和其后第一个/
的部分,然后剩余部分作拼接处理
1.5.3版本的shiro修复如下:
shiro使用了标准的getServletPath(request) + getPathInfo(request)
来进行URL的处理,同时不再获取ContextPath
,之后会进行格式化处理,就无法利用;
进行绕过。
- 02
- CommonsBeanUtils04-19
- 03
- 基于Tomcat全局存储进行回显04-16