...
}
return URLDecoder.decode(source);
}
}
所以这里的poc/hello/a%25%32%66a------>传入到shiro自动解码一次变成//hello/a%2fa------>经过 decodeRequestString 变成//hello/a/a由于这里我们的拦截器是map.put("/hello/*", "authc");,这里需要了解一下shiro的URL是ant格式,路径是支持通配符表示的
?:匹配一个字符
*:匹配零个或多个字符串
**:匹配路径中的零个或多个路径
/*只能命中/hello/aaa这种格式,无法命中/hello/a/a,所以经过 shiro 进行权限判断的时候自然无法命中 。
文章插图
而在spring当中,理解的 servletPath是/hello/a%2fa,所以自然命中@GetMapping("/hello/{name}")这个mapping,又springboot转发到响应的路由当中 。
文章插图
另一种利用方式来自这里《Apache Shiro权限绕过漏洞分析(CVE-2020-11989)》(https://xz.aliyun.com/t/7964),这里提到了
1.应用不能部署在根目录,也就是需要context-path,server.servlet.context-path=/test,如果为根目录则context-path为空,就会被CVE-2020-1957的patch将URL格式化,值得注意的是若Shiro版本小于1.5.2的话那么该条件就不需要 。
文章插图
这里原因在于需要绕过 getRequestUri当中的格式化uri,当context-path为空的时候,处理结果为//hello/aaaa
public static String getRequestUri(HttpServletRequest request) {
String uri = (String) request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE);
if (uri == ) {
uri = valueOrEmpty(request.getContextPath) + "/" +
valueOrEmpty(request.getServletPath) +
valueOrEmpty(request.getPathInfo);
}
return normalize(decodeAndCleanUriString(request, uri));
}
文章插图
当 context-path不为空的时候,处理结果为/;/test/hello/aaaa,然后我们知道decodeAndCleanUriString会根据;进行截断,截断之后的结果是/自然无法命中拦截器map.put("/hello/*", "authc");,所以自然就绕过了 。
文章插图
文章插图
修复
在1.5.3版本,采用标准的 getServletPath和getPathInfo进行uri处理,同时取消了url解码 。
public static String getPathWithinApplication(HttpServletRequest request) {
return normalize(removeSemicolon(getServletPath(request) + getPathInfo(request)));
}
文章插图
3、CVE-2020-13933
原理
/hello/%3baaaa
上面的代码进来之后,通过 getPathWithinApplication处理之后变成了/hello/;aaaa
文章插图
而 removeSemicolon会根据;进行截断,返回的uri自然是/hello/
private static String removeSemicolon(String uri) {
int semicolonIndex = uri.indexOf(';');
return (semicolonIndex != -1 ? uri.substring(0, semicolonIndex) : uri);
}
这个 uri自然无法命中拦截器map.put("/hello/*", "authc");自然就过了
文章插图
修复
加了一个 filter类InvalidRequestFilter来针对一些东西进行处理 。
private static final List<String> SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
private static final List<String> BACKSLASH = Collections.unmodifiableList(Arrays.asList("\", "%5c", "%5C"));
文章插图
No.3
小结
总结来看,就是利用 shiro 解析uri 和spring解析uri之间的差异来挖这个洞 。
招聘启事
安恒雷神众测SRC运营(实习生)
————————
【职责描述】
1. 负责SRC的微博、微信公众号等线上新媒体的运营工作,保持用户活跃度,提高站点访问量;
2. 负责白帽子提交漏洞的漏洞审核、Rank评级、漏洞修复处理等相关沟通工作,促进审核人员与白帽子之间友好协作沟通;
3. 参与策划、组织和落实针对白帽子的线下活动,如沙龙、发布会、技术交流论坛等;
推荐阅读
- 详解Apache Hudi如何配置各种类型分区
- 使用Apache协议的是自由软件吗?
- 黑客大神告诉你:Linux下的权限维持
- Apache HTTP Server 2.4.46 发布,修复全问题和bug
- 停滞数年后,ElasticJob 携首个 Apache 版本 3.0.0-alpha 回归
- Apache顶级项目,SkyWalking为何一枝独秀?
- Apache中.htaccess文件利用的总结与新思路拓展
- 掌握Linux文件权限,看这篇就够了
- 如何加密整个项目,像HMI一样,不同级别有不同的权限
- 基于springboot+shiro+freemarker的快速开发框架,代码免费分享