低于1.5.0版本shiro身份绕过漏洞分析
文章目录
测试环境
- shiro 1.4.0
- springboot
shiro过滤器配置如下:
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//设置未认证(登录)时,访问需要认证的资源时跳转的页面
shiroFilterFactoryBean.setLoginUrl("/index");
//设置访问无权限的资源时跳转的页面
shiroFilterFactoryBean.setUnauthorizedUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/login");
//指定路径和过滤器的对应关系
Map<String, String> filterMap = new HashMap<>();
//设置/index和/login不需要登录就能访问
filterMap.put("/login", "anon");
filterMap.put("/index", "anon");
//设置/admin/index需要登录用户拥有角色p1n93r时才能访问
filterMap.put("/admin/*", "roles[p1n93r]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
前置知识
- shiro对Servlet容器的FilterChain进行了代理,即shiroFilter在Servlet容器的Filter链之前。
- 如果请求的url和shiro规则匹配,则在FilterChainResolver中使用ProxiedFilterChain对Servlet容器的FilterChain进行代理,即走Shiro的Filter体系,然后才会走Servlet的Filter链。
- 绕过原理就是:通过绕过匹配规则,使得在FilterChainResolver中不对Servlet容器的FilterChain进行代理,直接走Servlet容器的FilterChain,从而绕过了shiro的验证。
代码分析
分析入口为 org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver
,如下:
现在问题是,如何构造请求的url,让 pathMatches(pathPattern, requestURI)
返回false,且该请求的url还能让springmvc匹配正确的控制器。通过给 pathMatches(pathPattern, requestURI)
所在行打断点,追踪代码,最终可以达到下面:
所以我们在请求的最后加一个“/”符号,就能不走shiro的代理,绕过shiro(同时spring下 /index/admin/
和 /index/admin
是等效的)。如下:
① 第一次没加“/”,被拦截:
② 第二次末尾加“/”,绕过shiro:
文章作者 P1n93r
上次更新 2020-11-06