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