天天看點

學點算法搞安全之HMM(下篇)

前言

上篇我們介紹了hmm的基本原理以及常見的基于參數的異常檢測實作,這次我們換個思路,把機器當一個剛入行的白帽子,我們訓練他學會xss的攻擊文法,然後再讓機器從通路日志中尋找符合攻擊文法的疑似攻擊日志。

學點算法搞安全之HMM(下篇)

通過詞法分割,可以把攻擊載荷序列化成觀察序列,舉例如下:

學點算法搞安全之HMM(下篇)

詞集/詞袋模型

詞集和詞袋模型是機器學習中非常常用的一個資料處理模型,它們用于特征化字元串型資料。一般思路是将樣本分詞後,統計每個詞的頻率,即詞頻,根據需要選擇全部或者部分詞作為哈希表鍵值,并依次對該哈希表編号,這樣就可以使用該哈希表對字元串進行編碼。

詞集模型:單詞構成的集合,集合自然每個元素都隻有一個,也即詞集中的每個單詞都隻有一個

詞袋模型:如果一個單詞在文檔中出現不止一次,并統計其出現的次數

本章使用詞集模型即可。

假設存在如下資料集合:

dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'], ['my', 'dalmation', 'is', 'so', 'cute', 'i', 'love', 'him'], ['stop', 'posting', 'stupid', 'worthless', 'garbage'], ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'], ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]

首先生成詞彙表:

vocabset = set()

for doc in dataset:

vocabset |= set(doc)

vocablist = list(vocabset)

根據詞彙表生成詞集:

# 詞集模型

sow = []

vec = [0]*len(vocablist)

for i, word in enumerate(vocablist):

if word in doc:

vec[i] = 1

sow.append(doc)

簡化後的詞集模型的核心代碼如下:

fredist = nltk.freqdist(tokens_list) # 單檔案詞頻

keys=fredist.keys()

keys=keys[:max] #隻提取前n個頻發使用的單詞 其餘泛化成0

for localkey in keys: # 擷取統計後的不重複詞集

if localkey in wordbag.keys(): # 判斷該詞是否已在詞集中

continue

else:

wordbag[localkey] = index_wordbag

index_wordbag += 1

常見的xss攻擊載荷列舉如下:

<script>alert(‘xss’)</script>

%3cscript%3ealert(‘xss’)%3c/script%3e

%22%3e%3cscript%3ealert(‘xss’)%3c/script%3e

<img src=”javascript:alert(‘xss’);”>

<img src=javascript:alert(“xss”)>

<img src=javascript:alert(‘xss’)>

<img src=xss onerror=alert(1)>

<img “”"><script>alert(“xss”)</script>”>

<img src=javascript:alert(string.fromcharcode(88,83,83))>

<img src=”jav ascript:alert(‘xss’);”>

<body background=”javascript:alert(‘xss’)”>

<body onload=alert(‘xss’)>

需要支援的詞法切分原則為:

單雙引号包含的内容 ‘xss’

<>标簽 <script>

<>标簽開頭 <body

屬性标簽 onload=

<>标簽結尾 >

函數體 “javascript:alert(‘xss’);”

字元數字标量 代碼實作舉例如下:

tokens_pattern = r”’(?x)

“[^"]+”

|http://\s+

|</\w+>

|<\w+>

|<\w+

|\w+=

|>

|\w+\([^<]+\) #函數 比如alert(string.fromcharcode(88,83,83))

|\w+

”’

words=nltk.regexp_tokenize(line, tokens_pattern)

另外,為了減少向量空間,需要把數字和字元以及超連結範化,具體原則為:

#數字常量替換成8

line, number = re.subn(r’\d+’, “8″, line)

#幹掉注釋

line, number = re.subn(r’\/\*.?\*\/’, “”, line)

範化後分詞效果示例為:

#原始參數值:”><img src=x onerror=prompt(0)>)

#分詞後:

['>', '<img', 'src=', 'x', 'onerror=', 'prompt(8)', '>']

#原始參數值:<iframe src=”x-javascript:alert(document.domain);”></iframe>)

['<iframe', 'src=', '"x-javascript:alert(document.domain);"', '>', '</iframe>']

#原始參數值:<marquee><h1>xss by xss</h1></marquee> )

['<marquee>', '<h8>', 'xss', 'by', 'xss', '</h8>', '</marquee>']

#原始參數值:<script>-=alert;-(1)</script> “onmouseover=”confirm(document.domain);”" </script>)

['<script>', 'alert', '8', '</script>', '"onmouseover="', 'confirm(document.domain)', '</script>']

#原始參數值:<script>alert(2)</script> “><img src=x onerror=prompt(document.domain)>)

['<script>', 'alert(8)', '</script>', '>', '<img', 'src=', 'x', 'onerror=', 'prompt(document.domain)', '>']

結合詞集模型,完整的流程舉例如下:

學點算法搞安全之HMM(下篇)

訓練模型

将範化後的向量x以及對應的長度矩陣x_lens輸入即可,需要x_lens的原因是參數樣本的長度可能不一緻,是以需要單獨輸入。

remodel = hmm.gaussianhmm(n_components=3, covariance_type=”full”, n_iter=100)

remodel.fit(x,x_lens)

整個系統運作過程如下:

學點算法搞安全之HMM(下篇)

驗證階段利用訓練出來的hmm模型,輸入觀察序列擷取機率,進而判斷觀察序列的合法性,訓練樣本是1000條典型的xss攻擊日志,通過分詞、計算詞集,提煉出200個特征,全部樣本就用這200個特征進行編碼并序列化,使用20000條正常日志和20000條xss攻擊識别(類似jsfuck這類編碼的暫時不支援),準确率達到90%以上,其中驗證環節的核心代碼如下:

with open(filename) as f:

for line in f:

line = line.strip(‘\n’)

line = urllib.unquote(line)

h = htmlparser.htmlparser()

line = h.unescape(line)

if len(line) >= min_len:

words = do_str(line)

vers = []

for word in words:

if word in wordbag.keys():

vers.append([wordbag[word]])

vers.append([-1])

np_vers = np.array(vers)

pro = remodel.score(np_vers)

if pro >= t:

print “score:(%d) xss_url:(%s) ” % (pro,line)

本文來自合作夥伴“阿裡聚安全”,發表于2017年05月11日 11:33.

繼續閱讀