如何進行Struts2-057漏洞分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Struts2-057,2018/8/22剛爆發的一個struts2的遠程代碼執行漏洞,網上已經有很多復現的文章了,這里并不打算對漏洞做復現,只是在代碼層面研究漏洞。
官方對這次漏洞的描述是:
1.定義XML配置時如果namespace值未設置且上層動作配置(Action Configuration)中未設置或用通配符namespace時可能會導致遠程代碼執行。
2.url標簽未設置value和action值且上層動作未設置或用通配符namespace時可能會導致遠程代碼執行。
Namespace用于將action分為邏輯上的不同模塊,可以有效避免action重名的情況。默認的namespace為空,當所有namespace中都找不到時才會在這個namespace中尋找。
先解釋第一種情況:在struts.xml配置文件中,如果沒有為基礎xml配置中定義的result設置namespace,且上層<action>標簽中沒有設置namespace或者是使用通配符namespace時,則可能存在遠程代碼執行漏洞。(而各個result類型中只有redirectAction、chain以及postback這三種下面有namespace這個參數。)
示例:
<struts> <package ....> <action name="a1"> <result type="redirectAction"> <param name="actionName">a2.action</param> </result> </action> </package></struts>
第二種情況:如果struts的url標簽<s:url>中未設置value和action值,且關聯的action標簽未設置或使用通配符namespace時可能會導致遠程代碼執行。
示例:
<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的核心控制器,負責攔截所有的用戶請求,然后FilterDispatcher通過調用ActionMapper(接口)來決定調用哪個Action。
出問題的第一步就在這里:
Struts2默認的是調用DefaultActionMapper這一實現類中的getMapping這一方法解析request來判斷調用哪個action(報錯namespace、name、method),其中ActionMapper是通過parseNameAndParameters方法來獲取namespace的。


可以需要說下alwaysSelectFullNamespace這個屬性,當alwaysSelectFullNamespace為true時,會嚴格按照uri提供的namespace去尋找action,找不到就會報404,所以這種情況下就算我們可以構造任意的namespace,但由于找不對應的action,在將namespace當ognl表達式執行代碼前請求就會報404的錯誤,攻擊不能成功。好在alwaysSelectFullNamespace的缺省值為true,這時
1.假設請求路徑的URI,例如url是:http://localhost:8081/項目名/path2/path3 /addUser.action
2.首先尋找namespace為/path2/path3的package,如果存在這個package,則在這個package中尋找名字為addUser的action,若找到則執行,否則轉步驟5;如果不存在這個package則轉步驟3。
3.尋找namespace為/path2的package,如果存在這個package,則在這個package中尋找名字為addUser的action,若找到則執行,否則轉步驟5;如果不存在這個package則轉步驟4。
4.尋找namespace為/的package,如果存在這個package,則在這個package中尋找名字為addUser的action,若找到則執行,轉步驟5;如果不存在轉步驟5。
5.如果存在缺省的命名空間,就在該package下查找名字為addUser的action,若找到則執行,否則頁面提示找不到action;否則提示面提示找不到action。
這也就是前文中所描述的為什么攻擊需要“上層<action>標簽中沒有設置namespace或者是使用通配符namespace時”這一條件,這種情況下,可以構造任意namespace而請求不會出錯。(這里就是source點了)
出問題的第二步(也就是sink點):
僅僅構造了任意的namespace還不夠,還需要一個爆發點才行。這里以edirectAction這一返回類型來進行分析,redirectAction對應的類是org.apache.struts2.result.ServletActionRedirectResult。(實際上不止這一個類有問題,chain和postback這兩個返回類型都有問題)。
在所請求的Action執行完后,會調用ServletActionRedirectResult.execute()進行重定向Result的解析,通過ActionMapper.getUriFromActionMapping()重組namespace和name后,由setLocation() 將帶namespace的location放入父類ServletRedirectResult中調用exectue方法,然后ServletRedirectResult又會調用父類StrutsResultSupport中的exectue方法。



最后由StrutsResultSupport調用conditionalParse(location,invocation)方法,通過TextParseUtil.translateVariables()調用OgnlTextParser.evaluate()解析執行url中的OGNL表達式,導致代碼執行。


關于如何進行Struts2-057漏洞分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。