摘 要: 利用虛擬機技術(shù)對惡意代碼進行動態(tài)分析的方法成為目前安全領(lǐng)域研究的重點,國內(nèi)外相關(guān)的研究大部分集中于理論方面,而相關(guān)的應(yīng)用較少。提出以基于全系統(tǒng)模擬器QEMU作為監(jiān)控平臺,通過編寫遠程控制模塊,對目標程序進行動態(tài)的實時分析,提取出目標程序的API調(diào)用序列以及對應(yīng)的參數(shù)信息,并利用污點標記技術(shù)對產(chǎn)生的數(shù)據(jù)進行關(guān)聯(lián),有效地提取出目標代碼的行為特征,給判斷未知程序是否為惡意代碼提供了依據(jù)。實驗表明,相比同類工具,自動分析平臺具有更好的分析結(jié)果。
關(guān)鍵詞: 惡意代碼; 行為監(jiān)控; QEMU; 動態(tài)污點標記
中圖分類號: TN915.08?34 文獻標識碼: A 文章編號: 1004?373X(2015)13?0076?05
Abstract: The method to dynamically analyze the malicious code with virtual machine technology has become a research emphasis in security domain. Generally speaking, most of relevant researches at home and abroad focused on theory, while less on application. In this paper, a new method is proposed, which takes full?system emulator QEMU as monitoring platform to proceed dynamic real?time analysis on the target program by programming remote control program, and to extract the API calling sequence and its corresponding parameter information of the target program. The stain labeling technique is used to relate the generated data to extract behavior features of the target program effectively. It provides a theoretical basis for judging whether unknown programs are malicious codes. Experimental results indicate that the realized automatic analysis platform can achieve better analysis result than other similar tools.
Keywords: malicious code; behavior monitoring; QEMU; dynamic stain labeling
0 引 言
Windows操作系統(tǒng)上運行的用戶態(tài)程序,包括病毒、木馬等常見惡意代碼,一般都通過調(diào)用Win32環(huán)境提供的Win32 API接口來完成各項操作。借助逆向工程和調(diào)試技術(shù),反病毒工程師可以分析可疑程序API及參數(shù)的調(diào)用情況,從而判斷上報的可疑是否為惡意代碼。如何將這種人工分析的方法自動化,并最終實現(xiàn)自動化檢測惡意代碼,已成為反惡意代碼研究領(lǐng)域的一個熱點。
伴隨計算機系統(tǒng)發(fā)展而發(fā)展的虛擬機技術(shù),則提供了很好的隔離機制。在虛擬機制下,一個系統(tǒng)可以被模擬出來,被模擬出來的系統(tǒng)可以完全不了解另外的系統(tǒng)。樣本在虛擬機中運行對客戶操作系統(tǒng)造成的損害,完全可以通過快照,重新還原,重啟虛擬機等方式,對宿主操作系統(tǒng)不造成任何實質(zhì)上的危險,所以基于虛擬機的惡意代碼自動分析平臺成為解決上述難題的關(guān)鍵。
德國曼海姆大學(xué)可靠性分布式系統(tǒng)實驗室的CWSandbox,在虛擬機軟件VMware中分析樣本[1],采用API Hook技術(shù)跟蹤程序行為,自動化產(chǎn)生分析報告。Norman Sandbox是Norman公司推出的在線病毒分析服務(wù)[2],通過重新實現(xiàn)內(nèi)核Windows系統(tǒng),仿真了整個計算機和一個連接的網(wǎng)絡(luò)環(huán)境,仿真環(huán)境下不需要惡意進程的干預(yù)、感染、更改其他運行的進程,因為沒有其他的進程運行在仿真環(huán)境下,很多相互干涉的重要信息也會丟失。Chas Tomlin的Litterbox與之前的分析系統(tǒng)不同[3],這種分析方法是讓惡意軟件執(zhí)行在一個真實的Window系統(tǒng)上,而不是模擬或仿真的系統(tǒng),每過60 s系統(tǒng)被強制從一個Linux鏡像文件中重啟,重啟后,Litterbox加載Windows分區(qū)并提取出Windows注冊表和文件列表,這樣分區(qū)就回到了干凈的狀態(tài)。在惡意代碼執(zhí)行期間,Windows主機通過虛擬網(wǎng)絡(luò)連接到一個正在運行的IRC服務(wù)器,它能夠應(yīng)答所有到IRC的連接請求,這個工具能捕捉到所有要到其他網(wǎng)絡(luò)的數(shù)據(jù)包。Litterbox只是做了一個被感染的系統(tǒng)的鏡像,它并不能監(jiān)視像新進程創(chuàng)建這樣的動態(tài)行為。
針對以上工具存在的問題,本文提出利用開源模擬器QEMU[4]做監(jiān)控平臺,并對產(chǎn)生的分析結(jié)果,采用污點標記技術(shù)進行關(guān)聯(lián),能夠更好地提供惡意代碼的行為特征。
1 系統(tǒng)框架
整個體系架構(gòu)的最終目標是通過用戶在客戶機提交Windows PE文件樣本,網(wǎng)絡(luò)傳輸?shù)椒?wù)器端上已安裝的定制虛擬環(huán)境中,獲取到目標文件的各種信息,然后通過行為抽象,對API數(shù)據(jù)報告進行處理,從而構(gòu)建樣本的行為特征,通過對比數(shù)據(jù)庫中的行為庫,產(chǎn)生分類報告,最后通過網(wǎng)絡(luò)反饋給客戶機,完成一次未知程序的分析過程。
本文主要工作集中在數(shù)據(jù)的獲取部分,在系統(tǒng)中作為前端平臺,圖1是前端平臺的框架圖。
由圖1可以看出,系統(tǒng)主要由四部分構(gòu)成:客戶端(Client),服務(wù)器端(Sever),中間件(Coodinator),模擬器(WinQEMU)。這四部分構(gòu)成了前端數(shù)據(jù)獲取平臺的主要功能模塊。
首先啟動客戶操作系統(tǒng)(Guest OS),運行其中的服務(wù)器端程序;然后在宿主操作系統(tǒng)(Host OS)上啟動客戶端程序,選擇目標程序,上傳到客戶操作系統(tǒng)中,并掛起;在WinQEMU里設(shè)置相關(guān)數(shù)據(jù),若完成,則運行目標程序,開始動態(tài)監(jiān)控,對獲取到的數(shù)據(jù),通過中間件傳送到宿主操作中,從而完成一次分析過程。
通過上述四個模塊的相互協(xié)調(diào),可以對目標程序進行API調(diào)用序列以及參數(shù)信息的獲取。下面是簡單的測試,驗證其結(jié)果的準確性以及有效性。
測試程序主要是一個實現(xiàn)exe注入的惡意代碼,目的是將自身代碼注入到傀儡進程,不需要DLL文件支持。工作原理如下:
(1) CreateProcess創(chuàng)建一個掛起的IE進程;
(2) 得到裝載基址,使用函數(shù)ZwUnmapViewOfSection卸載這個基址內(nèi)存空間的數(shù)據(jù);
(3) 用VirtualAllocEx為IE進程重新分配內(nèi)存空間,大小為要注入程序的大小;
(4) 使用WriteProcessMemory重新寫IE進程的基址,就是剛才分配的內(nèi)存空間地址;
(5) 用WriteProcessMemory將自己的代碼注入IE的內(nèi)存空間,用SetThreadContext設(shè)置進程狀態(tài);
(6) 使用ResumeThread繼續(xù)運行IE進程。
圖2是這個惡意代碼在工具中運行得到的報告。
通過圖2可以看出,本系統(tǒng)實現(xiàn)的監(jiān)控平臺,能較好地提取出目標程序的API調(diào)用序列以及對應(yīng)的參數(shù)信息。然而數(shù)據(jù)之間并無關(guān)聯(lián),在惡意代碼檢測中,難以具有實際的應(yīng)用,如何去掉冗余的API調(diào)用以及挖掘數(shù)據(jù)內(nèi)在的關(guān)聯(lián)關(guān)系,更好地表現(xiàn)出惡意代碼的行為特征,是惡意代碼分析技術(shù)中研究的關(guān)鍵。
2 污點標記的應(yīng)用
基于以上需求,提出采用污點標記技術(shù)完成基于參數(shù)規(guī)則的函數(shù)依賴關(guān)系的建立。在本文框架中,污點標記技術(shù)在兩個方面起主要作用。
(1) 在構(gòu)建系統(tǒng)的特征行為庫中起到預(yù)處理作用。特征庫的構(gòu)建一直是基于行為特征檢測惡意程序技術(shù)中的難點,大部分文獻成果基本采用人工構(gòu)建的經(jīng)驗分析法,這種方法強烈依賴于相關(guān)研究人員的專業(yè)素質(zhì),從而無法客觀地保證行為庫的有效性以及準確性。通過動態(tài)污點傳播分析技術(shù),提取惡意程序的關(guān)鍵API信息,自動去掉冗余和混淆API調(diào)用,清晰地表達出API相互之間的依賴關(guān)系,從而對特征庫進行擴充,因此較好的克服了這個難點;
(2) 將目標樣本送入到分析平臺中,進行信息獲取并采取污點傳播分析技術(shù),提取出典型特征,然后通過特征匹配算法,與已經(jīng)構(gòu)建的行為特征庫中的基本行為進行匹配,層次化的匹配過程中,當滿足一定的條件,必然呈現(xiàn)出目標樣本的高級行為,從而完成對樣本高層語義行為的理解,最終完成檢測結(jié)果。
2.1 污點標記的原理
通過對不信任的輸入數(shù)據(jù)做標記,動態(tài)跟蹤程序運行過程中污點數(shù)據(jù)的傳播路徑,檢測使用污點數(shù)據(jù)的內(nèi)存區(qū)域以及操作方式,用這種方法可以檢測到敏感數(shù)據(jù)(如字符串參數(shù))被改寫而造成的緩沖區(qū)溢出、不可靠數(shù)據(jù)的非法使用等問題。當來自內(nèi)存或者網(wǎng)絡(luò)的數(shù)據(jù)被用到敏感操作中時,污點分析技術(shù)可以提供詳細的操作路徑,從而根據(jù)這種數(shù)據(jù)流的流向,完整地建立起操作不可靠數(shù)據(jù)的若干API函數(shù)之間的依賴關(guān)系[5]。
定理1:令(P,[≤])是任意的有限格。令([2N,?])為由[N]的有限子集形成的滿足關(guān)系的格。那么([P,≤])可以嵌入到([2N,?])中,即存在映射[φ:p→2n,]使得[a≤b?φ(a)∈φ(b)]對于任意[x∈p,][φ(x)]是N的有限子集。
對于形如函數(shù)調(diào)用語句return_value=api_call(src_1,src_2,…)
src_1對應(yīng)于參數(shù)1;src_2對應(yīng)于參數(shù)2;return_value表示返回值;api_call表示函數(shù)調(diào)用,可得參數(shù)與返回值之間的傳播關(guān)系。
若src_1,src_2,return_value[∈P,]構(gòu)造[φ(src_1)={1},][φ(src_2)={2},φ(return_value)={1,2},]那么由[{1}∈{1,2},][{2}∈{1,2}]可得[src_1≤][return_value,src_2≤return_value。]若不能構(gòu)造滿足包含關(guān)系的子集,那么函數(shù)參數(shù)到返回值未進行污點傳播,其語義不反映污點作用。
2.2 API層技術(shù)實現(xiàn)
在API層實現(xiàn)污點標記技術(shù),首先要考慮的是如何選取污點源以及制定傳播規(guī)則。這里的污點源主要是針對函數(shù)的參數(shù)和返回值,函數(shù)的參數(shù)在傳遞方向上有傳入?yún)?shù)[in]和傳出參數(shù)[out]之分,傳入的參數(shù)供函數(shù)內(nèi)部使用,而傳出的參數(shù)一般用作其他函數(shù)的傳入?yún)?shù),所以參數(shù)中的污點源標記部分只針對傳出參數(shù)[out],因為這樣可以記錄數(shù)據(jù)的流向。同樣,返回值的功能類似于傳出參數(shù),也需要作為污點源進行標記。但是,返回值如果是void或者bool等類型,則明顯對后續(xù)數(shù)據(jù)操作無意義,所以返回值一般只關(guān)注句柄、指針、字符串和緩沖區(qū)等操縱資源或內(nèi)存的類型。同樣針對傳出參數(shù)[out]而言,主要標記三種類型:字符串類型、句柄類型以及緩沖區(qū)類型。對于整型參數(shù),則意義不大,而且重復(fù)性太強,沒有典型特征[6]。
這里污點傳播技術(shù)最終需要達到的目的是對上述兩種情況——參數(shù)以及返回值進行污點標記,從而構(gòu)建函數(shù)間調(diào)用的依賴關(guān)系,例如:
int a[6]={1,2,3,4,5,9};
HANDLE hFile;
hFile=CreateFile(“srcfile.txt”,0,0,NULL,OPEN_ALWAYS,F(xiàn)ILE_ATTRIBUTE_ARCHIVE, NULL);
WriteFile(hFile,(LPCVOID)a,sizeof(a[0]*6),lpNumberOfBytesWritten,NULL);
DeleteFile(“srcfile”);
首先是CreateFile函數(shù),創(chuàng)建了一個“srcfile.txt”文件,然后返回所創(chuàng)建文件的句柄 hFile,下面有兩個函數(shù)分別用到這兩個地方:第一個是WriteFile函數(shù),利用前面的函數(shù)返回值hFile文件句柄,查找創(chuàng)建的文件,寫入數(shù)據(jù);第二個是DeleteFile函數(shù),利用參數(shù)“srcfile.txt”作為傳入?yún)?shù),查找名為“srcfile.txt”的文件,然后進行刪除。
由此可以看出,CreateFile,WriteFile,DeleteFile這三個函數(shù),對同一個文件對象進行了相關(guān)操作,而這種操作關(guān)系構(gòu)成了三者之間的依賴關(guān)系,表現(xiàn)出代碼的軟件行為特征。而這種對相同對象進行操作的關(guān)系則是三者之間進行關(guān)聯(lián)的規(guī)則條件,如何體現(xiàn)這種規(guī)則以及構(gòu)建這種依賴關(guān)系,則是污點傳播技術(shù)完成的工作。就本段代碼而言,首先確定兩個污點源——CreateFile函數(shù)中的字符串類型的函數(shù)名“srcfile.txt”以及句柄類型的返回值hFile,然后根據(jù)后面兩個函數(shù)的傳入?yún)?shù)是否對這兩個污點源進行操作進行判斷,最終形成依賴關(guān)系序列。判斷的標準則基于污點傳播的規(guī)則制定。
API層的傳播規(guī)則制定比較復(fù)雜,不同的需求對應(yīng)的規(guī)則設(shè)計不同,所以算法的設(shè)計沒有統(tǒng)一標準,在本文中制定的規(guī)則為:
(1) 構(gòu)建兩個雙向鏈表,分別為地址鏈表以及API序列圖鏈表。地址鏈表主要是用來保存每個函數(shù)以及函數(shù)的所有參數(shù)信息和對應(yīng)的內(nèi)存地址(包括返回值信息和對應(yīng)的內(nèi)存地址),而API序列圖主要是保存具有依賴關(guān)系的API集合,雙向鏈表的結(jié)構(gòu)保證了對于數(shù)據(jù)的回溯查詢,從而明確表現(xiàn)出傳播的路徑。
(2) 對于QEMU模擬的虛擬內(nèi)存,在訪問數(shù)據(jù)時,總會通過影子頁表,轉(zhuǎn)換到宿主機上的物理內(nèi)存地址,所以對于污點傳播里面重要的污點標簽操作,這里采取利用參數(shù)的真實物理機地址作為標簽。
下面是設(shè)計的具體規(guī)則:
(1) 若目標程序運行過程中,指令寄存器里面的地址匹配到一條API函數(shù),則保存函數(shù)的所有參數(shù)到地址鏈表數(shù)組中。然后對匹配到的API進行時序判斷,是否屬于第一個需要監(jiān)控的API,如果是,轉(zhuǎn)向第(2)步,如果不是,轉(zhuǎn)向第(3)步;
(2) 如果監(jiān)控到的API函數(shù)屬于目標程序的第一個調(diào)用函數(shù),此時污點傳播尚未開始,所以將API函數(shù)名加入到API序列圖中第一個位置中,加入時序信息,并且對函數(shù)中符合污點源的參數(shù)以及返回值進行污點標簽標記,然后轉(zhuǎn)向第(1)步;
(3) 查看函數(shù)名是否屬于終止類型函數(shù),比如關(guān)閉進程,關(guān)閉句柄,關(guān)閉文件等,如果是,則將函數(shù)中的參數(shù)對比前面保存的打開進程,創(chuàng)建句柄和文件等參數(shù),若相同,則結(jié)束本條污點傳播路徑;若不同,則轉(zhuǎn)向第(4)步。
(4) 根據(jù)函數(shù)名對應(yīng)的參數(shù)數(shù)組,找出已經(jīng)保存的參數(shù)序列,參數(shù)類型為前面介紹的APIParam類型。取出第一個參數(shù),判斷其type的類型,主要分為三種:字符串類型,句柄類型,緩沖區(qū)類型(整型比較的意義不大,忽略);然后分別送到相應(yīng)的處理函數(shù)中(分為三個處理函數(shù):句柄類型handle_cmp(DWORD handle_addr),緩沖區(qū)類型buffer_cmp(char buff[],int length),字符串類型string_cmp(char*str)),與地址序列圖中其他相同類型的參數(shù)或者返回值進行比較,如果相同,證明參數(shù)之間或者參數(shù)和返回值之間操縱了同一資源對象或者內(nèi)存對象等,具有一定的依賴關(guān)系,轉(zhuǎn)向第(5)步;若不同,則繼續(xù)查找函數(shù)的第二個參數(shù),做相同的操作,直到參數(shù)全部比較完畢。若此函數(shù)的參數(shù)與其他函數(shù)的參數(shù)并無關(guān)系,則屬于單獨節(jié)點,轉(zhuǎn)向第(6)步;
(5) 遍歷鏈表,找出操作相同對象的參數(shù)所對應(yīng)的API函數(shù)名,然后存入數(shù)組,作個函數(shù)標記。隸屬于同一函數(shù)的參數(shù)在與其他函數(shù)參數(shù)進行比較的過程中,所有獲取的關(guān)聯(lián)API函數(shù)名,存入一個數(shù)組中,說明這個函數(shù)與其他若干個函數(shù)發(fā)生依賴關(guān)系;然后根據(jù)數(shù)組里面保存的API函數(shù)名對比API序列圖中的函數(shù)名,利用函數(shù)name_cmp(const char* name)分別找出對應(yīng)的序列號,然后將此函數(shù)的API函數(shù)名分別加入到相應(yīng)序列號中的API函數(shù)名的位置add_namelist(const char* name),跳向第(1)步;
(6) 在API序列表中新加入節(jié)點,然后將此函數(shù)加入到新節(jié)點的API函數(shù)名位置,同時轉(zhuǎn)向第(1)步,進行循環(huán)。
通過上面的規(guī)則,最終完成污點傳播路徑的標記,經(jīng)測試,可以成功構(gòu)建出函數(shù)在API層的依賴關(guān)系,如圖3所示。
2.3 實驗結(jié)果分析
從通過添加污點標記之后的測試結(jié)果圖3可以看出,API函數(shù)調(diào)用之間存在的參數(shù)依賴關(guān)系已經(jīng)根據(jù)相應(yīng)的規(guī)則歸類到同一依賴關(guān)系序列中。例如圖中所示的1,2,3這三個數(shù)字標記,API函數(shù)VirtualAllocEx的返回值是一個內(nèi)存句柄類型,值是0x00400000,而后面的API函數(shù)WriteProcessMemory的第三個調(diào)用參數(shù),方向是傳入[in],參數(shù)類型也是地址指針類型,符合API層的污點傳播規(guī)則,兩者值進行比較,由于函數(shù)WriteProcessMemory的值也是0x00400000,所以函數(shù)WriteProcessMemory和VirtualAllocEx則構(gòu)成一定的依賴關(guān)系,其依賴序列采用VirtualAllocEx的時序序號25。因此WriteProcessMemory的依賴關(guān)系序列中添加序號25。
觀察標記在依賴關(guān)系序列10上的三個梯形粗線。可以看出三個時序序號為24,25,26的三個函數(shù)ZwUnmapViewOfSection,VirtualAllocEx和WriteProcessMemory均在參數(shù)調(diào)用中操作了具有相同句柄值0x0000007d0的對象,而這三個函數(shù)都歸類于依賴關(guān)系10序列,說明時序序號為10的API函數(shù)的返回值或者傳出參數(shù)產(chǎn)生了句柄值為0x0000007d0的對象,而后續(xù)的API函數(shù)對此進行了某種操作,因而它們之間構(gòu)成依賴關(guān)系,如圖3所示,在行為依賴關(guān)系中給予表現(xiàn)。
實驗結(jié)果表明污點標記在函數(shù)依賴關(guān)系建立中具有重要的意義。通過對API層以及指令層的污點技術(shù)應(yīng)用,可以看出,原本孤立毫無關(guān)系的單獨API調(diào)用,由于參數(shù)之間的相互調(diào)用關(guān)系,結(jié)合污點標記的路徑傳播,若干個API函數(shù)之間構(gòu)建起依賴關(guān)系,從而為后續(xù)工作——提取惡意代碼的行為特征以及構(gòu)建軟件行為特征庫提供了準確且完善的數(shù)據(jù)信息。
3 結(jié) 語
本文的主要工作是實現(xiàn)了對惡意代碼的動態(tài)監(jiān)控,實時分析,并結(jié)合動態(tài)污點標記技術(shù),對提取的信息進行管理,挖掘數(shù)據(jù)間的依賴關(guān)系,更好地表現(xiàn)出惡意代碼的行為特征。但是由于全系統(tǒng)模擬器QEMU的效率不高,運行較慢,且分析一次需要重新啟動,較難大批量的分析惡意代碼,構(gòu)建惡意代碼行為庫,因此,后續(xù)的工作將集中在改進QEMU的執(zhí)行效率,加快分析過程,從而更好地實際應(yīng)用。
參考文獻
[1] WILLEMS C. CWSandbox: automatic behaviour analysis of malware [J/OL]. [2006?09?12]. http://www.cwsandbox.org/,2006.
[2] Norman. Normal sandbox [EB/OL]. [2006?07?23]. http://sandbox.norman.no/.2006.
[3] TOMLIN C. LitterBox [EB/OL]. [2005?02?09]. http://www.wiul.org/.2005.
[4] BELLARD F. QEMU [EB/OL]. [2005?03?21]. http://fabrice.bellard.free.fr/qemu/.2005.
[5] 孔德光,鄭烇,帥建梅,等.基于污點分析的源代碼脆弱性檢測技術(shù)[J].小型微型計算機系統(tǒng),2009,30(1):78?83.
[6] BAYER U, KRUEGEL C, KIRDA E. TTAnalysz: a tool for analyzing malware [C]// Annual Conference of the 15th European Institute for Computer Antivirus Research. Vienna: EICAR. 2005, 128?131.
[7] BELLARD F. Qemu, a fast and portable dynamic translator [C]// Proceedings of 2005 USENIX Conference on Annual Usenix Technical. Marriott Anaheim, USA: USENIX, 2005: 41?46.
[8] 吳浩.二進制翻譯系統(tǒng)QEMU的優(yōu)化技術(shù)[D].上海:上海交通大學(xué),2007.
[9] 柏志文.基于動態(tài)二進制翻譯的污點檢測設(shè)計和實現(xiàn)[D].西安:西安電子科技大學(xué),2008.
[10] 陳培,高維.惡意代碼行為獲取的研究與實現(xiàn)[J].計算機應(yīng)用,2009(z2):76?78.
[11] 梁曉.惡意代碼行為自動化分析的研究與實現(xiàn)[D].成都:電子科技大學(xué),2008.
[12] 張斌,李孟君,吳波,等.基于動態(tài)污點分析的二進制程序?qū)蛐阅:郎y試方法[J].現(xiàn)代電子技術(shù),2014,37(19):89?94.