web攻击识别-机器学习

一次简单的机器学习实践,学了一些机器学习模型、文本处理、特征工程、超参数调优等,以及数据清理、特征提取、文本处理等处理大数据方法。

要求:对提供的训练集进行分析,通过特征工程、机器学习和深度学习等方法构建AI模型

由于之前没有机器学习的基础,因为本次实验参考了一些论文。一开始作为小白,是完全不懂这个要咋搞的,后来看了周志华的《机器学习》和《python大战机器学习》了解一下基础概念。像一些算法、模型的具体的原理其实了解一下大概就好放在代码里无非也就是一个函数的调用

数据处理

观察数据集,可以看到有6种不同攻击类型的数据集,以及1个测试集,里面的访问请求就是正常抓包获得的请求,包含浏览器类型、user_id等

按照流程,首先进行数据处理,第一步通过正则匹配获取url中请求的参数

1
2
3
4
def get_url_query(s):
li = re.split('[=&]', urlparse(s)[4])
return [li[i] for i in range(len(li)) if i % 2 == 1]
# https://example.com/page?name=John&age=25&city=NewYork"['John', '25', 'NewYork']

其次是将url解码,也就是将其中的特殊字符转化为%+数字的形式,略

还要匹配文件扩展名,也就是.后的字符(正则表达式学得不好)

1
return re.search(r'\.[a-z]+', x).group()

user-agent信息提取:

1
2
3
4
# user-agent信息提取
df['ua_short'] = df['user_agent'].apply(lambda x: x.split('/')[0]) # 斜杠分割后的第一个部分,也就是浏览器类型
df['ua_first'] = df['user_agent'].apply(lambda x: x.split(' ')[0]) # 浏览器或设备名称
eg: # Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36

用TF-IDF算法提取特征

在开始提取特征之前,首先还需要分析特征,这里由于给了6种不同类型的训练集,因此一开始我打算针对不同训练集分别进行特征提取
针对不同类型的Web攻击,可以提取以下特征进行训练集的构建:
比如针对SQL注入,可以提取SQL语句特征,检测SQL查询中的关键字和结构,如SELECT、INSERT等,针对XSS跨站脚本,可以提取HTML标签特征和HTTP头部特征等,如Content-Type、Set-Cookie等。

然鹅搞了一半觉得这样还是可能有考虑不到的地方….遂上网上找代码,发现网上的更简洁,一位大哥的思路是直接把数据集合并成一个,然后提取url查询参数、参数长度等共同特征,我心想原来如此,那我还搞个P啊,于是我也从简单的入手,直接6个数据集ctrl cv合并,然后代码一焯提取共同特征:

1
2
3
4
5
6
7

df['url_query'] = df['url_unquote'].apply(lambda x: get_url_query(x)) # 提取url里的查询参数
df['url_query_num'] = df['url_query'].apply(len) # 存储每个url里查询参数的个数
df['url_query_max_len'] = df['url_query'].apply(find_max_str_length) # 每个url查询参数的最大长度
df['url_query_len_std'] = df['url_query'].apply(find_str_length_std) # 查询参数的长度的变化程度(标准差)
df['url_path_len'] = df['url_path'].apply(len) # 路径的长度
df['url_path_num'] = df['url_path'].apply(lambda x: len(re.findall('/', x))) # url里的斜杠数量

然后就是提取特征了

1
2
3
4
5
6
7
8
9
10
11
12
13
def add_tfidf_feats(df, col, n_components=16): 
text = list(df[col].values)
tf = TfidfVectorizer(min_df=1,
analyzer='char_wb',
ngram_range=(1, 2), # 1-2的ngram特征: 允许长度1、2、3的字符序列
tf.fit(text) # 进行拟合
X = tf.transform(text) # 将tf转化为TF-IDF特征矩阵x
svd = TruncatedSVD(n_components=n_components) # 截断奇异值分解(高阶矩阵->低阶)
svd.fit(X)
X_svd = svd.transform(X)
for i in range(n_components):
df[f'{col}_tfidf_{i}'] = X_svd[:, i]
return df

创建一个TF-IDF对象 tf,然后给定参数,比如n_components用于指定截断奇异值分解后所保留的奇异值个数,也就是要将原始的 TF-IDF 特征矩阵降维到的维度数量,具体这块涉及算法

有些特征后续是8需要考虑的,比如’id’, ‘user_agent’, ‘url’, ‘body’, ‘url_unquote’, ‘url_query’, ‘url_path’, ‘label’这些

利用lightGBM开始训练

用lightGBM模型训练,起码要了解K折交叉验证对象的含义,才能选择参数填进去
“k折交叉验证基本思想是将原始数据集分成k个子集,其中一个子集被保留作为验证模型的数据,剩下的k-1个子集被用来训练模型。这个过程重复k次,每次选择不同的子集作为验证集,其余子集作为训练集。最终,通过对每次验证结果的平均值进行评估,得到最终的模型性能指标”

好,肥肠简单是不是,然后进入超参数调优环节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
learning_rate:学习率,控制每次迭代中模型参数更新的步长。较小的学习率可以提高模型在训练集上的稳定性,但可能需要更多的迭代次数才能达到最优解。
metric:评估指标,用于衡量模型的性能。在这里,使用了 multiclass,表示多分类问题,模型会输出每个类别的概率分布。
objective:优化目标,定义了模型的损失函数。在这里也是 multiclass,表示多分类问题。
num_classes:类别数量,指定了分类任务中的类别数量。
feature_fraction:特征采样比例,用于控制每次迭代中随机选择的特征比例。它可以有效地减少过拟合。
bagging_fraction:样本采样比例,用于控制每次迭代中随机选择的样本比例。也是为了减少过拟合。
bagging_freq:样本采样频率,指定了进行样本采样的频率。设置为2表示每两次迭代进行一次样本采样。
n_jobs:并行运行的作业数量。设置为-1表示使用所有可用的 CPU 核心进行并行计算。
seed:随机种子,用于控制随机初始化和数据划分的随机性,保证结果的可重复性。
max_depth:树的最大深度,控制了每棵树的复杂度。较大的深度可以增加模型的拟合能力,但也容易导致过拟合。
num_leaves:叶子节点数量,是树的另一种控制复杂度的参数。它决定了每棵树的叶子节点数量。
lambda_l1:L1 正则化参数,用于控制模型的复杂度。增加这个参数的值可以增加模型的稀疏性。
lambda_l2:L2 正则化参数,与 lambda_l1 类似,用于控制模型的复杂度。
verbose:控制输出信息的详细程度。设置为-1表示不输出任何信息,通常用于静默模式。

哈哈哈看不懂寄了(bushi)
赶紧百度:

找到了

睡觉了,完了再更


web攻击识别-机器学习
https://bl4zygao.github.io/2024/02/09/web攻击识别-机器学习小项目/
Author
bl4zy
Posted on
February 9, 2024
Licensed under