范志鵬, 李 軍, 劉宇強, 鈕 焱
(湖北工業(yè)大學計算機學院, 武漢 430068)
隨著互聯(lián)網(wǎng)的發(fā)展以及大數(shù)據(jù)、云服務等計算機技術的廣泛應用,同時也帶來了新環(huán)境下的網(wǎng)絡安全問題。惡意軟件也變得更加復雜多樣化。根據(jù)報告[1]顯示, 2018年全球就有54個國家的超過50萬臺路由器和設備被黑客組織用來控制電腦。由于惡意代碼檢測的局限性,部分惡意代碼產(chǎn)生的變種代碼給惡意代碼的檢測帶來了極大的困難。Greengard[2]研究表明大多數(shù)惡意代碼都是由已知的惡意代碼變種而來,變種代碼之間的差異性只有不到2%。因此,認清這些惡意代碼類別可以幫助研究人員更好地掌握惡意代碼變種規(guī)律,同時可以提供準確的防范機制。
為了確定惡意代碼功能屬性并對其進行分類,研究人員探索了許多對惡意代碼檢測和識別的方法[3-4],但面對大量使用混淆技術的惡意代碼來說,傳統(tǒng)的分析方法都存在一定的局限性[5]。靜態(tài)分析容易受到混淆技術干擾,動態(tài)分析只有在滿足惡意代碼觸發(fā)條件時才能檢測出惡意行為。為了提高檢測效率,克服現(xiàn)有分歧技術的特點,通過將惡意代碼可視化與神經(jīng)網(wǎng)絡訓練相結(jié)合的方法進行研究已經(jīng)成為惡意代碼檢測的新的研究方向。
近年來,通過這種方法對惡意代碼檢測有很多有意義的研究成果。Ranveer等[6]提出通過提取指紋特征來進行惡意代碼分類檢測,建立特征庫對于惡意行為進行分類。但由于分類模糊,隨著樣本數(shù)量增多,不及時更新特征庫就會延誤檢測。Gove等[7]以視覺的方式對惡意代碼庫中大型屬性集進行比較,能更直觀地看出同類別惡意代碼的共通之處,便于解決惡意代碼中混淆技術難題。Hashemi等[8]利用惡意文件的微觀模式觀測不同文件的攻擊行為和功能,在不丟失邊緣數(shù)據(jù)的同時對惡意文件進行檢測。任卓君等[9]提出利用N-gram特征進行惡意代碼可視化,有效減少了冗余信息改變?nèi)謭D像特征的問題。王國棟等[10]對惡意代碼4個家族4 418個樣本采用深度學習方法分類,證實了通過圖像方法來進行惡意代碼分類能夠有效判定惡意代碼家族類別。孫博文等[11]通過將原始灰度圖像作為輸入,構建三維圖像進行訓練,比直接訓練原始灰度圖像取得了更好的效果。
本文的基于改進的灰度紋理指紋的惡意代碼分類方法是將惡意軟件代碼理解為圖像并提取指紋特征,利用深度學習算法來提升檢測的準確率。主要貢獻是以下幾個部分:①將惡意代碼建模為灰度圖,由二進制特征值轉(zhuǎn)化為像素特征值,并通過二維和三維的灰度共生矩陣(gray-level co-occurrence matrix,GLCM)提取灰度圖的指紋特征(指紋紋理圖);②本方法與直接對二進制文件進行靜態(tài)檢測,避免了直接執(zhí)行帶來的危害后果,也能夠很好地克服加密、變形后的惡意代碼識別問題,③結(jié)合匯編指令的長度屬性取不同的步長作為不同的特征訓練集,并改進GLCM算法對圖像特征降維; ④使用深度學習中卷積神經(jīng)網(wǎng)絡(convolutional neural networks, CNN)算法實現(xiàn)惡意代碼分類,并與機器學習分類算法進行比較。
對于惡意代碼檢測目前主要有兩個方向[[12-13]:一種是基于惡意代碼二進制文件的靜態(tài)檢測方法,將惡意代碼反匯編后的文件和文件組織構建樣本特征;另一種是基于惡意代碼行為的動態(tài)檢測,在惡意代碼運行時分析具體行為來構造索引進行檢測分類。對于靜態(tài)檢測,Bayer等[14]提出通過函數(shù)靜態(tài)調(diào)用圖提取每個惡意樣本的細粒度特征,該方法創(chuàng)新于用圖片來作為兩個惡意代碼之間的對比,但沒有數(shù)據(jù)支撐。在此之后Conti等[15]首次提出了對于惡意代碼圖像化的想法;2011年Nataraj等[12]提出了完整的將惡意代碼轉(zhuǎn)化成圖像的方案,此方案中對特定的數(shù)據(jù)集取得了98%的準確率。此方法一經(jīng)推出,立刻引發(fā)研究人員的廣泛關注。惡意代碼二進制文件由于都是操作指令,可以轉(zhuǎn)化為形成具有一定頻率的紋理圖像。劉舒等[16]研究發(fā)現(xiàn),當圖像的灰度級較低時,利用灰度共生矩陣可以很好地提取圖像的紋理特征,便于圖像的進一步研究。Kancherla等[17]提出用強度和紋理特征來對惡意代碼進行分類檢測,取得了95%的準確率,但算法使用的是支持向量機(support vector machine, SVM)算法,并且樣本并沒有使用公開數(shù)據(jù)集。韓曉光等[18]在惡意代碼圖像紋理聚類和選擇上做出創(chuàng)新性進展,通過灰度共生矩陣選擇6個貢獻最大的特征值來創(chuàng)建紋理特征庫,通過對比特征庫來進行識別。Samira等[19]研究表明,在圖像識別方面,深度學習算法比傳統(tǒng)的機器學習算法更加優(yōu)秀。在2015年微軟舉辦的惡意代碼分類比賽中,其中獲得冠軍的團隊[20]就是使用了將惡意代碼轉(zhuǎn)化為圖像的方法進行分類,最終以較大優(yōu)勢奪得冠軍,本文數(shù)據(jù)集也來源于此次大賽。
動態(tài)檢測則利用虛擬化技術使惡意代碼在模擬環(huán)境下充分執(zhí)行,通過對比執(zhí)行前后的環(huán)境和驗證其惡意行為來進行判斷分類。Rieck等[21]首次利用動態(tài)行為特征,使用K鄰近(K-nearest neighbor, KNN)算法達到了88%的準確率。隨著虛擬化技術的不斷進步,動態(tài)檢測準確率也在不斷提高。Tang等[22]提出了提取API調(diào)用序列的動態(tài)分析法,然后使用顏色映射規(guī)則表示惡意軟件行為的特征圖像,通過卷積神經(jīng)網(wǎng)絡達到了較高的訓練效果。Zhang等[23]提出了利用靜態(tài)分析的方法可以將操作序列碼轉(zhuǎn)化為N-gram序列,此方法對于勒索代碼達到了最好的91%準確率。中國還有許多將動態(tài)分析與靜態(tài)分析結(jié)合分析的研究。張晨斌等[24]利用深度學習caffe框架在安卓平臺上搭建了一個惡意軟件分類平臺,該平臺能夠在線檢測和分類惡意代碼,通過靜態(tài)分析匹配惡意代碼的特征碼和信息摘要算法(message-digest algorithm, MDA)(由文件產(chǎn)生的固定密碼散列函數(shù)),在無法匹配時采用分離惡意代碼中的dex文件,利用深度學習算法進行訓練。劉全飛等[25]利用云平臺技術對惡意代碼的動態(tài)檢測,在云平臺中每個使用者都可以上傳自己評價標準,通過結(jié)合所有權重來實現(xiàn)信息的動態(tài)維護,從而實現(xiàn)自主防護。孫博文[26]實現(xiàn)了一種基于惡意代碼應用程序編程接口(application programming interface, API)的變種檢測方法,先將惡意代碼的API轉(zhuǎn)換為詞向量,再通過改進的深度學習算法來進行檢測,該方法對于遷移檢測有著很好的檢測效果,在惡意代碼變種檢測上有了一定的進展。
綜上所述,目前惡意代碼分類檢測已經(jīng)取得了較多的研究成果,但無論是靜態(tài)檢測還是動態(tài)檢測都具有一定的局限性,靜態(tài)特征無法適應新變種的出現(xiàn),動態(tài)檢測容易受到緩延遲技術的影響[27],調(diào)用大量無關API占用系統(tǒng)資源,使檢測超出系統(tǒng)設置的執(zhí)行時間,從而規(guī)避檢測。現(xiàn)提出基于靜態(tài)代碼分析的方法,將惡意代碼的二進制文件理解為圖像,提取紋理指紋并規(guī)范化,該方法不需要動態(tài)地執(zhí)行過程,可以克服動態(tài)分析的主要局限,也有很強的泛化性。
鑒于目前圖像識別算法成熟的優(yōu)勢性,主要將惡意代碼二進制文件理解為圖像并進行分類檢測。惡意代碼主要是經(jīng)過系統(tǒng)編譯過的二進制指令,也可以轉(zhuǎn)換為基礎的匯編指令,由于單個惡意代碼大小比常規(guī)圖像識別中的圖像要大很多,且惡意代碼當中本來就有一定的干擾代碼混入其中,因此需要將惡意代碼進行一定的分割降維處理,在分割上采用了在紋理分割上十分優(yōu)秀的灰度共生矩陣完成[28],同時以不同的步長分割出的惡意代碼作為對照組加入到原始數(shù)據(jù)集中進行學習,達到混淆特征的目的,隨后使用CNN方法來完成對惡意代碼的訓練分類??傮w方法思路如圖1所示。
圖1 惡意代碼識別分類流程Fig.1 Malware recognition classification flowchart
灰度共生矩陣是研究圖像像素的空間相關特性的常用方法。利用灰度紋理特征來表示大規(guī)模的圖像紋理數(shù)據(jù)集可以以最小的資源占比來歸納所有的圖像,Gotlieb等[29]在研究共生矩陣中研究出的一種歸納特征提取的方法,該方法后被證實對于細微紋理歸納時有良好的效果。灰度共生矩陣主要是對圖像上保持一定距離的像素點之間的灰度情況進行統(tǒng)計,根據(jù)圖像中距離為d、方位關系度數(shù)為θ的兩個像素點構建聯(lián)合概率分布p(g1,g2|d,θ),其中g1、g2表示矩陣內(nèi)兩點的坐標。對于聯(lián)合概率分布由于對角線通常進行了歸一化:
(1)
式(1)中:N為灰度常數(shù)。
通常以3個角度的聯(lián)合統(tǒng)計數(shù)據(jù)就能夠歸納出原始圖像的所有特征,通過選擇其中影響最大的幾個特征作為特征值,可以在關鍵信息丟失率最低的情況下進行降維處理。劉天時等[30]證明了將GLCM算法中提取出的特征代入到不同方向的權值因子,可以提高紋理圖像的識別準確率,并且GLCM算法能夠找出其相關性過大的部分進行分割,除了保存關鍵信息外,也能夠很好的剔除掉干擾混淆的部分。
對于GLCM算法中的特征值,Haralick等[31]提取了14種特征,但部分特征值線性相關性強,統(tǒng)計意義不大。為了降低分析模型的復雜度,同時也從人的主觀感受出發(fā),通常是以粗糙度、對比度、方向度、線性度、規(guī)則度和粗細度來概括出灰度圖的整體特征,最常見的特征為能量、熵、對比度、相關性。
能量(angular second moment)表示圖像的變化程度,能量越大表示圖像越無規(guī)律可循,通常也用來表示為圖像的噪聲,計算方法將GLCM算法矩陣當中所有值進行平方后求和,具體計算公式為
(2)
熵(entropy)中二維數(shù)組數(shù)字差異變化越大,表現(xiàn)出的圖像越復雜,具體公式為
(3)
為了盡量地保持信息率,在深度學習CNN中,用每個小圖像塊的熵值來代替了CNN過程中的卷積步驟。
每個惡意軟件文件的二進制代碼長度不一,經(jīng)過文本可視化后,可以看到惡意軟件代碼可以列為由眾多的1字節(jié)16進制數(shù)構成的一維向量,數(shù)據(jù)集中最長的長度為405 248×16 B,最短向量的長度為8 950×16 B。若直接理解為圖像,顯然圖像大小不一,帶來后續(xù)訓練和檢測的困難,因此,需要提取每個惡意軟件圖像的指紋特征,并形成統(tǒng)一大小的特征指紋圖像??紤]到代碼的順序結(jié)構執(zhí)行特征,只采用了水平方向的步長,而不考慮其他方向。
首先選擇步長為1、2、3,建立灰度共生矩陣。原因如下:在操作系統(tǒng)以及匯編指令手冊的分析中可以知道,計算機代碼中大部分由1字節(jié)、2字節(jié)、3字節(jié)指令構成,如分類1:沒有操作數(shù)的指令,指令長度為1字節(jié) ;分類2:操作數(shù)只涉及寄存器的指令,長度為2字節(jié);分類3:操作數(shù)涉及內(nèi)存地址的指令,長度為3字節(jié)等。因此,在灰度共生矩陣中采用了1字節(jié)、2字節(jié)和3字節(jié)的灰度共生矩陣。首先分別以1字節(jié)、2字節(jié)、3字節(jié)為單位切割惡意軟件代碼行向量并做統(tǒng)計。通?;叶裙采仃嚳紤]的是距離為d的1字節(jié)同時出現(xiàn)的統(tǒng)計,在文獻[18,24]均為1字節(jié)矩陣。該矩陣行列坐標為0~255,統(tǒng)計每個字節(jié)中對應的數(shù)值出現(xiàn)個數(shù)。對于2字節(jié)灰度矩陣,則行代表第一字節(jié),列代表第二字節(jié),如EB 3C代表(EB行,3C列),每出現(xiàn)1次該代碼,則該位置值加1,直至循環(huán)遍歷整個惡意軟件代碼。其中,1字節(jié)和2字節(jié)矩陣均可形成256×256的標準輸入矩陣,1字節(jié)灰度共生矩陣為主對角對稱矩陣。
惡意軟件中的單個操作碼與普通代碼并無太大差異,而較長的操作碼具有預測現(xiàn)象發(fā)生的能力。為了減少這種信息的丟失,以3字節(jié)切割,繼續(xù)生成3字節(jié)的灰度共生矩陣(256×256×256)。對于每個惡意軟件樣本,均生成了3個指紋紋理圖像,為了統(tǒng)一為256×256維度,改進了單字節(jié)的GLCM,特別提出了二維和三維的GLCM,并對三維的 GLCM 進行了線性降維主成分分析 (principal components analysis, PCA)方法處理。
降維是機器學習中非常重要的一種方法,保障數(shù)據(jù)在訓練的過程有著合理的稀疏性。程序代碼每3個字節(jié)分節(jié)對應著(x,y,z)3個維度,每個維度為(0~255),構成了三維矩陣A,任2個維度之間如(x,y)的協(xié)方差表示了2組數(shù)據(jù)的相關性,具體公式為
(4)
設數(shù)據(jù)集p={x,y,z},相應的,依次計算其他二維協(xié)方差,從而構建出三維矩陣的協(xié)方差矩陣為
(5)
式(5)為三維協(xié)方差矩陣,對角線為樣本每一維的本身方差,將其所有數(shù)據(jù)進行去中心化操作,如對于x:
(6)
由式(6)中心化后,式(5)可以簡化為:
(7)
m=3,對式(7)做特征值分解,求出特征值w1、w2、w3和相應的特征向量,得到式(8),對特征值做對角化處理并排序,取最大的2個特征值,并列出所對應的特征向量,具體公式如下:
(8)
這時找到了矩陣E,滿足ETCE是一個對角矩陣,E中向量由單位化的特征向量構成。因E對應Λ中特征值,因特征向量從上到下排列,則用E的前2行組成的矩陣乘以原始數(shù)據(jù)矩陣x,就得到了需要的降維后的數(shù)據(jù)矩陣y。并且對角元素按從大到小依次排列,那么p的前k行就是要尋找的基,用p的前k行組成的矩陣乘以x就使得x從N維降到了K維并滿足上述優(yōu)化條件。將特征向量對應的特征值按照大小從上到下進行排列,取前di行組成矩陣p,最終得到降維后的數(shù)據(jù)為B=pA。
通過PCA方法,將256×256×256矩陣降至為256×256,并盡量保持了原始的信息量,這樣,每個惡意代碼樣本就得到了3個共生灰度矩陣,并將每個樣本圖像增加為3個,作為增強型數(shù)據(jù),擴大了樣本量,為后續(xù)的CNN網(wǎng)絡訓練提供了很好的訓練集。以樣本文件0aKlH1MRxLmv34QGhEJP.bytes為例,通過可視化得到了圖2所示的3個指紋紋理圖像。
圖2 樣本文件指紋紋理圖像Fig.2 Sample file fingerprint texture image
使用 keras-learn作為機器學習庫。Keras是一個高級神經(jīng)網(wǎng)絡API,用Python編寫,能夠運行在TensorFlow、CNTK或Theano之上, 該學習庫將深度學習模型理解為一個獨立的、完全可配置的模塊的序列或圖,神經(jīng)層、成本函數(shù)、優(yōu)化器、初始化方案、激活函數(shù)和正則化方案都是獨立的模塊,可以組合起來創(chuàng)建新的模型。由于用于監(jiān)督和非超級組合問題傳統(tǒng)的卷積神經(jīng)網(wǎng)絡在進行卷積池化的過程中會損失一定的信息,對于識別物體來說,損失的信息可以通過關鍵信息來彌補,但會造成識別準確率一定程度的降低,對于紋理圖像來說,單純的卷積操作通常將3×3或5×5的矩形塊由某種均值或最大值代替,而代碼往往是線性執(zhí)行的,更強調(diào)順序性。因此對于常規(guī)的池化操作來進行卷積操作會造成一定的信息率丟失,因此,對該卷積層采用了灰度共生矩陣的信息熵來代替。構建的CNN模型中,采用了1層卷積+1層熵值。將灰度共生矩陣進一步劃分成5×5的小矩陣塊,并對每個小矩陣塊求熵,熵的計算過程采用了式(3)的方法。該方法在原始CNN模型上做出了改進,將灰度共生矩陣每個小矩形塊熵作為池化方式,為了進一步降維,在第2層中采用了傳統(tǒng)的卷積操作,選擇3×3矩形塊,在盡量避免池化過程丟失信息的同時,數(shù)據(jù)的規(guī)模也得到了縮小。
通過使用keras-learn,可以調(diào)整算法的參數(shù)。經(jīng)過在不同算法中使用不同參數(shù)的多次測試,最終選擇了以下參數(shù)。輸入圖像維數(shù)為(256,256,1),第2層卷積核為(3,3),activation函數(shù)設為tanh,dropout率為0.2,全連接層為10,學習的最大深度為5,學習率為0.005??紤]到部分惡意軟件代碼非常大,例如,樣本集中最大的文件達到14.2 M,預處理和輸入圖像(256×256)都較耗費內(nèi)存,不適合整體讀入訓練,因此采用了分批訓練的方式,每次讀入10個圖像。
為了檢驗基于惡意代碼圖像紋理特征提取的效果,繼續(xù)采用傳統(tǒng)的機器學習算法來驗證該特征提取方式的有效性。主要包括隨機森林(random forest, RF)、K最近鄰[32]。隨機森林算法是一種能夠?qū)Υ罅繑?shù)據(jù)進行準確分類的新型分類技術[33],KNN聚類是一種基于相似性將數(shù)據(jù)對象分為多個簇的分塊聚類方法。分別對直接的原始數(shù)據(jù)和GLCM特征提取后的數(shù)據(jù)進行分類比較。
采用的數(shù)據(jù)集為微軟2015年惡意代碼分類大賽中指定數(shù)據(jù)集,BIG2015數(shù)據(jù)集包含9個惡意家族的21 741個樣本,其中10 868個樣本為帶標簽的訓練集,其他為不帶標簽的測試集。訓練集中,每一個樣本包含一個20字符的哈希ID和一個整數(shù)值的家族標簽,分別為Ramnit、Lollipop、Kelihos ver3、Vundo、Simda、Tracur、Kelihos、ver1、Obfuscator.ACY和Gatak。每個惡意樣本包含兩個文件,分別為十六進制表示、去除PE頭的二進制文件和反匯編工具IDA生成的包含機器碼、匯編指令等的元數(shù)據(jù)文件。在通過切割代碼后,經(jīng)過上一節(jié)GLCM算法來自不同步長的矩后,對形成的不同圖像做訓練對比。實驗使用的操作系統(tǒng)為CentenOS 7.0 64位, Tensorflow框架。
模型的訓練時間與內(nèi)存、CPU直接相關,而在檢測時主要的時間耗費在預處理的計算上,預處理所需的時間與惡意軟件代碼長度有關,隨著代碼長度的增加而增加,而訓練時間卻可以忽略不計。如表1所示,每個文件由于要預處理3個灰度共生矩陣,故隨著惡意代碼大小而檢測時間增加明顯。
表1 檢測時間比較Table 1 Detection time comparison
為了比較特征提取效果,同時對比了機器學習研究領域較為傳統(tǒng)的典型分類算法,RAW代表直接處理原始數(shù)據(jù),GLCM為采用灰度共生矩陣數(shù)據(jù)分類。具體檢測結(jié)果如表2所示,可以看出,基于GLCM的CNN模型方法具有更高的準確率。采用了GLCM特征提取后的分類方法效果均比以前有了顯著的提高,其中,GLCM-RF隨機森林方法準確率達到了96%,較未采用圖像特征提取的RF方法提高了約10%,CNN方法提高了約4%。
表2 各分類算法結(jié)果的比較Table 2 Comparison of results of different classification algorithms
另一方面,為了比較第1節(jié)相關研究中的分類算法,對于惡意代碼文件,也將樣本文件直接理解為一個灰度圖片,但是這個灰度圖片隨著代碼長度不同而大小不一,為了能夠應用深度學習,采用了統(tǒng)一的尺寸512×512作為輸入。對于小于該尺寸的代碼,在代碼后面補0,而超過該尺寸的代碼,直接截取前面512×512個字節(jié)(絕大部分文件未超過此長度)。實驗發(fā)現(xiàn),直接訓練也取得了不錯的準確率(表2中RAW-CNN)。考慮到特征提取的時耗,還采用了直接提取惡意代碼文件的前64 K字節(jié)作為數(shù)據(jù)集來進行比較,通過分析統(tǒng)計數(shù)據(jù)可以看出,該訓練過程很早就出現(xiàn)了過擬合現(xiàn)象,雖然達到了100%的訓練正確率,但在實際泛化識別過程中,識別率降為了89%。
圖3所示為上文所述數(shù)據(jù)集分別采用原始數(shù)據(jù)的圖像灰度圖和灰度共生矩陣在訓練過程中準確率(RAW/GLCM/64 k)和損失率隨迭代次數(shù)變化的曲線圖。通過比較可以看出,模型GLCM+CNN相比于直接的灰度圖像CNN 模型在訓練的收斂速度和損失率上有著明顯的優(yōu)勢。基于灰度紋理指紋的惡意代碼分類訓練集準確率為99.2%,在測試集中檢測準確率為96.2%。
圖3 原始數(shù)據(jù)/改進灰度指紋圖像/64K原始數(shù)據(jù)的CNN模型訓練過程比較Fig.3 A comparison of the training process of original data/improved gray fingerprint image/64K original data
研究了針對惡意代碼分類中圖像特征提取的優(yōu)劣,提出一種基于改進的GLCM惡意代碼分類方法,使用代碼的增強的灰度共生矩陣作為對象特征,通過機器學習算法訓練和檢測惡意代碼圖像,實現(xiàn)了從圖像紋理角度對惡意代碼家族進行分類。實驗表明,基于灰度紋理特征的惡意代碼分類方法效果優(yōu)于傳統(tǒng)的卷積神經(jīng)網(wǎng)絡、隨機森林、K鄰近算法,提高了識別準確率,并且泛化效果更好。