什么是shiro
Apache Shiro是一个强大且易用的java安全框架,执行身份验证,授权,密码和会话管理,使用Shiro的API,可以快速获取任何应用程,从最小的移动应用到最大的网络和企业应用程序
shiro权限绕过的原因
Apache Shiro是一个java的安全管理框架,可以和spring一起使用
shiro框架通过拦截器来实现对用户访问权限的控制和拦截
shiro常见的拦截器有anon,authc等
anon:匿名拦截器,不需要登录就可以访问,一般用于静态资源,或者移动端接口
authc:登录拦截器,需要登录认证才能访问资源
shiro权限绕过的限制条件
- 网站同时使用shiro和spring
- shiro满足特定的版本
Shiro拦截器
Shiro框架通过拦截器功能来实现对用户访问的控制和拦截,Shiro中常见的拦截器有anon,authc等拦截器
1.anon为匿名拦截器,不需要登录就能访问,一般用于静态资源,或者移动端接口
2.authc为登录拦截器,需要认证才能访问资源
用户可以在shiro.ini编写匹配URL配置,将会拦截匹配的URL,并执行响应的拦截器,从而实现对URL的访问控制,URL路径表达式通常为ANT格式,如下配置,访问/index.html主页的时候,shiro将不会对其进行登录判断anon拦截器不需要登录就能进行访问,而对于某些/api/敏感接口,shiro会使用authc拦截器来对其进行登录判断,有登录认证才能访问资源
[urls]
/index.html=anon
/api/=authc
Shiro的URL路径表达式为Ant格式,路径通配符支持?***等
?:匹配一个字符
*:匹配零个或者多个字符串
**:匹配路径中的零个或者多个路径
在shiro中*可以表示-匹配零个或者多个字符串,例如:/*可以匹配/index这个页面,无法匹配搭配/index/这个路径,在authc拦截器中,如果管理员对/admin进行了authc拦截,用户直接访问/admin,authc会进行权限判断,这里我们假设将请求的URI设置为/*admin/,/*URL路径表达式将无法正确匹配因为不知道到底是路径还是页面接口,接着放行然后到spring(Servlet)拦截器,注意的是:spring中/admin形式和/hello/形式的URL访问的资源是一样的
拦截器优先级:从上到下,从左到右,如果有匹配的拦截器就会阻断并返回,例如:访问js/a.js,第一个拦截器就是anon符合,就返回true了,不会再往下匹配了,注意最后一个拦截最后一句是/**=user,test意思就是除了上面的那些,其他的所有都要经过,user和frameperms.如果没有登陆user就会阻断,就不会执行到frameperms.test就是我们自定义实现的过滤器,从数据库中查询用户的权限,判断当前用户是否有权限访问拦截的URL
springranin的配置
<property name= "filterChainDefinitions">
<value>
/js/** = anon
/css/** = anon
/images/** = anon
/mvimg/**= anon
/unauth = anon
/getCaptcha=anon
/login = anon
/favicon.ico =anon
/index = user
/logout = logout
/menu/leftMenu=user
/**/ajax/** = user
/**= user,test
</value>
</property>
访问控制的含义
访问控制广泛应用于各个系统中,抽象的说,都是某个主题对某个主体对某个客体需要实施某种操作,而系统对这种操作的限制就是权限控制
在一个安全系统中,去欸的那个主体的身份是"认证"解决问题;而客体是一种资源,是主体发起的请求对象,在主体对客体进行操作的过程中,系统控制主体不能"无限制"的对客体进行操作,这个过程就是"访问控制"
CVE-2016-6802
shiro版本: shiro < 1.5.0
shiro于spring的URI中末尾的/不同导致的权限绕过
这个版本shiro使用的/或者*进行匹配零个或多个字符串,/*后面的字符串都会匹配到此规则,例如/admin,但匹配不到/admin/因为*通配符无法匹配路径,
假设/admin接口设置了authc拦截器,访问/admin将会被进行权限判断,如果请求的URI为/admin/,/*的URL路径表达式讲无法进行匹配,然后进行放行,然后进入到spring(servlet)拦截器,而spring中/admin形式和/admin/形式的URL访问的资源是一样的,从而导致了绕过
CVE-2020-1957
shiro版本: shiro < 1.5.2
payload:
/XXX/..;/admin/
/.;/admin/
通过网络判断,网站处理URI时会先经过shiro处理,再转发到springboot进行路由分发工作,而在shiro中,在对URI中的;进行处理时会将URI进行截断,然后对/xxx/..进行权限校验,这样我们就可以成功访问到原本访问不到的接口了
验证流程大致如下:
客户端发起请求/xxx/..;/admin
shiro处理之后返回/xxx/..校验通过
springboot处理/xxx/..;/admin/返回/admin/
最后访问到需要权限校验的资源
环境搭建
启动docker服务
systemctl start docker
安装docker
1.uname -a 内核版本大于3.1![](https://img-blog.csdnimg.cn/130a965223ae468a80510d911271b423.png)
2.换源
vim /etc/apt/sources.list
删除所有内容更换为 注意可以使用gedit编译
#其他apt源
#此处,笔者仅添加中科达和阿里的,其他注释掉
#中科大
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
#阿里云
deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
#清华大学
#deb http://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free
#deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free
#浙大
#deb http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free
#deb-src http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free
#东软大学
#deb http://mirrors.neusoft.edu.cn/kali kali-rolling/main non-free contribp.kali.org/kali kali-rolling main non-free contrib
#重庆大学
#deb http://http.kali.org/kali kali-rolling main non-free contrib
#deb-src http://http.kali.org/kali kali-rolling main non-free contrib
3.安装docker
apt-get update && apt-get upgrade && apt-get dist-upgrade
下载vulhub靶场
https://github.com/vulhub/vulhub
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
搭建fastjson漏洞环境
unzip vulhub-master.zip #解压vulhub-master.zip
cd vulhub-master/shiro/CVE-2020-1957 #vulhub-master目录下
docker-compose up -d #使用docker-compose拉取启动shiro靶场
URL权限配置如下
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form
chainDefinition.addPathDefinition("/logout", "logout");
chainDefinition.addPathDefinition("/admin/**", "authc");
return chainDefinition;
}
环境启动后访问网址即可
对于此页面我们进行192.168.1.1:8000/admin/访问
流量包如下![](https://img-blog.csdnimg.cn/38148eb89e664a8c839120ed27449b39.png)
漏洞原因[代码审计]
在PathMatchingFilterChainResolver的FilterChain getChain函数下,PatchMatchingFilter根据URL路径匹配中配置的urI路径表达式来匹配输入URL,判断是否匹配拦截器,匹配成功将会返回响应拦截器执行链,让shirofither执行权限操作
使用pathmatches函数进行匹配如果我们在URI后面加入/就可以绕过pathmatches函数![](https://img-blog.csdnimg.cn/91708c9fed1c45d8953d495f9a59819d.png)
我们在patchMatches函数zhongshiro.util.AntPathMatcher类中doMatch的对于ant格式的pathPattern和requestURI进行匹配,简单来说/admin/1可以匹配/admin/,shiro的Ant格式的pathPattern中的通配符是不支持匹配路径的,/admin/1/是匹配不到/admin/*所以直接false我们也因此直接越权
版权归原作者 呆呆想摆烂 所有, 如有侵权,请联系我们删除。