當前位置:
首頁 > 最新 > 機器學習實踐-DGA檢測

機器學習實踐-DGA檢測

什麼是DGA

DGA(Domain Generate Algorithm域名生成演算法)是一種使用時間,字典,硬編碼的常量利用一定的演算法生成的域名。DGA生成的域名具有為隨機性,用於中心結構的殭屍網路中與C&C伺服器的連接,以逃避域名黑名單檢測技術。

DGA域名使用的大致流程如下:首先攻擊者通過運行演算法生成DGA域名,然後隨機選擇其中的少量域名進行註冊,並將域名綁定到C&C伺服器。受害者的機器被植入惡意程序後運行DGA演算法生成域名,並檢測域名是否可以連接,如果不能連接就嘗試下一個域名,如果可以連接就選取該域名作為該惡意程序的控制端伺服器域名。

DGA域名特點主要有以下幾點:1)DGA域名大部分都沒有註冊,因為註冊域名需要一定的成本,而且從DGA域名的使用流程來說只需要註冊一個域名就可以達到目的。2)DGA域名具有偽隨機性,與正常的域名具有一定的差別,一般正常的域名在拼寫上符合一定的規律。3)DGA域名一般長度較長,長度短的域名往往已經被註冊了。

DGA域名舉例:

CryptoLocker(ryhqdtlbwacoikd.net)

Gameover(ocdjtg1pm9csac7cbzpx7r75a.com)

Necurs(mjlglqmatygruta.pw)

Wannacry(iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com)

xshell(xmponmzmxkxkh.com)

ccleaner(ab3d685a0c37.com)

pykspa_v2_fake(sgsqoqmyceqm.org)

基於DGA域名的特點,雖然採用傳統的域名黑名單也可以檢測一些已知的DGA域名,但是對於一些未知DGA域名就束手無策了。我們還可以通過域名長度,是否註冊,以及註冊的時間和註冊信息進行判斷,但是這種方式需要藉助第三方信譽系統,而且效果往往也不是很理想。由於DGA域名和正常域名存在一定的差異,以及存在大量的正負樣本,所以可以嘗試使用機器學習來進行DGA域名的檢測。

機器學習二分類演算法的衡量指標

1)混淆矩陣

說到二分類問題的性能指標,我們首先會想到混淆矩陣,下面為混淆矩陣的示意圖

FP表示預測為YES實際為NO的數量

TP表示預測為YES實際為YES的數量

FN表示預測為NO實際為YES的數量

TN表示預測為NO實際為NO的數量

Y』=TP+FP 表示預測為YES的數量

N』=FN+TN表示預測為NO的數量

Y=TP+FN表示實際為YES的數量

N=FP+TN表示實際為NO的數量

有了混淆矩陣我們可以很方便的計算下面的準確率,精確率,召回率等指標

2)準確率

準確率是使用最普遍和直觀的指標,意義是預測準確樣本的占所有樣本的比例,可表示為(TP+TN)/(Y+N)

3)精確率

精確率也叫查准率,意義是所有預測正確的正類占預測為正類的比例,可表示為P=TP/Y』

4)召回率

召回率也叫查全率,意義是所有預測正確的正類占實際為正類的比例,可表示為R=TP/Y

5)特異度

特異度也稱真陰性率,意義是所有預測正確的負類占實際為負的樣本負類的比例,可表示為TN/N

6)誤報率

誤報率意義是所有預測錯誤的正類占實際為負類的比例,可表示為FP/N

7)漏報率

漏報率意義是所有預測錯誤的負類占實際為正類的比例,可表示為FN/Y

8)綜合評價指標(F-Measure又稱為F-Score)

精確率和召回率時常會產生矛盾的情況,需要綜合考量他們,於是就有了F-Measure(又稱為F-Score)。F-Measure是Precision和Recall加權調和平均F=(a*a+1)P*R/a*a*(P+R)

當參數α=1時,就是最常見的F1,也即F1=2P*R/(P+R)。可知F1綜合了P和R的結果,當F1較高時則能說明試驗方法比較有效。

9)ROC曲線

ROC曲線的全稱叫做Receiver Operating Characteristic,常常被用來判別一個分類器的好壞程度。如下圖所示:

上圖引自(http://alexkong.net/2013/06/introduction-to-auc-and-roc/)

橫坐標可表示為FPR=FP/N,也就是誤報率

縱坐標可表示為TPR=TP/Y,也就是查全率

一些分類器得到的結果往往不是0,1這樣的標籤,如神經網路得到諸如0.5,0.8這樣的分類結果。這時,我們人為取一個閾值比方說0.6,那麼小於0.6的歸為0類,大於等於0.6的歸為1類,可以得到一個分類結果。同樣,這個閾值我們可以取0.1或0.2等等。取不同的閾值,最後得到的分類情況也就不同。通過遍歷不同的閾值,分別計算FPR和TPR,作為一個點。將這些點連接起來就組成了ROC曲線。ROC曲線越靠近左上角,分類器效果越好。

10)AUC

AUC全稱Area Under ROC Curve。是一種用來度量分類模型好壞的一個標準,ROC雖然直觀,但是不夠量化。AUC是對ROC的量化,其值為ROC曲線所覆蓋的區域面積,顯然,AUC越大,分類器分類效果越好。

AUC = 1,是完美分類器,但是絕大多數預測的場合,不存在完美分類器。

0.5

AUC = 0.5,等同於隨機猜測,模型沒有意義。

AUC

訓練數據

正常域名採用長度小於5的字元串組合以及alexa發布的排名前100萬的網站域名,其下載地址為http://s3.amazonaws.com/alexa-static/top-1m.csv.zip

另外,在進行模型訓練時,盡量保證正常域名數量和DGA域名數量在一個量級。

DGA分類識別-樸素貝葉斯


從正常域名拼寫符合一定拼寫規律,DGA域名偽隨機性來看,可以使用N-GRAM模型進行建模,這裡我們採用2-GRAM,首先將域名當作一個字元串,去除頂級域然後進行建模。那pingan.com舉例:去除頂級域後得到字元串pingan,進行2-gram處理得到字元串列表』pi』 『in』 』ng』 『ga』 『an』。我們可以使用python庫sklearn提供的CountVectorizer函數直接進行處理即可:

from sklearn.feature_extraction.text import CountVectorizerngram_vectorizer = CountVectorizer(analyzer="char", ngram_range=(2, 2),dtype=np.int32)


使用python庫sklearn提供的MultinomialNB

代碼片段:

from sklearn.naive_bayes import MultinomialNB

代碼流程介紹:

1)將數據集劃分訓練集和測試集

x_train, x_test, y_train, y_test = train_test_split(X , y, test_size=0.2)

2)將數據集進行2-GRAM處理,並進行數據擬合和標準化。

count_vec = CountVectorizer(analyzer="char", ngram_range=(2, 2),dtype=np.int32)x_train = count_vec.fit_transform(x_train)x_test = count_vec.transform(x_test)

3)生成樸素貝葉斯演算法模型,並在訓練集上訓練,獲得模型數據

mtnb = MultinomialNB()mtnb.fit(x_train,y_train)

4)使用模型在測試集上進行預測,並列印各項分類性能指標

y_pred=mtnb.predict(x_test)print(classification_report(y_test, y_pred)) //列印精確度,召回率 F1-score等指標print metrics.confusion_matrix(y_test, y_pred) //列印混淆矩陣t_probs = mtnb.predict_proba(x_test)[:,1]t_auc = sklearn.metrics.roc_auc_score(y_test, t_probs)print("MultinomialNB: auc = %f " % ( t_auc)) //列印AUC


如下圖所示:精確度77%,召回率76% f1-Score 76% , AUC 87%,效果不是很理想。

DGA分類識別-XGBoost

同樣採用2-GRAM進行處理


使用python的xgboost庫,代碼片段:

import xgboost as xgb


1)將數據集劃分訓練集和測試集

x_train, x_test, y_train, y_test = train_test_split(X , y, test_size=0.2)

2)將數據集進行2-GRAM處理,並進行數據擬合和標準化。

count_vec = CountVectorizer(analyzer="char", ngram_range=(2, 2),dtype=np.int32)x_train = count_vec.fit_transform(x_train)x_test = count_vec.transform(x_test)

3)生成樸素貝葉斯演算法模型,並在訓練集上訓練,獲得模型數據

model = xgb.XGBClassifier()model.fit(x_train, y_train)

4)使用模型在測試集上進行預測,並列印各項分類性能指標

y_pred=model .predict(x_test)print(classification_report(y_test, y_pred)) //列印精確度,召回率 F1-score等指標print metrics.confusion_matrix(y_test, y_pred) //列印混淆矩陣t_probs = model.predict_proba(x_test)[:,1]t_auc = sklearn.metrics.roc_auc_score(y_test, t_probs)print( "XGBClassifier: auc = %f " % ( t_auc)) //列印AUC


如下圖所示:精確度84%,召回率81% f1-Score 81% , AUC 91.7264%,效果尚可。

DGA分類識別-神經網路多層感知機


同樣採用2-GRAM進行處理


Keras是一個高層級的python神經網路框架,Keras後端可以在Tensorflow或者Theano上運行,Keras 是為支持快速實驗而生,具有高度模塊化,極簡,和可擴充特性。我們選用keras進行神經網路多層感知機模型的測試。


1)將數據集進行2-GRAM處理,並進行數據擬合和標準化。然後將數據集劃分訓練集和測試集

ngram_vectorizer = CountVectorizer(analyzer="char", ngram_range=(2, 2),dtype=np.int32)count_vec = ngram_vectorizer.fit_transform(X) //數據擬合和標準化max_features = count_vec.shape[1] //計算輸入維度

//劃分訓練集和測試集

X_train, X_test, y_train, y_test, _, label_test = train_test_split(count_vec, y,labels, test_size=0.2)X_train, X_holdout, y_train, y_holdout = train_test_split(X_train, y_train, test_size=0.05)

2)利用keras生成神經網路多層感知機模型。這裡簡要介紹下其中一些概念:

激活函數activation:激活函數的主要作用是提供網路的非線性建模能力,常見的有 sigmoid函數,tanh函數,ReLU函數, ELU函數, PReLU函數,softmax函數等

損失函數loss:就是一個評分函數,用來對模型預測準確性進行打分,模型的訓練就是要通過樣本將損失函數最小化,常見的有:0-1損失函數 ,平方損失函數,絕對損失函數,對數損失函數等

優化器optimizer:最小化損失函數的求解方法。(常用的有最小二乘法,梯度下降法)

//創建一個Sequential模型

model = Sequential()//添加一個全連接層,激活函數使用sigmoid,輸出維度128model.add(Dense(128, input_dim=max_features, activation="sigmoid"))//添加一個Dropout層,用於防止過擬合model.add(Dropout(0.5))model.add(Dense(64, activation="relu"))model.add(Dropout(0.5))model.add(Dense(1, activation="sigmoid"))//編譯模型,損失函數採用對數損失函數,優化器選用adammodel.compile(loss="binary_crossentropy",optimizer="adam")

3)使用模型進行最多50輪訓練,並記錄訓練每輪AUC的值,在相隔兩輪的AUC值沒有增加時退出訓練

for ep in range(50): model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=1) t_probs = model.predict_proba(X_holdout) t_auc = sklearn.metrics.roc_auc_score(y_holdout, t_probs)//計算AUC值 if t_auc > best_auc: best_auc = t_auc best_iter = ep //列印分類模型指標 probs = model.predict_proba(X_test) print(classification_report(y_test, probs > .5)) print("mlp: auc = %f " %confusion_matrix(y_test, probs > .5)) else: if (ep-best_iter) > 2: Break


如下圖所示:精確度99%,召回率99% f1-Score 99% , AUC 99.9138%,效果很好。

DGA分類識別-循環神經網路單層LSTM


簡單的將域名轉換為整數下標列表,然後使用keras的Embedding嵌入層轉換為固定大小的向量


我們選用keras進行循環神經網路單層LSTM的測試。


1)將數據集轉換為整數下標數組的模式,並將數據劃分為訓練集和測試集

site_chars="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"valid_chars = max_features = len(valid_chars) + 1 //計算特徵字元長度maxlen = np.max([len(x) for x in X]) //記錄最長的域名長度X = [[valid_chars[y] for y in x] for x in X] //轉換為下標數組X = sequence.pad_sequences(X, maxlen=maxlen)//進行長度填充//劃分訓練集和測試集X_train, X_test, y_train, y_test, _, label_test = train_test_split(X, y, labels,test_size=0.2)X_train, X_holdout, y_train, y_holdout = train_test_split(X_train, y_train, test_size=0.05)

2)利用keras生成循環神經網路單層LSTM模型:

//創建一個Sequential模型model = Sequential()//添加一個嵌入層,輸出向量大小256,嵌入層是將正整數(下標)轉換為具有固定大小的向量,//其本質就是word2vec,底層實現是2-gram(詞頻)+神經網路model.add(Embedding(max_features, output_dim=256, input_length=maxlen))//添加長短期記憶網路LSTM,從樣本中學習特徵,這個是核心層model.add(LSTM(128))//添加Dropout層防止過擬合model.add(Dropout(0.5))//添加全連接層,激活函數使用"sigmoid"model.add(Dense(1, activation="sigmoid"))//編譯模型,損失函數採用對數損失函數,優化器選用rmsprop,//該優化器通常是面對遞歸神經網路時的一個良好選擇model.compile(loss="binary_crossentropy",optimizer="rmsprop")

3)使用模型進行最多25輪訓練,並記錄訓練每輪AUC的值,在相隔兩輪的AUC值沒有增加時退出訓練

for ep in range(25): model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=1) t_probs = model.predict_proba(X_holdout) t_auc = sklearn.metrics.roc_auc_score(y_holdout, t_probs)//計算AUC值 if t_auc > best_auc: best_auc = t_auc best_iter = ep //列印分類模型指標 probs = model.predict_proba(X_test) print(classification_report(y_test, probs > .5)) print("Single LSTM: auc = %f " %confusion_matrix(y_test, probs > .5)) else: if (ep-best_iter) > 2: Break


如下圖所示:精確度99%,召回率99% f1-Score 99% , AUC 99.9233%,效果很好。

DGA分類識別-循環神經網路多層LSTM

特徵提取和模型選擇同單層LSTM


1)將數據集轉換為整數下標數組的模式,並將數據劃分為訓練集和測試集

site_chars="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"valid_chars = max_features = len(valid_chars) + 1 //計算特徵字元長度maxlen = np.max([len(x) for x in X]) //記錄最長的域名長度X = [[valid_chars[y] for y in x] for x in X] //轉換為下標數組X = sequence.pad_sequences(X, maxlen=maxlen)//進行長度填充//劃分訓練集和測試集X_train, X_test, y_train, y_test, _, label_test = train_test_split(X, y, labels,test_size=0.2)X_train, X_holdout, y_train, y_holdout = train_test_split(X_train, y_train, test_size=0.05)

2)利用keras生成循環神經網路多層LSTM模型:

//創建一個Sequential模型model = Sequential()//添加一個嵌入層,輸出向量大小256,嵌入層是將正整數(下標)轉換為具有固定大小的向量,//其本質就是word2vec,底層實現是2-gram(詞頻)+神經網路model.add(Embedding(max_features, output_dim=256, input_length=maxlen))//添加長短期記憶網路LSTM,從樣本中學習特徵,這個是核心層model.add(LSTM(128, return_sequences=True)) //返回維度128的向量序列model.add(LSTM(64, return_sequences=True)) //返回維度64的向量序列model.add(LSTM(64)) //返回維度64的單個向量//添加全連接層,激活函數使用"sigmoid"model.add(Dense(1, activation="sigmoid"))//編譯模型,損失函數採用對數損失函數,優化器選用rmsprop,//該優化器通常是面對遞歸神經網路時的一個良好選擇model.compile(loss="binary_crossentropy",optimizer="rmsprop")

4)使用模型進行最多25輪訓練,並記錄訓練每輪AUC的值,在相隔兩輪的AUC值沒有增加時退出訓練

for ep in range(25): model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=1) t_probs = model.predict_proba(X_holdout) t_auc = sklearn.metrics.roc_auc_score(y_holdout, t_probs)//計算AUC值 if t_auc > best_auc: best_auc = t_auc best_iter = ep //列印分類模型指標 probs = model.predict_proba(X_test) print(classification_report(y_test, probs > .5)) print("Single LSTM: auc = %f " %confusion_matrix(y_test, probs > .5)) else: if (ep-best_iter) > 2: Break


如下圖所示:精確度99%,召回率99% f1-Score 99% , AUC 99.9476%,效果很好。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器學習 的精彩文章:

Facebook用機器學習鑒別假新聞,是否比人還有效?
Opanga網路公司利用機器學習演算法來改善網路流量擁堵

TAG:機器學習 |