CVE-2020-11989 Shiro认证绕过

前言

无。


环境搭建

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

攻击方法1

跟CVE-2020-1957相似的方法,用分号;绕过。

好像1.5.2版本要利用还要配置tomcat根目录,我这用的SpringBoot,就不管它了。

攻击方法2

通过双重URL编码绕过:

原因很好猜,肯定是shiro对双重URL编码的处理跟spring之间出了点偏差,继续去getRequestUri函数看看:

可以看到,此时从tomcat中取到的uri已经经过了一次URL解码,而在后面的处理函数decodeAndCleanUriString函数中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static String decodeAndCleanUriString(HttpServletRequest request, String uri) {
uri = decodeRequestString(request, uri);
int semicolonIndex = uri.indexOf(';');
return (semicolonIndex != -1 ? uri.substring(0, semicolonIndex) : uri);
}

public static String decodeRequestString(HttpServletRequest request, String source) {
String enc = determineEncoding(request);
try {
return URLDecoder.decode(source, enc);
} catch (UnsupportedEncodingException ex) {
...
return URLDecoder.decode(source);
}
}

可以看到会再进行一次URL解码,也就是说最后获得的就是//admin//:

经过normalize处理后就变成了/admin/,匹配不上,也就绕过了认证。

修复方法

1.5.3版本下,getPathWithinApplication函数做了修改:

1
2
3
4
5
6
7
8
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);
}

不做URL解码了。


参考文章

https://www.freebuf.com/vuls/249380.html

https://www.freebuf.com/articles/network/254664.html


CVE-2020-11989 Shiro认证绕过
http://yoursite.com/2021/11/10/CVE-2020-11989-Shiro认证绕过/
作者
Aluvion
发布于
2021年11月10日
许可协议