11.3 示例:使用Apriori算法挖掘XSS相关参数

在安全领域,Apriori的应用非常广泛,凡是需要挖掘潜在关联关系的都可以尝试使用,比如关联WAF的accesslog与后端数据库的sqllog,识别SSH操作日志中异常操作等。我们这里以分析accesslog为例子,完整演示代码请见本书GitHub上的11-2.py。

我们从xssed网站的样例以及WAF的拦截日志中提取XSS攻击日志作为样本,示例日志如下:


/0_1/?%22onmouseover='prompt(42873)'bad=%22%3E
/0_1/api.php?op=map&maptype=1&city=test%3Cscript%3Ealert%28/42873/%29%3C/script%3E
/0_1/api.php?op=map&maptype=1&defaultcity=%e5%22;alert%28/42873/%29;//

我们目标是分析出潜在的关联关系,然后作为SVM、KNN等分类算法的特征提取依据之一。机器没有办法直接识别日志,需要逐行将日志文本向量化,最简单的方式就是按照一定的分割符切割成单词向量,示例代码如下:


myDat=[]
with open("xss-train.txt") as f:
for line in f:
tokens=re.split('\=|&|\?|\%3e|\%3c|\%3E|\%3C|\%20|\%22|<|>|\\n|\(|\)|\'|\"|;|:|,',line)
myDat.append(tokens)
f.close()

切割后的向量示例如下:


['/0_1/', '', 'onmouseover', '', 'prompt', '42873', '', 'bad', '', '', '', '']
['/0_1/api.php', 'op', 'map', 'maptype', '1', 'city', 'test', 'script', 'alert%28/42873/%29', '/script', '', '']

我们以十分严格的置信度来运行,试图找到关联关系接近100%的情况:


L, suppData = Apriori(myDat, 0.1)
rules = generateRules(L, suppData, minConf=0.99)

有趣的现象出现了:


frozenset(['//', '1']) --> frozenset(['', 'alert']) conf: 1.0
frozenset(['1', 'script']) --> frozenset(['', '/script']) conf: 1.0
frozenset(['a', 'c']) --> frozenset(['', 'm']) conf: 1.0
frozenset(['1', '/', 'script']) --> frozenset(['', '/script']) conf: 1.0
frozenset(['1', 'alert', 'script']) --> frozenset(['', '/script']) conf: 1.0
frozenset(['alert', '/', 'script']) --> frozenset(['', '/script']) conf: 0.997416020672
frozenset(['1', 'alert', '/', 'script']) --> frozenset(['', '/script']) conf: 1.0

有些结果容易理解,比如'script'和'1'、'alert'出现的话,会100%地导致'/script'。有些结果匪夷所思,比如'a'和'c'出现的话,会100%地导致'm'。

我们进一步降低门槛,将支持度也下降到0.001,这意味着即使对应的关联关系出现的概率只有千分之一,只要它对应的是强关联,置信度超过0.99,我们也认为这是一种有价值的关联:


L, suppData = Apriori(myDat, 0.001)
rules = generateRules(L, suppData, minConf=0.99)

这个学习过程会比较慢,我们选取了部分结果:


frozenset(['version']) --> frozenset(['', 'base64', '0FEBF34C4A2EBF825F60025D6C0576F2', 'signMsg', 'text/html', 'object', 'PHNjcmlwdD5hbGVydCg0Mjg3Myk8L3NjcmlwdD4', 'data']) conf: 1.0
frozenset(['signMsg']) --> frozenset(['', 'object', '0FEBF34C4A2EBF825F60025D6C0576F2', 'version', 'text/html', 'base64', 'PHNjcmlwdD5hbGVydCg0Mjg3Myk8L3NjcmlwdD4', 'data']) conf: 1.0
frozenset(['0FEBF34C4A2EBF825F60025D6C0576F2']) --> frozenset(['', 'object', 'signMsg', 'text/html', 'base64', 'PHNjcmlwdD5hbGVydCg0Mjg3Myk8L3NjcmlwdD4', 'version', 'data']) conf: 1.0

我们通过关联挖掘识别一种潜在的关联关系:'object''base64''data''text/html'。

通过分析20万条XSS攻击样本数据,完全通过机器学习的方式挖掘潜在的关联关系,得到的结果举例如下。

'object''base64''data''text/html'对应举例:


/0/252/admin/receive.php?signMsg=0FEBF34C4A2EBF825F60025D6C0576F2&version=%3Cobject%20data=data:text/html;base64,PHNjcmlwdD5hbGVydCg0Mjg3Myk8L3NjcmlwdD4=%3E

alert script 1对应举例:


/0/252/include/dialog/select_media.php?adminDirHand=%22/%3E%3C/script%3E%3Cscript%3Ealert(1);%3C/script%3E

script prompt对应举例:


/0_1/?callback=%3Cscript%3Eprompt(42873)%3C/script%3E

script svg onload alert对应举例:


/commonDetail.asp?infotype=1"'></textarea></script><svg onload=alert `43873`>&id=461

textarea autofocus onfocus alert对应举例:


/index.php?siteid=1&a=sg"'></textarea></script><textarea autofocus onfocus=alert(2014)>&nszixunid=291&m=nszixun

src javascript iframe对应举例:


/%22/e/?xss_test%3Ciframe%20src=javascript:this[%22%5Cx61%5Cx6c%5Cx65%5Cx72%5Cx74%22](%2242873%22)%3E

style expression alert对应举例:


/144/user.php?back_act=http://127.0.0.1%22style=x:expression(alert(42873))%3E