ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

《Web安全之机器学习入门》笔记:第十二章 12.3 隐式马尔可夫算法识别XSS攻击(一)

2022-02-03 20:01:49  阅读:154  来源: 互联网

标签:__ Web 10000 泛化 XSS 样本 12.3 xss ax


本小节通过使用隐式马尔可夫来识别XSS攻击,通过xss白名训练马尔可夫模型,然后用马尔可夫模型测试xss攻击黑名单,这样。单示例隐式马尔可夫在网络安全中的使用。

1、参数建模

对于XSS攻击,首先我们需要对数据进行泛化,比如:

  • [a-zA-Z]泛化为A
  • [0-9]泛化为N
  • [-_]泛化为C
  • 其他字符泛化为T

      根据如上原则admin123泛化为AAAAANNN,root泛化为AAAA。

      如下图所示,url参数wjq_2014为例,对应泛化为AAACNNNN,隐藏序列为S1 S1 S1 S2 S3 S3 S3 S3。

        正常http请求中参数的取值范围是固定的,比如userid字段有字母和特殊字符'-_'组成。以uid为例,可以对其泛化通过三阶段HMM来判断其观察序列,隐藏序列即在S1-S4之间循环转化,这个概率成为转移概率矩阵。同时四个状态都有确定的概率,以观察序列中的A、C、N、T共4个状态展现,这个概率即为发射概率矩阵。HMM建模就是通过学习样本,生成两个矩阵的过程。

  

2、数据处理与特征提取

训练样本即为白名单,可以选择'./good-xss-10000.txt'文件即可,我们来看一下白样本的内容:

源码如下 

    X = [[0]]
    X_lens = [1]

    with open(filename, encoding='utf-8') as f:
        for line in f:
            line=line.strip('\n')
            line=parse.unquote(line)
            vers = etl(line)
            X=np.concatenate( [X,vers])
            X_lens.append(len(vers))

对于样本,首先我们根据第一点提到的泛化规则,需要对数据进行泛化,这里选取的原则如下:

  • [a-zA-Z]泛化为A
  • [0-9]泛化为N
  • [-_]泛化为C
  • 其他字符泛化为T

代码如下所示

def etl(str):
    vers=[]
    for i, c in enumerate(str):
        c=c.lower()
        if   ord(c) >= ord('a') and  ord(c) <= ord('z'):
            vers.append([ord('A')])
        elif ord(c) >= ord('0') and  ord(c) <= ord('9'):
            vers.append([ord('N')])
        elif c in SEN:
            vers.append([ord('C')])
        else:
            vers.append([ord('T')])
    return np.array(vers)

3、训练模型

这里选择三阶段HMM训练白样本

    remodel = hmm.GaussianHMM(n_components=3, covariance_type="full", n_iter=100)
    remodel.fit(X,X_lens)

4、模型验证

(1)白样本测试

这里基于白样本特征,采用与训练相同的方法

    x = []
    y = []
    with open(filename, encoding='utf-8') as f:
        for line in f:
            line=line.strip('\n')
            line=parse.unquote(line)
            vers = etl(line)
            pro = remodel.score(vers)
            x.append(len(vers))
            y.append(pro)

    return x,y

(2)黑样本测试

接下来看一下黑样本’xss-10000.txt’,打开文件查看下具体内容

为了避免中文等字符的干扰,ASCII大于127或者小于32的可以不处理直接跳过

SEN=['<','>',',',':','\'','/',';','"','{','}','(',')']

def ischeck(str):
    if re.match(r'^(http)',str):
        return False
    for i, c in enumerate(str):
        # 排除中文干扰 只处理127以内的字符
        if ord(c) > 127 or ord(c) < 31:
            return False
        if c in SEN:
            return True

    return False

从每条黑样本中提取url参数,通过python接口解决url编码、参数抽取等问题,验证代码如下: 

    x = []
    y = []
    with open(filename, encoding='utf-8') as f:
        for line in f:
            # 切割参数
            result = parse.urlparse(line)
            # url解码
            query = parse.unquote(result.query)
            params = parse.parse_qsl(query, True)
            for k, v in params:
                if ischeck(v) and len(v) >=N :
                    vers = etl(v)
                    pro = remodel.score(vers)
                    x.append(len(vers))
                    y.append(pro)

    return x,y

5、基础函数完整代码

#-*- coding:utf-8 –*-
from urllib import parse
import re
from hmmlearn import hmm
import numpy as np
import matplotlib.pyplot as plt

import joblib
#处理参数值的最小长度
MIN_LEN=6

#其他字符
SEN=['<','>',',',':','\'','/',';','"','{','}','(',')']

def ischeck(str):
    if re.match(r'^(http)',str):
        return False
    for i, c in enumerate(str):
        # 排除中文干扰 只处理127以内的字符
        if ord(c) > 127 or ord(c) < 31:
            return False
        if c in SEN:
            return True

    return False

def etl(str):
    vers=[]
    for i, c in enumerate(str):
        c=c.lower()
        if   ord(c) >= ord('a') and  ord(c) <= ord('z'):
            vers.append([ord('A')])
        elif ord(c) >= ord('0') and  ord(c) <= ord('9'):
            vers.append([ord('N')])
        elif c in SEN:
            vers.append([ord('C')])
        else:
            vers.append([ord('T')])
    #print(vers)
    return np.array(vers)

def train(filename):
    X = [[0]]
    X_lens = [1]

    with open(filename, encoding='utf-8') as f:
        for line in f:
            line=line.strip('\n')
            line=parse.unquote(line)
            vers = etl(line)
            X=np.concatenate( [X,vers])
            X_lens.append(len(vers))

    remodel = hmm.GaussianHMM(n_components=3, covariance_type="full", n_iter=100)
    remodel.fit(X,X_lens)
    joblib.dump(remodel, "xss-train1.pkl")

    return remodel

def test_normal(filename):
    remodel = joblib.load("xss-train1.pkl")
    x = []
    y = []
    with open(filename, encoding='utf-8') as f:
        for line in f:
            line=line.strip('\n')
            line=parse.unquote(line)
            vers = etl(line)
            pro = remodel.score(vers)
            x.append(len(vers))
            y.append(pro)

    return x,y

def test(filename):
    remodel = joblib.load("xss-train1.pkl")
    x = []
    y = []
    with open(filename, encoding='utf-8') as f:
        for line in f:
            # 切割参数
            result = parse.urlparse(line)
            # url解码
            query = parse.unquote(result.query)
            params = parse.parse_qsl(query, True)
            for k, v in params:
                #print('k:',k,'v:',v,'line:',line)
                if ischeck(v) and len(v) >=MIN_LEN :
                    vers = etl(v)
                    pro = remodel.score(vers)
                    x.append(len(vers))
                    y.append(pro)

    return x,y

6、测试对比

        作者配套源码乱七八糟,很多内容与书上写的内容都不一样,包括函数调用参数也没有指明(比如训练样本是哪个文件、测试样本是哪个文件),这部分包括得分pro与阈值T的值设定(书上说10,但是源码-200),也没有写明白,实验结果与书上也不一致。

(1)黑样本测试方法

       这里我使用实验数据,图示对比使用test函数进行对比 测试均使用黑样本测试函数,代码如下

if __name__ == '__main__':
    train('./good-xss-10000.txt')

    x1,y1=test('./good-xss-10000.txt')
    x2,y2=test('./xss-10000.txt')

    fig,ax=plt.subplots()
    ax.set_xlabel('Line Length')
    ax.set_ylabel('HMM Score')
    ax.scatter(x2, y2, color='g', label="xss",marker='v')
    ax.scatter(x1, y1, color='r', label="good",marker='*')
    ax.legend(loc='best')
    plt.show()

白样本10000,黑样本10000个 

11 10100

运行结果如下:

        这是因为绝大多数白样本在parse.parse_qsl函数和ischeck(v) and len(v) >=MIN_LEN

处理后,得到的k和v基本上都是[],这种黑白样本之间的差别,使得大多数白样本使用test函数验证时,基本上都被过滤掉了,一万个就剩下11个左右,约剩下千分之一。

        刚刚使用的是各10000个黑白样本进行测试,这里选择各200000个黑白样本再次测试。

if __name__ == '__main__':
    train('./good-xss-10000.txt')
    x1,y1=test('../data/good-xss-200000.txt')
    x2,y2=test('../data/xss-200000.txt')
    print(len(y1), len(y2))
    fig,ax=plt.subplots()
    ax.set_xlabel('Line Length')
    ax.set_ylabel('HMM Score')
    ax.scatter(x2, y2, color='g', label="xss",marker='v')
    ax.scatter(x1, y1, color='r', label="good",marker='*')
    ax.legend(loc='best')
    plt.show()

如下所示,这20w的白样本和20w的黑样本测试结果中,白样本没过滤的仅128个,比例约千分之一。而黑样本20w也被过滤剩下14752个了,这也侧面说明这种方式不太靠谱。

128 14752

从图示来看,黑样本和没过滤掉的白样本特征也差不太多 

(2)白样本测试对比

       这里我使用实验数据,图示对比使用test_normal函数进行对比 测试均使用和训练相同的白样本测试函数,代码如下

f __name__ == '__main__':
    train('./good-xss-10000.txt')

    x1,y1=test_normal('./good-xss-10000.txt')
    x2,y2=test_normal('./xss-10000.txt')
  
    fig,ax=plt.subplots()
    ax.set_xlabel('Line Length')
    ax.set_ylabel('HMM Score')
    ax.scatter(x2, y2, color='g', label="xss",marker='v')
    ax.scatter(x1, y1, color='r', label="good",marker='*')
    ax.legend(loc='best')
    plt.show()

白样本10000,黑样本10000个 

10000 10000

8.黑白样本测试对比3

if __name__ == '__main__':
    train('./good-xss-10000.txt')

    x1,y1=test_normal('./good-xss-10000.txt')
    x2,y2=test('./xss-10000.txt')
   
    fig,ax=plt.subplots()
    ax.set_xlabel('Line Length')
    ax.set_ylabel('HMM Score')
    ax.scatter(x2, y2, color='g', label="xss",marker='v')
    ax.scatter(x1, y1, color='r', label="good",marker='*')
    ax.legend(loc='best')
    plt.show()

白样本10000,黑样本10100个 

10000 10100

本小节由于实验效果不好,作者配套源码也比较乱,资料不多,调试代码很久,主要是HMM识别效果不算上佳,但是这本书的读书目的也不是为了学完后效果一定很好。尤其是数据集、源码与书也不太一致,学习到基本的方用法即可。

后续如果有深刻的理解,再补充修改这篇笔记。

标签:__,Web,10000,泛化,XSS,样本,12.3,xss,ax
来源: https://blog.csdn.net/mooyuan/article/details/122768148

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有