GitChat · 安全 | 基於機器學習的 Webshell 發現技術探索

GitChat 做者:兜哥
原文: 基於機器學習的 Webshell 發現技術探索
關注公衆號:GitChat 技術雜談,一本正經的講技術php

第十一章WebShell檢測

WebShell就是以ASP、PHP、JSP或者CGI等文件形式存在的一種命令執行環境,也能夠將其稱作爲一種網頁後門。黑客在入侵了一個網站後,一般會將ASP或PHP後門文件與網站服務器web目錄下正常的網頁文件混在一塊兒,而後就可使用瀏覽器來訪問ASP或者PHP後門,獲得一個命令執行環境,以達到控制網站服務器的目的。顧名思義,「web」的含義是顯然須要服務器開放web服務,「shell」的含義是取得對服務器某種程度上操做權限。WebShell經常被稱爲入侵者經過網站端口對網站服務器的某種程度上操做的權限。因爲WebShell其大可能是以動態腳本的形式出現,也有人稱之爲網站的後門工具。html

在攻擊鏈模型中,整個攻擊過程分爲如下幾個步驟:前端

  • Reconnaissance(踩點)
  • Weaponization(組裝)
  • Delivery(投送)
  • Exploitation(攻擊)
  • Installation(植入)
  • C2(控制)
  • Actions (行動

enter image description here

攻擊鏈模型git

在針對網站的攻擊中,一般是利用上傳漏洞,上傳WebShell,而後經過WebShell進一步控制web服務器,對應攻擊鏈模型是Install和C2環節。程序員

常見的WebShell檢測方法主要有如下幾種:github

靜態檢測,經過匹配特徵碼,特徵值,危險函數函數來查找WebShell的方法,只能查找已知的WebShell,而且誤報率漏報率會比較高,可是若是規則完善,能夠減低誤報率,可是漏報率一定會有所提升。web

動態檢測,執行時刻表現出來的特徵,好比數據庫操做、敏感文件讀取等。算法

語法檢測,根據PHP語言掃描編譯的實現方式,進行剝離代碼、註釋,分析變量、函數、字符串、語言結構的分析方式,來實現關鍵危險函數的捕捉方式。這樣能夠完美解決漏報的狀況。但誤報上,仍存在問題。sql

統計學檢測,經過信息熵、最長單詞、重合指數、壓縮比等檢測。shell

本章主要以常見的WebShell數據集爲例子介紹基於WebShell文件特徵的檢測技術。 介紹WebShell檢測使用的數據集以及對應的特徵提取方法,介紹使用的模型以及對應的驗證結果,包括樸素貝葉斯和深度學習的MLP、CNN。基於WebShell文件訪問特徵的檢測方法不在本章範圍內。

數據集

數據集包含WebShell樣本2616個,開源軟件PHP文件9035個。

WebShell數據來自互聯網上常見的WebShell樣本,數據來源來自github上相關項目,爲了演示方便,所有使用了基於PHP的WebShell樣本。

enter image description here

github上WebShell相關項目

白樣本主要使用常見的基於PHP的開源軟件,主要包括如下幾種。

WordPress

WordPress是一種使用PHP語言開發的博客平臺,用戶能夠在支持PHP和MySQL數據庫的服務器上架設屬於本身的網站。也能夠把 WordPress看成一個內容管理系統(CMS)來使用。

WordPress是一款我的博客系統,並逐步演化成一款內容管理系統軟件,它是使用PHP語言和MySQL數據庫開發的。用戶能夠在支持 PHP 和 MySQL數據庫的服務器上使用本身的博客。

WordPress有許多第三方開發的免費模板,安裝方式簡單易用。不過要作一個本身的模板,則須要你有必定的專業知識。好比你至少要懂的標準通用標記語言下的一個應用HTML代碼、CSS、PHP等相關知識。WordPress官方支持中文版,同時有愛好者開發的第三方中文語言包,如wopus中文語言包。WordPress擁有成千上萬個各式插件和不可勝數的主題模板樣式。

項目地址爲:https://wordpress.org/

enter image description here

WordPress主頁

PHPCMS

PHPCMS是一款網站管理軟件。該軟件採用模塊化開發,支持多種分類方式,使用它可方便實現個性化網站的設計、開發與維護。它支持衆多的程序組合,可輕鬆實現網站平臺遷移,並可普遍知足各類規模的網站需求,可靠性高,是一款具有文章、下載、圖片、分類信息、影視、商城、採集、財務等衆多功能的強大、易用、可擴展的優秀網站管理軟件。

PHPCMS由國內80後知名創業者鍾勝輝(網名:淡淡風)於2005年創辦,是國內知名的站長建站工具。2009年,PHPCMS創辦人鍾勝輝離開PHPCMS,創辦國內針對媒體領域的CMS產品CmsTop(思拓合衆)。

項目地址爲:http://www.phpcms.cn/

enter image description here

phpcms主頁

phpMyAdmin

phpMyAdmin 是一個以PHP爲基礎,以Web-Base方式架構在網站主機上的MySQL的數據庫管理工具,讓管理者可用Web接口管理MySQL數據庫。藉由此Web接口能夠成爲一個簡易方式輸入繁雜SQL語法的較佳途徑,尤爲要處理大量資料的匯入及匯出更爲方便。其中一個更大的優點在於因爲phpMyAdmin跟其餘PHP程式同樣在網頁服務器上執行,可是您能夠在任何地方使用這些程式產生的HTML頁面,也就是於遠端管理MySQL數據庫,方便的創建、修改、刪除數據庫及資料表。也可藉由phpMyAdmin創建經常使用的php語法,方便編寫網頁時所須要的sql語法正確性。

項目地址爲:https://www.phpMyAdmin.net/

enter image description here

phpMyAdmin主頁

Smarty

Smarty是一個使用PHP寫出來的模板引擎,是目前業界最著名的PHP模板引擎之一。它分離了邏輯代碼和外在的內容,提供了一種易於管理和使用的方法,用來將本來與HTML代碼混雜在一塊兒PHP代碼邏輯分離。簡單的講,目的就是要使PHP程序員同前端人員分離,使程序員改變程序的邏輯內容不會影響到前端人員的頁面設計,前端人員從新修改頁面不會影響到程序的程序邏輯,這在多人合做的項目中顯的尤其重要。

項目地址爲:https://github.com/smarty-php/smarty

Yii

Yii是一個基於組件的高性能PHP框架,用於開發大型Web應用。Yii採用嚴格的OOP編寫,並有着完善的庫引用以及全面的教程。從 MVC,DAO/ActiveRecord,widgets,caching,等級式RBAC,Web服務,到主題化,I18N和L10N,Yii提供了今日Web 2.0應用開發所須要的幾乎一切功能。事實上,Yii是最有效率的PHP框架之一。

Yii是一個高性能的PHP5的web應用程序開發框架。經過一個簡單的命令行工具 yiic 能夠快速建立一個web應用程序的代碼框架,開發者能夠在生成的代碼框架基礎上添加業務邏輯,以快速完成應用程序的開發。

項目地址爲:http://www.yiiframework.com/

enter image description here

Yii主頁

特徵提取

方法一:詞袋&TF-IDF模型

咱們使用最多見的詞袋模型&TF-IDF提取文件特徵。

把一個PHP文件做爲一個完整的字符串處理,定義函數load_one_file加載文件到一個字符串變量中返回。

def load_one_file(filename):
​    x=""
​    with open(filename) as f:
​        for line in f:
​            line = line.strip('\r')
​            x+=line
​    return x

因爲開源軟件中包含大量圖片、js等文件,因此遍歷目錄時須要排除非php文件。另外開源軟件的目錄結構相對複雜,不像前面章節的垃圾郵件、垃圾短信等是平面目錄結構,因此要求咱們遞歸訪問指定目錄並加載指定文件。

def load_files_re(dir):
​    files_list = []
​    g = os.walk(dir)
​    for path, d, filelist in g:
​        for filename in filelist:
​            if filename.endswith('.php'):
​                fulepath =
os.path.join(path, filename)
​                print "Load %s"
% fulepath
​                t = load_file(fulepath)
​                files_list.append(t)
​    return files_list

加載蒐集到的WebShell樣本,並統計樣本個數,將WebShell樣本標記爲1。

WebShell_files_list = load_files_re(WebShell_dir)
y1=[1]*len(WebShell_files_list)
black_count=len(WebShell_files_list)

加載蒐集到的開源軟件樣本,並統計樣本個數,將開源軟件樣本標記爲0。

wp_files_list =load_files_re(whitefile_dir)
y2=[0]*len(wp_files_list)
white_count=len(wp_files_list)

將WebShell樣本和開源軟件樣本合併。

x=WebShell_files_list+wp_files_list
y=y1+y2

使用2-gram提取詞袋模型,並使用TF-IDF進行處理。

CV = CountVectorizer(ngram_range=(2, 2),
decode_error="ignore",max_features=max_features,
token_pattern = r'\b\w+\b',min_df=1, max_df=1.0)
x=CV.fit_transform(x).toarray()
transformer = TfidfTransformer(smooth_idf=False)
x_tfidf = transformer.fit_transform(x)
x = x_tfidf.toarray()

所謂的2-gram是詞袋模型的一個細分類別,也有的機器學習書籍裏面單獨把2-gram或者說n-gram做爲單獨的模型介紹。n-gram基於這樣一種假設,第n個單詞只和它前面的n-1個詞有關聯,每n個單詞做爲一個處理單元。

enter image description here

2-gram舉例

經過設置CountVectorizer函數的ngram_range參數和token_pattern便可實現n-gram,其中ngram_range代表n-gram的n取值範圍,若是是2-gram設置成(2,2)便可。token_pattern代表詞切分的規則,一般設置爲r'\b\w+\b'便可。

劃分訓練集與測試集,測試集的比例爲40%。

x_train, x_test, y_train,y_test = train_test_split(x, y, test_size=0.4, random_state=0)

方法二:opcode&n-gram模型

opcode是計算機指令中的一部分,用於指定要執行的操做, 指令的格式和規範由處理器的指令規範指定。除了指令自己之外一般還有指令所須要的操做數,可能有的指令不須要顯式的操做數。這些操做數多是寄存器中的值,堆棧中的值,某塊內存的值或者IO端口中的值等等。一般opcode還有另外一種稱謂:字節碼(byte codes)。 例如Java虛擬機(JVM),.NET的通用中間語言(CIL: Common Intermeditate Language)等等。PHP中的opcode則屬於前面介紹中的後着,PHP是構建在Zend虛擬機(Zend VM)之上的。

PHP的opcode就是Zend虛擬機中的指令,常見的opcode以下圖所示。

enter image description here

PHP常見opcode

一般能夠經過PHP的VLD(Vulcan Logic Dumper,邏輯代碼展示)是擴展來查看PHP文件對應的opcode。

wget http://pecl.php.net/get/vld-0.13.0.tgz

tar zxvf vld-0.13.0.tgz

cd ./vld-0.13.0

/configure--with-php-config=/usr/local/php/bin/php-config --enable-vld

make && makeinstall

而後在php.ini配置文件中添加extension=vld.so 用於激活VLD,其中php.ini默認位置位於lib目錄中。VLD還能夠從github上下載並安裝,步驟爲:

git clone https://github.com/derickr/vld.git

cd vld

phpize

./configure

make && makeinstall

VLD項目的主頁爲:

http://pecl.php.net/package/vld

enter image description here

VLD擴展下載主頁

以PHP文件hello.php爲例:

<?php

   echo"Hello World";

   $a = 1 +1;

   echo $a;

?>

經過使用PHP的VLD擴展查看對應的opcode,其中vld.active=1表示激活VlD,vld.execute=0表示只解析不執行。

php -dvld.active=1 -dvld.execute=0hello.php

顯示結果爲:

function name:  (null)

number of ops:  5

compiled vars:  !0 = $a

line     #* E I O op                         fetch          ext  return  operands

\-----------------------------------------------------------------------------

   2     0  E >  ECHO                                              'Hello+World'

   3     1       ADD                                            ~0      1, 1

​         2       ASSIGN                                                 !0, ~0

   4     3       ECHO                                                   !0

   6     4     > RETURN                                                 1

 

branch: #  0; line:    2-    6; sop:     0; eop:     4; out1:  -2

path #1: 0,

對應的opcode爲:

ECHO     

ADD       

ASSIGN

ECHO

以一個常見的一句話木馬爲例:

<?php

​         echo $_GET['r'];

?>

經過VLD查看的結果爲:

function name:  (null)

number of ops:  5

compiled vars:  none

line     #* E I O op                         fetch          ext  return  operands

\-------------------------------------------------------------------------------------

   2     0  E >  FETCH_R                     global              $0     '_GET'

​         1       FETCH_DIM_R                                    $1      $0, 'r'

​         2       ECHO                                                   $1

   4     3       ECHO                                                   '+%0A'

​         4     > RETURN                                                 1

 

branch: #  0; line:    2-    4; sop:     0; eop:     4; out1:  -2

path #1: 0,

對應的opcode爲:

FETCH_R

FETCH_DIM_R 

ECHO 

ECHO

RETURN

使用2-gram對opcode進行分組,結果爲:

(FETCH_R, FETCH_DIM_R) (FETCH_DIM_R, ECHO) (ECHO, ECHO) (ECHO, RETURN)

完整的處理流程爲:

enter image description here

PHP代碼處理流程圖

代碼實現方面,首先使用VLD處理PHP文件,把處理的結果保存在字符串中。

t=""
cmd=php_bin+" -dvld.active=1 -dvld.execute=0 "+file_path
output=commands.getoutput(cmd)

PHP的opcode都是由大寫字母和下劃線組成的單詞,使用findall函數從字符串中提取所有知足條件的opcode,並以空格鏈接成一個新字符串。

t=output
tokens=re.findall(r'\s(\b[A-Z_]+\b)\s',output)
t=" ".join(tokens)

遍歷讀取指定目錄下所有PHP文件,保存其對應的opcode字符串。

def
load_files_opcode_re(dir):
​    files_list = []
​    g = os.walk(dir)
​    for path, d, filelist in g:
​        for filename in filelist:
​            if filename.endswith('.php')
:
​                fulepath =
os.path.join(path, filename)
​                print "Load %s
opcode" % fulepath
​                t =
load_file_opcode(fulepath)
​                files_list.append(t)
​    return files_list

依次讀取保存WebShell樣本以及正常PHP文件的目錄,加載對應的opcode字符串,其中標記WebShell爲1,正常PHP文件爲0。

WebShell_files_list
= load_files_re(WebShell_dir)
y1=[1]*len(WebShell_files_list)
black_count=len(WebShell_files_list)
wp_files_list =load_files_re(whitefile_dir)
y2=[0]*len(wp_files_list)
white_count=len(wp_files_list)

使用2-gram處理opcode字符串,其中經過設置ngram_range=(2, 2)就能夠達到使用2-gram的目的,同理若是使用3-gram設置ngram_range=(3, 3)便可。

CV
= CountVectorizer(ngram_range=(2, 2), decode_error="ignore",max_features=max_features,
token_pattern = r'\b\w+\b',min_df=1, max_df=1.0)
x=CV.fit_transform(x).toarray()

使用TF-IDF進一步處理。

transformer
= TfidfTransformer(smooth_idf=False)
x_tfidf = transformer.fit_transform(x)
x = x_tfidf.toarray()

另外,開發調試階段會頻繁解析相同的PHP文件獲取對應的opcode,可使用PHP的opcode緩存技術提升效率。opcode緩存技術[6]能夠有效減小沒必要要的編譯步驟,減小cpu和內存的消耗。正常狀況下PHP代碼的執行過程會經歷文本掃描、語法解析、建立opcode、執行opcode這幾部。

enter image description here

未使用opcode緩存的狀況下PHP代碼執行過程

使用了opcode緩存技術後,對於曾經解析過的PHP文件,opcode會緩存下來,遇到一樣內容的PHP文件就能夠直接進入opcode執行階段。

enter image description here

使用opcode緩存的狀況下PHP代碼執行過程.

開啓opcode的緩存功能很是方便,PHP 5.5.0之後在編譯PHP源碼的時候開啓--enable-opcache,編譯選型爲:

./configure--prefix=/opt/php --enable-opcache

config.status:creating php5.spec

config.status:creating main/build-defs.h

config.status:creating scripts/phpize

config.status:creating scripts/man1/phpize.1

config.status:creating scripts/php-config

config.status:creating scripts/man1/php-config.1

config.status:creating sapi/cli/php.1

config.status:creating sapi/cgi/php-cgi.1

config.status:creating ext/phar/phar.1

config.status:creating ext/phar/phar.phar.1

config.status:creating main/php_config.h

config.status:executing default commands

編譯安裝

make-j4 & make install

修改配置文件php.ini,加載對應的動態庫。

zend_extension=/full/path/to/opcache.so

配置opcode緩存對應的配置選項,典型的配置內容以下所示。

engine= On

zend_extension=/lib/php/extensions/no-debug-non-zts-20131226/opcache.so

opcache.memory_consumption=128

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=4000

opcache.revalidate_freq=60

opcache.fast_shutdown=1

opcache.enable_cli=1

opcache.enable=1

方法三:opcode調用序列模型

在opcode&n-gram模型中,咱們假設第n個opcode之與前n-1個opcode有關聯,如今咱們以一個更加長的時間範圍來看opcode的調用序列,把整個PHP的opcode當成一個調用序列來分析,爲了便於程序處理,截取整個文件opcode的固定長度的opcode序列分析,超過固定長度的截斷,不足的使用0補齊。以一個常見的一句話木馬爲例:

<?php

​         echo $_GET['r'];

?>

enter image description here

圖11-13 解析PHP文件獲取opcode調用序列的過程

該文件經過VLD處理得到對應的opcode爲:

FETCH_R

FETCH_DIM_R 

ECHO 

ECHO

RETURN

得到對應的opcode序列爲:

(FETCH_R,FETCH_DIM_R,ECHO,ECHO,RETURN )

模型訓練與驗證

方法一:樸素貝葉斯算法

使用樸素貝葉斯算法,特徵提取使用詞袋&TF-IDF模型,完整的處理流程爲:

  1. 將WebShell樣本以及常見PHP開源軟件的文件提取詞袋。
  2. 使用TF-IDF處理。
  3. 隨機劃分爲訓練集和測試集。
  4. 使用樸素貝葉斯算法在訓練集上訓練,得到模型數據。
  5. 使用模型數據在測試集上進行預測。
  6. 驗證樸素貝葉斯算法預測效果。

enter image description here

特徵提取使用詞袋&TF-IDF模型算法使用樸素貝葉斯的流程圖

實例化樸素貝葉斯算法,並在訓練集上訓練數據,針對測試集進行預測。

gnb = GaussianNB()
gnb.fit(x_train,y_train)
y_pred=gnb.predict(x_test)

評估結果的準確度和TP、FP、TN、FN四個值。

print metrics.accuracy_score(y_test, y_pred)
print metrics.confusion_matrix(y_test, y_pred)

在詞袋最大特徵數爲15000的狀況下,使用詞袋&TF-IDF模型時,TP、FP、TN、FN矩陣以下表所示。

表1-1 基於詞袋&TF-IDF模型的樸素貝葉斯驗證結果

類型名稱** 相關** 不相關**
檢索到 3566 52
未檢索到 71 972

整個系統的準確率爲94.92%,召回率爲93.19%。

完整輸出結果爲:

metrics.accuracy_score:

0.97361081313

metrics.confusion_matrix:

[[3566   52]

 [  71  972]]

metrics.precision_score:

0.94921875

metrics.recall_score:

0.931927133269

metrics.f1_score:

0.940493468795

方法二:深度學習算法之MLP

使用MLP算法,隱含層設計爲2層,每次節點數分別爲5和2。

enter image description here
MLP隱藏層設計

使用MLP算法,特徵提取使用詞袋&TF-IDF模型,完整的處理流程爲:

  1. 將WebShell樣本以及常見PHP開源軟件的文件提取詞袋。
  2. 使用TF-IDF處理。
  3. 隨機劃分爲訓練集和測試集。
  4. 使用MLP算法在訓練集上訓練,得到模型數據。
  5. 使用模型數據在測試集上進行預測。
  6. 驗證MLP算法預測效果。

實例化MLP算法,並在訓練集上訓練數據,針對測試集進行預測。

clf = MLPClassifier(solver='lbfgs',
​                    alpha=1e-5,
​                    hidden_layer_sizes =
(5, 2),
​                    random_state = 1)
print  clf
clf.fit(x_train, y_train)
y_pred = clf.predict(x_test)

評估結果的TP、FP、TN、FN四個值。

print metrics.accuracy_score(y_test, y_pred)
print metrics.confusion_matrix(y_test, y_pred)

評估結果的準確率與召回率以及F1分值。

print "metrics.precision_score:"
print metrics.precision_score(y_test, y_pred)
print "metrics.recall_score:"
print metrics.recall_score(y_test, y_pred)
print "metrics.f1_score:"
print metrics.f1_score(y_test,y_pred)

在詞袋最大特徵數爲15000且同時使用TF-IDF模型的狀況下, TP、FP、TN、FN矩陣以下表所示。

表1-2 基於詞袋和TF-IDF模型的MLP驗證結果

類型名稱** 相關** 不相關**
檢索到 3583 35
未檢索到 51 992

準確率爲96.59%,召回率爲95.11%。

完整輸出結果爲:

metrics.confusion_matrix:

[[3583   35]

 [  51  992]]

metrics.precision_score:

0.965920155794

metrics.recall_score:

0.951102588686

metrics.f1_score:

0.95845410628

使用MLP算法,特徵提取使用特徵提取使用opcode&n-gram,完整的處理流程爲:

  1. 將WebShell樣本以及常見PHP開源軟件的文件提取opcode.
  2. 使用n-gram處理。
  3. 隨機劃分爲訓練集和測試集。
  4. 使用MLP算法在訓練集上訓練,得到模型數據。
  5. 使用模型數據在測試集上進行預測。
  6. 驗證MLP算法預測效果。

特徵提取使用opcode&n-gram,n取4,最大特徵數取2000的狀況下,TP、FP、TN、FN矩陣以下表所示。

表1-3 基於opcode&n-gram模型的MLP驗證結果

類型名稱** 相關** 不相關**
檢索到 2601 97
未檢索到 20 484

準確率爲83.30%,召回率爲96.03%。

完整輸出結果爲:

0.963460337289

metrics.confusion_matrix:

[[2601   97]

 [  20 484]]

metrics.precision_score:

0.833046471601

metrics.recall_score:

0.960317460317

metrics.f1_score:

0.892165898618

方法三:深度學習算法之CNN

使用方法二中生成的opcode&n-gram數據,算法使用CNN,完整的處理流程爲:

  1. 將WebShell樣本以及常見PHP開源軟件的文件提取opcode.
  2. 使用n-gram處理。
  3. 隨機劃分爲訓練集和測試集。
  4. 使用CNN算法在訓練集上訓練,得到模型數據。
  5. 使用模型數據在測試集上進行預測。
  6. 驗證CNN算法預測效果。

使用方法二中生成的opcode&n-gram數據,得到訓練數據集和測試數據集。

x, y = get_feature_by_opcode()

x_train, x_test, y_train, y_test = train_test_split(x, y,test_size = 0.4, random_state = 0)

將訓練和測試數據進行填充和轉換,不到最大長度的數據填充0,因爲是二分類問題,把標記數據二值化。定義輸入參數的最大長度爲文檔的最大長度。

trainX = pad_sequences(trainX, maxlen=max_document_length,
value=0.)
testX = pad_sequences(testX, maxlen=max_document_length, value=0.)
# Converting labels to binary vectors
trainY = to_categorical(trainY, nb_classes=2)
testY = to_categorical(testY, nb_classes=2)

network = input_data(shape=[None,max_document_length],name='input')

定義CNN模型,使用3個數量爲128,長度分別爲三、四、5的一維卷積函數處理數據。

network = tflearn.embedding(network, input_dim=1000000,
output_dim=128)
branch1 = conv_1d(network, 128, 3, padding='valid', activation='relu',
regularizer="L2")
branch2 = conv_1d(network, 128, 4, padding='valid', activation='relu',
regularizer="L2")
branch3 = conv_1d(network, 128, 5, padding='valid', activation='relu',
regularizer="L2")
network = merge([branch1, branch2, branch3], mode='concat', axis=1)
network = tf.expand_dims(network, 2)
network = global_max_pool(network)
network = dropout(network, 0.8)
network = fully_connected(network, 2, activation='softmax')
network = regression(network, optimizer='adam', learning_rate=0.001,
loss='categorical_crossentropy', name='target')

實例化CNN對象並進行訓練數據,一共訓練5輪。

model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit(trainX, trainY,
​          n_epoch=5, shuffle=True,
validation_set=0.1,
​          show_metric=True,
batch_size=100,run_id="webshell")

完整的CNN結構以下圖所示。

enter image description here

用於識別WebShell的CNN結構圖

考覈CNN對應的準確率、召回率,誤報數和漏報數。

print "metrics.accuracy_score:"
print metrics.accuracy_score(y_test, y_pred)
print "metrics.confusion_matrix:"
print metrics.confusion_matrix(y_test, y_pred)
print "metrics.precision_score:"
print metrics.precision_score(y_test, y_pred)
print "metrics.recall_score:"
print metrics.recall_score(y_test, y_pred)
print "metrics.f1_score:"
print metrics.f1_score(y_test,y_pred)

運行程序,通過5輪訓練,在的狀況下,使用opcode&n-gram模型時,n取4,TP、FP、TN、FN矩陣以下表所示。

表1-4 基於opcode&n-gram模型的CNN驗證結果

類型名稱** 相關** 不相關**
檢索到 2669 29
未檢索到 367 137

整個系統的準確率爲82.53%,召回率爲27.18%。

完整輸出結果爲:

metrics.accuracy_score:

0.87632729544

metrics.confusion_matrix:

[[2669   29]

 [ 367 137]]

metrics.precision_score:

0.825301204819

metrics.recall_score:

0.271825396825

metrics.f1_score:

0.408955223881

使用方法三中生成的opcode序列數據,算法使用CNN,完整的處理流程爲:

  1. 將WebShell樣本以及常見PHP開源軟件的文件提取opcode.
  2. 使用詞袋處理,針對opcode進行編號,生成opcode序列。
  3. 隨機劃分爲訓練集和測試集。
  4. 使用CNN算法在訓練集上訓練,得到模型數據。
  5. 使用模型數據在測試集上進行預測。
  6. 驗證CNN算法預測效果。

使用方法三中opcode調用序列編碼後的數據,得到訓練數據集和測試數據集。

x_train, x_test, y_train, y_test= get_feature_by_opcode ()

運行程序,通過5輪訓練,在opcode序列長度爲3000的狀況下,使用opcode序列模型時,TP、FP、TN、FN矩陣以下表所示。

表1-5 基於opcode序列模型的CNN驗證結果

類型名稱** 相關** 不相關**
檢索到 2685 13
未檢索到 89 415

整個系統的準確率爲96.96%,召回率爲82.34%。

完整輸出結果爲:

metrics.accuracy_score:

0.968144909432

metrics.confusion_matrix:

[[2685   13]

 [  89 415]]

metrics.precision_score:

0.969626168224

metrics.recall_score:

0.823412698413

metrics.f1_score:

0.890557939914

本章小結

本章基於蒐集的PHP的WebShell數據集介紹了WebShell的識別方法。針對PHP的WebShell數據集,特徵提取方法有詞袋&TF-IDFopcode&n-gram以及opcode序列三種方法。訓練模型介紹了樸素貝葉斯以及深度學習的MLP和CNN算法,其中基於基於詞袋和TF-IDF模型的MLP準確率和召回率綜合表現最佳,基於opcode序列模型的CNN準確率較高。



實錄:《劉焱: 基於機器學習發現 Webshell 實戰解析》


這裏寫圖片描述

相關文章
相關標籤/搜索