Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

admin 2021年2月7日10:00:50评论110 views字数 3358阅读11分11秒阅读模式

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

作者:jweny@360云安全


Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

漏洞描述

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

当它和 Spring 结合使用时,在一定权限匹配规则下,攻击者可通过构造特殊的 HTTP 请求包完成身份认证绕过。

影响范围:Apache Shiro < 1.7.1

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

漏洞环境搭建

shiro 1.7.0

https://github.com/jweny/shiro-cve-2020-17523 两种姿势的漏洞环境均已更新。

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

poc测试

姿势一:

http://127.0.0.1:8080/admin/%20 或 http://127.0.0.1:8080/admin/%20/

使用空格等空字符,可绕过shiro身份验证。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

姿势二:

经过和p0desta师傅交流,发现还有另一种特殊场景下的利用方式。

http://127.0.0.1:8080/admin/%2e 或 http://127.0.0.1:8080/admin/%2e/

但是.(还有/)在Spring的路径匹配的规则中是代表路径分隔符的,不作为普通字符进行匹配。因此在默认条件下访问 /admin/.会返回404。

但是在开启全路径的场景下setAlwaysUseFullPath(true)是可以正常匹配的。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

漏洞分析

Shiro中对于URL的获取及匹配在org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain

先简单看下这个getChain方法:

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

该方法先检查requestURI是否以/结尾,如果是,就删掉最后一个/。

然后在匹配路径的循环中,会先判断下路径规则pathPattern是否以/结尾,如果是也会删除。然后再去调用pathMatches()方法进行路径匹配。

因此两种利用方式中,是否以/结尾都没有关系,因为开始经过getChain方法就会被删除。


4.1 空格绕过分析

关注下pathMatches()方法:

调出Evaluate,分别计算一下pathMatches("/admin/*","/admin/1")和pathMatches("/admin/*","/admin/ "),前者正常匹配,后者匹配失败。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

开始调试,调试开始会经过一阵漫长的F7。一直到doMatch("/admin/*","/admin/ ")。可见,tokenizeToStringArray返回的pathDirs已经没有第二层路径了。因此会导致/admin/*和/admin不匹配。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

跟一下tokenizeToStringArray方法,发现其调用tokenizeToStringArray方法时的trimTokens参数为true。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

而tokenizeToStringArray方法,在参数trimTokens为true时,会经过trim()处理,因此导致空格被清除。再次返回getChain时最后一个/被删除。因此tokenizeToStringArray返回的pathDirs没有第二层路径。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

总结一下:存在漏洞的shiro版本,由于调用tokenizeToStringArray方法时,trimTokens参数默认为true,空格会经过trim()处理,因此导致空格被清除。再次返回getChain时最后一个/被删除,所以/admin与/admin/*匹配失败,导致鉴权绕过。而Spring接受到的访问路径为/admin/%20,按照正常逻辑返回响应,因此导致权限被绕过。


4.2 /./绕过分析

看到第二种姿势的/.和/./,是不是想起了某个熟悉方法?没错,就是normalize()。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

简单翻译下就是:

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)
所以/admin/.在被处理成/admin/./之后变成了/admin/。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

在经过org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain处理,由于/结尾,如果是,就删掉最后一个/,变成了/admin。`/admin与/admin/*不匹配,因此绕过了shiro鉴权。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

而此时Spring收到的请求为/admin/.。如果没有开启全路径匹配的话,在Spring中.和/是作为路径分隔符的,不参与路径匹配。因此会匹配不到mapping,返回404。

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

开启全路径匹配的话,会匹配整个url,因此Spring返回200。

这里附上开启全路径匹配的代码:

@SpringBootApplicationpublic class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(SpringbootShiroApplication.class); }
public static void main(String[] args) {
SpringApplication.run(SpringbootShiroApplication.class, args); }
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof RequestMappingHandlerMapping) { ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true); } return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }}

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

官方的修复方案

经过以上的分析,造成shiro权限绕过的原因有两个:

  1. tokenizeToStringArray函数没有正确处理空格。

  2. 处理最后一个/的逻辑,不应在循环匹配路径的逻辑之前。

因此官方的修复方案为:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. 将tokenizeToStringArray的trimTokens参数置为false。Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

  2. 调整删除最后一个/的逻辑。修改成先匹配原始路径,匹配失败后再去走删除最后一个/的逻辑。Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

关于trim

原理上来说trim()会清空字符串前后所有的whitespace,空格只是其中的一种,但是在测试中发现除了空格以外的其他whitespace,例如%08、%09、%0a,spring+tomcat 处理时都会返回400。

因此第一种姿势除了空格,尚未发现其他好用的payload。

 

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

参考

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

(点击“阅读原文”查看链接)

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)


- End -
精彩推荐
新型Linux恶意软件竟然可以从超级计算机中窃取SSH数据
App隐私合规简论
惊喜驾到 | 2020年安全客认证作者奖励出炉啦!
基于智能手机的近源渗透测试案例分享(二)——“点到为止”的测试成都某消防部门

Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

戳“阅读原文”查看更多内容

本文始发于微信公众号(安全客):Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年2月7日10:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Apache Shiro 两种姿势绕过认证分析(CVE-2020-17523)https://cn-sec.com/archives/263855.html

发表评论

匿名网友 填写信息