項家齊, 王軼駿, 薛質(zhì)
(上海交通大學信息安全工程學院,上海200240)
網(wǎng)頁木馬是最近幾年非常流行的一種惡意代碼分發(fā)的形式,它通常被用作一種自動向受害者植入惡意程序的手段。網(wǎng)頁木馬一般是由一段或者一系列互相有鏈接關系的惡意的HTML片段以及惡意腳本所構成,它通常位于正常網(wǎng)頁之中。當客戶端訪問該網(wǎng)頁時,會同時加載和渲染網(wǎng)頁木馬所嵌入的代碼,導致瀏覽器本身以及相關的插件中的漏洞被利用,從而可以隱蔽地下載惡意程序并進行安裝、執(zhí)行。國外一般稱這種類型的攻擊方式為drive-by-download attack[1],即“下載驅(qū)動型攻擊”。
近年來網(wǎng)頁木馬也不斷進化,從最初的不成體系的特征明顯的單一攻擊代碼,轉(zhuǎn)而形成了一系列復雜的、具有良好可擴展性的惡意代碼框架[2],這類框架被稱之為exploit kit,即“漏洞利用工具包”。這些工具包提供了對多種的惡意代碼的支持,其不僅引入了多種多樣的躲避和反制檢測的機制,同時還兼具有自動化的部署和攻擊支持,并且生成的也不再是針對單一漏洞或者某一特定軟件進行攻擊的代碼,而是多種惡意代碼的復合代碼。這一系列的特性使得攻擊者所需要達到的技術門檻大大降低,而其危害程度則大大增加。面對這種網(wǎng)頁木馬進化的趨勢,檢測和防御方也有必要對網(wǎng)頁木馬的樣本的代碼特征進行抓取和分析,以了解其流行態(tài)勢和新近的躲避和反制檢測的機制。
本文主要關注網(wǎng)頁木馬為了隱藏自身并提高攻擊成功率而引入的混淆技術,通過利用抽象語法樹(Abstract syntax tree,下文中稱AST)對網(wǎng)頁中的腳本進行分析和預處理,再利用低交互式客戶端蜜罐的模擬瀏覽器和模擬腳本執(zhí)行的上下文環(huán)境,從而達到解混淆的目的。通過利用這種解混淆技術,可以降低分析網(wǎng)頁木馬的門檻,為研究其特點、工作機制和攻擊特性提供寶貴的分析數(shù)據(jù),從而為進一步的研究提供了一種新的思路。
對于網(wǎng)頁木馬的人工分析通常是利用一些靜態(tài)分析用的工具,首先抓取被掛馬網(wǎng)頁的HTML源碼,然后人工查看其中是否存在可疑的混淆代碼或者攻擊代碼,然后利用這些靜態(tài)工具中提供的一些簡單的解混淆函數(shù)或者功能來進行解混淆分析。這種分析方法對分析人員的經(jīng)驗要求較高,需要能夠正確地發(fā)現(xiàn)混淆代碼并挑選出正確的解混淆功能來使用。
另外一種常見的人工分析的手段是利用一些瀏覽器或者工具中存在的調(diào)試功能,跟蹤被掛馬網(wǎng)頁的加載過程,從而發(fā)現(xiàn)其中的可疑的混淆代碼或者攻擊代碼,并利用一些調(diào)試功能對這些代碼進行人工解混淆和分析。比如Firefox插件JavaScript deobfuscator[3]。
基于展開的自動化解混淆是當前被最為廣泛使用的一種對網(wǎng)頁木馬代碼進行自動解混淆和分析的手段。網(wǎng)頁木馬的攻擊代碼中經(jīng)常使用一系列的可以動態(tài)執(zhí)行代碼的函數(shù),比如eval()和document.write()函數(shù)來避免攻擊代碼的直接出現(xiàn),以躲避特征碼等靜態(tài)檢測方法。利用這一特點,基于展開的自動化解混淆系統(tǒng)給出了以下這樣的一種假設:“被混淆前的原始攻擊代碼一定會在某一個javascript上下文環(huán)境中以明文出現(xiàn)?!?/p>
基于這一假設,許多網(wǎng)頁木馬檢測系統(tǒng)都引入了解混淆的能力,如 Zozzle[4],JSAND[5]等。
這種自動解混淆手段是相對成熟有效的,但是Lu等人提出了可以精心構造出一種違反上文中假設的混淆代碼[6],使得大多數(shù)基于展開的自動化解混淆手段無法有效地完成解混淆。
基于代碼行為語義分析的自動化代碼解混淆是由Lu等人提出的一種對javascript混淆代碼進行解混淆的手段[6]。這種手段并不追求完全還原出原始的攻擊源代碼的解混淆方式,而是通過保持語義的方式來進行解混淆。Lu等人認為如果兩段代碼和他們的執(zhí)行上下文環(huán)境以相同的方式進行交互,則可以認為這兩段代碼是觀察等價的,可以互相取代的,Lu等人稱這種等價為“語義保持”。
基于這種思路Lu提出了根據(jù)代碼對系統(tǒng)調(diào)用的參數(shù)的影響來判別其是否是“語義相關”的方法,并通過javascript的字節(jié)碼層面上的分析,從而生成相對于混淆代碼“語義保持”的解混淆代碼,完成對代碼的解混淆。其他類似的系統(tǒng)還包括 JSOD[7]等。
本文第1節(jié)中所提到了兩種自動化代碼解混淆的手段各有其優(yōu)勢和缺點,基于展開的自動化解混淆較為成熟有效,但是存在被躲過的方法;而基于代碼行為語義分析的自動化解混淆采用的“語義保持”的等價方法還原出的并不是原始的攻擊代碼。
針對這些問題,本文提出了一種自動解混淆的原型系統(tǒng),在基于展開的自動化解混淆技術上進行擴展,引入AST和開源客戶端蜜罐Thug[8],以實現(xiàn)更加準確有效的解混淆。
如圖1中所示,系統(tǒng)主要由三部分組成:
(1)AST預處理模塊
(2)混淆信息采集模塊
(3)混淆代碼還原模塊
圖1 系統(tǒng)基本結構
首先向系統(tǒng)輸入含有混淆后代碼的被掛馬頁面,系統(tǒng)的AST預處理模塊解析頁面中的腳本代碼并生成對應的AST,然后對AST進行預處理后并還原為腳本,以便通過客戶端蜜罐采集相關的混淆信息;混淆信息采集模塊主要利用客戶端蜜罐本身的功能,從而采集到一些腳本的運行時信息;在混淆信息采集模塊采集到相關信息之后,再由混淆代碼還原模塊對最初生成的AST進行處理,最后根據(jù)處理后的AST還原出解混淆后的腳本代碼,完成一次“展開”的解混淆,而輸出的腳本代碼可以再一次輸入系統(tǒng),從而實現(xiàn)“多次展開”的解混淆。
抽象語法樹是一種用于表示源代碼的抽象語法結構的樹狀結構。一般來說,直接對源代碼的處理是相對復雜困難的,而將其轉(zhuǎn)換為抽象語法樹后,各個結點的屬性和位置將會變得更便于處理,而抽象語法樹本身并不依賴于源語言的文法,從而使得可以通過一些簡單通用的方法來處理抽象語法樹,達到對源代碼的分析和處理的目的。其定義如定義1所示。
定義1給定一個圖G=(V,E),V是圖中所有節(jié)點的集合,E是圖中所有邊的集合,若其滿足以下條件:
G是無向樹
?v∈V,v滿足:
v={p1,p2,...,pn},
pi:< key,value> or<key,v'> ,v'∈V
?pi∈v,pi:< ″type″,value >
?e∈E,e=(v1,v2),v1,v2∈V
?p∈v1,p:< key,v2>
則稱圖G為一個抽象語法樹;稱V中的所有節(jié)點為語法結點,代表著語言的基本結構;稱每個節(jié)點所包含的元素p為節(jié)點屬性,代表語言基本結構的一些屬性,key為屬性名,value為屬性值;稱E中的所有邊為語法關系,代表著語言基本結構之間的關系。
由于各類主流的javascript解析引擎在其支持的語法標準上存在一定的差異,本文以最通用的 ECMAScript 5.1標準[9]為基準,參照Mozilla Parser AST[10]中設計的接口和定義來表示一棵抽象語法樹。圖2給出了一段javascript代碼所對應的抽象語法樹。
圖2 一個抽象語法樹的例子
對于一份輸入被掛馬頁面,首先要解析出其中所包含的javascript腳本,然后再分別將各部分javascript腳本解析為AST,進行預處理后,最后再還原為javascript腳本。AST預處理的工作過程如圖3所示。
圖3 AST預處理過程
腳本解析部分由Thug中的Beautiful Soup 4負責,通過解析HTML源代碼,根據(jù)標簽來取得所需要的javascript腳本代碼;AST解析部分則利用 Esprima[11]來獲得一個符合 Mozilla Parser AST標準的以JSON表示的AST字符串,并解析JSON來將其轉(zhuǎn)換為一個真正的AST對象;隨后對AST對象進行預處理,并在AST對象中生成信息采集表;最后利用Escodegen[12]將處理后的AST重新轉(zhuǎn)換為javascript腳本代碼,與處理后的AST對象一同交還給Thug繼續(xù)進行處理。處理過程的算法如算法1所示。
算法1 預處理算法
經(jīng)過預處理的javascript腳本代碼中包含著一系列回調(diào)語句,當Thug的腳本引擎V8執(zhí)行到預處理中嵌入的回調(diào)語句時,會觸發(fā)Thug調(diào)用對應的處理函數(shù),通過嵌入特定的回調(diào)語句并實現(xiàn)Thug中對應的處理函數(shù)可以使得Thug在運行中采集到系列與混淆有關的信息,如回調(diào)位置,當前調(diào)用函數(shù)的參數(shù)等等,Thug會將這些信息存儲入對應AST對象的信息采集表中,以供后續(xù)混淆代碼還原時使用。
通過預處理和信息采集后,AST對象中已經(jīng)包含了原始腳本預處理后的AST的和相應采集的信息,首先利用算法2中所描述的混淆代碼還原算法來對AST對象進行解混淆處理,隨后再通過Escodegen將處理后的AST對象轉(zhuǎn)換為javascript腳本代碼,最后輸出的即為完成一次“展開”后的javascript代碼。
算法2 預處理算法
由于混淆代碼的日益復雜,一次“展開”操作并不能完全還原出javascript代碼的原貌,這時需要對代碼進行多次“展開”。當獲得一次“展開”后的javascript代碼后,將其取代掛馬網(wǎng)頁中對應的原來的代碼,再將處理后的掛馬網(wǎng)頁作為新的掛馬網(wǎng)頁重新輸入系統(tǒng),得到的輸出即為二次“展開”的javascript代碼,重復進行多次這樣的操作即實現(xiàn)了多次“展開”。當結果輸入系統(tǒng)后不再觸發(fā)解混淆操作,即混淆信息采集過程中采集不到信息時,認為系統(tǒng)已經(jīng)無法再對代碼進行解混淆,此時輸出和輸入將會相同,再進行更多次的“展開”已經(jīng)無法得到更多有用的信息,可以結束多次“展開”的過程。
本文基于前文中闡述的解混淆技術,基于低交互式蜜罐Thug,AST解析模塊Esprima和AST還原模塊Escodegen,實現(xiàn)了一套原型系統(tǒng),并采用了一系列的測試用例來對系統(tǒng)的有效性進行了驗證。測試用例主要分為3類:人工構造的功能性測試網(wǎng)頁、真實被掛馬網(wǎng)頁和對照用的正常網(wǎng)頁,以下將逐一給出各類網(wǎng)頁的實驗結果。
這里選取了一個人工構造的含有多重混淆的斐波那契數(shù)列計算代碼為例對原型系統(tǒng)進行測試,其原始代碼如圖4所示:
圖4 功能性測試原始代碼
構建一個包含這段代碼的頁面并輸入原型系統(tǒng)后,輸出的代碼如圖5所示。
圖5 一次“展開”后的代碼
繼續(xù)將輸出的代碼輸入原型系統(tǒng),代碼展開的過程如圖6中所示。
在最后的結果中,除去一些混淆中使用的多余的變量聲明殘留外,系統(tǒng)已經(jīng)完全還原出可讀的完整的斐波那契數(shù)列的計算代碼,驗證了原型系統(tǒng)的功能性。
圖6 多次“展開”的過程
本文收集了五個最近抓取獲得的真實的被掛馬網(wǎng)頁來對原型系統(tǒng)進行驗證性測試,被掛馬網(wǎng)頁皆來源于網(wǎng)上公開公布的列表,并經(jīng)過人工驗證的確包含混淆后的惡意代碼。該部分實驗的測試結果如表1所示。
測試網(wǎng)站用例1的解混淆結果與人工解混淆的結果相比缺少了一個根節(jié)點的兒子節(jié)點及其子女,原因在于該部分代碼是根據(jù)不同瀏覽器環(huán)境分別觸發(fā)不同惡意代碼,通過修改Thug中的一些模擬瀏覽器的設置后即可抓取到該兒子結點及其子女。測試網(wǎng)站用例3的解混淆結果中則缺失了一個單一的葉子節(jié)點,原因在于該節(jié)點對應惡意腳本的地址已經(jīng)不再有效而無法訪問到。對于這種由于惡意代碼特性以及地址失效而導致的部分缺失是非致命的,可以認為系統(tǒng)仍然是正常工作的,故根據(jù)實驗的結果可以驗證系統(tǒng)的可用性和有效性,但同時也說明系統(tǒng)仍然欠缺一些適應性,仍然需要部分人工的介入來確保解混淆的完整。
表1 對于真實被掛馬網(wǎng)頁的測試果
這里選取了幾個國內(nèi)外著名網(wǎng)站的首頁來對實現(xiàn)的原型系統(tǒng)進行測試,并與直接查看到的源代碼進行比較,以驗證原型系統(tǒng)面對不含混淆的正常網(wǎng)頁也能夠正常工作。測試結果如表2。
通過對正常網(wǎng)頁的測試結果的分析,可以認為系統(tǒng)在面對各類網(wǎng)頁時基本能夠穩(wěn)定正常地工作。
表2 對于正常網(wǎng)頁的測試結果
本文提出了一種基于低交互式客戶端蜜罐和抽象語法樹分析和重構的網(wǎng)頁木馬解混淆技術,通過對代碼的多次展開,以達到對網(wǎng)頁木馬的攻擊代碼進行解混淆的效果。本文實現(xiàn)了一套原型系統(tǒng),并采用了多種類型的無混淆和混淆后的頁面對系統(tǒng)進行了測試,從而驗證了該解混淆技術的有效性。但是原型系統(tǒng)依然停留在驗證性階段,部分功能存在缺陷,多次“展開”也尚處于需要人工介入的階段,下個階段將進一步提高原型系統(tǒng)的可用性和適應性,以期能更好地面對各類網(wǎng)頁木馬中的混淆技術。
[1] DAY O,PALMEN B,GREENSTADT R.Reinterpreting the Disclosure Debate for Web Infections[M].Managing Information Risk and the Economics of Security.Springer.2009:179 -97.
[2] 張慧琳,鄒維,韓心慧.網(wǎng)頁木馬機理與防御技術[J].軟件學報,2013,24(4):843-858.
[3] PALANT W.FireFox add-on:JavaScript deobfuscator[EB/OL].(2013-07-30)[2014-11-26].https://addons.mozilla.org/en - US/firefox/addon/javascript- deobfuscator/.
[4] CURTSINGER C,LIVSHITS B,ZORN B G,et al.ZOZZLE:Fast and Precise In-Browser JavaScript Malware Detection[C]//Proceedings of the 20th USENIX conference on Security(SEC'11).Berkeley,CA,USA:USENIX Association,2011:3-3.
[5] COVA M,KRUEGEL C,VIGNA G.Detection and Analysis of Drive-by-Download Attacks and Malicious JavaScript Code[C]//Proceedings of the 19th International Conference on World Wide Web(WWW'10).New York,NY,USA:ACM,2010:281-290.
[6] LU G,DEBRAY S.Automatic Simplification of Obfuscated JavaScript code:A semantics- based Approach[C]//2012 6th International Conference on Software Security and Reliability.Gaithersburg,MD,USA:IEEE Reliability Society,2012:31-40.
[7] AL-TAHARWA I A,LEE H M,JENG A B,et al.JSOD:JavaScript obfuscation detector[J].Security and Communication Networks,2014.
[8] DELL'AERA A.Thug[EB/OL].(2014-11-11)[2014-11 -26].https://github.com/buffer/thug.
[9] ECMA International.ECMA -262,ECMAScript Language Specification Edition 5.1[S].Geneva:ECMA International,2009:1-245.
[10] NETWORK M D.Mozilla Parser AST[EB/OL].(2014-09 -22)[2014 -11-26].https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API.
[11] HIDAYAT A.Esprima[EB/OL].(2014-10-07)[2014-11 -11].http://esprima.org/
[12] SUZUKI Y.Escodegen[EB/OL].(2014-10-31)[2014-11 -26].https://github.com/Constellation/escodegen.