在当今数字化时代,企业或服务对网络基础设施的依赖性日益增强,这些基础设施支撑着组织IT运营的核心功能。因此,保持网络基础设施的健康状态并对其进行监控,以预防可能出现的问题至关重要。监控的目的不仅限于硬件故障或嵌入式软件中的bug,还可以扩展到安全漏洞的防护,或者至少避免可能的攻击。尽管网络基础设施大多得到了保护,但它们仍然容易受到机器人和分布式拒绝服务(DDoS)攻击的影响,这些攻击通常不会被视为可疑,因为它们针对的是网络设备的资源分配系统,在某些高利用率的情况下可能看起来是正常的。
然而,大多数情况下,这种资源分配不太可能在多个设备上引起风暴,因此可以通过时间域轻松跟踪以检测任何异常。大多数现代防火墙可以通过每秒SYN、ICMP连接请求的数量来检测可疑的请求模式,但这仍然无法提供任何结论。当深入研究异常时,可以发现一个可能由攻击者请求触发的模式。这种模式可能是设备的功耗、CPU利用率、内存等。
谈到异常,首先想到的是人工智能和机器学习。机器学习是人工智能的一个分支,它帮助机器或计算机从历史中学习,然后使用它来预测结果,这种预测的准确性应该足以满足目的。机器学习识别出负责特定结果(在这种情况下是攻击)的最小可能级别的统计模式,然后将该反应与进一步的参考联系起来。这就是它如何帮助预测结果的。
DDoS攻击的背景:DDoS攻击非常普遍,对绝大多数服务提供商构成主要威胁,其影响范围广泛。这些攻击在发生时占一个国家总互联网流量的高达25%。组织花费从数千到数百万美元来保护其基础设施免受这些威胁,但由于这些攻击倾向于保持吞吐量发送请求,最终会使设备资源忙碌直到设备挂起,就像电脑因重负载而崩溃一样,它们仍然会被破坏。攻击所利用的资源可能是内存、CPU或NVRAM,或者是网络拥塞。DDoS攻击的动机可能不是渗透网络以窃取信息,而是扰乱网络流量,足以导致公司遭受重大损失。
攻击机制:有许多类型的攻击,如IMPS洪水、Ping死亡、UDP洪水,它们都有一个共同点,那就是发送大量请求以保持设备或流量通道饱和。DDoS攻击是由攻击者通过计算机启动的,该计算机开始发送请求或在其他设备上更新恶意应用程序,利用它们作为机器人帮助攻击扩散并使其难以缓解。缓解情况可能需要很长时间,因为被破坏的网络需要释放被识别设备发送的所有请求。
机器学习如何提供帮助:像Statseeker、NNM这样的工具用于监控设备,它们显示了一个非常简单的图表,可以很容易地检查和得出状态。相同的概念可以用来收集数据点,并通过训练有素的机器学习模型运行它们,以检查更小离散尺度上的任何异常。但首先,需要教导模型并找到与攻击初始阶段最相关的常见模式。同样,需要一个数据集,该数据集要么是从实际攻击中收集的,要么是在测试空间中模拟的攻击。然后将进行模型的训练和测试。
实施:检测DDoS攻击的主要独立因素是每秒的数据包和比特流。为此,需要一些数据集形式,然后处理它以匹配要求。选择了来自博阿齐奇大学实验的数据集,可以在链接中找到,以及数据集的详细描述。这很容易理解概念和实施。这里收集的数据是通过Wireshark跟踪的网络设置并导出为CSV文件的。分别有TCP-SYN和UDP攻击的两个文件可用。
尽管数据集已经包含了大多数组件,但仍然需要做一些手动工作来调整它以进行特征选择。首先,导入了下载的数据集,提取了攻击的指定行,手动标记了文章中提到的行,以将攻击会话与正常流量分开。然后合并所有数据集到一个单独的文件中。
攻击类型包括TCP-SYN、UDP洪水和正常流量,分别被命名为Benign。TCP-SYN和UDP洪水可以通过高数据包和比特流以及大量的唯一IP地址来识别,这表明了欺骗。另一方面,即使Benign或正常流量有高数据包或比特率,仍然会有较少的IP地址被添加到内存表中。上述模式帮助为模型选择特征。
处理数据集,首先选择了“时间”、“攻击”、“源IP”、“帧长度”列。时间列用于通过迭代每一行直到找到下一秒的时间来获取每秒的IP地址集、数据包和字节长度。攻击用作每种攻击/流量类型的标签,源IP用于跟踪每秒的唯一IP请求数量,这在TCP SYN的情况下特别有用,因为进行了三次握手。帧长度表示帧的长度(以字节为单位),将迭代行并累积直到下一秒的时间。
处理后,有另一个数据集,实际上是没有不必要的错误、空值和消耗内存的大型数据类型的。另外,请注意,根据内存的可用性,可能需要将某些列转换为不同的数据类型以缩小范围。在情况下,为时间做了转换,因为没有需要高精度,因为已经缩放到秒,并转换为32位无符号整数。
# 导入所需库
from pandas import read_csv
from pandas.plotting import scatter_matrix
from matplotlib import pyplot
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
import numpy as np
import seaborn as sns
from pandas import DataFrame
file2 = r"mfnn9bh42m-1BOUN_DDoS datasetboun_tcp_Anon1.csv"
dataset = read_csv(file2, low_memory=False)
dataset = dataset[["Time","TTL","SYN","ACK","Attack","Source_ip",'Frame_length']]
dataset["SYN"] = dataset["SYN"].fillna(0)
dataset["ACK"] = dataset["ACK"].fillna(0)
dataset["SYN"] = dataset["SYN"].replace(['Set','Not set'],[1,0])
dataset["ACK"] = dataset["ACK"].replace(['Set','Not set'],[1,0])
dataset["Time"] = dataset["Time"].fillna(0)
dataset["Time"] = dataset["Time"].astype(np.uint32)
S=[]
packetno = 1
M=[]
bits = 0
for i in range(1,len(dataset)):
if dataset.loc[i,'Time']>=(dataset.loc[i-1,'Time'])+1 or dataset.loc[i,'Attack']!=dataset.loc[i-1,'Attack']:
M = set(M)
unique_ips = len(M)
Attack_type = dataset.loc[i,"Attack"]
S.append([packetno,unique_ips,bits,Attack_type])
packetno = 0
bits = 0
M = []
else:
bits += dataset.loc[i,'Frame_length']
M.append(dataset.loc[i,'Source_ip'])
packetno += 1
S = DataFrame(S,columns = ['packetno','unique_ips','bits','Attack_type'])
S = S.dropna()
print(S)
print(S.describe())
print(S.groupby("Attack_type").size())
import matplotlib.pyplot as plt
labels = 'TCPSYN','UDPFLOOD','BENIGN'
sizes = [len(S[S["Attack_type"]=="TCPSYN"]),len(S[S["Attack_type"]=="UDPFLOOD"]),len(S[S["Attack_type"]=="BENIGN"])]
colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue','yellow','purple','grey']
explode = (0, 0, 0) # explode 1st slice
plt.rcParams.update({'font.size': 10})
plt.figure(figsize=(8,8))
plt.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct='%1.1f%%', shadow=True, startangle=140)
plt.axis('equal')
plt.show()
models = []
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
results = []
names = []
for name, model in models:
kfold = StratifiedKFold(n_splits=10, random_state=1, shuffle=True)
cv_results = cross_val_score(model, X_train, Y_train, cv=kfold, scoring='accuracy')
results.append(cv_results)
names.append(name)
print('%s: %f (%f)' % (name, cv_results.mean(), cv_results.std()))