您好,登錄后才能下訂單哦!
如何進(jìn)行Struts2-057漏洞分析,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
Struts2-057,2018/8/22剛爆發(fā)的一個(gè)struts2的遠(yuǎn)程代碼執(zhí)行漏洞,網(wǎng)上已經(jīng)有很多復(fù)現(xiàn)的文章了,這里并不打算對(duì)漏洞做復(fù)現(xiàn),只是在代碼層面研究漏洞。
官方對(duì)這次漏洞的描述是:
1.定義XML配置時(shí)如果namespace值未設(shè)置且上層動(dòng)作配置(Action Configuration)中未設(shè)置或用通配符namespace時(shí)可能會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行。
2.url標(biāo)簽未設(shè)置value和action值且上層動(dòng)作未設(shè)置或用通配符namespace時(shí)可能會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行。
Namespace用于將action分為邏輯上的不同模塊,可以有效避免action重名的情況。默認(rèn)的namespace為空,當(dāng)所有namespace中都找不到時(shí)才會(huì)在這個(gè)namespace中尋找。
先解釋第一種情況:在struts.xml配置文件中,如果沒(méi)有為基礎(chǔ)xml配置中定義的result設(shè)置namespace,且上層<action>標(biāo)簽中沒(méi)有設(shè)置namespace或者是使用通配符namespace時(shí),則可能存在遠(yuǎn)程代碼執(zhí)行漏洞。(而各個(gè)result類(lèi)型中只有redirectAction、chain以及postback這三種下面有namespace這個(gè)參數(shù)。)
示例:
<struts> <package ....> <action name="a1"> <result type="redirectAction"> <param name="actionName">a2.action</param> </result> </action> </package></struts>
第二種情況:如果struts的url標(biāo)簽<s:url>中未設(shè)置value和action值,且關(guān)聯(lián)的action標(biāo)簽未設(shè)置或使用通配符namespace時(shí)可能會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行。
示例:
<s:url action="/hello/hello_struts2" var="hello" > <s:param name="messageStore.message">Struts2 Tags</s:param> </s:url> <a href="${hello}">你好Struts2 Tag</a>
FilterDispatcher是struts2的核心控制器,負(fù)責(zé)攔截所有的用戶(hù)請(qǐng)求,然后FilterDispatcher通過(guò)調(diào)用ActionMapper(接口)來(lái)決定調(diào)用哪個(gè)Action。
出問(wèn)題的第一步就在這里:
Struts2默認(rèn)的是調(diào)用DefaultActionMapper這一實(shí)現(xiàn)類(lèi)中的getMapping這一方法解析request來(lái)判斷調(diào)用哪個(gè)action(報(bào)錯(cuò)namespace、name、method),其中ActionMapper是通過(guò)parseNameAndParameters方法來(lái)獲取namespace的。
可以需要說(shuō)下alwaysSelectFullNamespace這個(gè)屬性,當(dāng)alwaysSelectFullNamespace為true時(shí),會(huì)嚴(yán)格按照uri提供的namespace去尋找action,找不到就會(huì)報(bào)404,所以這種情況下就算我們可以構(gòu)造任意的namespace,但由于找不對(duì)應(yīng)的action,在將namespace當(dāng)ognl表達(dá)式執(zhí)行代碼前請(qǐng)求就會(huì)報(bào)404的錯(cuò)誤,攻擊不能成功。好在alwaysSelectFullNamespace的缺省值為true,這時(shí)
1.假設(shè)請(qǐng)求路徑的URI,例如url是:http://localhost:8081/項(xiàng)目名/path2/path3 /addUser.action
2.首先尋找namespace為/path2/path3的package,如果存在這個(gè)package,則在這個(gè)package中尋找名字為addUser的action,若找到則執(zhí)行,否則轉(zhuǎn)步驟5;如果不存在這個(gè)package則轉(zhuǎn)步驟3。
3.尋找namespace為/path2的package,如果存在這個(gè)package,則在這個(gè)package中尋找名字為addUser的action,若找到則執(zhí)行,否則轉(zhuǎn)步驟5;如果不存在這個(gè)package則轉(zhuǎn)步驟4。
4.尋找namespace為/的package,如果存在這個(gè)package,則在這個(gè)package中尋找名字為addUser的action,若找到則執(zhí)行,轉(zhuǎn)步驟5;如果不存在轉(zhuǎn)步驟5。
5.如果存在缺省的命名空間,就在該package下查找名字為addUser的action,若找到則執(zhí)行,否則頁(yè)面提示找不到action;否則提示面提示找不到action。
這也就是前文中所描述的為什么攻擊需要“上層<action>標(biāo)簽中沒(méi)有設(shè)置namespace或者是使用通配符namespace時(shí)”這一條件,這種情況下,可以構(gòu)造任意namespace而請(qǐng)求不會(huì)出錯(cuò)。(這里就是source點(diǎn)了)
出問(wèn)題的第二步(也就是sink點(diǎn)):
僅僅構(gòu)造了任意的namespace還不夠,還需要一個(gè)爆發(fā)點(diǎn)才行。這里以edirectAction這一返回類(lèi)型來(lái)進(jìn)行分析,redirectAction對(duì)應(yīng)的類(lèi)是org.apache.struts2.result.ServletActionRedirectResult。(實(shí)際上不止這一個(gè)類(lèi)有問(wèn)題,chain和postback這兩個(gè)返回類(lèi)型都有問(wèn)題)。
在所請(qǐng)求的Action執(zhí)行完后,會(huì)調(diào)用ServletActionRedirectResult.execute()進(jìn)行重定向Result的解析,通過(guò)ActionMapper.getUriFromActionMapping()重組namespace和name后,由setLocation() 將帶namespace的location放入父類(lèi)ServletRedirectResult中調(diào)用exectue方法,然后ServletRedirectResult又會(huì)調(diào)用父類(lèi)StrutsResultSupport中的exectue方法。
最后由StrutsResultSupport調(diào)用conditionalParse(location,invocation)方法,通過(guò)TextParseUtil.translateVariables()調(diào)用OgnlTextParser.evaluate()解析執(zhí)行url中的OGNL表達(dá)式,導(dǎo)致代碼執(zhí)行。
關(guān)于如何進(jìn)行Struts2-057漏洞分析問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guā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)容。