范志鵬, 李 軍, 劉宇強, 鈕 焱
(湖北工業大學計算機學院, 武漢 430068)
隨著互聯網的發展以及大數據、云服務等計算機技術的廣泛應用,同時也帶來了新環境下的網絡安全問題。惡意軟件也變得更加復雜多樣化。根據報告[1]顯示, 2018年全球就有54個國家的超過50萬臺路由器和設備被黑客組織用來控制電腦。由于惡意代碼檢測的局限性,部分惡意代碼產生的變種代碼給惡意代碼的檢測帶來了極大的困難。Greengard[2]研究表明大多數惡意代碼都是由已知的惡意代碼變種而來,變種代碼之間的差異性只有不到2%。因此,認清這些惡意代碼類別可以幫助研究人員更好地掌握惡意代碼變種規律,同時可以提供準確的防范機制。
為了確定惡意代碼功能屬性并對其進行分類,研究人員探索了許多對惡意代碼檢測和識別的方法[3-4],但面對大量使用混淆技術的惡意代碼來說,傳統的分析方法都存在一定的局限性[5]。靜態分析容易受到混淆技術干擾,動態分析只有在滿足惡意代碼觸發條件時才能檢測出惡意行為。為了提高檢測效率,克服現有分歧技術的特點,通過將惡意代碼可視化與神經網絡訓練相結合的方法進行研究已經成為惡意代碼檢測的新的研究方向。
近年來,通過這種方法對惡意代碼檢測有很多有意義的研究成果。Ranveer等[6]提出通過提取指紋特征來進行惡意代碼分類檢測,建立特征庫對于惡意行為進行分類。但由于分類模糊,隨著樣本數量增多,不及時更新特征庫就會延誤檢測。Gove等[7]以視覺的方式對惡意代碼庫中大型屬性集進行比較,能更直觀地看出同類別惡意代碼的共通之處,便于解決惡意代碼中混淆技術難題。Hashemi等[8]利用惡意文件的微觀模式觀測不同文件的攻擊行為和功能,在不丟失邊緣數據的同時對惡意文件進行檢測。任卓君等[9]提出利用N-gram特征進行惡意代碼可視化,有效減少了冗余信息改變全局圖像特征的問題。王國棟等[10]對惡意代碼4個家族4 418個樣本采用深度學習方法分類,證實了通過圖像方法來進行惡意代碼分類能夠有效判定惡意代碼家族類別。孫博文等[11]通過將原始灰度圖像作為輸入,構建三維圖像進行訓練,比直接訓練原始灰度圖像取得了更好的效果。
本文的基于改進的灰度紋理指紋的惡意代碼分類方法是將惡意軟件代碼理解為圖像并提取指紋特征,利用深度學習算法來提升檢測的準確率。主要貢獻是以下幾個部分:①將惡意代碼建模為灰度圖,由二進制特征值轉化為像素特征值,并通過二維和三維的灰度共生矩陣(gray-level co-occurrence matrix,GLCM)提取灰度圖的指紋特征(指紋紋理圖);②本方法與直接對二進制文件進行靜態檢測,避免了直接執行帶來的危害后果,也能夠很好地克服加密、變形后的惡意代碼識別問題,③結合匯編指令的長度屬性取不同的步長作為不同的特征訓練集,并改進GLCM算法對圖像特征降維; ④使用深度學習中卷積神經網絡(convolutional neural networks, CNN)算法實現惡意代碼分類,并與機器學習分類算法進行比較。
對于惡意代碼檢測目前主要有兩個方向[[12-13]:一種是基于惡意代碼二進制文件的靜態檢測方法,將惡意代碼反匯編后的文件和文件組織構建樣本特征;另一種是基于惡意代碼行為的動態檢測,在惡意代碼運行時分析具體行為來構造索引進行檢測分類。對于靜態檢測,Bayer等[14]提出通過函數靜態調用圖提取每個惡意樣本的細粒度特征,該方法創新于用圖片來作為兩個惡意代碼之間的對比,但沒有數據支撐。在此之后Conti等[15]首次提出了對于惡意代碼圖像化的想法;2011年Nataraj等[12]提出了完整的將惡意代碼轉化成圖像的方案,此方案中對特定的數據集取得了98%的準確率。此方法一經推出,立刻引發研究人員的廣泛關注。惡意代碼二進制文件由于都是操作指令,可以轉化為形成具有一定頻率的紋理圖像。劉舒等[16]研究發現,當圖像的灰度級較低時,利用灰度共生矩陣可以很好地提取圖像的紋理特征,便于圖像的進一步研究。Kancherla等[17]提出用強度和紋理特征來對惡意代碼進行分類檢測,取得了95%的準確率,但算法使用的是支持向量機(support vector machine, SVM)算法,并且樣本并沒有使用公開數據集。韓曉光等[18]在惡意代碼圖像紋理聚類和選擇上做出創新性進展,通過灰度共生矩陣選擇6個貢獻最大的特征值來創建紋理特征庫,通過對比特征庫來進行識別。Samira等[19]研究表明,在圖像識別方面,深度學習算法比傳統的機器學習算法更加優秀。在2015年微軟舉辦的惡意代碼分類比賽中,其中獲得冠軍的團隊[20]就是使用了將惡意代碼轉化為圖像的方法進行分類,最終以較大優勢奪得冠軍,本文數據集也來源于此次大賽。
動態檢測則利用虛擬化技術使惡意代碼在模擬環境下充分執行,通過對比執行前后的環境和驗證其惡意行為來進行判斷分類。Rieck等[21]首次利用動態行為特征,使用K鄰近(K-nearest neighbor, KNN)算法達到了88%的準確率。隨著虛擬化技術的不斷進步,動態檢測準確率也在不斷提高。Tang等[22]提出了提取API調用序列的動態分析法,然后使用顏色映射規則表示惡意軟件行為的特征圖像,通過卷積神經網絡達到了較高的訓練效果。Zhang等[23]提出了利用靜態分析的方法可以將操作序列碼轉化為N-gram序列,此方法對于勒索代碼達到了最好的91%準確率。中國還有許多將動態分析與靜態分析結合分析的研究。張晨斌等[24]利用深度學習caffe框架在安卓平臺上搭建了一個惡意軟件分類平臺,該平臺能夠在線檢測和分類惡意代碼,通過靜態分析匹配惡意代碼的特征碼和信息摘要算法(message-digest algorithm, MDA)(由文件產生的固定密碼散列函數),在無法匹配時采用分離惡意代碼中的dex文件,利用深度學習算法進行訓練。劉全飛等[25]利用云平臺技術對惡意代碼的動態檢測,在云平臺中每個使用者都可以上傳自己評價標準,通過結合所有權重來實現信息的動態維護,從而實現自主防護。孫博文[26]實現了一種基于惡意代碼應用程序編程接口(application programming interface, API)的變種檢測方法,先將惡意代碼的API轉換為詞向量,再通過改進的深度學習算法來進行檢測,該方法對于遷移檢測有著很好的檢測效果,在惡意代碼變種檢測上有了一定的進展。
綜上所述,目前惡意代碼分類檢測已經取得了較多的研究成果,但無論是靜態檢測還是動態檢測都具有一定的局限性,靜態特征無法適應新變種的出現,動態檢測容易受到緩延遲技術的影響[27],調用大量無關API占用系統資源,使檢測超出系統設置的執行時間,從而規避檢測?,F提出基于靜態代碼分析的方法,將惡意代碼的二進制文件理解為圖像,提取紋理指紋并規范化,該方法不需要動態地執行過程,可以克服動態分析的主要局限,也有很強的泛化性。
鑒于目前圖像識別算法成熟的優勢性,主要將惡意代碼二進制文件理解為圖像并進行分類檢測。惡意代碼主要是經過系統編譯過的二進制指令,也可以轉換為基礎的匯編指令,由于單個惡意代碼大小比常規圖像識別中的圖像要大很多,且惡意代碼當中本來就有一定的干擾代碼混入其中,因此需要將惡意代碼進行一定的分割降維處理,在分割上采用了在紋理分割上十分優秀的灰度共生矩陣完成[28],同時以不同的步長分割出的惡意代碼作為對照組加入到原始數據集中進行學習,達到混淆特征的目的,隨后使用CNN方法來完成對惡意代碼的訓練分類??傮w方法思路如圖1所示。

圖1 惡意代碼識別分類流程Fig.1 Malware recognition classification flowchart
灰度共生矩陣是研究圖像像素的空間相關特性的常用方法。利用灰度紋理特征來表示大規模的圖像紋理數據集可以以最小的資源占比來歸納所有的圖像,Gotlieb等[29]在研究共生矩陣中研究出的一種歸納特征提取的方法,該方法后被證實對于細微紋理歸納時有良好的效果?;叶裙采仃囍饕菍D像上保持一定距離的像素點之間的灰度情況進行統計,根據圖像中距離為d、方位關系度數為θ的兩個像素點構建聯合概率分布p(g1,g2|d,θ),其中g1、g2表示矩陣內兩點的坐標。對于聯合概率分布由于對角線通常進行了歸一化:
(1)
式(1)中:N為灰度常數。
通常以3個角度的聯合統計數據就能夠歸納出原始圖像的所有特征,通過選擇其中影響最大的幾個特征作為特征值,可以在關鍵信息丟失率最低的情況下進行降維處理。劉天時等[30]證明了將GLCM算法中提取出的特征代入到不同方向的權值因子,可以提高紋理圖像的識別準確率,并且GLCM算法能夠找出其相關性過大的部分進行分割,除了保存關鍵信息外,也能夠很好的剔除掉干擾混淆的部分。
對于GLCM算法中的特征值,Haralick等[31]提取了14種特征,但部分特征值線性相關性強,統計意義不大。為了降低分析模型的復雜度,同時也從人的主觀感受出發,通常是以粗糙度、對比度、方向度、線性度、規則度和粗細度來概括出灰度圖的整體特征,最常見的特征為能量、熵、對比度、相關性。
能量(angular second moment)表示圖像的變化程度,能量越大表示圖像越無規律可循,通常也用來表示為圖像的噪聲,計算方法將GLCM算法矩陣當中所有值進行平方后求和,具體計算公式為
(2)
熵(entropy)中二維數組數字差異變化越大,表現出的圖像越復雜,具體公式為
(3)
為了盡量地保持信息率,在深度學習CNN中,用每個小圖像塊的熵值來代替了CNN過程中的卷積步驟。
每個惡意軟件文件的二進制代碼長度不一,經過文本可視化后,可以看到惡意軟件代碼可以列為由眾多的1字節16進制數構成的一維向量,數據集中最長的長度為405 248×16 B,最短向量的長度為8 950×16 B。若直接理解為圖像,顯然圖像大小不一,帶來后續訓練和檢測的困難,因此,需要提取每個惡意軟件圖像的指紋特征,并形成統一大小的特征指紋圖像??紤]到代碼的順序結構執行特征,只采用了水平方向的步長,而不考慮其他方向。
首先選擇步長為1、2、3,建立灰度共生矩陣。原因如下:在操作系統以及匯編指令手冊的分析中可以知道,計算機代碼中大部分由1字節、2字節、3字節指令構成,如分類1:沒有操作數的指令,指令長度為1字節 ;分類2:操作數只涉及寄存器的指令,長度為2字節;分類3:操作數涉及內存地址的指令,長度為3字節等。因此,在灰度共生矩陣中采用了1字節、2字節和3字節的灰度共生矩陣。首先分別以1字節、2字節、3字節為單位切割惡意軟件代碼行向量并做統計。通?;叶裙采仃嚳紤]的是距離為d的1字節同時出現的統計,在文獻[18,24]均為1字節矩陣。該矩陣行列坐標為0~255,統計每個字節中對應的數值出現個數。對于2字節灰度矩陣,則行代表第一字節,列代表第二字節,如EB 3C代表(EB行,3C列),每出現1次該代碼,則該位置值加1,直至循環遍歷整個惡意軟件代碼。其中,1字節和2字節矩陣均可形成256×256的標準輸入矩陣,1字節灰度共生矩陣為主對角對稱矩陣。
惡意軟件中的單個操作碼與普通代碼并無太大差異,而較長的操作碼具有預測現象發生的能力。為了減少這種信息的丟失,以3字節切割,繼續生成3字節的灰度共生矩陣(256×256×256)。對于每個惡意軟件樣本,均生成了3個指紋紋理圖像,為了統一為256×256維度,改進了單字節的GLCM,特別提出了二維和三維的GLCM,并對三維的 GLCM 進行了線性降維主成分分析 (principal components analysis, PCA)方法處理。
降維是機器學習中非常重要的一種方法,保障數據在訓練的過程有著合理的稀疏性。程序代碼每3個字節分節對應著(x,y,z)3個維度,每個維度為(0~255),構成了三維矩陣A,任2個維度之間如(x,y)的協方差表示了2組數據的相關性,具體公式為
(4)
設數據集p={x,y,z},相應的,依次計算其他二維協方差,從而構建出三維矩陣的協方差矩陣為

(5)
式(5)為三維協方差矩陣,對角線為樣本每一維的本身方差,將其所有數據進行去中心化操作,如對于x:
(6)
由式(6)中心化后,式(5)可以簡化為:
(7)
m=3,對式(7)做特征值分解,求出特征值w1、w2、w3和相應的特征向量,得到式(8),對特征值做對角化處理并排序,取最大的2個特征值,并列出所對應的特征向量,具體公式如下:
(8)
這時找到了矩陣E,滿足ETCE是一個對角矩陣,E中向量由單位化的特征向量構成。因E對應Λ中特征值,因特征向量從上到下排列,則用E的前2行組成的矩陣乘以原始數據矩陣x,就得到了需要的降維后的數據矩陣y。并且對角元素按從大到小依次排列,那么p的前k行就是要尋找的基,用p的前k行組成的矩陣乘以x就使得x從N維降到了K維并滿足上述優化條件。將特征向量對應的特征值按照大小從上到下進行排列,取前di行組成矩陣p,最終得到降維后的數據為B=pA。
通過PCA方法,將256×256×256矩陣降至為256×256,并盡量保持了原始的信息量,這樣,每個惡意代碼樣本就得到了3個共生灰度矩陣,并將每個樣本圖像增加為3個,作為增強型數據,擴大了樣本量,為后續的CNN網絡訓練提供了很好的訓練集。以樣本文件0aKlH1MRxLmv34QGhEJP.bytes為例,通過可視化得到了圖2所示的3個指紋紋理圖像。

圖2 樣本文件指紋紋理圖像Fig.2 Sample file fingerprint texture image
使用 keras-learn作為機器學習庫。Keras是一個高級神經網絡API,用Python編寫,能夠運行在TensorFlow、CNTK或Theano之上, 該學習庫將深度學習模型理解為一個獨立的、完全可配置的模塊的序列或圖,神經層、成本函數、優化器、初始化方案、激活函數和正則化方案都是獨立的模塊,可以組合起來創建新的模型。由于用于監督和非超級組合問題傳統的卷積神經網絡在進行卷積池化的過程中會損失一定的信息,對于識別物體來說,損失的信息可以通過關鍵信息來彌補,但會造成識別準確率一定程度的降低,對于紋理圖像來說,單純的卷積操作通常將3×3或5×5的矩形塊由某種均值或最大值代替,而代碼往往是線性執行的,更強調順序性。因此對于常規的池化操作來進行卷積操作會造成一定的信息率丟失,因此,對該卷積層采用了灰度共生矩陣的信息熵來代替。構建的CNN模型中,采用了1層卷積+1層熵值。將灰度共生矩陣進一步劃分成5×5的小矩陣塊,并對每個小矩陣塊求熵,熵的計算過程采用了式(3)的方法。該方法在原始CNN模型上做出了改進,將灰度共生矩陣每個小矩形塊熵作為池化方式,為了進一步降維,在第2層中采用了傳統的卷積操作,選擇3×3矩形塊,在盡量避免池化過程丟失信息的同時,數據的規模也得到了縮小。
通過使用keras-learn,可以調整算法的參數。經過在不同算法中使用不同參數的多次測試,最終選擇了以下參數。輸入圖像維數為(256,256,1),第2層卷積核為(3,3),activation函數設為tanh,dropout率為0.2,全連接層為10,學習的最大深度為5,學習率為0.005。考慮到部分惡意軟件代碼非常大,例如,樣本集中最大的文件達到14.2 M,預處理和輸入圖像(256×256)都較耗費內存,不適合整體讀入訓練,因此采用了分批訓練的方式,每次讀入10個圖像。
為了檢驗基于惡意代碼圖像紋理特征提取的效果,繼續采用傳統的機器學習算法來驗證該特征提取方式的有效性。主要包括隨機森林(random forest, RF)、K最近鄰[32]。隨機森林算法是一種能夠對大量數據進行準確分類的新型分類技術[33],KNN聚類是一種基于相似性將數據對象分為多個簇的分塊聚類方法。分別對直接的原始數據和GLCM特征提取后的數據進行分類比較。
采用的數據集為微軟2015年惡意代碼分類大賽中指定數據集,BIG2015數據集包含9個惡意家族的21 741個樣本,其中10 868個樣本為帶標簽的訓練集,其他為不帶標簽的測試集。訓練集中,每一個樣本包含一個20字符的哈希ID和一個整數值的家族標簽,分別為Ramnit、Lollipop、Kelihos ver3、Vundo、Simda、Tracur、Kelihos、ver1、Obfuscator.ACY和Gatak。每個惡意樣本包含兩個文件,分別為十六進制表示、去除PE頭的二進制文件和反匯編工具IDA生成的包含機器碼、匯編指令等的元數據文件。在通過切割代碼后,經過上一節GLCM算法來自不同步長的矩后,對形成的不同圖像做訓練對比。實驗使用的操作系統為CentenOS 7.0 64位, Tensorflow框架。
模型的訓練時間與內存、CPU直接相關,而在檢測時主要的時間耗費在預處理的計算上,預處理所需的時間與惡意軟件代碼長度有關,隨著代碼長度的增加而增加,而訓練時間卻可以忽略不計。如表1所示,每個文件由于要預處理3個灰度共生矩陣,故隨著惡意代碼大小而檢測時間增加明顯。

表1 檢測時間比較Table 1 Detection time comparison
為了比較特征提取效果,同時對比了機器學習研究領域較為傳統的典型分類算法,RAW代表直接處理原始數據,GLCM為采用灰度共生矩陣數據分類。具體檢測結果如表2所示,可以看出,基于GLCM的CNN模型方法具有更高的準確率。采用了GLCM特征提取后的分類方法效果均比以前有了顯著的提高,其中,GLCM-RF隨機森林方法準確率達到了96%,較未采用圖像特征提取的RF方法提高了約10%,CNN方法提高了約4%。

表2 各分類算法結果的比較Table 2 Comparison of results of different classification algorithms
另一方面,為了比較第1節相關研究中的分類算法,對于惡意代碼文件,也將樣本文件直接理解為一個灰度圖片,但是這個灰度圖片隨著代碼長度不同而大小不一,為了能夠應用深度學習,采用了統一的尺寸512×512作為輸入。對于小于該尺寸的代碼,在代碼后面補0,而超過該尺寸的代碼,直接截取前面512×512個字節(絕大部分文件未超過此長度)。實驗發現,直接訓練也取得了不錯的準確率(表2中RAW-CNN)。考慮到特征提取的時耗,還采用了直接提取惡意代碼文件的前64 K字節作為數據集來進行比較,通過分析統計數據可以看出,該訓練過程很早就出現了過擬合現象,雖然達到了100%的訓練正確率,但在實際泛化識別過程中,識別率降為了89%。
圖3所示為上文所述數據集分別采用原始數據的圖像灰度圖和灰度共生矩陣在訓練過程中準確率(RAW/GLCM/64 k)和損失率隨迭代次數變化的曲線圖。通過比較可以看出,模型GLCM+CNN相比于直接的灰度圖像CNN 模型在訓練的收斂速度和損失率上有著明顯的優勢?;诨叶燃y理指紋的惡意代碼分類訓練集準確率為99.2%,在測試集中檢測準確率為96.2%。

圖3 原始數據/改進灰度指紋圖像/64K原始數據的CNN模型訓練過程比較Fig.3 A comparison of the training process of original data/improved gray fingerprint image/64K original data
研究了針對惡意代碼分類中圖像特征提取的優劣,提出一種基于改進的GLCM惡意代碼分類方法,使用代碼的增強的灰度共生矩陣作為對象特征,通過機器學習算法訓練和檢測惡意代碼圖像,實現了從圖像紋理角度對惡意代碼家族進行分類。實驗表明,基于灰度紋理特征的惡意代碼分類方法效果優于傳統的卷積神經網絡、隨機森林、K鄰近算法,提高了識別準確率,并且泛化效果更好。