您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)Apache Shiro 權(quán)限繞過(guò)漏洞CVE-2020-11989的分析是怎樣的,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證、授權(quán)、密碼和會(huì)話管理。使用Shiro的易于理解的API,可以快速、輕松地獲得任何應(yīng)用程序,從最小的移動(dòng)應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序。內(nèi)置了可以連接大量安全數(shù)據(jù)源(又名目錄)的Realm,如LDAP、關(guān)系數(shù)據(jù)庫(kù)(JDBC)、類似INI的文本配置資源以及屬性文件等。
Apache Shiro 1.5.3之前版本,由于Shiro攔截器與requestURI的匹配流程和Web框架的攔截器的匹配流程有差異,攻擊者構(gòu)造一個(gè)特殊的http請(qǐng)求,可以繞過(guò)Shiro的認(rèn)證,未授權(quán)訪問敏感路徑。此漏洞存在兩種攻擊方式。
First Attack
傳入的payload首先被服務(wù)器接收,并傳送給Shiro攔截器處理(org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter方法作為入口)。
調(diào)用createSubject方法創(chuàng)建Subject,并調(diào)用execute方法進(jìn)入Shiro FilterChain中。
進(jìn)入org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain方法中,首先獲取請(qǐng)求URI路徑。
在Shiro1.5.2版本中,對(duì)于requestURI處理的方式存在一些不同,此處也是漏洞觸發(fā)點(diǎn)所在。Shiro1.5.2使用的是request.getContextPath(),request.getServletPath(),request.getPathInfo()拼接的方式。由于getServletPath()方法會(huì)對(duì)requestURI進(jìn)行一次url解碼,在之后的decodeAndCleanUriString方法中進(jìn)行第二次url解碼。
回到getChain方法中,迭代獲取攔截器的表達(dá)式。
這里重點(diǎn)關(guān)注/hello/*表達(dá)式。代碼進(jìn)入pathMatches方法,最終調(diào)用org.apache.shiro.util.AntPathMatcher#doMatch方法進(jìn)行傳入的requestURI與攔截器表達(dá)式進(jìn)行匹配。
匹配過(guò)程中,分別將攔截器表達(dá)式與requestURI以/作為分隔符進(jìn)行字符串到數(shù)組的轉(zhuǎn)換,通過(guò)循環(huán)匹配數(shù)組中對(duì)應(yīng)的元素,判斷requestURI是否符合攔截器表達(dá)式匹配形式。
如果表達(dá)式中存在通配符*,會(huì)將containsStar標(biāo)志位賦值為true,進(jìn)入 else if (patIdxEnd == 0)判斷條件,返回true。
最終回到doMatch方法中,通過(guò)判斷表達(dá)式數(shù)組的元素個(gè)數(shù)與requestURI的元素個(gè)數(shù),以及表達(dá)式中是否包含**,完成后續(xù)的匹配。
跟進(jìn)到Spring處理URI的代碼,進(jìn)入org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal方法,獲取requestURI。由于Spring獲取requestURI時(shí)使用getRequestURI()方法,此方法不會(huì)進(jìn)行URL解碼。只會(huì)在decodeAndCleanUriString完成一次url解碼。
進(jìn)入lookupHandlerMethod方法,調(diào)用addMatchingMappings方法,獲取Spring攔截器。
進(jìn)入org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#getMatchingCondition方法調(diào)用doMatch方法進(jìn)行requestURI和攔截器表達(dá)式的匹配。
Spring攔截器匹配流程和Shiro大致相同,同樣是將字符串轉(zhuǎn)換為數(shù)組進(jìn)行匹配。
由于Spring只進(jìn)行了一次URL解碼,所以將未完全解碼的部分作為一個(gè)整體,從而完成了攔截器表達(dá)式與requestURI的匹配。
Second Attack
漏洞觸發(fā)點(diǎn)同樣是Shiro在修復(fù)CVE-2020-1957漏洞時(shí),使用request.getContextPath(),request.getServletPath(),request.getPathInfo()拼接的方式,進(jìn)行requestURI的獲取。<br>直接跟蹤到uri = valueOrEmpty(request.getContextPath()) + "/" + valueOrEmpty(request.getServletPath()) + valueOrEmpty(request.getPathInfo());
在調(diào)用getContextPath()方法獲取context-path時(shí),會(huì)調(diào)用removePathParameter方法清除掉分號(hào)以及分號(hào)到下一個(gè)/中間的數(shù)據(jù)。
接下來(lái)進(jìn)入for循環(huán)中匹配candidate與conotext-path是否相同。
如果不同,則從傳入的URL中繼續(xù)讀取下一級(jí)目錄,直到condidate與context-path相同,返回從URL截取的目錄作為contextPath。由于context-path獲取方式和removePathparameters方法對(duì)URL的處理,攻擊者可以請(qǐng)求,讓contextPath變量獲取到帶有分號(hào)的非預(yù)期值。
在進(jìn)行requestURI拼接時(shí),構(gòu)造出根路徑帶有分號(hào)的requestURI。利用CVE-2020-1957漏洞原理,經(jīng)過(guò)decodeAndCleanUriString方法時(shí),截?cái)鄏eqeustURI中分號(hào)后的數(shù)據(jù),并返回。從而繞過(guò)了shiro權(quán)限控制。
回顧C(jī)VE-2020-1957漏洞
在URI正規(guī)化處理時(shí),先調(diào)用decodeAndCleanUriString方法進(jìn)行路徑的解碼,并清理URI。
進(jìn)入decodeAndCleanUriString方法,發(fā)現(xiàn)此方法會(huì)以分號(hào)將傳入的URI進(jìn)行截?cái)?,并將分?hào)以及分號(hào)后面的數(shù)據(jù)進(jìn)行清空,返回分號(hào)前面的URI數(shù)據(jù),從而讓/a/b;/c變?yōu)?a/b。
繼續(xù)跟進(jìn)到Spring攔截器的decodeAndCleanUriString方法中。
從代碼中可以發(fā)現(xiàn),Spring對(duì)于分號(hào)處理的方式與Shiro不同,Spring會(huì)先獲取分號(hào)的位置,并檢測(cè)分號(hào)后是否存在/,如果有,將/的位置記錄在slashIndex變量中,并將分號(hào)前的數(shù)據(jù)與/之后的數(shù)據(jù)進(jìn)行拼接,從而讓/a/b;/c變?yōu)?a/b/c。返回處理后的requestURI。
補(bǔ)丁分析
對(duì)比Shiro 1.5.2與Shiro 1.5.3版本的改動(dòng),在org.apache.shiro.web.util.WebUtils類中添加了刪除requestURI結(jié)尾的/的代碼。
補(bǔ)丁主要優(yōu)化了getPathWithinApplication方法,并單獨(dú)定義了getServletPath方法,getPathInfo方法。補(bǔ)丁修復(fù)后,調(diào)用getPathWithinApplication方法獲取requestURI只會(huì)在進(jìn)行g(shù)etServletPath方法中進(jìn)行一次url解碼,保持與Spring獲取requestURI過(guò)程中相同的url解碼次數(shù)。防御了雙重url編碼繞過(guò)。
獲取requestURI直接調(diào)用getServletPath方法和getPathInfo方法進(jìn)行拼接,由于不需要與contextpath拼接,從而防御了First Attack攻擊。
搭建Apache Shiro漏洞環(huán)境,使用構(gòu)造的payload進(jìn)行攻擊,最終繞過(guò)授權(quán)訪問到未授權(quán)資源,效果如圖:
正常訪問:
First Attack
Second Attack
目前受影響的Apache Shiro版本:
Apache Shiro < 1.5.3
Apache Shiro最新版本已經(jīng)修復(fù)此漏洞,請(qǐng)受漏洞影響的用戶下載最新版本, 下載鏈接:http://shiro.apache.org/download.html
以上就是Apache Shiro 權(quán)限繞過(guò)漏洞CVE-2020-11989的分析是怎樣的,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。