Skip to content

Latest commit

 

History

History
411 lines (294 loc) · 22.6 KB

File metadata and controls

411 lines (294 loc) · 22.6 KB

八、绕过入侵检测系统

部署入侵检测系统对于每个现代公司来说都是必不可少的,以便抵御攻击者。在前面的章节中,我们学习了如何构建基于机器学习的入侵检测系统。现在,是学习如何通过对抗性学习绕过这些系统的时候了;为了保护你的系统,你需要先学会如何攻击它们。

在本章中,我们将介绍以下内容:

  • 对抗式机器学习算法
  • 机器学习威胁模型
  • 利用对抗性网络系统绕过入侵检测系统

技术要求

在本章中,您将需要以下库:

  • 皮亚马尔

  • 努比

  • 松软的

  • CVXPY

  • Python 3

  • Matplotlib

  • scikit 学习

  • 进步

  • 令人感伤的特质

  • CVXOPT(可选,作为 CVXPY 解算器)

  • Jupyter 笔记本

您可以在找到代码文件 https://github.com/PacktPublishing/Mastering-Machine-Learning-for-Penetration-Testing/tree/master/Chapter08

对抗式机器学习算法

在研究对抗式机器学习之前,让我们先探讨两个重要术语:过度拟合和欠拟合。

过盈和欠盈

过度拟合是机器学习实践者面临的最大障碍之一。知道如何发现过度拟合是构建健壮的机器学习模型所必需的技能,因为达到 99%的准确率并不是故事的终点。在机器学习中,我们进行预测。根据定义,拟合是我们逼近目标函数的程度。正如我们在第一章中看到的,监督学习的目的是在输入数据和目标之间映射函数。因此,良好的拟合是该函数的良好近似。

过度拟合发生在模型学习到训练数据中的细节和噪声时,其程度会对模型的性能产生负面影响。换言之,噪声是由模型拾取和学习的,因此当输入新数据时,它不再具有良好的泛化能力。下图说明了过度拟合的情况。你会注意到模型训练得太好了,这使得我们在向模型输入数据时很难达到准确度。

另一个障碍是不合适。当机器学习模型不能很好地适应数据时,就会发生这种情况。换句话说,当模型过于简单时:

使用 Python 进行过拟合和欠拟合

让我们通过 scikit learn 了解一个关于过度拟合和欠拟合的真实演示。导入所需的模块:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score

现在,我们将构建一个小模型,并将模型、样本和true函数可视化,以查看过度拟合和欠拟合。我们将使用以下代码:

np.random.seed(0)
n_samples = 30
degrees = [1, 4, 15]
X = np.sort(np.random.rand(n_samples))
y = np.cos(1.5 * np.pi * X) + np.random.randn(n_samples) * 0.1
plt.figure(figsize=(14, 5))

for i in range(len(degrees)):
 ax = plt.subplot(1, len(degrees), i + 1)
 plt.setp(ax, xticks=(), yticks=())

 polynomial_features = PolynomialFeatures(degree=degrees[i],
 include_bias=False)
 linear_regression = LinearRegression()
 pipeline = Pipeline([("polynomial_features", polynomial_features),
 ("linear_regression", linear_regression)])
 pipeline.fit(X[:, np.newaxis], y)

 # Evaluate the models using crossvalidation
 scores = cross_val_score(pipeline, X[:, np.newaxis], y,
 scoring="neg_mean_squared_error", cv=10)

 X_test = np.linspace(0, 1, 100)
 plt.plot(X_test, pipeline.predict(X_test[:, np.newaxis]), label="Model")
 plt.plot(X_test, true_fun(X_test), label="True function")
 plt.scatter(X, y, edgecolor='b', s=20, label="Samples")
 plt.xlabel("x")
 plt.ylabel("y")
 plt.xlim((0, 1))
 plt.ylim((-2, 2))
 plt.legend(loc="best")
 plt.title("Degree {}\nMSE = {:.2e}(+/- {:.2e})".format(
 degrees[i], -scores.mean(), scores.std()))
plt.show()

通过运行前面的脚本,我们绘制了以下图表,说明了 3 种情况:欠拟合、良好拟合和过度拟合(从左到右):

下表是使用前面代码中突出显示的术语以及相应的 URL 创建的:

| 模块 | URL | | plt.subplot | https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplot.html#matplotlib.pyplot.subplot | | plt.setp | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.setp.html#matplotlib.pyplot.setp | | PolynomialFeatures | http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html#sklearn.preprocessing.PolynomialFeatures | | LinearRegression | http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression | | Pipeline | http://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline | | np.newaxis | http://docs.scipy.org/doc/numpy-1.8.1/reference/arrays.indexing.html#numpy.newaxis | | cross_val_score | http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_val_score.html#sklearn.model_selection.cross_val_score | | np.newaxis | http://docs.scipy.org/doc/numpy-1.8.1/reference/arrays.indexing.html#numpy.newaxis | | np.linspace | http://docs.scipy.org/doc/numpy-1.8.1/reference/generated/numpy.linspace.html#numpy.linspace | | plt.plot | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot | | plt.scatter | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter | | plt.xlabel | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.xlabel.html#matplotlib.pyplot.xlabel | | plt.ylabel | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.ylabel.html#matplotlib.pyplot.ylabel | | plt.xlim | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.xlim.html#matplotlib.pyplot.xlim | | plt.ylim | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.ylim.html#matplotlib.pyplot.ylim | | plt.legend | http://matplotlib.org/api/legend_api.html#matplotlib.legend | | plt.title | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.title.html#matplotlib.pyplot.title | | plt.show | http://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html#matplotlib.pyplot.show |

检测过拟合

为了检测过拟合,强烈建议将初始数据集拆分为训练集和测试集。如果训练集的性能比测试集好,那么我们就有问题了。此外,强烈建议从一个简单的算法开始,然后再转到更复杂的模型,检查是否值得升级复杂性级别。为了防止过度拟合,我们可以使用交叉验证。交叉验证是通过具有不同子集(k子集)的训练模型来评估许多机器学习技术的过程。

对抗式机器学习

对抗式机器学习是研究如何打破和保护机器学习模型的艺术。你可以认为它是机器学习和信息安全的交叉点。作为一名安全专业人员,学习如何通过机器学习构建防御层非常重要,但知道如何打破防御层也是您技能集的一个惊人补充:

2006 年,Ballino 等人提出了针对机器学习系统的威胁模型的分类法。该模型基于三个轴:

  • 影响
  • 违反安全规定
  • 特异性

2011 年,Huang 等人对该模型进行了扩展,以包括另一个轴,称为隐私。2016 年,Papernot、McDaniel、Jha、Fredrikson、Celik 和 Swami 引入了一种新的分类法,只关注两个轴:

  • 攻击的复杂性
  • 攻击者的知识

下图说明了机器学习威胁分类法:

为了攻击机器学习模型,攻击者可以执行以下部分介绍的许多技术。

逃避攻击

为了执行机器学习绕过攻击,网络犯罪分子试图通过观察模型的工作方式绕过学习结果,尤其是通过尝试许多不同的样本(只需向模型输入不同的输入并试图找到学习模式),从而绕过学习结果。这种技术非常流行。例如,如果攻击者想要绕过机器学习垃圾邮件过滤器,他需要向系统发送不同的电子邮件,并搜索使垃圾邮件通过(未被检测为垃圾邮件)的模式,只需对以前检测到的电子邮件进行几次修改即可绕过检测。

以下工作流说明了绕过攻击的工作原理:

中毒袭击

在机器学习中毒攻击中,攻击者通过在模型训练阶段添加恶意数据,对模型进行中毒,以改变学习结果。例如,可以通过在网络操作期间进行数据采集时发送和注入精心设计的样本来执行此方法,以训练网络入侵检测系统模型。以下工作流说明了中毒攻击是如何发生的:

意大利模式识别和应用实验室进行了一些关于对抗性机器学习的最伟大研究,包括对支持向量机的毒害攻击,当时 Battista Biggio 和他的团队提出了一个攻击支持向量机系统的伟大框架。步骤如下:

  1. 确定适当对手的目标

  2. 定义对手的知识

  3. 制定相应的优化问题

  4. 相应地对收集的(培训和测试)数据重新取样

  5. 对重采样数据评估分类器的安全性

  6. 对不同级别的对手知识重复评估

如果您熟悉 MATLAB,我强烈建议您尝试ALFASVMLib。这是一个 MATLAB 库,用于支持向量机的对抗性标签翻转攻击。您可以从下载 https://github.com/feuerchop/ALFASVMLib

对抗聚类

聚类技术广泛应用于许多实际应用中。攻击者正在提出新的技术来攻击集群模型。其中一种是对抗性集群,其中攻击者操纵输入数据(添加一小部分攻击样本),以便新添加的样本可以隐藏在现有集群中。

对抗性特征

特征选择是每个机器学习项目中的一个重要步骤。攻击者还使用对抗性特征选择攻击模型。我强烈建议您阅读同一个团队(意大利模式识别和应用实验室研究人员所做的研究,该研究发表在一篇名为的论文中,即特征选择是否能防止训练数据中毒?

研究小组发现,通过毒害嵌入的特征选择算法,包括套索、岭回归和 ElasticNet,他们愚弄了一个 PDF 恶意软件检测器。

研究人员开发了许多 Python 框架和开源项目来攻击和评估机器学习模型,如CleverHans对抗性机器学习AML)库和T7】。

克利夫汉斯

克利夫汉斯正在不断发展;它是一个对抗性示例库,用于构建攻击、构建防御,并对机器学习系统在对抗性攻击中的脆弱性进行基准测试。

您可以从中克隆它 https://github.com/tensorflow/cleverhans

也可以使用pip实用程序进行安装,如图所示:

反洗钱图书馆

AML 库是一个博弈论对抗式机器学习库,由范德比尔特大学计算经济学研究实验室开发。博弈论是指研究智能决策主体之间合作的数学模型。您可以从克隆库 https://github.com/vu-aml/adlib

梅勒姆动物园

EVADML 动物园是对抗机器学习的基准和可视化工具,由弗吉尼亚大学的机器学习小组和安全研究小组开发。您可以从下载 https://github.com/mzweilin/EvadeML-Zoo

利用对抗性网络系统绕过入侵检测系统

到目前为止,您已经对对抗式机器学习以及如何攻击机器学习模型有了相当的了解。现在是深入研究更多技术细节的时候了,学习如何使用 Python 绕过基于机器学习的入侵检测系统。您还将学习如何防御这些攻击。

在本演示中,您将学习如何使用中毒攻击攻击模型。如前所述,我们将注入恶意数据,以便影响模型的学习结果。下图说明了中毒攻击将如何发生:

在本次攻击中,我们将使用基于雅可比矩阵的显著性图攻击JSMA)。这是通过只修改输入中有限数量的像素来搜索对抗性示例来实现的。

让我们看看如何使用 Python 攻击基于机器的入侵检测系统。代码有点长,所以我只想包括一些重要的片段;稍后,您可以在本章的 GitHub 存储库中找到完整的代码。

对于这个项目,我们需要 NumPy、pandas、Keras、CleverHans、TensorFlow、scikit learn 和 matplotlib Python 库。

以下是一些导入的库:

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense , Dropout
from keras.optimizers import RMSprop , adam
from cleverhans.attacks import fgsm , jsma
from cleverhans.utils_tf import model_train , model_eval , batch_eval
from cleverhans.attacks_tf import jacobian_graph
from cleverhans.utils import other_classes
import tensorflow as tf
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score , roc_curve , auc , f1_score
from sklearn.preprocessing import LabelEncoder , MinMaxScaler
import matplotlib.pyplot as plt

下一步是预处理数据:

names = ['duration', 'protocol', 'service ', 'flag', 'src_bytes', 'dst_bytes', 'land',
'wrong_fragment ','urgent ', 'hot', 'num_failed_logins ', 'logged_in ', 'num_compromised ', 'root_shell ', 'su_attempted ','num_root ', 'num_file_creations ', 'num_shells ', 'num_access_files ', 'num_outbound_cmds ','is_host_login ', 'is_guest_login ', 'count', 'srv_count ', 'serror_rate', 'srv_serror_rate ','rerror_rate ', 'srv_rerror_rate ', 'same_srv_rate ', 'diff_srv_rate', 'srv_diff_host_rate ','dst_host_count ', 'dst_host_srv_count ', 'dst_host_same_srv_rate ', 'dst_host_diff_srv_rate ','dst_host_same_src_port_rate ', 'dst_host_srv_diff_host_rate ', 'dst_host_serror_rate ','dst_host_srv_serror_rate ','dst_host_rerror_rate ', 'dst_host_srv_rerror_rate ','attack_type ', 'other ']

然后,我们将用熊猫加载数据:

TrainingData = pd.read_csv('KDDTrain+.txt', names=names , header=None)
TestingData = pd.read_csv('KDDTest+.txt', names=names , header=None)

然后,连接训练集和测试集:

All = pd.concat ([TrainingData, TestingData])
assert full.shape[0] == TrainingData.shape[0] + TestingData.shape[0]

选择数据并识别特征:

All['label'] = full['attack_type']

要识别 DoS 攻击,请使用以下命令:

All.loc[All.label == 'neptune ', 'label'] = 'dos'
All.loc[All.label == 'back', 'label '] = 'dos'
All.loc[All.label == 'land', 'label '] = 'dos'
All.loc[All.label == 'pod', 'label'] = 'dos'
All.loc[All.label == 'smurf ', 'label'] = 'dos'
All.loc[All.label == 'teardrop ', 'label '] = 'dos'
All.loc[All.label == 'mailbomb ', 'label '] = 'dos'
All.loc[All.label == 'processtable ', 'label'] = 'dos'
All.loc[All.label == 'udpstorm ', 'label '] = 'dos'
All.loc[All.label == 'apache2 ', 'label'] = 'dos'
All.loc[All.label == 'worm', 'label '] = 'dos'

使用相同的技术识别其他攻击(用户到根目录U2R)、远程到本地R2L)和探测)。

要生成一个热编码,请使用以下命令:

full = pd.get_dummies(All , drop_first=False)

再次确定培训和测试集:

features = list(full.columns [:-5])
y_train = np.array(full[0:TrainingData.shape[0]][[ 'label_normal ', 'label_dos ', 'label_probe
label_r2l ', 'label_u2r ']])
X_train = full[0:TrainingData.shape[0]][ features]
y_test = np.array(full[TrainingData.shape[0]:][[ 'label_normal ', 'label_dos ', 'label_probe ', '
label_r2l ', 'label_u2r ']])
X_test = full[TrainingData.shape[0]:][features]

要缩放数据,请使用以下命令:

scaler = MinMaxScaler().fit(X_train)

scale X_train的一个例子如下:

X_train_scaled = np.array(scaler.transform(X_train))

假设我们要攻击一个逻辑回归模型;我们需要处理数据以训练该模型并生成标签编码:

labels = All.label.unique()
En = LabelEncoder()
En.fit(labels)
y_All = En.transform(All.label)
y_train_l = y_All[0:TrainingData.shape[0]]
y_test_l = y_All[TrainingData.shape[0]:]

我们现在已经完成了预处理阶段。

对于基于 Jacobian 的显著性映射攻击,我们将使用以下 Python 实现:

results = np.zeros((FLAGS.nb_classes , source_samples), dtype='i')
perturbations = np.zeros((FLAGS.nb_classes , source_samples), dtype='f')
grads = jacobian_graph(predictions , x, FLAGS.nb_classes)
X_adv = np.zeros(( source_samples , X_test_scaled.shape [1]))
for sample_ind in range(0, source_samples):
current_class = int(np.argmax(y_test[sample_ind ]))
for target in [0]:
if current_class == 0:
Break
adv_x , res , percent_perturb = jsma(sess , x, predictions , grads,X_test_scaled[sample_ind: (sample_ind+1)],target , theta=1, gamma =0.1,increase=True , back='tf',clip_min=0, clip_max =1)
X_adv[sample_ind] = adv_x
results[target , sample_ind] = res
perturbations[target , sample_ind] = percent_perturb

要构建MultiLayer Perceptron网络,请使用以下代码段:

def mlp_model ():
    Generate a MultiLayer Perceptron model
    model = Sequential ()
    model.add(Dense (256, activation='relu', input_shape =( X_train_scaled.shape [1],)))
    model.add(Dropout (0.4))
    model.add(Dense (256, activation='relu'))
    model.add(Dropout (0.4))
    model.add(Dense(FLAGS.nb_classes , activation='softmax '))model.compile(loss='categorical_crossentropy ',optimizer='adam',metrics =['accuracy '])
    model.summary ()
    return model

对于对抗性预测,请使用以下方法:

y_pred_adv = dt.predict(X_adv)
fpr_dt_adv , tpr_dt_adv , _ = roc_curve(y_test[:, 0], y_pred_adv [:, 0])
roc_auc_dt_adv = auc(fpr_dt_adv , tpr_dt_adv)
print("Accuracy score adversarial:", accuracy_score(y_test , y_pred_adv))
print("F1 score adversarial:", f1_score(y_test , y_pred_adv , average='micro '))
print("AUC score adversarial:", roc_auc_dt_adv)

最后,我们需要通过提供对抗性测试数据来评估模型:

如果出现错误,请检查章节的 GitHub 存储库。本书出版后,可能会对代码进行更新和增强。

总结

在本章中,我们概述了对抗式学习技术,并描述了攻击者和网络罪犯如何对机器学习模型进行攻击。

下一章将是一个很好的补充指南,探索如何攻击人工神经网络和深度学习网络。您将了解攻击者如何使用对抗式深度学习和强化学习绕过现代反恶意软件系统。

问题

  1. 你能简单地解释一下为什么过度训练机器学习模式不是一个好主意吗?
  2. 过盈和过盈的区别是什么?
  3. 逃避攻击和中毒攻击有什么区别?
  4. 对抗式集群是如何工作的?
  5. 使用何种类型的对抗性攻击来避免入侵检测系统?
  6. 前一次攻击是逃避攻击还是中毒攻击?

进一步阅读