查看原文
其他

Apache Shiro权限绕过漏洞分析(CVE-2020-11989)

淚笑 边界无限 2022-11-05

Apache Shiro 作为常用的 Java 安全框架,拥有执行身份验证、授权、密码和会话管理等功能,通常会和 Spring 等框架一起搭配使用来开发 Web 应用。笔者最近捣鼓 Shiro 本来是打算参考最近 Shiro 的一些 issue 然后为 SCTF 出题的,但在测试过程中却发现了一些新的缺陷能导致权限绕过,便报告给 Apache Shiro 官方。在此同时玄武实验室安全研究人员也单独发现了另外一种绕过方式,具体可见参考链接。


影响范围

  • Apache Shiro < 1.5.3

  • Spring 框架中只使用 Shiro 鉴权


漏洞复现

测试 Demo :


https://github.com/l3yx/springboot-shiro


权限配置如下,其中 /admin 下的路由需要登录才能访问


@BeanShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager()); bean.setLoginUrl("/login"); bean.setSuccessUrl("/index"); bean.setUnauthorizedUrl("/unauthorizedurl"); Map<String, String> map = new LinkedHashMap<>(); map.put("/doLogin", "anon"); map.put("/admin/*", "authc"); bean.setFilterChainDefinitionMap(map); return bean;}---@GetMapping("/admin/page")public String admin() { return "admin page";}

maven 打包项目为 test.war ,部署于 Tomcat 。该漏洞成功利用存在下面两个条件


1.应用不能部署在根目录,也就是需要 context-path , server.servlet.context-path=/test ,如果为根目录则 context-path 为空,就会被 CVE-2020-1957 的 patch 将 URL 格式化,值得注意的是若 Shiro 版本小于 1.5.2 的话那么该条件就不需要。


2. Spring 控制器中没有另外的权限校验代码


如果直接访问 /test/admin/page ,会返回302跳转要求登录

但是访问/;/test/admin/page , 就能直接绕过 Shiro 权限验证,访问到 /admin 路由中的信息


 漏洞分析

由于Shiro的权限校验是通过判断 URL 匹配来做的,如果能找到 Shiro 获取的 URL 与 Web 框架处理 URL 不一致的情况就能造成权限绕过。Shiro 中对于 URL 的获取及匹配在

org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain

以访问 /;/test/admin/page 举例,通过 getPathWithinApplication 函数得到的路径为 / 

跟入该函数的处理逻辑org.apache.shiro.web.util.WebUtils#getPathWithinApplication

可以看到 org.apache.shiro.web.util.WebUtils#getRequestUri 获取到的是 

这里分别通过 getContextPath() getServletPath() getPathInfo() 获取并拼接得到 /;/test//admin/page ,传入后 decodeAndCleanUriString 变成了 / , org.apache.shiro.web.util.WebUtils#decodeAndCleanUriString


在 decodeAndCleanUriString ,会根据 Ascii 为 59 的字符也就是 ; 进行 URL 的截断,所以最终返回了 / 

回到最开始的 /;/test/admin/page 请求,该 request 请求会进入 Spring 中, Spring 处理 URL 函数如下org.springframework.web.util.UrlPathHelper#getPathWithinServletMapping

在 getPathWithinApplication 处理下是能正确获取到 context-path 与路由,最终经过 getPathWithinServletMapping 函数格式化处理后,得到最终路径为 /admin/page ,所以我们可以正常访问到该页面

因此总结来说就是当 URL 进入到 Tomcat 时, Tomcat 判断 /;test/admin/page 为 test 应用下的 /admin/page 路由,进入到 Shiro 时被 ; 截断被认作为 / ,再进入 Spring 时又被正确处理为 test 应用下的 /admin/page 路由,最后导致 Shiro 的权限绕过。


漏洞修复与安全建议

Shiro 1.5.3 修改了 URL 获取的逻辑,不单独处理 context-path ,具体代码如下所示 org.apache.shiro.web.util.WebUtils#getPathWithinApplication


因此就无法再通过构造 context-path 的方式来进行绕过了。

建议组件使用者升级至 Apache Shiro 1.5.3 或更高版本


漏洞处理时间线

  • 2020-6-18 16:30 边界无限安全研究员淚笑向 Apache Shiro 官方报告漏洞

  • 2020-6-19 00:04 Apache Shiro 开始处理漏洞,issue 为 SHIRO-782 

  • 2020-6-22 22:49 Apache Shiro 发布致谢


参考链接

  • https://xlab.tencent.com/cn/2020/06/30/xlab-20-002/ 





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存