CVE-2020-13933 Apache Shiro 身份验证绕过漏洞复现
0x00 Shiro
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
之前Apache Shiro身份验证绕过漏洞CVE-2020-11989的修复补丁存在缺陷,在1.5.3及其之前的版本,由于shiro在处理url时与spring仍然存在差异,依然存在身份校验绕过漏洞由于处理身份验证请求时出错,远程攻击者可以发送特制的HTTP请求,绕过身份验证过程并获得对应用程序的未授权访问。
0x01 影响范围
Apache Shiro < 1.6.0
0x02 EXP
1 | admin/%3b/page |
在未登陆的情况下,使用;的url编码可以绕过身份验证
302转向登录

%3b绕过

分析
本质原因是因为shiro和spring对uri的处理方式不同
先来看shiro的处理。
shiro对于uri的处理在org.apache.shiro.web.util.Webutils#getPathWithinApplication
1 | public static string getPathWithinApplication(HttpServletRequest request) { |
注意这里获取到的是解码后的url,也就是admin/;page接着取出其中的路径,最后返回分号之前的路径,跟进removeSemicolon
1 | private static String removeSemicolon(String uri){ |
这里把url中;以后的部分(包括;)全部去除然后返回给getPathWithinApplication,实际上,传入的/admin/;page最后会变成/admin,在shiro看来这个路径和源码中的路径是不匹配的。会移交给error处理,而error产生的错误页面是允许访问的,在这之后shiro的鉴权结束,uri处理将会交给spring的过滤器。
而spring的处理顺序不同,spring会先做removesemicolon,然后再decodeRequestString,getSanitizedPath
1 | private String decodeAndCleanUriString(HttpServletRequest request, String uri) { |
- removeSemicolonContent 是把(url未解码前的uri里的;后面的内容给删除)
- decodeRequestString 把uri进行urldecode解码
- getSanitizedPath 是把”//“ 替换成 “/“
shiro正相反,先解码,再去分号。这就导致了shiro认为处理过后页面可以访问,但当真正的uri传给spring的时候,spring开始做路由匹配spring把;page当成了name。从而导致了身份绕过。

1 |
|

至此漏洞复现完成。