前言
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
当它和 Spring 结合使用时,在一定权限匹配规则下,攻击者可通过构造特殊的 HTTP 请求包完成身份认证绕过。
影响范围:Apache Shiro < 1.7.1
复现环境
https://github.com/jweny/shiro-cve-2020-17523
漏洞分析
org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain
这个if语句判断请求地址是否以/结尾,为真则去掉/。
这个while里的pathMatchs()方法是个重点。
这里设置了拦截器链进行三次循环匹配
1 pathMatches("/doLogin","/admin/ ")
2 pathMatches("/admim/*","/admin/ ")
3 pathMatches("/**","/admin/ ")
在这里我们探究为什么在doMatch方法中”/admin/*” 和”/admin/ “为什么不能匹配
先来试试/admin/*与/admin/1
先执行表达式看看结果,返回true,表示成功匹配此路径,继续跟进。
在这里调用tokenizeToStringArray方法对请求路径用/进行切割,返回数组。
第一个字符串为admin。
PathDIrs为{“admin”,”1”}
PattDirs为{“admin”,”*”}
在进行字符串逐一匹配都为true.
这里匹配最后一个字符 *和1,进行判断,最终结果返回true。
最后return pattern为/admin/*说明被拦截器拦截到了。
再以同样方式看下”/admin/*”和”/admin/ ”
关键也在于调用tokenizeToStringArray会对字符串进行trim()处理。
token = token.trim(),这里token去掉空格,导致无字符串返回。
其实这里的路径经过trim()后相当于/admin/*和/admin 匹配校验。
返回false,匹配失败,导致权限绕过。
再进入第三个默认的全路径匹配,这里就没什么影响了
后面spring接受到的路径为”/admin/ “,按照正常逻辑返回admin页面。
参考文章
https://paper.seebug.org/1478/#0x05
https://blog.csdn.net/cpongo3/article/details/90234883
天磊卫士|专注网络安全服务
咨询热线:400-654-0108
官网:https://www.uguardsec.com
分支机构:深圳、海口、北京、青岛、汕尾
漏洞扫描|整改加固|渗透测试|APP安全评估|安全运维
系统入网|上线安全评估|代码审计|应急响应|应急演练
原文始发于微信公众号(天磊卫士安全团队):漏洞复现 | Shiro1.70认证绕过分析(CVE-2020-17523)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论