shiro权限绕过
shiro权限绕过
什么是shiro
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
shiro权限绕过的原因
Apache Shiro是一个Java的安全管理框架,可以和spring一起使用。这次的权限绕过漏洞就出在和spring boot搭配这里。
shiro框架通过拦截器来实现对用户访问权限的控制和拦截。Shiro常见的拦截器有anon,authc等。
- anon:匿名拦截器,不需登录就能访问,一般用于静态资源,或者移动端接口。
- authc:登录拦截器,需要登录认证才能访问的资源。
我们通过在配置文件中配置需要登录才可访问的url,实现对url的访问控制。其中,url的路径表达式为Ant格式。
/hello
:只匹配url,比如 http://demo.com/hello/h?
:只匹配url,比如 http://demo.com/h+任意一个字符/hello/*
:匹配url下,比如 http://demo.com/hello/xxxx 的任意内容,不匹配多个路径/hello/**
:匹配url下,比如 http://demo.com/hello/xxxx/aaaa 的任意内容,匹配多个路径
shiro权限绕过的限制条件
- 网站同时使用shiro和spring
- shiro满足特定的版本
CVE-2016-6802
shiro版本:shiro < 1.5.0
shiro与spring的URI中末尾的/
不同导致的权限绕过
其中*
表示匹配零个或多个字符串,/*
可以匹配/hello,但匹配不到/hello/因为*通配符无法匹配路径。
假设/hello接口设置了authc拦截器,访问/hello将会被进行权限判断,如果请求的URI为/hello/呢,/*的URL路径表达式将无法正确匹配,放行。然后进入到spring(Servlet)拦截器,而spring中 /hello 形式和 /hello/形式的URL访问的资源是一样的,从而导致了绕过。
CVE-2020-1957
shiro版本:shiro < 1.5.2
#绕过的payload
/xxx/..;/hello/aaaa
/.;/hello/aaaa
通过网络判断,网站处理URI时会先经过 shiro 处理,再转发到 springboot 进行路由分发工作。而在shiro中,在对URI中的;
进行处理时会将URI进行截断,然后对/xxx/..
进行权限校验,校验通过之后再由springboot进行路由分发,然后springboot会将URI/xxx/..;/hello/aaaa
解释为/hello/aaaa
,这样我们就可以成功访问到原本访问不到的接口了。
大致流程如下:
用户发起请求/xxx/..;/hello/aaaa
—–>shiro处理之后返回/xxx/..
通过校验的—–>springboot处理/xxx/..;/hello/aaaa
返回/hello/aaaa
,最后访问到需要权限校验的资源。
CVE-2020-11989
shiro版本:shiro < 1.5.3
这里的 shiro 拦截器需要变成map.put("/hello/*", "authc");
,这里有两种poc,都是可以绕过
#绕过的payload
/hello/a%25%32%66a
/;/test/hello/aaa
利用;
绕过的大致流程和上面基本一致,而利用编码绕过的流程如下:
/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转发到响应的路由当中。
%25 -- %
%32 -- 2
%66 -- f
%2f -- /
%3b -- ;
CVE-2020-13933
shiro版本: shiro < 1.6.0
#绕过的payload
/hello/%3baaaa
上面的代码进来之后,通过 shiro 处理之后变成了/hello/;aaaa
,然后shiro会根据;
进行截断,返回的 URI自然是/hello/
,这个 URI 自然无法命中拦截器map.put("/hello/*", "authc");
自然就过了
SpringBoot默认不解析任何脚本文件,因此一般通过shiro权限绕过进入后台也很难通过文件上传getshell