mag1c7
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
漏洞描述
When using Apache Shiro before 1.11.0 together with Spring Boot 2.6+, a specially crafted HTTP request may cause an authentication bypass. The authentication bypass occurs when Shiro and Spring Boot are using different pattern-matching techniques. Both Shiro and Spring Boot < 2.6 default to Ant style pattern matching.
**Mitigation:**Update to Apache Shiro 1.11.0, or set the following Spring Boot configuration value:
spring.mvc.pathmatch.matching-strategy = ant_path_matcher
[1]
漏洞条件
shiro < 1.110
spring boot 2.6+
Spring Boot 2.6前后区别的区别[2]
匹配策略:
//org. springframework. boot. autoconfigure.web.servlet.WebMvcProperties.MatchingStrategy
public static enum MatchingStrategy {
ANT_PATH_MATCHER,
PATH_PATTERN_PARSER;
private MatchingStrategy() {
}
}
版本 | 默认模式(pattern)匹配策略 |
---|---|
spring boot<2.6 | ANT_PATH_MATCHER |
spring boot>= 2.6 | PATH_PATTERN_PARSER |
org.springframework.util.AntPathMatcher的匹配规则:
org.springframework.web.util.pattern.PathPattern!
漏洞分析
本次漏洞的payload其实是和CVE-2020-17510相同的的,故不再重复:
漏洞原因都是,shiro对诸如“/..","/."的路径进行规范化(normalize),而spring则不会,反而将”.."或“."当作路径参数。两者差异造成了shiro的绕过。
为什么payload一致?
CVE-2020-17510的补丁在springboot2.6后就失效了,具体原因如下:
spring.web获取处理器入口:org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//在此处获取查询路径
String lookupPath = initLookupPath(request);
this.mappingRegistry.acquireReadLock();
try {
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
进入initLookupPath:
protected String initLookupPath(HttpServletRequest request) {
//分支1
if (usesPathPatterns()) {
request.removeAttribute(UrlPathHelper.PATH_ATTRIBUTE);
RequestPath requestPath = ServletRequestPathUtils.getParsedRequestPath(request);
String lookupPath = requestPath.pathWithinApplication().value();
return UrlPathHelper.defaultInstance.removeSemicolonContent(lookupPath);
}
else {//分支2
return getUrlPathHelper().resolveAndCacheLookupPath(request);
}
}
springboot2.6后,默认采取PathPattern匹配模式,所以必然会进入第一分支,导致CVE-2020-17510的补丁失效:
//补丁,可以通过@Import导入这个配置
//显然该补丁是在走分支2时才起效的。
@Configuration
public class ShiroRequestMappingConfig {
public ShiroRequestMappingConfig(RequestMappingHandlerMapping requestMappingHandlerMapping) {
requestMappingHandlerMapping.setUrlPathHelper(new ShiroUrlPathHelper());
}
}
漏洞修复
因此为了挽救失效的补丁,做了如下修复:[2]
将匹配模式强行改成ANT_PATH_MATCHER,如此,才会在获取查询路径时(initLookupPath),进入分支2,CVE-2020-17510的补丁变的有效
Reference
[1] Security Reports | Apache Shiro
[2] Add Spring EnvironmentPostProcessor · apache/shiro@e167a71
[3] CVE-2020-17510
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
