盧 帥
(1.武漢郵電科學研究院 武漢 430070)(2.南京烽火星空通信發展有限公司 南京 210005)
互聯網黑客通過制造危險漏洞、勒索病毒、遠程木馬等入侵服務器,竊取賬戶信息。勒索交費,成為互聯網灰色產業鏈中規模很大的牟利方式;甚至有企業雇傭黑客惡意打擊競爭對手。2017年3月7號,安全研究人員發現J2EE框架Struts2存在遠程代碼執行的漏洞,攻擊者可通過修改HTTP請求頭中的Content-Type值來觸發該漏洞,造成系統被控[1]。此漏洞被Struts2官方確認,漏洞編號為S2-045,CVE編號為CVE-2017-5638,被定級為高級風險,是一種常見Web應用漏洞[2]。利用Struts2“命令執行漏洞”,黑客可輕易獲得網站服務器ROOT權限、執行任意命令,從而竊取重要數據或篡改網頁,目前國內至少有3500家網站存在該高危漏洞[3]。
Struts2作為一種使用及其廣泛的Web框架,就意味著在目前的企業應用中仍有大量的平臺網站采用它,即使springmvc、springcloud越來越成為新的一代的web框架,但是采用Struts2的網站的數據量是龐大的,根據瑞星安全研究院的掃碼結果顯示,國內仍有大量管理員未能及時修補漏洞[4]。S2-045漏洞一經證實,就表示無數這樣的網站面臨著巨大的威脅。尤其是像政府的政務平臺、金融機構的交易平臺、還是各大高校的教務管理平臺,無疑對社會的秩序,公民的正常的活動來說,影響是不言而喻的。
Web應用通常有三層架構,任何一層出現安全問題都會導致整個Web應用受到威脅[5]。Struts通常采用MVC三層模型,包括上層展示數據等信息的用戶界面,中間層的服務程序,還有底層的數據庫。而這些都是黑客的目標,通過修改界面,讓用戶跳轉惡意鏈接,篡改、刪除服務端的程序,使得程序無法運行,讓網站崩潰達到商業目的,黑進網站數據庫,獲得用戶的私人信息,從而盜取用戶的賬號資產等對用戶不利的行為。常見的攻擊方式有SQL注入[6]、跨站腳本(XSS)[7~8]。而S2-045漏洞則是通過發http請求來攻擊,它是一種常見的信息泄露漏洞[9],利用漏洞,黑客可發起遠程攻擊,輕則竊取兩站數據信息,重則可収得兩站服務器控制權,構成信息泄露和運行安全威脅[10]。
OGNL是一種對象圖導航語言,作為Struts2的默認表達式語言,可以用來設置和獲取Java對象的屬性。在Struts2中,為了解決數據在MVC框架的不同層次流轉時的數據類型不同而導致無法正常匹配的問題,采用的是XWORK[11]的OGNL方案,并且加入了值棧(ValueStack[12])這種機制。
ValueStack是一個接口,在Struts2中使用OGNL表達式實際上是使用實現了ValueStack接口的類OgnlValueStack,這個類是OgnlValueStack的基礎。每當Struts2接受一個請求時,就會創建ActionContext,ValueStack,action。ActionContext就是Struts2里的OGNL上下文環境。然后,把action實例的數值壓到ValueStack值棧當中。ActionContext實際上包含一個Map結構,其中維護著一個ValueStack(其中的對象都是根對象),還有一些經過Struts2封裝的一些servlet對象如:parameters,request,session,application,attr等,這些對象都不是根對象。結構圖如圖1。

圖1 Struts2的ActionContext上下文環境結構圖
因此,利用ognl表達式可以訪問ActionContext的所有對象。一般的ongl表達式可以有這些作用:
1)用來調用對象的方法,如:objName.method-Name();
2)支持類靜態的方法調用和值的訪問,表達式的格式為:(1)@ClassName;(2)@methodName|value;
3)支持賦值的操作和表達式串聯;
4)訪問OGNL上下文(如ActionContext);
5)操作集合對象。
在Stucts2框架里,每一次請求都要經過以下的方法,根據這個流程找到OGNL代碼執行的地方。
每一次Web請求都會執行StrutsPrepareAndExecuteFilter的doFilter方法,之后調用相應的方法,PrepareOperations的wrapRequest方法用來包裝出自己的request對象。然后根據content-type屬性判斷,這是S2-045攻擊的關鍵,當表達式為真,會調用JakartaMultiPartRequest類,它的parse方法是用來文件解碼的。當文件體header內容根本不是“multipart/form-data”編碼時,而是一段ognl表達式,就會調用xwork框架的工具庫方法。其中find-Text時搜索關鍵字的方法,對其中包含的參數defautlMessage(e.getMessage())調用了Ognl表達式解釋方法進行解釋,而此參數defautlMessage是就是前端Heaher里的Content-type的值。OgnlTextParser的evaluate方法就是最終解釋Ognl表達式的語句。黑客就是向此處注入代碼ProcessBuilder或Runtime的代碼,從而調用cmd或shell命令,從而操制操作系統。
由上面的分析可知,利用S2-045漏洞,黑客可以通過各種方式向網站或者服務器發送包含惡意的content-type內容的http請求,從而執行Ognl表達式,來實現獲取服務器數據、或者篡改資源等目的。

圖2 S2-045攻擊代碼在Stucts2框架中的執行流程
上面介紹了S2-045在Stucts2框架中的執行流程,下面通過攻擊的復現介紹一次攻擊的代碼執行過程。
根據Struts2官方報告可知,S2-045漏洞影響的范圍Struts2.3.5-2.3.31版本以及2.5-2.5.10版本,因此我們在github上找了一個使用該版本的web應用,以此作為研究的基礎。為了簡單方便,在本地搭載了一套環境。實體機配置:cpu:i7-7700h,內存:8g,系統:windows10,軟件:VMwareWorkStation12pro、Wireshark。在Vm虛擬機里分別搭了兩個系統,一個是centos7,一個是ubuntu16.04,其中centos7上部署上述的具有漏洞的Web環境。而ubuntu則作為一個攻擊的平臺,模擬一些攻擊行為。在win10系統里安裝Wireshark用來抓包,證實攻擊的http實體數據包。

圖3 虛擬攻擊平臺網絡拓撲圖
在GitHub上找了一段關于S2-045的poc代碼,在虛擬機A中執行這段代碼即可攻擊虛擬機B上的網站,通過win10實體機抓包軟件即可發現其攻擊的代碼。圖4是抓到的報文通過處理之后的核心代碼段截圖,
其中1)通過ognl表達式靜態調用獲取ognl.OgnlContext的DEFAULT_MEMBER_ACCESS屬性,并將獲取的結果覆蓋_memberAccess屬性,這樣就可以繞過SecurityMemberAccess的限制,2)判斷當前的系統類型,獲取命令解釋器,然后新建一個線程,執行cmd值對應的指令,最后將指令執行的結果復制到輸出流。
實際上,我們是基于S2漏洞的攻擊報文做的檢測,本質上也是一種文本分類[13]。在已知的分類目標中,使得待分類的目標根據文本內容自動劃分到某一個類別中,從而實現根據已知的數據實現未知數據的分類。它是一個監督學習的過程,根據已有的文本數據集作為基礎,通過分類器找出文本類別與特征的關系。接著利用分類器對新的文本進行分類。如下所示:

其中,f1={a1,a2,a3,…,an},f2={b1,b2,b3,…,bn}。其中f1是待分類的數據集,f2是類別的集合。
S2-045漏洞的檢測過程其實是獲取帶有攻擊行為的http報文,然后提取出有效的字段拼接成有效的待處理的數據集,通過提取它的特征向量來訓練一個SVM分類器,最后可以通過這個模型來檢測出一次訪問行為中是否是利用了漏洞來攻擊。其原理如圖5所示。

圖5 檢測過程方框圖
目前應用于文本分類的技術和算法很多,例如有樸素貝葉斯算法、K最近鄰算法、神經網絡、支持向量機(SupportVectorMachine,SVM)等[14],SVM分類器是解決非線性樣本數據分類問題最簡單有效的方法,SVM分類方法具有很好的泛化能力[15]。主流SVM的分類器有兩種,包括:1)一對一的分類器,最后包括兩種分類;2)一對多的分類器,將2分類的分類器構造出多個來。本文只是做帶有s2漏洞攻擊行為和不帶攻擊行為的區分,因此采用的是一對一的SVM分類器。
SVM是通過最小化降低結構風險的方法來解決分類問題,構造一個超平面將兩類數據以最大的距離分開,此平面就是最優的超平面。
其基本原理為假設存在這樣的一批數據集{(xi,yi)},i=1,2,3,…,k,能 夠 被 某 個 超 平 面wT·x+b=0完全分開,其中xi∈Rn,yi∈{-1,+1},k為樣本個數,Rn為n維實數空間。當兩類的樣本點和這個超平面的距離最大時的這個平面稱為最優超平面,如圖6所示,H為最優超平面。

圖6 SVM原理圖
圖6 中的空心圓點和正方形代表兩類不同類別的樣本,其中H為分類線,H1、H2這兩直線是經過與分類線最近且平行于分類線的直線。要使得兩類樣本點與超平面的距離最大,就要使得H1、H2距離最大。
若yi=+1,wT·xi+b≥+1;若yi=-1,wT·xi+b≤-1。H1和H2兩直線的距離通過歸一化之后為

它被稱為“間隔”[16]。為了獲得最大分類間隔,就要使得

通過拉格朗日方法[17]能夠將原問題轉化為其對偶問題,滿足
下對ai求最大值:

ai為原問題中與分類線對應的拉格朗日乘子。該問題存在唯一最優解,可以證明,有些乘子ai不為零,它也就是支持向量。求解該問題得到最優平面的w*和b*,此時最優分類函數為

實驗數據來源于廣東省某部門采集的網絡黑客的攻擊數據,樣本數據中有S2-045的數據有4000條,非S2-045的數據4000。取兩類數據各2000條作為訓練集,各2000條作為測試集。提取的特征向量主要來自特殊字段的代碼行數、代碼長度、特殊ognl函數調用比如:cmd.exe/os.name等20個文本特征屬性。本實驗基于anaconda軟件的sklearn的SVM函數做的處理分析。
在對S2-045進行檢測時,可能出現四種情況:
當前預測值是S2-045攻擊樣本,事實上也是如此,則記錄當前的結果為TP。
當前預測值是S2-045攻擊樣本,事實上并非如此,則記錄當前的結果為FP。
當前預測值非S2-045攻擊樣本,事實上是攻擊樣本,則記錄當前的結果為FN。
當前預測值非S2-045攻擊樣本,事實上也是如此,則記錄當前的結果為TN。
采取的廣泛使用的標準作為檢測依據,精確率:TP/(TP+FP),召回率:TP/(TP+FN),準確率:(TP+TN)/(TP+FP+TN+FN)[18]。
傳統的檢測方法是基于流量的WebShell行為檢測方法[19],通過檢測payload[20]是否包含關鍵字來判斷某個樣本數據是否是S2-045的攻擊樣本,通過與SVM算法比較來分析方法的優劣?,F在從準確率、召回率、精確率來進行比較,結果如下表1所示:

表1 傳統檢測方法和SVM算法各項指標對比
由圖表可知,基于SVM分類器的S2-045檢測方法在精確度、召回率、精確度三個評測標準上均優于傳統的方法。

圖7 傳統檢測方法和SVM算法各項指標對比
本文詳盡地描述了S2-045的漏洞攻擊原理,并通過在虛擬環境復現攻擊來分析攻擊代碼的執行過程?;诖颂崛×丝捎玫奶卣飨蛄?,并采用了SVM分類器的檢測方法,在仿真平臺實現了與傳統的檢測方法對比,發現采用SVM算法的在準確率、召回率、精確率三項指標上具有顯著的提升?;谏鲜龅乃悸房梢孕纬梢环N流量分析引擎,嵌入到現有的網關設備上,實現在線的S2-045漏洞的檢測和分析。