0x00 漏洞簡述
Apache Shiro 1.5.3之前的版本中,當將Apache Shiro與Spring動態控制器一起使用時,精心編制的請求可能會導致繞過身份驗證,如果直接訪問 /shiro/admin/page ,會返回302跳轉要求登錄,訪問 /;/shiro/admin/page , 就能直接繞過Shiro權限驗證,訪問到/admin路由中的信息
0x01 漏洞影響
Apache Shiro 1.5.3之前的版本
Spring 框架中只使用 Shiro 鑒權
0x02 環境搭建
1.下載項目到本地https://github.com/l3yx/springboot-shiro
2.通過idea編輯器對其進行編譯成war包,然后講放入到tomcat下的webapps目錄中,運行即可。
這里已編譯好war包:
https://github.com/backlion/demo/blob/master/shiro.war
0x03 漏洞復現
1.權限配置如下,其中/admin下的路由需要登錄才能訪問
@Bean ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager()); bean.setLoginUrl("/login"); bean.setSuccessUrl("/index"); bean.setUnauthorizedUrl("/unauthorizedurl"); Map<String, String> map = new LinkedHashMap<>(); map.put("/doLogin", "anon"); map.put("/admin/*", "authc"); bean.setFilterChainDefinitionMap(map); return bean; } --- @GetMapping("/admin/page") public String admin() { return "admin page"; }
2.maven打包項目為shiro.war,部署於Tomcat。該漏洞成功利用存在下面兩個條件
- 應用不能部署根目錄root目錄下,也就是需要context-path,server.servlet.context-path=/shiro,如果為根目錄則context-path為空,就會被CVE-2020-1957的patch將URL格式化,值得注意的是若Shiro版本小於1.5.2的話那么該條件就不需要。
- Spring控制器中沒有另外的權限校驗代碼
3.如果直接訪問 /shiro/admin/page ,會返回302跳轉要求登錄

4.但是訪問 /;/shiro/admin/page , 就能直接繞過Shiro權限驗證,訪問到/admin路由中的信息

0x04 漏洞分析
由於Shiro的權限校驗是通過判斷url匹配來做的,如果能找到Shiro獲取的url與Web框架處理url不一致的情況就能造成權限繞過。Shiro中對於URL的獲取及匹配在org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain
以訪問/;/shiro/admin/page舉例,通過getPathWithinApplication函數得到的路徑為/

跟入該函數的處理邏輯
org.apache.shiro.web.util.WebUtils#getPathWithinApplication

可以看到 org.apache.shiro.web.util.WebUtils#getRequestUri 獲取到的是/

這里分別通過getContextPath() getServletPath() getPathInfo()獲取並拼接得到/;/test//admin/page,傳入后decodeAndCleanUriString變成了/,
org.apache.shiro.web.util.WebUtils#decodeAndCleanUriString

在decodeAndCleanUriString,會根據ascii為59的字符也就是;進行URL的截斷,所以最終返回了/
回到最開始的/;/shiro/admin/page請求,該request請求會進入spring中,spring處理url函數如下
org.springframework.web.util.UrlPathHelper#getPathWithinServletMapping


在getPathWithinApplication處理下是能正確獲取到context-path與路由,最終經過getPathWithinServletMapping函數格式化處理后,得到最終路徑為/admin/page,所以我們可以正常訪問到該頁面

因此總結來說就是當URL進入到Tomcat時,Tomcat判斷/;shiro/admin/page ,為shiro應用下的/admin/page路由,進入到Shiro時被;截斷被認作為/,再進入Spring時又被正確處理為test應用下的/admin/page路由,最后導致shiro的權限繞過。
0x05 漏洞修復
升級到最新版,官方已在新版本中修復了該漏洞