通常情況下Apriori算法主要用于推薦系統,在網絡安全中如何使用呢?本小節通過挖掘XSS相關參數,來我家潛在的關聯關系。
1.資料集
本小節通過xssed網站的樣例以及WAF攔截日志提取的XSS攻擊日志作為樣本,位于data/xss-2000.txt中,具體如下
機器是沒有辦法将其識别為日志的,需要逐行讀取資料,并将其向量化。比較簡單的做法就是按照一定的分隔符切割為單詞向量,代碼如下所示
myDat=[]
with open("../data/xss-2000.txt") as f:
for line in f:
#/discuz?q1=0&q3=0&q2=0%3Ciframe%20src=http://xxooxxoo.js%3E
index=line.find("?")
if index>0:
line=line[index+1:len(line)]
tokens=re.split('\=|&|\?|\%3e|\%3c|\%3E|\%3C|\%20|\%22|<|>|\\n|\(|\)|\'|\"|;|:|,|\%28|\%29',line)
myDat.append(tokens)
f.close()
列印前三行token
print(myDat[0])
print(myDat[1])
print(myDat[2])
如下所示
['', 'onmouseover', '', 'prompt', '42873', '', 'bad', '', '', '', '']
['op', 'map', 'maptype', '1', 'city', 'test', 'script', 'alert', '/42873/', '', '/script', '', '']
['op', 'map', 'maptype', '1', 'defaultcity', '%e5', '', 'alert', '/42873/', '', '//', '']
2. 使用Apriori算法挖掘
這裡采取置信度接近1,如下所示
L, suppData = apriori(myDat, 0.15)
rules = generateRules(L, suppData, minConf=0.6)
3.完整代碼
from apriori import apriori
from apriori import generateRules
import re
if __name__ == '__main__':
myDat=[]
with open("../data/xss-2000.txt") as f:
for line in f:
#/discuz?q1=0&q3=0&q2=0%3Ciframe%20src=http://xxooxxoo.js%3E
index=line.find("?")
if index>0:
line=line[index+1:len(line)]
tokens=re.split('\=|&|\?|\%3e|\%3c|\%3E|\%3C|\%20|\%22|<|>|\\n|\(|\)|\'|\"|;|:|,|\%28|\%29',line)
myDat.append(tokens)
f.close()
L, suppData = apriori(myDat, 0.15)
rules = generateRules(L, suppData, minConf=0.99)
print('rules:\n', rules)
4.運作結果
frozenset({'a'}) --> frozenset({''}) conf: 1.0
frozenset({'c'}) --> frozenset({''}) conf: 1.0
frozenset({'c'}) --> frozenset({'42873'}) conf: 1.0
frozenset({'page'}) --> frozenset({''}) conf: 1.0
frozenset({'/'}) --> frozenset({''}) conf: 1.0
frozenset({'/'}) --> frozenset({'1'}) conf: 0.9936507936507937
frozenset({'//'}) --> frozenset({''}) conf: 1.0
frozenset({'//'}) --> frozenset({'alert'}) conf: 0.9941348973607038
frozenset({'/script'}) --> frozenset({''}) conf: 1.0
frozenset({'1'}) --> frozenset({''}) conf: 1.0
frozenset({'alert'}) --> frozenset({''}) conf: 1.0
frozenset({'script'}) --> frozenset({''}) conf: 1.0
frozenset({'script'}) --> frozenset({'/script'}) conf: 1.0
frozenset({'42873'}) --> frozenset({''}) conf: 1.0
frozenset({'c'}) --> frozenset({'42873', ''}) conf: 1.0
frozenset({'/'}) --> frozenset({'1', ''}) conf: 0.9936507936507937
frozenset({'//'}) --> frozenset({'', 'alert'}) conf: 0.9941348973607038
frozenset({'script'}) --> frozenset({'', '/script'}) conf: 1.0
frozenset({'script', 'alert'}) --> frozenset({'', '/script'}) conf: 1.0
frozenset({'1', 'script'}) --> frozenset({'', '/script'}) conf: 1.0
frozenset({'1', 'script', 'alert'}) --> frozenset({'', '/script'}) conf: 1.0
rules:
[(frozenset({'a'}), frozenset({''}), 1.0), (frozenset({'c'}), frozenset({''}), 1.0), (frozenset({'c'}), frozenset({'42873'}), 1.0), (frozenset({'page'}), frozenset({''}), 1.0), (frozenset({'/'}), frozenset({''}), 1.0), (frozenset({'/'}), frozenset({'1'}), 0.9936507936507937), (frozenset({'//'}), frozenset({''}), 1.0), (frozenset({'//'}), frozenset({'alert'}), 0.9941348973607038), (frozenset({'/script'}), frozenset({''}), 1.0), (frozenset({'1'}), frozenset({''}), 1.0), (frozenset({'alert'}), frozenset({''}), 1.0), (frozenset({'script'}), frozenset({''}), 1.0), (frozenset({'script'}), frozenset({'/script'}), 1.0), (frozenset({'42873'}), frozenset({''}), 1.0), (frozenset({'c'}), frozenset({'42873', ''}), 1.0), (frozenset({'/'}), frozenset({'1', ''}), 0.9936507936507937), (frozenset({'//'}), frozenset({'', 'alert'}), 0.9941348973607038), (frozenset({'script'}), frozenset({'', '/script'}), 1.0), (frozenset({'script', 'alert'}), frozenset({'', '/script'}), 1.0), (frozenset({'1', 'script'}), frozenset({'', '/script'}), 1.0), (frozenset({'1', 'script', 'alert'}), frozenset({'', '/script'}), 1.0)]
如上所示,比如'script'和'1'、'alert'一起出現的話,基本上會100%導緻'/scipt'.