前言

无。


漏洞复现

要求版本:shiro<1.6.0,测试用的代码不变。

与CVE-2020-1957相似,在路径后加上URL编码后的分号;,即%3b就可以绕过认证:

漏洞分析

经过几个小版本的修改,此时的getPathWithinApplication函数如下:

public static String getPathWithinApplication(HttpServletRequest request) {
    return normalize(removeSemicolon(getServletPath(request) + getPathInfo(request)));
}

private static String removeSemicolon(String uri) {
    int semicolonIndex = uri.indexOf(';');
    return (semicolonIndex != -1 ? uri.substring(0, semicolonIndex) : uri);
}

使用getServletPath函数从tomcat中获取路径,结果在tomcat中会经过一次URL解码,为/admin/;admin:

然后使用removeSemicolon函数截断分号;,再用normalize标准化,最后的返回结果就是/admin/:

再被去掉末尾的/,在doMatch函数就匹配不上了,就绕过了认证。

将分号URL编码可以让tomcat不会对分号做处理,这样到了spring的部分就不会出现404。

漏洞修复

在1.6.0版本中再访问,会出现400:

通过调试可以看到,在匹配不到filter时,getChain函数会使用默认的InvalidRequestFilter:

其中会经过其isAccessAllowed函数来判断该请求是否合法:

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
    String uri = WebUtils.toHttp(request).getRequestURI();
    return !containsSemicolon(uri)
        && !containsBackslash(uri)
        && !containsNonAsciiCharacters(uri);
}

简单来说就是不能包含分号、反斜杠和非ASCII字符(虽然这里的uri是没经过URL解码的,但是这两个contains函数里面把字符跟他们的URL编码,包括大小写形式都ban了。非ASCII字符虽然没有做URL编码的处理,但是好像也没什么用法了)。


参考文章

https://www.freebuf.com/articles/web/252539.html


Web Shiro

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

机器学习入门1
CVE-2020-11989 Shiro认证绕过