基于机器学习的WEB异常检测

使用机器学习方法检测SQL注入,往小方面说是能够识别出SQL注入流量,往大方面说是检测WEB异常流量,能够检测SQL注入、XSS、恶意POC等异常流量,完成WAF的功能。

一、背景

使用机器学习方法检测SQL注入,往小方面说是能够识别出SQL注入流量,往大方面说是检测WEB异常流量,能够检测SQL注入、XSS、恶意POC等异常流量,完成WAF的功能。

传统web入侵检测技术通过维护规则集对入侵访问进行拦截。一方面,硬规则在灵活的黑客面前,很容易被绕过,且基于以往知识的规则集难以应对0day攻击,规则写的太宽泛易误杀,写的太细易绕过。

图1 黑产高价收购WAF绕过方式,完全绕过的价格可达到一万+

 

另一方面,攻防对抗水涨船高,防守方规则的构造和维护门槛高、成本大。规则库维护困难,人员交接工作,甚至时间一长,原作者都很难理解当初写的规则,一旦有误报发生,上线修改都很困难。

基于机器学习技术的新一代web入侵检测技术有望弥补传统规则集方法的不足,为web对抗的防守端带来新的发展和突破。机器学习方法能够基于大量数据进行自动化学习和训练,已经在图像、语音、自然语言处理等方面广泛应用。

然而,机器学习应用于web入侵检测也存在挑战,其中最大的困难就是标签数据的缺乏。尽管有大量的正常访问流量数据,但web入侵样本稀少,且变化多样,对模型的学习和训练造成困难。

目前大多数web入侵检测都是基于无监督的方法,针对大量正常日志建立模型,而与正常流量不符的则被识别为异常。这个思路与拦截规则的构造恰恰相反。拦截规则意在识别入侵行为,因而需要在对抗中“随机应变”;而基于模型的方法旨在建模正常流量,在对抗中“以不变应万变”,且更难被绕过。

二、技术思路

机器学习模型较为重要的是收集数据和特征工程,“特征工程”是机器模型中最重要的一部分,往往依赖于专家的“直觉”和专业领域经验,机器学习有句话经常被提起,“特征工程决定了现有数据的预测能力上限,好的模型能逼近这个上限”,所以机器学习的价值体现在提炼出传统行业的数据特征,并用最合适的算法优化提升目前的水平。

目前建立模型主要有以下几种思路:

1.基于数据统计的模型

基于统计学习的web异常检测,通常需要对正常流量进行数值化的特征提取和分析。特征例如,URL参数个数、参数值长度的均值和方差、参数字符分布、URL的访问频率等等。接着,通过对大量样本进行特征分布统计,建立数学模型,进而通过统计学方法进行异常检测。

2.基于文本分析的机器学习模型

可以借鉴NLP中的一些方法思路,进行文本分析建模。

1)基于隐马尔科夫模型(HMM)的参数值异常检测。

2)基于TF-IDF的异常检测

本文使用此思路

  1. 先取得URL里的关键词列表
  2. 用 scikit learn的 TfidfVectorizer函数把每个URL里的关键词做TF-IDF得到向量化的特征
  3. 用 LogisticRegression 模型训练并进行评价。

3)基于词法分析和语法分析

在BlackHat2012会议中提出的libinjection使用了词法分析,这种方法应用的代表是长亭科技的SQLChop,现在已经整合到雷池Web应用防火墙

4)基于色谱样熵分析(Chromatography-Like Entropy Analysis)

比较另辟蹊径的方法,通过信息论中的熵值,提取文本特征

3.基于单分类模型

由于web入侵黑样本稀少,传统监督学习方法难以训练。基于白样本的异常检测,可以通过非监督或单分类模型进行样本学习,构造能够充分表达白样本的最小模型作为Profile,实现异常检测。

4.基于聚类模型

通常正常流量是大量重复性存在的,而入侵行为则极为稀少。因此,通过web访问的聚类分析,可以识别大量正常行为之外,小搓的异常行为,进行入侵发现。

三、建模与测试

首先对数据进行预处理

 

import numpy as np

import urllib



# 数据预处理

def getQueryFromFile(filename='badqueries.txt'):

directory = "C:\\fwaf"

filepath = directory + "\\" + filename

data = open(filepath,'r').readlines()

data = list(set(data))

queries = set()

for d in data:

d = d.strip()

try:

d = str(urllib.unquote(d).decode('utf8'))   #converting url encoded data to simple string

queries.add(d)

except:

print 'decode ' + d + ' error'

return list(queries)



badQueries = getQueryFromFile('badqueries.txt')

tempvalidQueries = getQueryFromFile('goodqueries.txt')

tempAllQueries = badQueries + tempvalidQueries



ybad = np.ones(len(badQueries))

ygood = np.zeros(len(tempvalidQueries))

y = np.hstack((ybad, ygood))



queries = tempAllQueries

构造3-gram特征,使用TF-IDF提取URL文本特征,并进行文本向量化

#tokenizer function, this will make 3 grams of each query

#构造3-gram特征

def getNGrams(query):

tempQuery = str(query)

ngrams = []

for i in range(0,len(tempQuery)-3):

ngrams.append(tempQuery[i:i+3])

return ngrams



from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.cross_validation import train_test_split



#converting data to vectors

#TF-IDF

vectorizer = TfidfVectorizer(tokenizer=getNGrams)

X = vectorizer.fit_transform(queries)

 

将这个数据集分成训练数据集和测试数据集两部分,然后用逻辑回归算法来训练。但此处先进行TD-IDF处理后再进行数据集分割训练,会导致数据泄露问题,使分数虚高,丢失了许多数据原有的信息,而且使用原有的训练集作为测试集,也会导致分数虚高。所以此算法的缺点在于缺乏泛化能力,对没有训练过的SQL注入语句或者web异常语句检测能力较低,一种解决方法是扩大训练集的样本数,尽可能多的覆盖常用注入手法。或者使用其他算法提取特征,比如在BlackHat2012会议中提出的libinjection使用了词法分析。此处得到的score是0.997874451441。

 

#splitting data

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)



from sklearn.linear_model import LogisticRegression

lgs = LogisticRegression()

lgs.fit(X_train, y_train) #training our model

print(lgs.score(X_test, y_test))  #checking the accuracy

最后测试一些例子

X_predict = [

'AND 1=1',

'ORDER BY 1-- ',

'<script>alert(xss)</script>/',

'and (select substring(@@version,1,1))=\'X\'',

'www.baidu.com',

'<?php @eval($_POST[\'c\']);?>'

]

X_vecpredict = vectorizer.transform(X_predict)

y_Predict = lgs.predict(X_vecpredict)

#printing predicted values

mapvalues={1:'Bad ',

0:'Good'}

for i in range(len(X_predict)):

print mapvalues[y_Predict[i]]+':'+X_predict[i]

 

Bad :AND 1=1结果是

Bad :ORDER BY 1--

Bad :<script>alert(xss)</script>/

Bad :and (select substring(@@version,1,1))='X'

Good:www.baidu.com

Bad :<?php @eval($_POST['c']);?>

 

四、总结与展望

本文介绍了机器学习用于web异常检测的几个思路,并使用文本分析方法3-gram 和TD-IDF提取特征,然后使用LogisticRegression算法训练。

web流量异常检测只是web入侵检测中的一环,用于从海量日志中捞出少量的“可疑”行为,但是这个“少量”还是存在大量误报,只能用于检测,还远远不能用于WAF直接拦截。一个完备的web入侵检测系统,还需要在此基础上进行入侵行为识别,以及降低误报等环节。

在网络安全中,机器学习还可以用来:

1.C&C随机域名检测

2.恶意URL检测(可以参考新加坡大学的一个团队综述https://arxiv.org/abs/1701.07179

3.UGC违规图片与评论 机器学习在安全领域的广泛应用还有很长的路要走。

 

 

参考链接:

[1]https://zhuanlan.zhihu.com/p/25139556

[2]https://github.com/faizann24/Fwaf-Machine-Learning-driven-Web-Application-Firewall

Spread the word. Share this post!

Meet The Author

Leave Comment