本發(fā)明涉及逆向分析與惡意代碼分析領(lǐng)域,具體涉及一種基于simhash與倒排索引的復(fù)用代碼庫(kù)構(gòu)建方法、快速溯源方法及系統(tǒng)。
背景技術(shù):
代碼復(fù)用通常以函數(shù)為基本單位,即使被編譯器高度優(yōu)化仍然保留大量函數(shù)整體,所以本文以函數(shù)為單位進(jìn)行溯源與相似判定更加符合復(fù)用場(chǎng)景。惡意代碼同源判定的主要依據(jù)是惡意代碼作者在不同惡意代碼中對(duì)個(gè)人編寫代碼的復(fù)用,如Sasser與Netsky、Flame與Gauss等的同源判定均依據(jù)它們共享的特殊函數(shù)。但是,為提高開發(fā)速度,惡意代碼作者經(jīng)常復(fù)用他人編寫的公開或半公開代碼,如Chthonic是一款在Zeus源碼基礎(chǔ)上修改開發(fā)的惡意代碼。同時(shí)據(jù)報(bào)告,Equation APT(Advanced Persistent Threat,高級(jí)持續(xù)性威脅)攻擊中使用的一個(gè)樣本,被判定屬于Zlob家族,說明APT攻擊組織也會(huì)復(fù)用開源代碼。為執(zhí)行需要,編譯器在編譯時(shí)通常插入大量代碼。經(jīng)測(cè)試,當(dāng)編譯僅有一個(gè)函數(shù)的C語(yǔ)言代碼時(shí),Windows下的VC6.0編譯器插入了103個(gè)函數(shù),Linux下的GCC4.7.2編譯器插入了18個(gè)函數(shù)。不同的編譯器插入的函數(shù)與函數(shù)的插入位置均不同,需要大量經(jīng)驗(yàn)與技巧才能識(shí)別這些函數(shù)。復(fù)用函數(shù)對(duì)惡意代碼分析與同源判定工作造成了很大干擾,目前主要依靠惡意代碼分析人員的經(jīng)驗(yàn)識(shí)別,導(dǎo)致同源判定效率不高??焖僮R(shí)復(fù)用函數(shù)將大大提高效率,并提升同源判定結(jié)論的可信度。
復(fù)用函數(shù)溯源的基礎(chǔ)是相似函數(shù)判定,若在某二進(jìn)制樣本中存在一個(gè)函數(shù)的相似函數(shù),則說明該函數(shù)為復(fù)用函數(shù)。目前相似函數(shù)判定技術(shù),具有很高的準(zhǔn)確率與召回率,但是判定效率較低,不適應(yīng)海量代碼的復(fù)用函數(shù)溯源。一個(gè)函數(shù)源碼的少量修改,編譯選項(xiàng)、所在位置的不同都會(huì)造成逆向后匯編代碼中指令順序、寄存器、跳轉(zhuǎn)位置等的差異,因此若使用哈希等方法進(jìn)行溯源將導(dǎo)致非常低的召回率。函數(shù)中,代碼塊的跳轉(zhuǎn)結(jié)構(gòu)是相似判定的重要特征,而跳轉(zhuǎn)關(guān)系提取、結(jié)構(gòu)圖的比對(duì)要耗費(fèi)大量時(shí)間,是導(dǎo)致目前相似判定準(zhǔn)確率、召回率與速度難以兼得的一個(gè)重要原因。
技術(shù)實(shí)現(xiàn)要素:
針對(duì)現(xiàn)有技術(shù)存在的技術(shù)問題,為了實(shí)現(xiàn)復(fù)用代碼的快速溯源與判定,本發(fā)明公開了一種基于simhash與倒排索引的復(fù)用代碼庫(kù)構(gòu)建方法、快速溯源方法及系統(tǒng)。
本發(fā)明以函數(shù)為單位,基于simhash與倒排索引技術(shù),能在海量代碼中快速溯源相似函數(shù)。首先逆向已有未加殼與已脫殼樣本獲取匯編代碼,將其中的函數(shù)依據(jù)跳轉(zhuǎn)指令劃分為多個(gè)代碼塊并計(jì)算代碼塊的simhash值,構(gòu)建simhash值與代碼塊、代碼塊與函數(shù)、函數(shù)與樣本間的三級(jí)倒排索引。溯源函數(shù),依據(jù)代碼塊的simhash值快速發(fā)現(xiàn)相似代碼塊,繼而倒排索引潛在相似函數(shù),并溯源至所在樣本。
本發(fā)明公開了一種基于simhash與倒排索引的用于復(fù)用代碼溯源的代碼庫(kù)構(gòu)建方法,基于該代碼庫(kù),使用本發(fā)明公開的溯源方法能快速溯源定位相似函數(shù)及其所在的樣本。具體包括4個(gè)步驟:
(1)逆向獲取每一可執(zhí)行程序樣本的匯編代碼;
(2)依據(jù)調(diào)用指令call與調(diào)用地址,提取匯編代碼中的函數(shù),并依據(jù)每一函數(shù)中的跳轉(zhuǎn)指令與跳轉(zhuǎn)地址將該函數(shù)拆分為多個(gè)代碼塊;
(3)使用simhash算法(2002年提出《Similarity estimation techniques from rounding algorithms》)計(jì)算每個(gè)代碼塊的simhash值;
(4)構(gòu)建三級(jí)倒排索引:simhash值索引對(duì)應(yīng)的代碼塊,代碼塊索引包含該代碼塊的函數(shù),函數(shù)索引包含該函數(shù)的樣本。
本發(fā)明公開了一種基于simhash與倒排索引的復(fù)用代碼快速溯源方法,對(duì)于待溯源函數(shù),使用該方法能快速在海量代碼庫(kù)中溯源到與該函數(shù)相似的函數(shù)及其所在樣本,若未溯源到相似函數(shù),在代碼庫(kù)基礎(chǔ)上可認(rèn)為該函數(shù)為非復(fù)用函數(shù)。具體包括5個(gè)步驟:
(1)將待溯源函數(shù)依據(jù)跳轉(zhuǎn)指令與跳轉(zhuǎn)地址拆分為多個(gè)代碼塊,并計(jì)算代碼塊的simhash值;
(2)在代碼庫(kù)中搜索與代碼塊simhash值的漢明距離在3以內(nèi)的simhash值,繼而通過倒排索引搜索出漢明距離在3以內(nèi)的每一simhash值對(duì)應(yīng)的代碼塊作為相似代碼塊;
(3)通過相似代碼塊與倒排索引搜索出潛在相似函數(shù),然后依據(jù)潛在相似函數(shù)與該待溯源函數(shù)的相似代碼塊的數(shù)量為每個(gè)潛在相似函數(shù)賦予一個(gè)權(quán)值,篩選出權(quán)值超過一定閾值的函數(shù);比如通過函數(shù)A的3個(gè)相似代碼塊,檢索出了兩個(gè)與函數(shù)A相似的潛在相似函數(shù)B、C,假如函數(shù)B與函數(shù)A有一個(gè)代碼塊相似,那么函數(shù)B的權(quán)值就是1/3,函數(shù)C與函數(shù)A有兩個(gè)代碼塊相似,那么函數(shù)C的權(quán)值是2/3;假如閾值是1/2,那么只會(huì)認(rèn)為函數(shù)C與函數(shù)A相似;
(4)通過比對(duì)(3)中篩選出的相似函數(shù)的相似代碼塊間的跳轉(zhuǎn)關(guān)系最終確定是否相似;本發(fā)明中設(shè)定只有當(dāng)代碼塊間的跳轉(zhuǎn)關(guān)系完全相似時(shí),才認(rèn)為函數(shù)相似。比如函數(shù)A與函數(shù)B有2個(gè)代碼塊(1、2)相似,假如在函數(shù)A中兩代碼塊間跳轉(zhuǎn)關(guān)系是1跳轉(zhuǎn)到2,但是在函數(shù)B中是2跳轉(zhuǎn)到1,那么函數(shù)A、B是不相似的,只有代碼塊間的跳轉(zhuǎn)關(guān)系相同時(shí),才認(rèn)為函數(shù)A、B相似。
(5)通過倒排索引溯源定位到相似函數(shù)所在的樣本。
本發(fā)明同時(shí)公開了一種基于simhash與倒排索引的復(fù)用代碼快速溯源系統(tǒng),主要由預(yù)處理模塊、代碼庫(kù)構(gòu)建模塊、函數(shù)溯源模塊3個(gè)模塊組成。
與現(xiàn)有技術(shù)相比,本發(fā)明的積極效果為:
本發(fā)明能在大量樣本中快速溯源與某函數(shù)相似的函數(shù)代碼及其所在樣本,且具有較高的準(zhǔn)確率與召回率。基于該方法可以開發(fā)代碼搜索引擎等工具,幫助逆向分析人員提高效率,提升同源判定工作的自動(dòng)化程度。
通過實(shí)驗(yàn)表明,本發(fā)明具有很高的準(zhǔn)確率、召回率與很快的溯源速度:
(1)使用32位WinXP系統(tǒng)中“Program Files”與“Windows”文件夾下的所有PE文件構(gòu)建了一個(gè)代碼庫(kù);
(2)使用VC6.0編譯僅包含一個(gè)main函數(shù),且僅有一條printf語(yǔ)句的C語(yǔ)言源代碼,編譯為Release版可執(zhí)行文件,逆向獲取該文件的匯編代碼,IDA Pro能自動(dòng)識(shí)別并剔除庫(kù)函數(shù),所以最終會(huì)被代碼中除main函數(shù)外還有19個(gè)編譯器插入函數(shù);
(3)由于WinXP系統(tǒng)中存在大量VC6.0編譯的文件,據(jù)此推測(cè)19個(gè)編譯器插入函數(shù)有一定概率在WinXP文件構(gòu)建的代碼庫(kù)中溯源到相似函數(shù),因此對(duì)19個(gè)編譯器插入函數(shù)進(jìn)行溯源,發(fā)現(xiàn)其中16個(gè)存在相似函數(shù),另外三個(gè)sub_401010、sub_4057BC與sub_402AD1未溯源到相似函數(shù),在配有16核Intel(R)Xeon(R)CPU E562與16G內(nèi)存的DellPower Edge R410服務(wù)器上進(jìn)行該實(shí)驗(yàn),每個(gè)函數(shù)的平均溯源時(shí)間約為0.149秒。
下表列出了部分溯源到的相似函數(shù):
附圖說明
圖1為基于simhash與倒排索引的代碼庫(kù)構(gòu)建方法流程圖;
圖2為三級(jí)倒排索引結(jié)構(gòu)圖;
圖3為函數(shù)溯源流程圖;
圖4為基于simhash與倒排索引的復(fù)用代碼快速溯源系統(tǒng)架構(gòu)圖.
具體實(shí)施方式
下面,結(jié)合具體的實(shí)施實(shí)例對(duì)本發(fā)明進(jìn)行詳細(xì)說明。
圖1給出了本發(fā)明提供的代碼庫(kù)構(gòu)建方法的流程,具體實(shí)施步驟如下:
(1)對(duì)加殼的樣本進(jìn)行脫殼處理
1)使用PeiD查殼工具判定樣本所使用的殼;
2)針對(duì)不同的殼使用不同的脫殼工具進(jìn)行脫殼處理;
3)舍棄其他使用特殊殼導(dǎo)致無法脫殼的樣本。
最終的樣本均為已脫殼樣本。
(2)使用逆向工具獲取各樣本的匯編代碼
本發(fā)明以IDA Pro為例。
(3)提取匯編代碼中的函數(shù)
逆向獲取的匯編代碼中,“proc near”標(biāo)識(shí)一個(gè)函數(shù)的開始,而“endp”標(biāo)識(shí)一個(gè)函數(shù)的結(jié)束,依據(jù)這兩個(gè)標(biāo)識(shí)從匯編代碼中提取函數(shù)。
(4)提取函數(shù)中的代碼塊
依據(jù)函數(shù)中的jnz、jz等跳轉(zhuǎn)指令與跳轉(zhuǎn)指令指向的地址,將函數(shù)代碼劃分為多個(gè)代碼塊,每個(gè)代碼塊或者沒有跳轉(zhuǎn)指令,或者最后一條為跳轉(zhuǎn)指令。
(5)代碼標(biāo)準(zhǔn)化處理
對(duì)源代碼的輕微改動(dòng)將造成匯編代碼中寄存器、立即數(shù)、內(nèi)存地址的大幅變動(dòng),為了忽略這種差異對(duì)代碼造成的影響,依據(jù)以下規(guī)則對(duì)匯編代碼進(jìn)行標(biāo)準(zhǔn)化處理:
●寄存器如eax、ax、al等依據(jù)所占位數(shù)分別標(biāo)準(zhǔn)化為REG32、REG16、REG18;
●內(nèi)存如[eax]、[edi+4]等均表示為MEM;
●立即數(shù)如0、5A4Dh表示為VAL;
●call指令調(diào)用外部的系統(tǒng)庫(kù)函數(shù)時(shí)指令不做處理,調(diào)用內(nèi)部函數(shù)如“call sub_105A8”時(shí)規(guī)范化為“call INNER”;
●跳轉(zhuǎn)指令如“jz short loc_4023E7”規(guī)范化為“jz loc”。
(6)計(jì)算代碼塊的simhash值
simhash是一種模糊哈希,常常用于有輕微差異的相似文本、網(wǎng)頁(yè)的判定工作。
1)創(chuàng)建一個(gè)64位的向量,并初始化為0;
2)對(duì)標(biāo)準(zhǔn)化的代碼塊進(jìn)行分詞處理,分詞為2-gram標(biāo)準(zhǔn)化的指令序列;
3)為每個(gè)分詞賦予權(quán)值,將分詞的頻率做為基礎(chǔ)權(quán)值,由于調(diào)用的API在很大程度上決定了函數(shù)的功能,所以調(diào)用指令在代碼塊中具有重要作用,因此對(duì)包含調(diào)用指令分詞的權(quán)值加倍;
4)對(duì)每個(gè)分詞使用MD5哈希算法做哈希處理,取MD5值中的64位做為該分詞的哈希值;
5)加權(quán)合并,對(duì)分詞哈希的每一位,如果該位為1,則向量相應(yīng)位的值加上該分詞的權(quán)值,否則減去該分詞的權(quán)值;
6)降維,對(duì)向量的每一位,若該位大于0,則設(shè)為1,否則設(shè)為0,形成一個(gè)64位的simhash值。
(7)構(gòu)建三級(jí)倒排索引
經(jīng)過前6步,提取了海量樣本包含的函數(shù)、函數(shù)中包含的代碼塊,并計(jì)算了每個(gè)代碼塊的simhash值,為這些元素構(gòu)建三級(jí)倒排索引,如圖2所示:
1)由simhash值索引具有該simhash值的代碼塊,simhash碰撞概率較大,所以存在幾個(gè)代碼塊具有同一個(gè)simhash值的情況;
2)由代碼塊索引代碼塊所在的函數(shù),代碼塊標(biāo)準(zhǔn)化后,增大了相似的概率,不相似的函數(shù)也有可能存在相同的標(biāo)準(zhǔn)化代碼塊;
3)由函數(shù)索引函數(shù)所在的樣本。
最終基于simhash與倒排索引在海量樣本的基礎(chǔ)上構(gòu)建了用于函數(shù)溯源的代碼庫(kù)。
圖3給出了在構(gòu)建的代碼庫(kù)上快速溯源函數(shù)的流程,具體實(shí)施步驟如下:
(1)待溯源函數(shù)代碼P,依據(jù)跳轉(zhuǎn)指令拆分為多個(gè)代碼塊,假設(shè)共有n個(gè),之后計(jì)算每個(gè)代碼塊的simhash值:
P→{sh1,sh2,…,shn} 【公式1】
(2)使用simhash多表索引方法,為shi|i∈[1,n]快速檢索海明距離在3以內(nèi)的相似simhash,構(gòu)成相似simhash集合:
shSeti={sh:d(shi,sh)≤3}|i∈[1,n] 【公式2】
d(shi,sh)表示shi與sh的海明距離,若所有的相似simhash集合均為空集,說明不存在與該函數(shù)具有相似代碼塊的函數(shù),否則,繼續(xù)下一步;
(3)依據(jù)已構(gòu)建的simhash與代碼塊的倒排索引,檢索simhash值屬于shSeti的代碼塊L,構(gòu)成相似代碼塊集合:
LSeti={L:simhash(L)∈shSeti}|i∈[1,n] 【公式3】
simhash(L)表示代碼塊L的simhash值;
(4)依據(jù)已構(gòu)建的代碼塊與所在函數(shù)的倒排索引,檢索相似代碼塊所在的函數(shù)P’,構(gòu)成函數(shù)集合:
(5)對(duì)每個(gè)檢索到的函數(shù),計(jì)算該函數(shù)P’在待溯源函數(shù)P中的代碼重合度,即該P(yáng)’與P的相似代碼在P中的占比,表示為iSim(P,P’),公式如下:
其中l(wèi)en(P)表示函數(shù)P的總指令數(shù),len(Li)表示代碼塊Li的指令數(shù),通過實(shí)驗(yàn)驗(yàn)證發(fā)現(xiàn)當(dāng)函數(shù)的代碼重合度不小于0.5時(shí)最有可能與待溯源函數(shù)代碼相似,因此最終得出潛在相似函數(shù)集合為:
PSet={P’:iSim(P,P’)≥0.5} 【公式6】
若潛在相似函數(shù)集合PSet為空集,說明不存在與待溯源函數(shù)具有足夠相似代碼的函數(shù),難以認(rèn)定它們相似,待溯源函數(shù)在已有代碼集上可認(rèn)為是原創(chuàng)函數(shù)。
(6)若潛在相似函數(shù)與待溯源函數(shù)均僅有一個(gè)相似代碼塊,則判定為相似函數(shù),若存在多個(gè)相似代碼塊時(shí),只有當(dāng)跳轉(zhuǎn)關(guān)系相同時(shí)判定為相似函數(shù)。
本發(fā)明公開的基于simhash與倒排索引的復(fù)用代碼快速溯源系統(tǒng)可用于快速溯源相似函數(shù),判定是否為復(fù)用函數(shù)以及復(fù)用的樣本,有助于提升惡意代碼分析效率、復(fù)用關(guān)系的檢測(cè)以及惡意代碼同源判定。基于simhash與倒排索引的復(fù)用代碼快速溯源系統(tǒng)主要由預(yù)處理模塊、代碼庫(kù)構(gòu)建模塊與函數(shù)溯源模塊3個(gè)模塊組成。
系統(tǒng)結(jié)構(gòu)如圖4所示。系統(tǒng)具體實(shí)施步驟如下:
(1)預(yù)處理
1)對(duì)每個(gè)樣本,做脫殼逆向反匯編處理獲取匯編代碼;
2)對(duì)每個(gè)匯編代碼,依據(jù)特殊標(biāo)識(shí)提取匯編代碼中的所有函數(shù);
3)對(duì)每個(gè)函數(shù),依據(jù)跳轉(zhuǎn)指令與跳轉(zhuǎn)關(guān)系劃分為多個(gè)代碼塊;
4)對(duì)每個(gè)代碼塊,做代碼標(biāo)準(zhǔn)化處理并計(jì)算代碼庫(kù)的simhash值。
(2)代碼庫(kù)構(gòu)建
基于海量樣本,以及預(yù)處理后獲取的函數(shù)、代碼塊、simhash值,構(gòu)建包含三級(jí)倒排索引的代碼庫(kù),由simhash值索引具有該simhash值的代碼塊,由代碼塊索引代碼塊所在的函數(shù),由函數(shù)索引函數(shù)所在的樣本。
(3)函數(shù)溯源
經(jīng)過預(yù)處理模塊,待溯源函數(shù)被劃分為多個(gè)代碼塊,并獲取了代碼塊的simhash值,首先基于代碼庫(kù)的simhash值檢索代碼庫(kù)中的相似代碼塊,其次經(jīng)相似代碼庫(kù)倒排索引到潛在相似函數(shù),最后基于代碼重合度與相似代碼塊間的跳轉(zhuǎn)關(guān)系判定是否為相似函數(shù)。