前言
2018年8月22日,apache Strust2發(fā)布最新安全公告,Apache struts2存在遠(yuǎn)程代碼執(zhí)行的高危漏洞(S2-057/CVE-2018-11776),該漏洞由Semmle Security Research team的安全研究員Man YueMo發(fā)現(xiàn)。
該漏洞是由于在struts2開發(fā)框架中使用Namespace功能定義xml配置時,namespace值未被設(shè)置且在上層動作配置(action configuration)中未設(shè)置或用通配符namespace,可能導(dǎo)致遠(yuǎn)程代碼執(zhí)行。同理,url標(biāo)簽未設(shè)置value和action值且上層動作未設(shè)置或用通配符namespace時也可能導(dǎo)致遠(yuǎn)程代碼執(zhí)行,經(jīng)過筆者自建環(huán)境成功復(fù)現(xiàn)漏洞且可以執(zhí)行命令回顯,文末有你們想要的 !
漏洞利用
筆者搭的環(huán)境分別是Strust2 2.3.20版本和 Strust2 2.3.34版本,漏洞利用大致分為三種方式:數(shù)值計算、彈出計算器、 命令回顯。
2.1 數(shù)值計算
數(shù)值計算相對最簡單,在URL上指定 %{100+200} 就可以發(fā)生跳轉(zhuǎn),得到計算的結(jié)果
2.2 彈出計算器
2.3.20版本的POC如下:
2.3.3 4版本參考的POC如下:
2.3 命令回顯
兩個版本都是利用com.opensymphony.xwork2.dispatcher.HttpServletResponse對象去打印命令執(zhí)行后的回顯數(shù)據(jù)
2.3.20版本的POC如下:
2.3.34版本的POC如下:
攻擊后效果如下圖
漏洞分析
在分析漏洞之前,需要配置struts.xml文件,這個文件就是struts2的核心配置文件,大多數(shù)的時候增減配置都需要操控這里;
總共兩處需要注意,第一處一定要配置struts.mapper.alwaysSelectFullNamespace? = true ,否則不能觸發(fā)漏洞,這個配置的目的是設(shè)定是否一直在最后一個斜線之前的任何位置選定NameSpace;第二處result標(biāo)簽返回的類型選擇 “ redirectAction 或 chain“ , 只有這兩個配置選項的值是可以將action轉(zhuǎn)發(fā)或者重定向;關(guān)于type具體可以參考下圖
說完了配置,開始動態(tài)分析。漏洞位于
struts2-core.jar!/org/apache/struts2/dispatcher/ServletActionRedirectResult.class
this.namespace這個成員的值來自于getNamespace()方法,再通過getUriFromActionMapping()返回URI字符串;
通過getUriFromActionMapping獲取的值賦給了tmplocation變量,接著表達(dá)式進(jìn)入setLocation方法
再通過super.execute方法調(diào)用了ServletActionResult ,而在execute方法體內(nèi)跟進(jìn)了conditionalParse方法,在這個方法內(nèi)調(diào)用了ONGL執(zhí)行的關(guān)鍵方法translateVariables。
獲得的param值傳入到translateVariables()方法內(nèi),最終在OnglTextPaser里導(dǎo)致了OGNL表達(dá)式執(zhí)行。
再彈出計算器后獲得lastFinalLocation的值為當(dāng)前執(zhí)行后的句柄,這個值作為響應(yīng)跳轉(zhuǎn)的action地址,也就是在瀏覽器中彈出計算器后在地址欄中出現(xiàn)的URI
到這里彈出計算器的分析到此為止,接下來看下基于命令執(zhí)行回顯結(jié)果的分析,基本上流程和上述一樣,唯一不同之處lastFinalLocation返回的值是NULL,這也就引發(fā)出提交后沒有做302的跳轉(zhuǎn),依舊是當(dāng)前的action,并且返回的值是200
知道了原理后小同事用python實現(xiàn)了exp檢測腳本,此腳本用途僅供學(xué)習(xí)研究;?
防御措施
1.???將框架版本升級到官方最新版本;
2.???對于Web應(yīng)用來說,盡量保證代碼的安全性;
3.???對于IDS規(guī)則層面來說,數(shù)值計算和彈計算器返回的狀態(tài)碼都是302,并且Location跳轉(zhuǎn)字段含有特征句柄字符串;如果是命令回顯返回的200狀態(tài)碼,且有命令結(jié)果輸出;