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