您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Apache Shiro權限繞過漏洞CVE-2020-1957怎么理解,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易于理解的API,可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。內置了可以連接大量安全數據源(又名目錄)的Realm,如LDAP、關系數據庫(JDBC)、類似INI的文本配置資源以及屬性文件等。
Apache Shiro 1.5.2之前的版本,由于Shiro攔截器和requestURI的匹配流程與Web框架的攔截器的匹配流程有差異,攻擊者構造一個特殊的http請求,可以繞過Shiro的認證,未授權訪問敏感路徑。
此漏洞有兩種攻擊方式,第一種攻擊方式適用于Shiro < 1.5.0版本,由于Shiro 1.5.0版本修復補丁考慮不全面,導致補丁繞過,出現了第二種攻擊方式,適用于Shiro < 1.5.2版本。
Shiro 1.4.2 -> 1.5.0 版本補丁分析
對比Shiro 1.4.2與Shiro 1.5.0版本的改動,Shiro在org.apache.shiro.web.filter.PathMatchingFilter類中添加了刪除requestURI結尾的/的代碼。
Shiro 1.4.2代碼分析
傳入的payload首先被服務器接收,并傳送給Shiro攔截器處理(org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter方法作為入口)。
調用createSubject方法創建Subject,并調用execute方法進入Shiro FilterChain中。
進入org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#
getChain方法中,首先獲取請求URI路徑,之后迭代獲取攔截器的表達式。
這里重點關注/hello/*表達式。代碼進入pathMatches方法,最終調用org.apache.shiro.util.AntPathMatcher#doMatch方法進行傳入的requestURI與攔截器表達式進行匹配。
匹配過程中,分別將攔截器表達式與requestURI以/作為分隔符進行字符串到數組的轉換,通過循環匹配數組中對應的元素,判斷requestURI是否符合攔截器表達式匹配形式。
如果表達式中存在通配符*,會將containsStar標志位賦值為true,進入 else if (patIdxEnd == 0)判斷條件,返回true。
繼續跟進代碼,在requestURI與攔截器表達式匹配結束后,還會進行一次判斷,而漏洞產生的原因也是由于判斷的條件。如果Shiro攔截器表達式不以/結尾,且requestURI以/結尾,判斷代碼將返回false表示匹配失敗,從而繞過Shiro認證。
跟進到Spring處理URI的代碼,進入org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal方法,獲取requestURI。
進入lookupHandlerMethod方法,調用addMatchingMappings方法,獲取Spring攔截器。
進入org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#getMatchingCondition方法進行調用doMatch方法進行requestURI和攔截器表達式的匹配。
Spring攔截器匹配流程和Shiro大致相同,都是將字符串轉換為數組進行匹配。
由于Spring多了一個環節,在檢測攔截器表達式與requestURI結尾是否為/之后,并沒有直接返回false。而是將攔截器表達式結尾添加/,并繼續進行
path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)
測試,從而完成了攔截器表達式與requestURI的匹配。
上述攻擊方式在Shiro 1.5.0版本中修復,但是被二次繞過,繞過分析如下。
Shiro 1.5.1 -> 1.5.2 版本補丁分析
對比Shiro 1.5.1與Shiro 1.5.2版本的改動
Shiro 1.5.2版本中,在進行decodeAndCleanUriString方法之前會先進行URI解析,調用request.getServletPath()和request.getPathInfo()獲取ServletPath和PathInfo并進行路徑拼接。
Shiro 1.5.1代碼分析
Shiro 1.5.0 - 1.5.1在認證過程中基本沒有變化,主要分析一下二次繞過的利用點。還是以org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain作為起點。
在獲取requestURI時,依舊會在getPathWithinApplication方法中調用getRequestUri方法進行requestURI的解析并獲取,但是在URI正規化處理時,先調用decodeAndCleanUriString方法進行路徑的解碼,并清理URI。
進入decodeAndCleanUriString方法,發現此方法會以分號將傳入的URI進行截斷,并將分號以及分號后面的數據進行清空,返回分號前面的URI數據,從而讓/a/b;/c變為/a/b。
繼續跟進到Spring攔截器的decodeAndCleanUriString方法中。
從代碼中可以發現,Spring對于分號的處理方式與Shiro不同,Spring會先獲取分號的位置,并檢測分號后是否存在/,如果有,將/的位置記錄在slashIndex變量中,并將分號前的數據與/之后的數據進行拼接,從而讓/a/b;/c變為/a/b/c。返回處理后的requestURI。
由于Spring與Shiro的decodeAndCleanUriString方法不同,攻擊者可以使用分號構造路徑,繞過Shiro認證,并可以匹配Spring的動態控制器。
搭建Apache Shiro漏洞環境,使用構造的payload進行攻擊,最終繞過授權訪問到未授權資源,效果如圖:
正常訪問:
Apache Shiro 1.4.2環境
Apache Shiro 1.5.1環境
目前受影響的Apache Shiro版本:
Apache Shiro < 1.5.2
Apache Shiro最新版本已經修復此漏洞,請受漏洞影響的用戶下載最新版本,下載鏈接:http://shiro.apache.org/download.html
關于Apache Shiro權限繞過漏洞CVE-2020-1957怎么理解就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。