友快網

導航選單

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

0×5 CVE-2020-13933

0x5。1 漏洞簡介

影響版本: shiro<1。6。0

型別: 許可權繞過

其他資訊:

這個洞跟CVE-2020-11989有點相似的地方就是就是利用URL解碼的差異性來實現繞過。

CVE-2020-13933:Apache Shiro 許可權繞過漏洞分析

0x5。2 漏洞配置

這個洞是不會受到Spring的版本限制的。

org。apache。shiro

shiro-web

1。5。3

org。apache。shiro

shiro-spring

1。5。3

Shiro配置,這個洞也是有限制的只能是ant的風格為單*號才可以:

map。put(“/hello/*”, “authc”);    @ResponseBody

@RequestMapping(value=“/hello” +            “” +            “/{index}”, method= RequestMethod。GET)

public  String hello1(@PathVariable String index){        return “Hello World”+ index。toString() + “!”;

}

0x5。3 漏洞演示

訪問302,然後poc:

/hello/%3bluanxie

看到這個POC的時候,我當時就覺得我前面分析兩個洞的時候,是不是漏了什麼關鍵點沒去分析。

然後最讓我頭疼的的是,為什麼需要對;要編碼才能利用成功,下面我們透過分析來複盤我們前兩次學習過程出現的問題。

0x5。4 漏洞分析

斷點依然是在上一次的修補點:

org。apache。shiro。web。util。WebUtils#getPathWithinApplication

這裡我們逐步跟進去,上一次我沒跟removeSemicolon, 因為從函式名這個其實就是Shiro一直以來的操作,就是去除;號後面的內容,然後normalize,這個並沒有很大問題。

然後函式返回的結果是這個:

本來應該獲取到uri的是/hello/,然後因為最早的那個shiro-682的洞,所以會執行去掉末尾的斜杆。

if (requestURI != null && !“/”。equals(requestURI) && requestURI。endsWith(“/”)) {

requestURI = requestURI。substring(0, requestURI。length() - 1);

}

變成了:/hello

首先透過,Iterator var6 = filterChainManager。getChainNames()。iterator()獲取了我們定義的filter,進入do迴圈逐個取值給pathPattern

其實都沒必要去看這個演算法怎麼做匹配的,因為/hello/*本來就不會匹配/hello,

那麼這樣,如果是這樣呢,map。put(“/hello/”, “authc”);,emm,在取出來進行匹配的時候,

就會被去掉/,那麼我來多幾個唄。

map。put(“/hello//”, “authc”);

稍微繞過了

這個時候我們就可以回頭去讀一下Shiro的匹配演算法了。

首先是如果pattern和path開頭不一樣直接false

然後就是StringUtils。tokenizeToStringArray分割字串得到陣列

然後一個迴圈,比較,如果出現某陣列字串不匹配,除開**就會返回false

只要沒有**出現的話,且字串陣列=1,就沒那麼複雜的解析過程,直接返回

pattern。endsWith(this。pathSeparator) ? path。endsWith(this。pathSeparator) : !path。endsWith(this。pathSeparator);

如果pattern是以/結尾的話,那麼是 True,返回path。endsWith(this。pathSeparator),這個時候path不是以/結尾的,所以最終也不匹配。

如果是/*的話,字串陣列>1,

那麼最終會進入

這個過程說明,/hello/* 可以匹配/hello/,但是沒辦法匹配到/hello,然後shiro又做了去除/處理,emmm,根本不可能構造出/hello/,構造出來也沒啥可用的

但是如果是,/hello/**,這裡就不返回false,直接跳到下面了,最終會返回True,沒辦法繞過。說明/hello/**可以匹配到/hello

其實來到這裡我們就明白了,第一步透過%3b解碼成;,然後以前的洞刪掉了/,導致了bypass Shiro。

如果我們不用%3b,而是直接

那麼;直接會被request。getServletPath()處理掉,從而變成了/hello/aa,被/hello/**這種ant所匹配,導致第一層都沒辦法繞過。(這個其實就是cve2020-1957的繞過思路呀!肯定是沒辦法的呀)

0x5。5 漏洞修復

說實話,關於這個洞,我當時思考的修復方式是,好像只能是去遮蔽%3b這個字元了,感覺真的很無奈。

diff:https://github。com/apache/shiro/compare/shiro-root-1。5。3…shiro-root-1。6。0

發現確實新增InvalidRequestFilter。java,但是具體作用不知道在哪裡起的,

然後在這個檔案被呼叫:

support/spring/src/main/java/org/apache/shiro/spring/web/ShiroFilterFactoryBean。java

這個檔案新增了一個/**匹配沒有設定filter型別,用於解決失配的時候還是可以呼叫預設的過濾器

然後輸入特殊字元的時候,過濾器會進行過濾,關於是如何進行過濾的,值得詳細寫一篇文章,這裡我們只要知道它的修復方式,是做了特殊字元,存在就丟擲400就行了。

return !this。containsSemicolon(uri) && !this。containsBackslash(uri) && !this。containsNonAsciiCharacters(uri);

0×6 CVE-2020-17510

0x6。1 漏洞簡介

影響版本: shiro<1。7。0

型別: 許可權繞過

其他資訊:

中風險,需結合Spring使用環境,危害偏低一點

0x6。2 漏洞分析

diff:https://github。com/apache/shiro/compare/shiro-root-1。6。0…shiro-root-1。7。0

改動:

這個洞我發現他增加了request。getPathInfo的方式檢測字元,而在Spring-boot預設這個值是空,但是在其他情況,這個值可控的話,我們可以在這裡插入;和。。實現繞過,結合前面的分析,可以知道URI是由request。getServletPath + request。getPathInfo得到的,所以是可以去繞過的,不過由於這個洞鮮少人討論,作者也沒去公開,這個利用方式研究價值很低,筆者對此沒有很大興趣,所以就沒去折騰場景來利用, 歡迎其他師傅感興趣地話繼續研究。

這些CVE的形成原因,最後再對成因做一個總結。

0×7 CVE-2020-17523

0x7。1 漏洞簡介

影響版本: shiro<1。7。0

型別: 許可權繞過

其他資訊:當Apache Shiro與Spring框架結合使用時,在一定許可權匹配規則下,攻擊者可透過構造特殊的 HTTP 請求包繞過身份認證。

0x7。2 漏洞配置

org。apache。shiro

shiro-web

1。6。0

org。apache。shiro

shiro-spring

1。6。0

這個漏洞我建議spring-boot用2。4。5的,這個版本預設會開啟全路徑匹配模式。

當Spring Boot版本在小於等於2。3。0。RELEASE的情況下,alwaysUseFullPath為預設值false,這會使得其獲取ServletPath,所以在路由匹配時相當於會進行路徑標準化包括對%2e解碼以及處理跨目錄,這可能導致身份驗證繞過。而反過來由於高版本將alwaysUseFullPath自動配置成了true從而開啟全路徑,又可能導致一些安全問題

0x7。3 漏洞演示

通殺版本:/hello/%20

高版本預設支援:/hello/%2e/ 或者 /hello/%2e

其實這個洞,基於之前的%3B實現繞過的思路,其實很容易想到去Fuzz下的,看看除了%3B是不是還有其他字元可以在Shiro中造成失配,而Spring-boot可以正常匹配的,都不用去分析具體程式碼的,就可以拿到的一個ByPass。

但是這兩種繞過方式其實非常不同的,出現在了兩個不同地方的錯誤處理方式。

0x7。4 漏洞分析

第一種繞過方式分析:

斷點打在org。apache。shiro。web。util。WebUtils#getPathWithinApplication

這裡處理結果和前面一樣,解碼了所以變成了空格。

跟進這裡看匹配,

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

很明顯,這裡和上次分析結果是一樣的,最終還是因為*返回了false,否則True。

那麼為什麼會這樣呢?那為什麼/hello/aa這樣就不行呢? 其實就是StringUtils。tokenizeToStringArray沒有正確分割字串導致的?%20 應該是被當做空字元了,導致分割的陣列長度=1,就會進入那個return false。

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

所以這裡成功Bypass了Shiro的檢測,最後讓我們來看下Spring-boot是怎麼處理的

斷點:org。springframework。web。servlet。DispatcherServlet#doDispatch

逐步跟到:org。springframework。web。servlet。handler。AbstractHandlerMethodMapping#lookupHandlerMethod

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

這裡是根據lookpath進行匹配,沒有直接被找到

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

下面進入用RequestMapping註冊的列表來匹配:

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

這裡繼續進入匹配:

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

最終這個org。springframework。util。AntPathMatcher#doMatch進行了解析,和之前演算法差不多,但是

this。tokenizePath(path)返回的結果是2包括%20,所以可以匹配成功,最終解析到了/hello/{index}

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

第二種繞過方式分析:

這個其實在分析cve-2020-13933的時候,我就考慮過這種方式去繞過(部分原理相同,利用預設去掉/造成的失配),然後當時實踐了,由於採取了低版本的spring-boot,預設沒開啟全路徑匹配模式,導致我當時沒成功。

首先說一下網上有些文章,分析的時候不夠全面,但是又概括性總結了原因,有一定的誤導,這裡我列出我的debug結果

/hello/%2e->request。getServletPath()->/hello/

/hello/%2e/->request。getServletPath()->urldecode->/helo/

/hello/%2e%2e ->request。getServletPath() -> urldecode->/

也就是說,request。getServletPath()針對%2e會先解碼,然後對此進行處理。

所以洞出現的問題是:

request。getServletPath() 處理這種URL時候會返回/hello/,然後shiro預設會去掉最後/,然後再進行匹配,導致了繞過。

0x7。5 漏洞修復

diff:https://github。com/apache/shiro/compare/shiro-root-1。7。0…shiro-root-1。7。1

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

這個處理就可以避免空白字元沒被正確分割出來的問題,解決了第一種繞過問題。

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

然後可以看到這裡為了避免%2e,這裡首先去掉了之前shiro-682,為了修補末尾/繞過問題,做的一個去掉預設路徑/的操作。

然後後面寫了個if/else的判斷

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

先不去掉/來做匹配,如果匹配失敗,在考慮去掉/,這樣考慮是基於以前的問題和現在的問題共同考慮

首先以前是 /hello被/hello/實現了繞過,那麼在做匹配的時候,那麼第一次匹配失敗,然後進入了第二個去掉/匹配成功

現在是/hello/*被先/hello/預設去掉/->/hello實現了繞過,那麼在做匹配的時候,第一次先保留/hello/可以成功被/hello/*匹配。

0×8 總結

cve-2020:apache shiroshiro許可權繞過漏洞分析0x5

漏洞的最基本原理,通俗來說就是,一個原始惡意構造的URL ,首先要繞過Shiro的判斷,然後被Spring解析到最終的函式,也就是Shiro解析URL和Spring解析URL的差異性。然後多次Bypass都是針對實現解析的環節存在一些問題導致。

行文頗長,若有不當之處,多多包涵。

上一篇:乾電腦行業的收入十分可觀,我想說:乾電腦行業的收入十分可觀
下一篇:安卓手機使用者注意:谷歌將推出隱私標籤功能,這對我們有什麼影響?