CVE-2020-1957 shiro权限绕过漏洞分析
0x00 前言
最近在看 CVE-2020-11989 ,11989是CVE-2020-1957后的⼀种绕过⽅法,这漏洞有references 所以按着来复现并写出了一些自己踩坑的点
0x01 漏洞背景
0x02 漏洞环境准备
1.下载demo代码
shiro-basic。
https://github.com/lenve/javaboy-code-samples/tree/master/shiro/shiro-basic
使用https://minhaskamal.github.io/DownGit/#/home 即可下载
2.导入idea,maven自动加载依赖
3.修改Shiro版本为1.4.2
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.2</version>
</dependency>
4.修改springboot 内置端口
在application.properties 中增加配置 server.post=端口号
5.修改ShiroConfig配置文件
添加authc拦截器的拦截正则
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//指定 SecurityManager
bean.setSecurityManager(securityManager());
//登录页面
bean.setLoginUrl("/login");
//登录成功页面
bean.setSuccessUrl("/index");
//访问未获授权路径时跳转的页面
bean.setUnauthorizedUrl("/unauthorizedurl");
//配置路径拦截规则,注意,要有序
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin", "anon");
//map.put("/**", "authc");
map.put("/hello/*", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
6.修改路由控制器方法
@GetMapping("/hello/{currentPage}")
public String hello(@PathVariable Integer currentPage) {
return "hello";
}
如果@PathVariable 报红色就用option+enter inport class即可
7.启动应用
springboot内置tomcat
0x03 漏洞复现
尝试访问http://127.0.0.1:8084/hello/1
由于我们修改了拦截的正则map.put("/hello/*", "authc");
访问/hello/1
接口,可以看到被authc拦截器拦截了,将会302跳转到登录接口进行登录。
1.修改host
由于burp不能抓本地包,需要修改host
sudo vim /etc/hosts
添加一行
127.0.0.1 test.com
### 2.访问/hello/1 抓包 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200828172944858.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIyODA3NDI1,size_16,color_FFFFFF,t_70#pic_center)
Follow redirection
3.绕过authc拦截
/hello/1/,绕过拦截
0x04 漏洞分析
根据参考文章漏洞初始成因定位到 PathMatchingFilterChainResolver的getChain函数下
该函数作用根据URL路径匹配中配置的url路径表达式来匹配输入的URL,判断是否匹配拦截器,匹配成功将会返回响应的拦截器执行链,让ShiroFither执行权限操作的。
其对于URL路径表达式和输入URL的匹配主要通过pathMathches函数进行匹配。
1.全局搜索PathMatchingFilterChainResolver的getChain
2.下断点,浏览器访问/hello/1
跟踪进pathMatches
发现会调用doMatch, AntPathMatcher (org.apache.shiro.util),继续跟踪下去
public boolean match(String pattern, String path) {
return this.doMatch(pattern, path, true);
}
当Shiro 的Ant格式的pathPattern 中的的
*
通配符是不支持匹配路径的,所以/hello/*
不能成功匹配/hello/1/
,也就不会触发authc拦截器进行权限拦截。从而成功绕过了Shiro拦截器
0x05 漏洞修复
https://github.com/apache/shiro/commit/589f10d40414a815dbcaf1f1500a51f41258ef70
增加了/结尾的判断,通过判断requestURI是否以/为结尾,如果以/结尾的话,则去掉尾部的/符号在与URL表达式进行比较。
后续的 有时间再调 先工作了,水平有限 不足之处还请原谅和提醒
0x06 References
- https://blog.riskivy.com/shiro-%e6%9d%83%e9%99%90%e7%bb%95%e8%bf%87%e6%bc%8f%e6%b4%9e%e5%88%86%e6%9e%90%ef%bc%88cve-2020-1957%ef%bc%89/
- https://github.com/lenve/javaboy-code-samples/tree/master/shiro/shiro-basic
- https://www.cnblogs.com/r00tuser/p/12575934.html