姜 天
(武漢郵電科學研究院,湖北 武漢 430074)
Webshell是一種Web安全威脅,通常以PHP、ASP等網(wǎng)頁文件的形式存在于Web服務器中。攻擊者可以通過遠程訪問Webshell后門得到一個命令執(zhí)行環(huán)境,進而獲得Web服務器的控制權[1]。
目前對于Webshell的解決方法主要有靜態(tài)檢測、動態(tài)檢測、語法檢測以及基于統(tǒng)計學的檢測。靜態(tài)檢測通過匹配規(guī)則來查找已知Webshell,動態(tài)檢測則是根據(jù)運行時表現(xiàn)出來的特征進行識別,然而這兩種方法的誤報率和漏報率都比較高。語法分析則是將代碼和注釋分離,通過分析語法結構來判斷函數(shù)調用是否危險,但是這種方法的誤報率依然很高。統(tǒng)計學檢測是當下比較流行的方法,通過信息熵等方式對混淆Webshell進行識別[2]。
本文通過Word2vec獲得PHP opcode對應的詞向量,并使用卷積神經(jīng)網(wǎng)絡對Webshell的特征操作序列進行提取,經(jīng)過多次訓練后可以獲得泛化能力較好的檢測模型。
本節(jié)首先介紹PHP opcode以及如何獲取特征操作序列對應的opcode集合,然后介紹如何使用Word2vec對該集合進行詞向量的轉換。
opcode屬于計算機指令中的一部分,通常由處理器對其格式進行規(guī)范。程序運行過程中,一方面需要指令序列調用相關的函數(shù)進行操作,另一方面也需要相應的操作數(shù)參與運算。opcode還有一個別名叫做字節(jié)碼(byte codes),是一種構建在Zend虛擬機上的指令[3]。由Zend引擎解析“ASSIGN”操作后的結果如圖1所示。
圖1 獲取PHP opcode
使用PHP的邏輯代碼展現(xiàn)(Vulcan Logic Dumper,VLD)可以查看解析后的opcode。VLD屬于PHP的擴展項中的一種,因此需要有PHP環(huán)境。在實驗過程中通過Python調用subprocess模塊下的getstatusoutput來獲取解析結果,并將結果保存在字符串中,方便后續(xù)的詞向量轉換操作。迭代多次后,可以得到所有文件的opcode序列。
另外,opcode緩存技術也常被用在開發(fā)調試階段中。這種技術減少了大量重復的編譯過程,節(jié)省了系統(tǒng)資源。
自然語言處理隨著計算機領域的不斷擴大而逐漸被人們重視。為了使計算機能夠處理自然語言,首先需要對自然語言進行建模。自然語言建模方法經(jīng)歷了從基于規(guī)則的方法到基于統(tǒng)計方法的轉變。從基于統(tǒng)計的建模方法得到的自然語言模型稱為統(tǒng)計語言模型[4]。
Bengio等人在2003年總結出了一套神經(jīng)網(wǎng)絡建立的統(tǒng)計語言模型(Neural Network Language Model,NNLM),并首次提出了word embedding的概念,這也為Word2vec、Doc2vec等模型的出現(xiàn)奠定了基礎[5]。
Word2vec是Google公司開發(fā)的一套將詞轉換為實值向量的工具,采用連續(xù)詞袋(Continuous Bag-Of-Words,CBOW)和Skip-Gram兩種模型。圖2展示了兩種模型的基本架構。
CBOW模型通過輸入某一個詞的上下文語境來預測這個詞本身,而Skip-Gram模型則是通過具體的一個詞來預測出它周圍有哪些詞語。兩個模型都是隨機初始化詞向量,且都可以使用層次化Softmax(Hierarchical Softmax)或負采樣(Negative Sampling)方法來提高訓練效率。
本文在獲得PHP opcode后使用了gensim模塊中的Word2vec模型進行詞向量的轉換。對于一個含有m個詞的文件來說,規(guī)定生成的向量維度為k,每一個詞對應的詞向量為Yj(j=1,2,…,m)∈Rk,則該文件對應的詞向量集合可以用一個大小為m×k的矩陣來表示[6]。
(1)
圖2 CBOW和Skip-Gram結構圖
各文件長度的不一致會導致卷積神經(jīng)網(wǎng)絡的輸入層出錯,因此實驗中設置了最大長度m=300,不足最大值的則在矩陣末尾添加全0的行向量來進行補齊。詞向量的維度k設置為100,Word2vec對象的處理窗口大小為10,詞出現(xiàn)的最小頻次門限值為10,迭代訓練次數(shù)設置為20次,默認采用CBOW模型。
卷積神經(jīng)網(wǎng)絡(Convolutional Neural Network,CNN)最早出現(xiàn)在圖像處理領域,用于解決數(shù)據(jù)量龐大而無法進行深度學習的問題[7]。由于本次數(shù)據(jù)預處理階段獲得的是opcode文字片段,因此應使用一維卷積函數(shù)來進行特征提煉。本文的CNN模型主要由以下幾個部分構成:輸入層、卷積層、拼接和池化層以及全連接層等。本節(jié)將介紹各個層的作用和具體細節(jié),CNN的基本結構如圖3所示。
圖3 CNN結構圖
由于在數(shù)據(jù)表示階段得到了opcode對應的詞向量,并使用新定義的數(shù)組來進行存放,因此CNN的輸入層傳入的是一個三維矩陣。
數(shù)據(jù)傳入前會先進行歸一化操作,傳入后通過一層卷積層的卷積操作。當卷積核處理窗口大小為h,數(shù)據(jù)維度為k時,對于給定輸入矩陣X1:m∈Rm×k中特定位置i的詞語來說[8],可得到卷積后的結果為:
ci=f(W·Xi:i+h-1+b)∈R
(2)
其中b表示偏離值;W是一個權值矩陣,起到過濾的作用;而f則代表非線性修正函數(shù)。實驗過程中該非線性函數(shù)選擇默認的“relu”,并使用“valid”有效填充,同時采用默認的L2正則降低模型復雜度。
采用由3個卷積核數(shù)量為100,處理窗口h的大小分別為3、4和5組成的一維卷積層進行局部特征的提取。
將卷積后的結果進行首尾拼接,得到融合的特征張量,接著通過全局池化操作來獲得張量中的最大特征值。最大池化層的存在降低了特征維數(shù),同時減少了計算開銷[8]。
實驗中還添加了隨機丟棄(random dropout)操作,用來防止反向傳播過程中過擬合現(xiàn)象的發(fā)生。設置比率為0.8,表示經(jīng)過該層后有大約80%的神經(jīng)元會停止工作[9],用公式可表示如下:
(3)
其中Bernoulli函數(shù)是為了生成概率r向量,即生成一個概率p為0或1的向量,用來代表停止或激活神經(jīng)元[9]。
此時第l層的神經(jīng)元更新為:
y′(l)=r(l)·y(l)
(4)
實驗結果表明,隨機丟棄可以起到平均輸出結果的作用,能讓一些“相反的”擬合互相抵消。
由于該模型的最終目標是識別Webshell文件,因此對于CNN來說這是一個0或1的二分類任務。實際過程中在全連接層使用了默認的激活函數(shù)“softmax”。
回歸層主要的作用是最小化損失函數(shù)“l(fā)oss”,同時可以提供模型好壞的度量標準,以評估模型性能。其中,優(yōu)化器選用“Adam”(Adaptive Moment Estimation,自適應矩估計),使用默認的分類交叉熵損失函數(shù)(categorical_crossentropy),學習率設置為0.001。本文采用的默認損失函數(shù)公式如下:
(5)
本次實驗針對的是PHP Webshell的檢測,因此收集了github上的數(shù)據(jù)作為目標文件。黑樣本主要來自bartblaze/PHP-backdoors、JoyChou93、b374k/b374k和JoyChou93/webshell等目錄,其中包含了攻擊者常用的所謂“小馬”、“大馬”等PHP文件。白樣本則選擇的是phpcms、WordPress以及yii等PHP基本框架文件。
總樣本數(shù)量為4 347,其中黑樣本有1 801個,白樣本有2 546個。訓練集與測試集的比例為6:4,設定CNN中的驗證集與測試集相同,同時設置批處理大小為100,迭代訓練20輪。
使用混淆矩陣(confusion matrix)來評估模型的性能?;煜仃囉直环Q作可能性表格或錯誤矩陣,其每一行代表預測值,每一列代表的是實際類別[11]。
矩陣中的元素從上到下依次代表正真例(True Positive,TP)、假反例(False Negative,FN)、假正例(False Positive,FP)和真反例(True Negative,TN)。在本次實驗的評估過程中,使用準確率(Accuracy)、精確率(Precision)、召回率(Recall)和平衡F分數(shù)(F1-score)四個數(shù)值來作為衡量模型性能的標準。
混淆矩陣的構成及衍生出的各項評價指標如圖4所示。
圖4 混淆矩陣及其衍生的評價指標
為了對比分析CNN模型的有效性,本文還引入了SVM、xgboost和mlp算法來處理相同的數(shù)據(jù)。其中mlp設置為2層,第一層有20個神經(jīng)元,第二層有2個神經(jīng)元,其他參數(shù)選擇默認設置。
首先使用tflearn提供的VocabularyProcessor(詞匯表模型)來進行特征opcode的提取,設置最大文本長度為400,詞出現(xiàn)的最小頻率為10次,選擇默認的其他參數(shù)值。表1展示了使用詞匯表模型后各算法在相同數(shù)據(jù)集上的性能表現(xiàn)。
表1 采用詞匯表模型提取特征 (%)
然后使用sklearn提供的CountVectorizer(詞袋模型)進行相同的特征提取操作。本文采用2-Gram來獲得詞袋模型,最小詞頻為10次,忽略解碼錯誤,其他參數(shù)保持默認狀態(tài)。表2是使用詞袋模型處理相同數(shù)據(jù)后的性能分析結果。
表2 采用詞袋模型提取特征 (%)
最后使用gensim模塊中的Word2vec模型處理數(shù)據(jù),具體參數(shù)設置可以參考1.2節(jié)中的內容。各算法的分類性能如表3所示。
表3 采用Word2vec提取特征 (%)
算法Word2vec模型準確率精確率召回率F1-scoreSVM87.0099.2369.8882.01xgboost97.8797.9597.0197.48mlp97.8197.0497.8397.43本文方法98.2299.5896.2097.86
通過表中的數(shù)據(jù)可以看出,同樣是使用Word2vec模型轉換獲得的數(shù)據(jù),本文提出的方法對于該分類任務的表現(xiàn)要優(yōu)于傳統(tǒng)機器學習算法,基于深度學習的CNN檢測模型在準確率、精確率等指標上都有明顯提升。
同時,相較于先前基于n-gram、詞匯表等模型的檢測模式,采用先提取PHP文件對應的opcode、后使用Word2vec算法進行詞向量轉換的方式對于檢測Webshell效果更好。
本文采用了基于卷積神經(jīng)網(wǎng)絡的檢測模型,在識別PHP Webshell方面的表現(xiàn)優(yōu)于傳統(tǒng)機器學習算法。同時,使用Word2vec算法對opcode進行詞向量轉換的方法更有利于特征提取。因此,本文提出的模型同樣可以用于其他文件類型的Webshell檢測。
由于Webshell文件較難收集,且大多都是未更新的代碼片段,導致黑樣本數(shù)量較少。同時模型的定長輸入會影響檢測效果,因此下一步任務主要是引進Webshell攻擊日志和流量,改進檢測模型,提升識別效率和泛化能力。