首页 > 代码库 > 学点算法搞安全之HMM(下篇)

学点算法搞安全之HMM(下篇)

前言
  上篇我们介绍了HMM的基本原理以及常见的基于参数的异常检测实现,这次我们换个思路,把机器当一个刚入行的白帽子,我们训练他学会XSS的攻击语法,然后再让机器从访问日志中寻找符合攻击语法的疑似攻击日志。
技术分享
 技术分享
  通过词法分割,可以把攻击载荷序列化成观察序列,举例如下:
技术分享
技术分享
词集/词袋模型
  词集和词袋模型是机器学习中非常常用的一个数据处理模型,它们用于特征化字符串型数据。一般思路是将样本分词后,统计每个词的频率,即词频,根据需要选择全部或者部分词作为哈希表键值,并依次对该哈希表编号,这样就可以使用该哈希表对字符串进行编码。
  • 词集模型:单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个
  • 词袋模型:如果一个单词在文档中出现不止一次,并统计其出现的次数
本章使用词集模型即可。
假设存在如下数据集合:
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]]
首先生成词汇表:
1 vocabSet = set()
2 for doc in dataset:    
3      vocabSet |= set(doc)
4      vocabList = list(vocabSet)
根据词汇表生成词集:
1 # 词集模型
2 SOW = []
3 for doc in dataset:    
4      vec = [0]*len(vocabList)    
5      for i, word in enumerate(vocabList):        
6               if word in doc:            
7                        vec[i] = 1
8      SOW.append(doc)
  简化后的词集模型的核心代码如下:
1 fredist = nltk.FreqDist(tokens_list)  # 单文件词频
2 keys=fredist.keys()
3 keys=keys[:max] #只提取前N个频发使用的单词 其余泛化成0
4 for localkey in keys:  # 获取统计后的不重复词集
5    if localkey in wordbag.keys():  # 判断该词是否已在词集中
6        continue
7    else:
8        wordbag[localkey] = index_wordbag
9        index_wordbag += 1
数据处理与特征提取
  常见的XSS攻击载荷列举如下:
<script>alert(XSS)</script>
%3cscript%3ealert(XSS)%3c/script%3e
%22%3e%3cscript%3ealert(XSS)%3c/script%3e
<IMG SRC=http://www.mamicode.com/"javascript:alert(‘XSS‘);">
<IMG SRC=javascript:alert("XSS")>
<IMG SRC=javascript:alert(XSS)>      
<img src=http://www.mamicode.com/xss one rror=alert(1)>"color: #800000">"""><SCRIPT>alert("XSS")</SCRIPT>">
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
<IMG SRC="http://www.mamicode.com/jav ascript:alert(‘XSS‘);">
<IMG SRC="http://www.mamicode.com/jav ascript:alert(‘XSS‘);">
<BODY BACKGROUND="javascript:alert(‘XSS‘)">
<BODY onl oad=alert(‘XSS‘)>
  需要支持的词法切分原则为:
  ● 单双引号包含的内容
XSS
  ● http/https链接
http://xi.baidu.com/xss.js
  ● <>标签
<script><>标签开头
<BODY
  ● 属性标签
ONLOAD=<>标签结尾
>
  ● 函数体
"javascript:alert(‘XSS‘);"
  ● 字符数字标量
  代码实现举例如下:
 1 tokens_pattern = r‘‘‘(?x)
 2 "[^"]+"
 3 |http://\S+
 4 |</\w+>
 5 |<\w+>
 6 |<\w+
 7 |\w+=
 8 |>
 9 |\w+\([^<]+\) #函数 比如alert(String.fromCharCode(88,83,83))
10 |\w+
11 ‘‘‘
12 words=nltk.regexp_tokenize(line, tokens_pattern)
  另外,为了减少向量空间,需要把数字和字符以及超链接范化,具体原则为:
#数字常量替换成8
line, number = re.subn(r\d+, "8", line)
#ulr日换成http://u
line, number = re.subn(r(http|https)://[a-zA-Z0-9\.@&/#!#\?]+, "http://u", line)
#干掉注释
line, number = re.subn(r\/\*.?\*\/, "", line)
  范化后分词效果示例为:
#原始参数值:"><img src=http://www.mamicode.com/x one rror=prompt(0)>)
#分词后:
[>, <img, src=http://www.mamicode.com/, x, onerror=, prompt(8), >]
#原始参数值:<iframe src="x-javascript:alert(document.domain);"></iframe>)
#分词后:
[<iframe, src=http://www.mamicode.com/, "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=http://www.mamicode.com/x one rror=prompt(document.domain)>)
#分词后:
[<script>, alert(8), </script>, >, <img, src=http://www.mamicode.com/, x, onerror=, prompt(document.domain), >]
  结合词集模型,完整的流程举例如下:
 技术分享
训练模型
  将范化后的向量X以及对应的长度矩阵X_lens输入即可,需要X_lens的原因是参数样本的长度可能不一致,所以需要单独输入。
1 remodel = hmm.GaussianHMM(n_components=3, covariance_type="full", n_iter=100)
2 remodel.fit(X,X_lens)
验证模型
  整个系统运行过程如下:
技术分享
技术分享
  验证阶段利用训练出来的HMM模型,输入观察序列获取概率,从而判断观察序列的合法性,训练样本是1000条典型的XSS攻击日志,通过分词、计算词集,提炼出200个特征,全部样本就用这200个特征进行编码并序列化,使用20000条正常日志和20000条XSS攻击识别(类似JSFUCK这类编码的暂时不支持),准确率达到90%以上,其中验证环节的核心代码如下:
 1 with open(filename) as f:
 2    for line in f:
 3        line = line.strip(\n)
 4        line = urllib.unquote(line)
 5        h = HTMLParser.HTMLParser()
 6        line = h.unescape(line)
 7        if len(line) >= MIN_LEN:
 8            line, number = re.subn(r\d+, "8", line)
 9            line, number = re.subn(r(http|https)://[a-zA-Z0-9\.@&/#!#\?:]+, "http://u", line)
10            line, number = re.subn(r\/\*.?\*\/, "", line)
11            words = do_str(line)
12            vers = []
13            for word in words:
14                if word in wordbag.keys():
15                    vers.append([wordbag[word]])
16                else:
17                    vers.append([-1])
18            np_vers = np.array(vers)
19            pro = remodel.score(np_vers)
20            if pro >= T:
21                print  "SCORE:(%d) XSS_URL:(%s) " % (pro,line)

 

 
 
 
 
 

学点算法搞安全之HMM(下篇)