mmsrc

公告

【分享】Apache Shiro权限绕过漏洞分析(CVE-2020-17523)

来源:陌陌安全 发布时间:2021-02-03

https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-dad05094-ba9c-3dea-80f0-920553fd2afc.jpeg


背景

Apache Shiro是一个Java安全框架,它可以用来执行身份验证、授权、密码和会话管理。
在Shiro与Spring进行组合应用时,两者在对URI的处理中存在差异,常常导致Shiro认证绕过问题。

CVE-2020-17523复现


非漏洞作者,所以只能半猜测地复现该问题。先上payload:

> curl -v "http://host/admin/%20"
> curl -v "http://host/admin/%20/"

复现配置

SpringBoot + Shiro认证
(部分内容取自https://github.com/xhycccc/Shiro-Vuln-Demo/blob/main/shiro_cve-2020-13933)
向Spring中注入Bean
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean(){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
Map<String, String> map = new LinkedHashMap<>();
map.put("/admin/*", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}

构造接口

@GetMapping("/admin/{name}")
public String admin(@PathVariable String name) {
return "admin page";
}

可见,在未经过认证的情况下,可以访问到admin page.


https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-adf3d96a-7dc2-3fee-b9db-489a060f9665.jpeg


漏洞分析

在Shiro 1.7.1 与 1.7.0 的diff中,有两个文件值得关注。
diff: https://github.com/apache/shiro/compare/shiro-root-1.7.0...shiro-root-1.7.1
web/src/test/java/org/apache/shiro/web/filter/PathMatchingFilterParameterizedTest.java 90-93行。
该部分增加了很多有关空格的测试内容。猜测本次补丁与空格或%20有关。
core/src/main/java/org/apache/shiro/util/AntPathMatcher.java 这个文件是补丁的关键所在,后面再说。

先来跟踪一下payload在Shiro 1.7.0下路径规则判断过程。
Shiro的路径判断从org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver.getChain开始。因为payload中无分号,反斜线,非ASCII码等字符,所以requestURI会原样保留一直到进行AntMatch模式匹配。

https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-5cdf5be8-7c49-3a72-b067-2ee71de9c1e1.jpeg


可见,requestURI并没能与/admin/*匹配成功,那它匹配上了哪个规则呢?

https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-b63aec29-5cba-3e51-a430-9077e7a5d880.jpeg


它匹配到了/**这个规则。在ShiroFilter中,/**是没有配置认证的,因此绕过了认证过程。
再看Spring处理环节。Spring的路由匹配在org.springframework.web.servlet.DispatcherServlet.getHandler过程中获取对应的处理handler。这里给出调用栈。


https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-943c8c54-5ba1-31bc-ab05-c961142a7152.jpeg

由于Spring也没对路径中的空格进行特殊的处理,因此能获取到/admin/{name}所对应的Controller,从而访问到admin page。
一边(Shiro)是没能匹配到需要认证的规则路由,一边(Spring)又能够正常匹配到API路由。还是挺有意思的。
Shiro是怎么修复的呢?关键就在core/src/main/java/org/apache/shiro/util/AntPathMatcher.java#L121这里。
Shiro中StringUtils.tokenizeToStringArray的第三个参数控制了是否会对解析出的token进行trim操作。
在1.7.1之前,空格被trim了,所以第二层路径没有了,就没能匹配到/admin/*


https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-5bfefdd0-9b79-3208-a2b1-fa40e36cb07d.jpeg

在1.7.1中,正确处理了空格。

https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-c9d6487f-fbd0-3955-a7c9-1d7abb11bcc8.jpeg

当然,如果认证的路由写作/admin/**/*,就不会有问题了。


漏洞影响

该漏洞影响范围 Apache Shiro <= 1.7.0


修复建议

升级Apache Shiro组件到1.7.1



https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-4fd3571b-eab3-3759-b0a0-927d79cffc8b.png







https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-81a75047-b918-3d97-8125-4f3915cb37f0.png

https://momo-mmsrc.oss-cn-hangzhou.aliyuncs.com/img-80577815-781a-38e0-8028-fa27f9628adf.png