秦 英
(武漢郵電科學研究院,武漢 430074)
(南京烽火星空通信發展有限公司,南京 210019)
隨著Internet技術的興起和WWW瀏覽器技術的不斷成熟,人們已經熟悉瀏覽器的上網方式,使得基于B/S結構的Web應用在信息系統的開發建設中盛行起來.但由于Web系統開發人員的技術水平參差不齊,安全意識淡薄,防護能力不足,Web系統不斷面臨網絡安全威脅.例如,Web交互功能越來越豐富,人們可以快速便捷地傳遞信息、分享與獲取資源,但這也為黑客提供了多方面的攻擊手段.根據CNCERT今年4月發布的《2017年我國互聯網網絡安全態勢綜述》顯示,CNCERT監測發現境內外約2.4萬個IP地址對我國境內2.9萬余個網站植入后門.網站后門又被稱為WebShell,WebShell危害巨大,如果發現網站被植入了WebShell腳本,則意味著網站存在漏洞,而且攻擊者已經利用漏洞獲得了服務器的控制權限[1].因此檢測WebShell對于及時掌握網絡安全態勢具有極其重要的意義.
目WebShell是運用主流腳本語言如PHP、JSP、ASP等編寫的一種網頁腳本木馬.攻擊者在檢測到Web應用存在上傳漏洞后,常常將這些腳本木馬放置在網站服務器的Web目錄中,然后以訪問網頁的方式訪問腳本木馬,通過腳本木馬獲取更高的權限以控制網站服務器,對網站服務器實施文件的上傳、修改與下載、訪問數據庫篡改數據、執行任意程序命令等惡意操作[2].
WebShell具備很深的自身隱藏性、可偽裝性,它混雜在正常網頁中,和正常網頁一樣通過80端口與服務器或遠程主機交換機進行數據傳遞.這種數據傳遞屬于正常的HTTP協議,傳統防火墻無法對其進行攔截,也不會在系統日志中留下服務器管理操作,這給WebShell的檢測帶來很大的難度.
1.1.1 WebShell的特征
根據腳本程序的大小和功能,攻擊者通常將WebShell分為大馬、小馬和一句話木馬三類[1].
不同類型的WebShell不僅具有基本的WebShell特征,又有各自類型的獨有特征[3].WebShell的基本特征有:(1)訪問特性: WebShell的訪問出度和入度、訪問IP較正常網頁訪問有很大區別;(2)關聯特性:WebShell一般是個孤立的網頁文件,在頁面跳轉上存在特殊性;(3)文件特性: WebShell在文件創建時間、文件行數、文件大小上一般具有特殊性[1].在文件大小和文件行數上明顯區別于一般合法網頁;(4)文本特性:包含敏感函數的調用,或是通過加解密算法(混淆處理)隱藏敏感函數調用.
各類WebShell獨有特征:(1)大馬的文件大小超過70%的合法網頁、調用多種系統關鍵函數、包含開發者的版權信息,如4ngel、wefoiwe、c99shell等;(2)小馬文件小,功能單一,存在上傳行為;(3)一句話木馬長度短、可能嵌入到正常網頁中、通過POST方式傳遞參數.
WebShell檢測和逃逸如同一場曠日持久的博弈,腳本語言的靈活多變使得WebShell不斷變異躲避檢測[4],而檢測也從不同角度查殺WebShell.
1.2.1 WebShell逃逸技術
以PHP語言的WebShell為例,目前常見的WebShell變形技術有:
(1)加密算法隱藏敏感特征: 加密的方式非常多,在PHP語言中最常用的是內置的base64,rot13等加密技術,研究WebShell樣本可以發現很多的WebShell其實是eaval(base64_decode($_POST[X]))的變形.為了逃逸,有些惡意程序會自定義加密算法,或使用Weevely、phpjm、phpjiami等加密工具加密混淆代碼,隱藏特征函數.
(2)字符串拆分變形重組技術: 在字符串中插入注釋,字符替換,或是通過一些特殊字符的異或運算得到特定字符串,如“$__=("#"^"|").("."^"~").("/"^"‘").("|"^"/").("{"^"/")”,“$__”結果為“_POST”.字母多次自增或自減可以得到任意字母,再利用字符串的拼接特性同樣也能得到特定函數,比如“b”可由“a++”表示.
(3)隱蔽位置傳遞參數: 檢測未被查殺軟件掃描的字段,如“User-Agent”、“Accept-Language”等,利用這些字段傳遞參數.一些文件的描述信息也常會放置WebShell中需要的數據,如圖片的exif信息.此外,還可以將敏感函數名作為文件名的一部分,再在文件中訪問文件名得到敏感函數.
1.2.2 現有WebShell檢測技術
目前WebShell的檢測,可以大體分為腳本運行前的靜態檢測,腳本運行后的日志檢測,和腳本運行中的動態檢測.
靜態檢測: 傳統的靜態檢測是基于特征庫的匹配,如WebShell Detector有一個較大的特征庫,知名WebShell檢測器D盾對靜態屬性進行匹配.這類基于特征字符的匹配一般通過正則表達式來實現,而正則表達式具有無法完整覆蓋風險模型的問題[5],會造成一定的漏報和誤報,而且攻擊者使用混淆手段很容易躲避這類檢測.基于統計學的檢測,如開源項目NeoPI[6]提取文件的信息熵、最長單詞、重合指數和壓縮比檢測混淆WebShell,胡建康[7]提取內容屬性、基本屬性和高級屬性作為決策樹C4.5的分類特征.這類方法在混淆WebShell檢測上有一定的效果,但是近年隨著人們產權和安全保密意識的加強,許多開發者也會使用加密技術隱藏自己的代碼邏輯,從而呈現出類似的統計特征,這樣便增大了統計檢測誤報的可能性.靜態檢測不只停留在源碼層面,還從詞法分析語法角度、語義角度、字節碼角度進行惡意代碼檢測,減小代碼注釋和混淆變形對檢測結果的影響.
動態檢測: 傳統的動態檢測主要為分析腳本執行過程中的動態特性檢測惡意腳本,包括基于行為的WebShell檢測和基于流量的WebShell檢測.基于行為的WebShell檢測,以時間為索引,從行為模式上分析腳本對文件的、對系統的操作來判斷是否為WebShell[8].基于流量的檢測方法,在HTTP請求/響應中尋找可疑信息,分析訪問的訪問特征(IP/UA/Cookie),path特征,payload的行為特征區分WebShell與合法網頁.動態的檢測方式,不僅能有效檢測出已知的WebShell,還對未知的、偽裝性強的WebShell有較高的檢出率,但只能檢測到正在發生上傳或訪問WebShell的行為,對于網站中已有的且未使用WebShell無法檢測,存在工作量大,誤報率高等問題,在檢測效果上沒有特征值檢測效果好,還需深入研究.
日志檢測: 雖然WebShell與合法網頁一樣通過80端口進行HTTP請求/響應,不會在系統日志中留下記錄,但分析Web服務器日志時,可以在頁面訪問頻率、頁面關聯度、訪問IP等日志文本特征中找到WebShell的蛛絲馬跡.分析完整的日志上下文,能獲取黑客的攻擊意圖和還原整個攻擊過程,有助于發現未知、變種的WebShell腳本.但其缺點也很明顯,日志分析技術通常需要通過大量的日志數據來建立HTTP請求異常模型,數據處理起來耗時長、檢測速度慢,會影響服務器的性能.而且Web服務器業務功能復雜,存在一定數量的網頁很少被外界訪問,使得訪問次數/頻率不能作為明顯特征,另外,部分WebShell數據訪問時會模擬正常數據庫操作,這將對基于數據庫訪問規則的檢測造成干擾從而導致誤報.
綜上所述,基于各種角度的WebShell檢測有各自的優點,也存在各自的不足.WebShell的檢測困難主要來自如下方面:(1)無差別的檢測: 雖然機器學習已經應用到了WebShell檢測中,但是可以發現不同類型的WebShell依賴特征不同,特征覆蓋不全使得漏報誤報問題明顯,無差別的檢測有待提高.(2)特征不突出: 隨著人們對產權和安全保密意識的加強,許多開發者也會使用加密技術隱藏自己的代碼邏輯,呈現出類似WebShell的特征,增大了檢測誤報的可能性.
要解決以上問題,特征的提取和分類算法的選擇至關重要.現有的基于機器學習算法的WebShell檢測模型大多從單一層面提取特征,無法覆蓋各種類型WebShell的全部特征,具有種類偏向性,無差別的檢測效果差,泛化能力弱等問題.對于以上不足,本文提出一種新的基于隨機森林的檢測模型(其框架如圖1所示),創新性地將頁面文本層的特征和PHP編譯結果層的特征結合,建立組合的WebShell特征集,同時通過特征選擇方法解決特征維度過大導致特征冗余、模型過擬合的問題.在分類器上,本文利用組合分類器算法—隨機森林,進行模型訓練和分類,利用隨機森林的強大的泛化能力,提升模型檢測準確率.

圖1 檢測模型框架
由于PHP,ASP,JSP等不同語言編寫的WebShell非常相似,且在已知的WebShell中PHP編寫的WebShell占得比重較大,因此本文主要分析用PHP編寫的WebShell的數據處理方法.對其提取文本層和編譯結果層的組合特征,再進行特征選擇,建立降低維度后的數據特征集.
2.1.1 特征提取
(1)文本層靜態統計特征:
本文參考NeoPI的檢測特征,并加入非字母數字字符占比和基于特征碼的匹配結果.經過字符運算轉換的混淆WebShell頁面其非字母數字字符占比一般大于正常頁面.同時傳統的WebShell檢測是基于特征碼匹配的,加入基于特征碼的匹配結果能檢測出已知
的非正常函數調用,如: 關鍵函數、系統函數、數據庫和加解密函數的調用情況.具體的統計特征提取方法如表1所示.

表1 統計特征提取方法
(2)利用N元語言模型進行特征提取
1)文本層序列特征
WebShell的種類和變形逃逸手段雖然多樣,但都離不開shell的基本結構,即數據的傳遞和執行傳遞的數據,逃逸手段同樣圍繞傳遞參數的隱藏和執行方法的變形展開.目前我們沒有非常完善的方法定位數據傳遞的步驟,但可以比較方便的找到數據執行的位置:“(”(使用小括號并不是代碼執行的唯一方法).本文在代碼文本層采用一元語法模型(1-gram)切分樣本,切分出以左小括號結尾的連續字符串和以及字符串常量,分別作為一個詞組,同時統計每個詞組在樣本中出現的次數,得到文本層基于函數和字符串常量的詞頻矩陣,將其作為特征向量.
2)opcode序列特征
opcode是PHP編譯結果層的字節碼,是腳本編譯后的中間語言.PHP腳本在讀入腳本程序字符串后,經由詞法分析器將其轉換為語言片段Tokens,接著由語法分析器從中發現語法結構生成抽象語法樹AST,再經過靜態編譯器便生成了對應的opcode.最后由Zend虛擬機執行每一條opcode得到運行結果.通過PHP的擴展程序VLD可以直接得到腳本對應的opcode文本.
本文采用二元語法模型(2-gram)切分opcode文本,將相鄰的兩個opcode劃分到一個詞組中,統計該詞組在每個樣本中出現的次數[9],得到編譯結果層基于opcode序列的詞頻矩陣,將其作為特征向量.
2.1.2 特征選擇
應用上節的特征提取方法可以得到結合代碼文本層和編譯結果層的特征集,但是其維度可能非常高,會為后續模型訓練帶來巨大的計算壓力,本文在數據預處理階段采用特征選擇方法,以降低特征維度,降低后期模型訓練復雜度,節省數據存儲空間.特征選擇是機器學習、模式識別領域的研究熱點之一,通過從原始的高維特征中篩選出符合要求的特征子集以達到降低特征空間的目的[10].特征選擇主要有過濾式和封裝式兩種框架,也有嵌入式和混合式方法.Fisher線性判別是基于距離度量的過濾式特征選擇之一,比基于互信息度量的特征選擇方法計算量小、準確率高,可操作性強、節省運算時間,對高維數據在維數約簡與分類性能上有很好的效果.因此本文使用Fisher線性判別算法進行特征選擇,降低特征維度.
Fisher線性判別的思想是: 尋找一個合適的投影軸,使得樣本投影到這個軸上時同一類的投影點應可能靠近,不同類的投影點盡可能遠離,即類內離散度盡可能小,類間離散度盡可能大.線性判別分析時利用了樣本的類別信息,因此是有監督的方法,其目標函數表示為:

其中,w為投影方向,Sb類間散布矩陣,Sw為類內散布矩陣,J的值越大,w為的判別能力越強.Fisher特征選擇以特征作為投影軸,計算該特征方向的判別值,將每個特征根據其判別值從大到小排序,判別值越大,說明該特征對于分類的有效性越高,該特征也越重要.本文將特征提取后的各個特征根據其Fisher判別值進行從大到小排序,按適當的比例選擇出重要特征構成新的特征集,用于之后的模型訓練.
完成對樣本的特征提取后,即可將特征矩陣作為輸入,將標注結果作為預期輸出,訓練分類器.在分類器上,本文選擇隨機森林算法對樣本特征數據進行學習.隨機森林是集成學習器的一種,具有分析復雜相互作用特征的能力,對于噪聲數據和存在缺失值的數據具有很好的魯棒性,并且具有較快的學習速度[11],被譽為“代表集成學習技術水平的方法”.
隨機森林模型由多棵CART決策樹組成,每一棵CART決策樹都是通過兩個隨機過程進行構建的,其具體生成步驟如下:
(1)按照Bagging算法隨機從訓練樣本數據集中有放回地抽取K個訓練樣本,用于構建K棵決策樹;
(2)設樣本有n個特征,從每個訓練樣本的特征集中隨機抽樣m個特征作為每棵決策樹的新的特征集(m≤n);
(3)利用隨機抽取獲得的訓練樣本集和子特征集進行CART決策樹模型的構建,CART決策樹根據基尼指數來選擇劃分屬性,進行節點分裂.每棵樹最大限度地生長,不做任何剪枝,形成隨機森林.
(4)數據預測時,利用所有的決策樹進行預測,最后以投票的方式決定模型最終的預測結果.
本文將PHP語言編寫的WebShell腳本作為研究對象,共收集了1000個惡意PHP WebShell樣本和來自PHPCMS、WordPress等開源項目的2000個正常PHP樣本作為實驗數據.實驗將樣本隨機分為4份,任選3份訓練模型,剩下的樣本用于測試模型的檢測能力,最終結果為運算10次后的平均結果.
在本實驗中,WebShell標記為1,正常樣本標記為0,分類結果混淆矩陣如表2所示.
為了評估實驗效果,本文采用三個指標評估檢測方法性能: 準確率、召回率和誤報率.準確率(acc)定義為召回率(recall)定義為誤報率(error)定義為
實驗分三步進行:(1)將特征提取后的各個特征根據其Fisher判別值進行從大到小排序,分析選擇不同比例的重要特征集對隨機森林模型檢測效果的影響,從中選取適當比例的特征構建新的特征集,其中隨機森林決策樹的個數為10;(2)根據選取的新特征集,對比決策樹數目對隨機森林模型檢測效果的影響,從中確定取得較好平衡的決策樹個數treeNum用于完成本文檢測模型的構建;(3)比較基于SVM的檢測模型與本文構建的檢測模型的檢測效果.
圖2反映了選擇不同比例的特征集對隨機森林模型檢測效果的影響,分析圖2可得,在特征根據Fisher判別值排序后,選擇前10%特征集訓練的模型的準確率可達到97%左右,說明Fisher特征選擇可以選擇出重要的特征,降低特征維度.當特征選擇從10%增加到30%時,檢測準確率和召回率逐步上升,誤報率降低且穩定在0.6%左右.而此后隨著特征增加,模型檢測準確率、召回率和誤報率都沒有明顯改善,說明存在較多的冗余特征,因此本文選擇前30%的重要特征作為新的特征集.
在特征集選定后進行第二步實驗,由圖3可以得出,決策樹數目treeNum從1增加到50時其檢測性能也隨之逐步提高,當繼續增加treeNum時性能提升緩慢,在treeNum=200時準確率最高,之后繼續增加treeNum性能反而開始下降,但訓練時間卻一直不斷上升.綜合分析,在決策樹數目treeNum=200,特征集選取組合特征集的前30%的重要特征時,本論文提出的檢測模型達到最好效果.
表3對比了3種類型的WebShell檢測模型: 文本層基于SVM和靜態統計特征的WebShell檢測模型、編譯結果層基于SVM的檢測模型和本文的組合層面基于Fisher特征選擇和隨機森林的檢測模型.可以得出3種檢測模型都可以在較短的時間內完成檢測任務,綜合對比,編譯結果層的檢測效果優于文本層的基于靜態統計特征的檢測效果,而本文提出的檢測模型在準確率、召回率和誤報率上都優于以上兩種在單一層面的檢測模型,檢測時間也小于0.2秒,表明組合層面基于Fisher特征選擇和隨機森林的檢測模型具有更好的擬合能力和更好的對未知樣本的檢測能力.

圖2 選取不同比例特征的檢測效果

圖3 隨機森林檢測效果對比

表3 各種模型檢測效果
本文深入分析了WebShell的基本特征和各種類型的獨有特征,以及WebShell逃逸技術,指出現有WebShell檢測方法從單一層面提取特征,無法覆蓋各種類型WebShell的全部特征,無差別的檢測效果差,泛化能力弱的問題.為解決以上問題,本文提出了基于隨機森林和組合特征的WebShell檢測方法.分別從文本層和編譯結果層提取特征構建組合特征集,并引入Fisher特征選擇,解決特征集過大特征冗余的問題.在分類器上采用隨機森林算法用以提高檢測模型的泛化能力.經過實驗證明,本文提出的方法具有很好的WebShell檢測效果.但是如果將該檢測方法應用到實際的工程檢測引擎中,其檢測效率和效果還得進一步探討.