(Isolation Forest无监督)这个算法是随机森林的推广。

iTree树构造:随机选一个属性,再随机选该特征的一个值,对样本进行二叉划分,重复以上操作。

iTree构建好了后,就可以对数据进行预测啦,预测的过程就是把测试记录在iTree上走一下,看测试记录落在哪个叶子节点。iTree能有效检测异常的假设是:异常点一般都是非常稀有的,在iTree中会很快被划分到叶子节点,因此可以用叶子节点到根节点的路径h(x)长度来判断一条记录x是否是异常点。

越接近1表示是异常点的可能性高;

越接近0表示是正常点的可能性比较高;

如果大部分的训练样本的s(x,n)都接近于0.5,整个数据没有明显的异常。

Iforest构造:随机采样抽取一部分数据构造每一棵树,保证树的差异性。

与随机森林的区别:

1、随机森林需要采样集样本个数等于训练集个数,IForest也是随机采样,但样本个数小于训练集个数。因为我们的目的是异常点检测,只需要部分的样本我们一般就可以将异常点区别出来了

2、IForest采用随机选择一个划分特征,对划分特征随机选择一个划分阈值,RF划分需要使用信息增益或者信息增益率作为选择属性和阈值的依据。

URL异常检测(IForest)

数据源在这里

正常请求的数据

/103886/

/rcanimal/

/458010b88d9ce/

/cclogovs/

/using-localization/

/121006_dakotacwpressconf/

恶意请求的数据

/top.php?stuff='uname >q36497765 #

/h21y8w52.nsf?

/ca000001.pl?action=showcart&hop=">&path=acatalog/

/scripts/edit_image.php?dn=1&userfile=/etc/passwd&userfile_name= ;id;

这里就需要有文本向量化的知识,调用sklearn中CountVectorizer

from sklearn.feature_extraction.text import CountVectorizer
vectorizer=CountVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
print(vectorizer.fit_transform(corpus))
'''文本的序号,词的序号,词频'''
(0, 16) 1
(0, 3) 1
(0, 15) 2
print(vectorizer.get_feature_names())#I是停用词不统计,打印分割好的词向量
['and', 'apple', 'car', 'china', 'come', 'in', 'is', 'love', 'papers', 'polupar', 'science', 'some', 'tea', 'the', 'this', 'to', 'travel', 'work', 'write']
print(vectorizer.fit_transform(corpus).toarray()) //转换成矩阵打印,四行代表四句话,列上的数字代表出现频率,统计词频后的19维特征做为文本分类的输入



TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

TF(Term Frequency)词频,某个词在文章中出现的次数或频率。

IDF(inverse document frequency)逆文档频率。一个词语“权重”的度量,一个词越常见,IDF越低。

IDF计算公式:



N代表语料库中文本的总数,而N(x)代表语料库中包含词x的文本总数,有对应的词库

from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"] vectorizer=CountVectorizer() transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
print(tfidf)

得到(文本的序号,词的序号,TF-IDF值)



这块知识的相关参考文章:

https://www.cnblogs.com/pinard/p/6693230.html

https://www.cnblogs.com/pinard/p/6693230.html

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import IsolationForest
from sklearn.metrics import confusion_matrix
import itertools
from sklearn.metrics import accuracy_score
#data
good_data=pd.read_csv('goodqueries.txt',names=['url'])
good_data['label']=0
data=good_data
data.head()
##feature
vectorizer = TfidfVectorizer(min_df = 0.0, analyzer="char", sublinear_tf=True, ngram_range=(1,3)) #converting data to vectors
X = vectorizer.fit_transform(data['url'].values.astype('U')) #TF-IDF向量化



分为训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, data['label'].values, test_size=0.2, random_state=42) #splitting data
print(X_train) #y_test标签都设置为0表示都是正常数据集
clf=IsolationForest()
clf.fit(X_train)
y_pre = clf.predict(X_test)
ny_pre = np.asarray(y_pre)
ny_pre[ny_pre==1] = 0 ##最后输出1为正常,-1为异常 ==>0是正常,1是异常点
ny_pre[ny_pre==-1] = 1 ny_test = np.asarray(y_test) #y_test都是0因为只导入了goodqueries.txt数据集
accuracy_score(ny_test,ny_pre)

URL异常检测(LSTM)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/6/4 9:25
# @Author : afanti import sys
import os
import json
import pandas as pd
import numpy
import optparse
from keras.callbacks import TensorBoard
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence
from keras.preprocessing.text import Tokenizer
from collections import OrderedDict
from keras.models import load_model
from keras.models import model_from_json
def model():
dataframe = pd.read_csv('goodqueries.txt', names=['url'])
dataframe['label']=0
# dataframe.head()
dataframe1 = pd.read_csv('badqueries.txt', names=['url'])
dataframe1['label']=1
# dataframe1.head()
dataset=pd.concat([dataframe,dataframe1])
dataset=dataset.sample(frac=1).values
X = dataset[:,0]
Y = dataset[:,1]
for i in range(len(X)):
if type(X[i])==float:
X[i]=str(X[i])
tokenizer = Tokenizer(filters='\t\n', char_level=True)
tokenizer.fit_on_texts(X)
X = tokenizer.texts_to_sequences(X) #序列的列表,列表中每个序列对应于一段输入文本
word_dict_file = 'build/word-dictionary.json' if not os.path.exists(os.path.dirname(word_dict_file)):
os.makedirs(os.path.dirname(word_dict_file)) with open(word_dict_file, 'w',encoding='utf-8') as outfile:
json.dump(tokenizer.word_index, outfile, ensure_ascii=False) #将单词(字符串)映射为它们的排名或者索引 num_words = len(tokenizer.word_index)+1 #174 max_log_length = 100
train_size = int(len(dataset) * .75) # padding
X_processed = sequence.pad_sequences(X, maxlen=max_log_length)
# 划分样本集
X_train, X_test = X_processed[0:train_size], X_processed[train_size:len(X_processed)]
Y_train, Y_test = Y[0:train_size], Y[train_size:len(Y)] model = Sequential()
model.add(Embedding(num_words, 32, input_length=max_log_length))
model.add(Dropout(0.5))
model.add(LSTM(64, recurrent_dropout=0.5))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X_train, Y_train, validation_split=0.25, epochs=3, batch_size=128)
# Evaluate model
score, acc = model.evaluate(X_test, Y_test, verbose=1, batch_size=128)
print("Model Accuracy: {:0.2f}%".format(acc * 100))
# Save model
model.save_weights('securitai-lstm-weights.h5')
model.save('securitai-lstm-model.h5')
with open('securitai-lstm-model.json', 'w') as outfile:
outfile.write(model.to_json()) df_black = pd.read_csv('badqueries.txt', names=['url'], nrows=20000)
df_black['label'] = 1
X_waf = df_black['url'].values.astype('str')
Y_waf = df_black['label'].values.astype('str')
X_sequences = tokenizer.texts_to_sequences(X_waf)
X_processed = sequence.pad_sequences(X_sequences, maxlen=max_log_length)
score, acc = model.evaluate(X_processed, Y_waf, verbose=1, batch_size=128)
print("Model Accuracy: {:0.2f}%".format(acc * 100))

这里用到了keras的Tokenizer分词器

from keras.preprocessing.text import Tokenizer
import keras
tokenizer = Tokenizer(char_level=True)
text = ["/javascript/nets.png", "/javascript/legacy.swf"]
tokenizer.fit_on_texts(text)
# tokenizer.word_counts #[[2, 5]] False
tokenizer.texts_to_sequences(["nets swf"])
tokenizer.word_index

当char_level=True时,会按char-level将字符频度进行统计,如下图a出现次数最多,

输出结果,nets swf输出在上面图查找:

#[[11, 12, 6, 3, 3, 17, 18]] True 语义没了

输入数据做了padding操作,这里补成了128维

# padding
X_processed = sequence.pad_sequences(X, maxlen=max_log_length)



相关Tokenizer操作看这里:

https://blog.csdn.net/wcy23580/article/details/84885734

https://blog.csdn.net/wcy23580/article/details/84957471

训练模型前Embedding层做一次word embedding,单词嵌入是使用密集的矢量表示来表示单词和文档的一类方法。output_dim这是嵌入单词的向量空间的大小,input_dim这是文本数据中词汇的取值可能数这里是173,input_length:输入文档都由1000个字组成,那么input_length就是1000.

下面我们定义一个词汇表为173的嵌入层(例如从1到173的整数编码的字,包括1到173),一个32维的向量空间,其中将嵌入单词,以及输入文档,每个单词有128个字符

嵌入层自带学习的权重,如果将模型保存到文件中,则将包含嵌入图层的权重。

model = Sequential()
model.add(Embedding(input_dim=num_words, output_dim=32, input_length=max_log_length))
model.add(Dropout(0.5))
model.add(LSTM(64, recurrent_dropout=0.5))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

总的来说就是char-level+统计向量化+词嵌入+神经网络LSTM

相关参考在这里:https://juejin.im/entry/5acc23f26fb9a028d1416bb3

URL异常检测(LR)

导入数据

# -*- coding:utf8 -*-
from sklearn.externals import joblib
from sklearn.feature_extraction.text import TfidfVectorizer
import os
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
import urllib.parse
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt def loadFile(name):
directory = str(os.getcwd())
filepath = os.path.join(directory, name)
with open(filepath,'r',encoding="utf8") as f:
data = f.readlines()
data = list(set(data))
result = []
for d in data:
d = str(urllib.parse.unquote(d)) #converting url encoded data to simple string
result.append(d)
return result badQueries = loadFile('badqueries.txt')
validQueries = loadFile('goodqueries.txt') badQueries = list(set(badQueries))
validQueries = list(set(validQueries))
allQueries = badQueries + validQueries
yBad = [1 for i in range(0, len(badQueries))] #labels, 1 for malicious and 0 for clean
yGood = [0 for i in range(0, len(validQueries))]
y = yBad + yGood
queries = allQueries

划分测试集训练集

X_train, X_test, y_train, y_test = train_test_split(queries, y, test_size=0.2, random_state=42) #splitting data
badCount = len(badQueries) #44532
validCount = len(validQueries) #1265974

Pipeline可以将许多算法模型串联起来,比如将特征提取、归一化、分类组织在一起形成一个典型的机器学习问题工作流。

tfidf TfidfVectorizer类参数analyzer定义特征为词(word)或n-gram字符。

sublinear_tf 应用线性缩放TF,例如,使用1+log(tf)覆盖tf。

ngram_range要提取的n-gram的n-values的下限和上限范围class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,而类型1的权重为10%。

pipe_lr = Pipeline([('tfidf', TfidfVectorizer(min_df = 0.0, analyzer="char", sublinear_tf=True, ngram_range=(1,3))),
('clf', LogisticRegression(class_weight="balanced"))
])
pipe_lr.fit(X_train, y_train) predicted = pipe_lr.predict(X_test)
predicted=list(predicted)
fpr, tpr, _ = metrics.roc_curve(y_test, (pipe_lr.predict_proba(X_test)[:, 1]))
auc = metrics.auc(fpr, tpr) print("Bad samples: %d" % badCount)
print("Good samples: %d" % validCount)
print("Baseline Constant negative: %.6f" % (validCount / (validCount + badCount)))
print("------------")
print("Accuracy: %f" % pipe_lr.score(X_test, y_test)) #checking the accuracy
print("Precision: %f" % metrics.precision_score(y_test, predicted))
print("Recall: %f" % metrics.recall_score(y_test, predicted))
print("F1-Score: %f" % metrics.f1_score(y_test, predicted))
print("AUC: %f" % auc)
joblib.dump(pipe_lr,"lr.pkl")



测试

from urllib.parse import urlparse
from sklearn.externals import joblib
lr=joblib.load("lr.pkl")
def url(url):
try:
parsed_url=urlparse(url)
paths=parsed_url.path+parsed_url.query
result=lr.predict([paths]) if result==[0]:
return False
else:
return True
except Exception as err:
#print(str(err))
pass result=url('http://br-ofertasimperdiveis.epizy.com/examples/jsp/cal/feedsplitter.php?format=../../../../../../../../../../etc/passwd\x00&debug=1')
result1=url('http://br-ofertasimperdiveis.epizy.com/produto.php?linkcompleto=iphone-6-plus-apple-64gb-cinza')
result2=url('http://br-ofertasimperdiveis.epizy.com/?q=select * from x')

char-level/word-level+n-gram+tfidf一把梭下来,可以解决很多问题了,包括较长文本和短文本,而安全中的很多关键信息都可以看成是长文本和短文本,比如域名请求,恶意代码,恶意文件。

https://www.freebuf.com/articles/network/131279.html

https://github.com/exp-db/AI-Driven-WAF/blob/master/waf.py

https://www.kdnuggets.com/2017/02/machine-learning-driven-firewall.html

N-Gram模型理解

总参考连接:

https://xz.aliyun.com/t/5288#toc-4

# URL异常检测的更多相关文章

  1. 基于机器学习的web异常检测

    基于机器学习的web异常检测 Web防火墙是信息安全的第一道防线.随着网络技术的快速更新,新的黑客技术也层出不穷,为传统规则防火墙带来了挑战.传统web入侵检测技术通过维护规则集对入侵访问进行拦截.一 ...

  2. 思科安全:加密流量威胁检测、加密流量威胁和恶意软件检测、识别无线干扰或威胁、Talos 情报源可加强对已知和新型威胁的防御、分布式安全异常检测

    思科DNA竞品比较工具 您的网络能够驱动数字化转型吗? 根据IDC调查,45%的受调研公司计划在未来两年内做好网络数字化的准备.查看数字化网络带来的结果和商业价值. 下载报告 思科 HPE 华为 Ar ...

  3. 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否

    基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...

  4. 利用KD树进行异常检测

    软件安全课程的一次实验,整理之后发出来共享. 什么是KD树 要说KD树,我们得先说一下什么是KNN算法. KNN是k-NearestNeighbor的简称,原理很简单:当你有一堆已经标注好的数据时,你 ...

  5. 5-Spark高级数据分析-第五章 基于K均值聚类的网络流量异常检测

    据我们所知,有‘已知的已知’,有些事,我们知道我们知道:我们也知道,有 ‘已知的未知’,也就是说,有些事,我们现在知道我们不知道.但是,同样存在‘不知的不知’——有些事,我们不知道我们不知道. 上一章 ...

  6. 异常检测算法--Isolation Forest

    南大周志华老师在2010年提出一个异常检测算法Isolation Forest,在工业界很实用,算法效果好,时间效率高,能有效处理高维数据和海量数据,这里对这个算法进行简要总结. iTree 提到森林 ...

  7. 机器学习:异常检测算法Seasonal Hybrid ESD及R语言实现

    Twritters的异常检测算法(Anomaly Detection)做的比较好,Seasonal Hybrid ESD算法是先用STL把序列分解,考察残差项.假定这一项符合正态分布,然后就可以用Ge ...

  8. Spark实战4:异常检测算法Scala语言

    异常检测原理是根据训练数据的高斯分布,计算均值和方差,若测试数据样本点带入高斯公式计算的概率低于某个阈值(0.1),判定为异常点. 1 创建数据集转化工具类,把csv数据集转化为RDD数据结构 imp ...

  9. Andrew Ng机器学习课程笔记--week9(上)(异常检测&推荐系统)

    本周内容较多,故分为上下两篇文章. 一.内容概要 1. Anomaly Detection Density Estimation Problem Motivation Gaussian Distrib ...

随机推荐

  1. osg机械臂模拟

    实现自由旋转  

  2. Flutter中的事件广播event_bus的基本使用

    官方包参考地址: https://pub.dev/packages/event_bus https://github.com/marcojakob/dart-event-bus 1.pubspec.y ...

  3. npm教程、脚手架

    使用之前,我们先来掌握3个东西是用来干什么的. npm: Nodejs下的包管理器. webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资源的 ...

  4. spark中的cache和persist的区别

    在使用中一直知其然不知其所以然的地使用RDD.cache(),系统的学习之后发现还有一个与cache功能类似看起来冗余的persist 点进去一探究竟之后发现cache()是persist()的特例, ...

  5. (三)UML之类图关系

    泛化(generalization):表示is-a的关系,是对象之间耦合度最大的一种关系,子类继承父类的所有细节.直接使用语言中的继承表达.在类图中使用带三角箭头的实线表示,箭头从子类指向父类.如下图 ...

  6. Java中四个作用域的可见范围

    作用域 当前类 同一包 子孙类 其他包 public √ √ √ √ protected √ √ √ × friendly或default(即没有修饰符时的权限) √ √ × × private √ ...

  7. Win10使用Tex Live和VS Code和Latex Workshop插件编写Latex文档(未完成版本)

    首先取Tex Live官网下载安装包:https://www.tug.org/texlive/acquire-netinstall.html 我下载的是 http://mirror.ctan.org/ ...

  8. 【Leetcode_easy】617. Merge Two Binary Trees

    problem 617. Merge Two Binary Trees     参考 1. Leetcode_easy_617. Merge Two Binary Trees; 完    

  9. 《Fluid Engine Development》 学习笔记2-基础

    断断续续花了一个月,终于把这本书的一二两章啃了下来,理解流体模拟的理论似乎不难,无论是<Fluid Simulation for Computer Graphics>还是<计算流体力 ...

  10. 移动架构-IOC架构设计

    控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency Inject ...