Shiro权限绕过2
Shiro漏洞复盘系列--1.5.2版本以下的权限绕过复现分析。(CVE-2020-1957)
# 简介
漏洞影响范围:shiro < 1.5.2
# 配置
<!-- shiro dependence -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.2</version>
</dependency>
shiro config同上一篇文章。
# 分析
访问/admin/
,已经无法绕过shiro过滤器的拦截:
访问/;/admin
,成功绕过shiro拦截:
# shiro
还是在org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain
,打下断点,发送请求:
主要在getPathWithApplication
方法里:
这里会获取到请求的contextPath
和requestUri
,获取到uri
为/;/admin
之后进入decodeAndCleanUriString
方法中:
decodeAndCleanUriString
方法中把请求的uri
按分号进行截断:
/;/admin
经过shiro的处理之后,我们请求的路由就变成了/
,由于/
路由下没有设置过滤器,所以就shiro的过滤器无法匹配,绕过了shiro的权限认证。
# Spring
依然在org.springframework.web.util.UrlPathHelper#getLookupPathForRequest
方法中打下断点,发送请求开始调试:
这次主要跟入getPathWithinApplication
方法:
再跟入getRequestUri
方法:
主要看decodeAndCleanUriString
方法,这个方法中对请求的路由做了一些处理:
跟入第一个方法removeSemicolonContent
,经过这部分代码处理之后/;/admin
变成了//admin
,在这个方法中,会把;
到后面第一个/
之间的字符串全部去掉(包括;
),比如/;xxx/
经过处理之后就变成了//
:
再跟入第三个方法getSanitizedPath
,在获取到//
的索引值之后,直接删除该索引上对应的字符,//admin
也就变了/admin
:
最后也就返回了/admin
的路由,之后就是正常匹配 hanlderMethod 的过程了,不再赘述:
# 修复
1.5.2版本的org.aoache.shiro.web.util.WebUtils#getRequestUri
方法如下:
public static String getRequestUri(HttpServletRequest request) {
String uri = (String)request.getAttribute("javax.servlet.include.request_uri");
if (uri == null) {
uri = valueOrEmpty(request.getContextPath()) + "/" + valueOrEmpty(request.getServletPath()) + valueOrEmpty(request.getPathInfo());
}
return normalize(decodeAndCleanUriString(request, uri));
}
uri获取的规则变成了ContextPath
、ServletPath
、PathInfo
三者拼接而成:
getServletPath
方法可以正确处理分号,再经过后续方法处理,/;/admin
就被正常处理为了/admin
,之后就会被shiro的过滤器正常拦截。
- 02
- CommonsBeanUtils04-19
- 03
- 基于Tomcat全局存储进行回显04-16