基于机器学习的攻击检测系统
字数 1203 2025-08-18 11:37:45
基于机器学习的攻击检测系统教学文档
1. 概述
本文档详细介绍了如何利用机器学习技术构建网络攻击检测系统,主要涵盖XSS攻击和SQL注入攻击的检测方法。文档内容包括特征提取、数据集准备、算法选择和实现过程等关键环节。
2. 核心问题
构建机器学习攻击检测系统需要解决三个关键问题:
- 攻击特征提取:如何从请求数据中提取有区分度的特征
- 数据集获取:如何获取足够数量和质量的正常与恶意请求数据
- 算法选择:选择何种机器学习算法进行训练和预测
3. 前期准备
3.1 特征提取方法
TF-IDF方法
- 基本原理:字词重要性与其在文件中出现次数成正比,与在语料库中出现频率成反比
- 实现方式:使用n-gram分割请求字符串
def split_url(data_set, num=3): data_str = [] for s in data_set: s = s.strip() s = " ".join([s[i:i+num] for i in range(len(s)-2)]) data_str.append(s) return data_str
自编码特征方法
提取以下统计特征:
- URL长度
- 参数部分长度
- 参数个数
- 参数最大长度
- 参数中数字个数
- 参数值中数字比例
- 参数值中字母比例
- 特殊字符个数
- 特殊字符比例
实现代码片段:
for i in range(len(data_link)):
per_fea = []
url_len = len(data_link[i])
per_fea.append(url_len)
s = data_link[i].split("?")
if len(s) != 1:
par_len = len(s[1])
par = s[1].split("&")
par_num = len(par)
par_max_l = 0
number_num = 0
str_num = 0
spe_num = 0
for pa in par:
[par_name,par_val] = pa.split("=")
if par_max_l < len(par_val):
par_max_l = len(par_val)
number_num = number_num + len(num_regex.findall(par_val))
str_num = str_num + len(zimu_regex.findall(par_val))
spe_num = len(par_val) - len(num_regex.findall(par_val)) - len(zimu_regex.findall(par_val))
number_rt = number_num / len(par_val)
str_rt = str_num / len(par_val)
spe_rt = spe_num / len(par_val)
3.2 数据集准备
使用三类数据集:
- GitHub上的payload集合(恶意请求)
- secrepo上的http.log数据(正常请求)
- HTTP DATASET CSIC 2010数据集(36000条正常请求和25000条恶意请求)
数据预处理示例:
def parse_data(file_path):
data_set = []
with open(file_path) as f:
lines_list = f.readlines()
for s in lines_list:
if s.startswith("GET") or s.startswith("POST"):
s = s.split()[1][30:]
s = re.split(r"\s", s)
s = " ".join(s)
data_set.append(s)
print(len(data_set))
np.save("normal_traffic.npy", data_set)
4. 算法实现与比较
4.1 传统机器学习算法
XSS检测结果
- 逻辑回归:98.9%准确率
- 朴素贝叶斯:98.3%准确率
- KNN (n=6):94.8%准确率(速度较慢)
SQL注入检测结果
- 朴素贝叶斯:97.3%准确率
- 逻辑回归:98%准确率
- KNN (n=6):97.9%准确率
多类型攻击检测(自编码特征)
- 逻辑回归:73%准确率
- 朴素贝叶斯:50.2%准确率
- SVM:92.1%准确率(速度较慢)
- KNN (n=6):90.9%准确率(速度较快)
4.2 卷积神经网络(CNN)实现
网络结构构建:
# 初始化权重
def init_weight(shape, std_dev):
weight = tf.Variable(tf.truncated_normal(shape, stddev=std_dev))
return weight
# 初始化偏置
def init_bias(shape, std_dev):
bias = tf.Variable(tf.truncated_normal(shape, stddev=std_dev))
return bias
# 定义卷积层
def conv_2d(x, w):
return tf.nn.conv2d(x, w, strides=[1,1,1,1], padding="SAME")
# 池化层
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
# 全连接层
def fully_connected(input_layer, weights, biases):
layer = tf.add(tf.matmul(input_layer, weights), biases)
return tf.nn.tanh(layer)
# 卷积模型
shape_w = [10,3,1,32]
shape_b = [32]
weight_1 = init_weight(shape_w, std_dev=0.01)
bias_1 = init_bias(shape_b, std_dev=0.01)
layer1 = max_pool_2x2(tf.nn.relu(tf.add(conv_2d(x_data, weight_1), bias_1)))
遇到的问题:
- 数据维度太高,使用PCA降维(保留98%特征)
- 训练过程中loss无法优化,准确率在40-50%之间波动
5. 系统实现
使用Flask框架构建Web界面,包含三个模块:
- 首页
- 训练页面
- 可选择攻击类型(XSS/SQLI/综合)
- 可选择算法(朴素贝叶斯/KNN/SVM/逻辑回归)
- 检测页面
- 输入待检测请求
- 输出检测结果
6. 经验总结
-
特征工程至关重要:良好的特征表示能显著提高模型性能
- 对于静态请求,需全面考虑攻击特征
- 自编码特征在某些算法上表现不佳(如朴素贝叶斯)
-
算法选择需权衡:
- SVM准确率高但计算复杂度高
- KNN在准确率和速度间取得较好平衡
-
未来改进方向:
- 结合NLP技术分析请求语义
- 考虑请求上下文和时序特征(攻击通常具有连续性)
- 尝试其他降维方法(如Gibbs采样)
-
数据质量要求:
- 机器学习对数据质量敏感
- 需要足够数量和代表性的正常与恶意样本
7. 关键代码片段
7.1 模型训练示例
# 逻辑回归
lr = LogisticRegression()
lr.fit(x_train, y_train)
predictions = lr.predict(x_test)
# 朴素贝叶斯
nb = MultinomialNB()
nb.fit(x_train, y_train)
predictions = nb.predict(x_test)
# KNN
ner = KNeighborsClassifier(n_neighbors=6).fit(x_train, y_train)
predictions = ner.predict(x_test)
7.2 PCA降维
pca = PCA(n_components=0.98)
pca.fit(data)
data_set = pca.transform(data)