Share This
Связаться со мной
Крути в низ
Categories
//Обнаружение DDos-атак при помощи AI

Обнаружение DDos-атак при помощи AI

24.11.2020Category : Python

DDoS-атака — один из самых мощных методов взлома в интернете. Для уничтожения или разрушения сайтов используется сетевой трафик. Существуют различные подкатегории такой атаки, отличающиеся способами, которыми хакер пытается проникнуть в сеть. В данной статье мы обсудим подход к обнаружению угрозы DDoS-атаки при помощи модели искусственного интеллекта, точность которой составляет 96%. Мы классифицировали 7 различных подкатегорий угроз DDoS, а также безопасную или надежную сеть.

Введение

DDos-атаки нацелены на сайты и онлайн-сервисы. Смысл такой атаки — заблокировать сеть или сервер чрезмерным трафиком. Эффективность достигается за счет использования нескольких скомпрометированных систем в качестве источников атакующего трафика.

DDoS-атаки делятся на различные подкатегории в зависимости от уровня сетевого подключения, которое они пытаются атаковать (имеется в виду уровень по модели OSI). В ходе нашего исследования мы классифицировали следующие подкатегории: SYN Flood, UDP Flood, MSSQL, LDAP, Portmap, NetBIOS.

Машинное и глубокое обучение в наши дни является основой искусственного интеллекта. Мы используем эти методологии для решения проблем в различных областях с точностью, близкой к человеческой. В данном исследовании мы в очередной раз проверили пределы искусственного интеллекта в обнаружении угроз в области кибербезопасности.

Предподготовка данных

Подготовка данных была одной из первых проблем, с которыми мы столкнулись. У данных было 88 атрибутов или, иначе говоря, свойств. Обработка таких огромных массивов данных в ограниченной оперативной памяти была для нас действительно непростой задачей. Поэтому мы понизили тип данных атрибутов и, следовательно, уменьшили расход памяти. Типы данных float64 понижены до float32, int64 — до int32, int32 — до uint32 и так далее. Таким образом удалось сэкономить почти 42% памяти. Но в нашем датафрейме все еще оставались атрибуты с очень большими значениями и их также пришлось обработать на предварительном этапе.

def Pre_process_data(df,col):     '''     Input: Data-frame and Column name.     Operation: Fills the nan values with the minimum value in their respective column.     Output: Returns the pre-processed data-frame.     '''     #df['primary_use'] = df['primary_use'].astype("category").cat.codes     print("Name of column with NaN: "+str(col))     print(df[col].value_counts(dropna=False, normalize=True).head())     df[col].replace(np.inf, -1, inplace=True)          return df 
def reduce_mem_usage(df):     '''     Input - data-frame.     Operation - Reduce memory usage of the data-frame.     '''     start_mem_usg = df.memory_usage().sum() / 1024**2      print("Memory usage of properties dataframe is :",start_mem_usg," MB")     #NAlist = [] # Keeps track of columns that have missing values filled in.      for col in df.columns:         if df[col].dtype != object:  # Exclude strings                         # Print current column type             print("******************************")             print("Column: ",col)             print("dtype before: ",df[col].dtype)                         # make variables for Int, max and min             IsInt = False             mx = df[col].max()             mn = df[col].min()             #print("min for this col: ",mn)             #print("max for this col: ",mx)             # Integer does not support NA, therefore, NA needs to be filled             if not np.isfinite(df[col]).all():                  #NAlist.append(col)                 df = Pre_process_data(df,col)                                 # test if column can be converted to an integer             asint = df[col].fillna(0).astype(np.int64)             result = (df[col] - asint)             result = result.sum()             if result > -0.01 and result < 0.01:                 IsInt = True                         # Make Integer/unsigned Integer datatypes             if IsInt:                 if mn >= 0:                     if mx < 255:                         df[col] = df[col].astype(np.uint8)                     elif mx < 65535:                         df[col] = df[col].astype(np.uint16)                     elif mx < 4294967295:                         df[col] = df[col].astype(np.uint32)                     else:                         df[col] = df[col].astype(np.uint64)                 else:                     if mn > np.iinfo(np.int8).min and mx < np.iinfo(np.int8).max:                         df[col] = df[col].astype(np.int8)                     elif mn > np.iinfo(np.int16).min and mx < np.iinfo(np.int16).max:                         df[col] = df[col].astype(np.int16)                     elif mn > np.iinfo(np.int32).min and mx < np.iinfo(np.int32).max:                         df[col] = df[col].astype(np.int32)                     elif mn > np.iinfo(np.int64).min and mx < np.iinfo(np.int64).max:                         df[col] = df[col].astype(np.int64)                 # Make float datatypes 32 bit             else:                 df[col] = df[col].astype(np.float32)                          # Print new column type             print("dtype after: ",df[col].dtype)             print("******************************")     # Print final result     print("___MEMORY USAGE AFTER COMPLETION:___")     mem_usg = df.memory_usage().sum() / 1024**2      print("Memory usage is: ",mem_usg," MB")     print("This is ",100*mem_usg/start_mem_usg,"% of the initial size")     return df 

Распределение целевых переменных

labels = 'UDPLag', 'Syn', 'UDP', 'NetBIOS','Portmap','MSSQL','BENIGN' sizes = [len(data_[data_[' Label']=='UDPLag']), len(data_[data_[' Label']=='Syn']),           len(data_[data_[' Label']=='UDP']), len(data_[data_[' Label']=='NetBIOS']),          len(data_[data_[' Label']=='Portmap']),len(data_[data_[' Label']=='MSSQL']),          len(data_[data_[' Label']=='BENIGN'])] colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue','yellow','purple','grey'] explode = (0, 0.1, 0, 0,0,0,0)  # explode 1st slice  # Plot plt.rcParams.update({'font.size': 22}) plt.figure(figsize=(10,10)) plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True, startangle=140)  plt.axis('equal') plt.show() 

obnaruzhenie ddos atak pri pomoshhi ai 7db379c - Обнаружение DDos-атак при помощи AI

Как видите, мы попытались сохранить равномерное распределение целевых переменных относительно друг друга.

Так как UDPLag несколько выбивается из этой картины, мы рассмотрим эту переменную отдельно.

Исследовательский анализ данных

plt.figure(figsize=(20,16)) g1 = sns.countplot(x=' Label', hue=' Label', data=data_) gt = g1.twinx() gt = sns.pointplot(y=' Flow Packets/s', x=' Label', data=data_, color='black', legend=False) gt.set_ylabel(" Flow Packets/s", fontsize=16) 

obnaruzhenie ddos atak pri pomoshhi ai 924587d - Обнаружение DDos-атак при помощи AI

plt.figure(figsize=(20,16)) g1 = sns.countplot(x=' Label', hue=' Label', data=data_) gt = g1.twinx() gt = sns.pointplot(y='Flow Bytes/s', x=' Label', data=data_, color='black', legend=False) gt.set_ylabel("Flow Bytes/s", fontsize=16)

obnaruzhenie ddos atak pri pomoshhi ai ce7da02 - Обнаружение DDos-атак при помощи AI

В двух приведенных выше графиках мы можем ясно заметить, что существует дрейф в потоке битов и потоке пакетов во время DDoS-атаки по сравнению с безопасным соединением.

plt.figure(figsize=(20,16)) g1 = sns.scatterplot(y=' Total Fwd Packets', x='Total Length of Fwd Packets',                      sizes=(200, 400), size=' Flow Duration',data=data_)  gt = g1.twinx() t = sns.pointplot(y='Fwd Packets/s', x=' Label', data=data_, color='black', legend=False) gt.set_ylabel("Fwd Packets/s", fontsize=16) 

obnaruzhenie ddos atak pri pomoshhi ai 1c1d896 - Обнаружение DDos-атак при помощи AI

plt.figure(figsize=(20,16)) g1 = sns.scatterplot(y=' Total Backward Packets', x=' Total Length of Bwd Packets',                      sizes=(200, 400), size=' Flow Duration',data=data_) gt = g1.twinx() t = sns.pointplot(y=' Bwd Packets/s', x=' Label', data=data_, color='black', legend=False) gt.set_ylabel("Bwd Packets/s", fontsize=16)

obnaruzhenie ddos atak pri pomoshhi ai 778ccaf - Обнаружение DDos-атак при помощи AI

Мы также проанализировали распределение угроз всех видов внутри каждого типа протокола и входящих угроз. Ниже приведены диаграммы, отображающие этот анализ.

plt.figure(figsize=(20,16)) g1 = sns.countplot(x=' Label', data=data_,alpha=0.5) gt = g1.twinx() gt = sns.countplot(x=' Protocol', hue=' Label',alpha=0.7, data=data_) gt.set_ylabel(" Protocol", fontsize=16) 

obnaruzhenie ddos atak pri pomoshhi ai ad529f3 - Обнаружение DDos-атак при помощи AI

plt.figure(figsize=(20,16)) g1 = sns.countplot(x=' Label', data=data_,alpha=0.5) gt = g1.twinx() gt = sns.countplot(x=' Inbound', hue=' Label',alpha=0.7, data=data_) gt.set_ylabel(' Inbound', fontsize=16) 

obnaruzhenie ddos atak pri pomoshhi ai b9a1be8 - Обнаружение DDos-атак при помощи AI

plt.figure(figsize=(20,16)) g1 = sns.countplot(x='SimillarHTTP', hue=' Label',alpha=0.7, data=data_) gt = g1.twinx() gt = sns.countplot(x=' Label', data=data_,alpha=0.4)

obnaruzhenie ddos atak pri pomoshhi ai 1204394 - Обнаружение DDos-атак при помощи AIobnaruzhenie ddos atak pri pomoshhi ai e237cea - Обнаружение DDos-атак при помощи AIobnaruzhenie ddos atak pri pomoshhi ai 8d7b1b3 - Обнаружение DDos-атак при помощи AIobnaruzhenie ddos atak pri pomoshhi ai 61361de - Обнаружение DDos-атак при помощи AI

Обнаружение угрозы при помощи обучения без учителя

При обучении без учителя у нас нет целевых переменных, мы учимся непосредственно на входных данных, самостоятельно обнаруживая в них информацию и закономерности.

Преподготовка данных перед обучением. Мы удалили из наших данных столбцы Flow ID, Source IP, Source Port, Destination IP, Destination Port, Timestamp, Flow Packets / s, Flow Bytes / s ‘. «Flow plackets / s» и «Flow Bytes / s» были удалены потому, что даже после стандартного масштабирования значения этих переменных были бы слишком велики или, наоборот, очень малы.

scale = preprocessing.StandardScaler() X = scale.fit_transform(X) X_norm = preprocessing.normalize(X) 

Мы отмасштабировали наши данные при помощи стандартной функции масштабирования с последующей их нормализацией. Для уменьшения размерности был использован метод главных компонент.

pca = PCA(n_components=2)  principalComponents = pca.fit_transform(X_norm) plt.figure(figsize=(16,16)) g1 = sns.scatterplot(principalComponents[:, 0], principalComponents[:, 1], s= 100, hue=data_[' Label'], cmap='Spectral',alpha=0.7) plt.title('Visualizing DDoS attacks through PCA', fontsize=24); 

obnaruzhenie ddos atak pri pomoshhi ai d7b776a - Обнаружение DDos-атак при помощи AI

pca_ = PCA(n_components=2)  principalComponents = pca_.fit_transform(X_norm) tsne_ = TSNE(random_state = 42, n_components=2,verbose=0, perplexity=40, n_iter=600).fit_transform(principalComponents) plt.figure(figsize=(16,16)) g1 = sns.scatterplot(tsne_[:, 0], tsne_[:, 1], s= 100, hue=data_[' Label'], cmap='Spectral',alpha=0.7) plt.title('Visualizing DDoS attacks through t-SNE', fontsize=24); 

obnaruzhenie ddos atak pri pomoshhi ai 6a6ae5a - Обнаружение DDos-атак при помощи AI

Итак, из двух вышеупомянутых визуализаций можно ясно увидеть, что наш алгоритм умеет в некоторой степени успешно выделять различные угрозы из данных.

Давайте посмотрим, как наша модель обучения без учителя может маркировать сгенерированные кластеры.

Agglo = AgglomerativeClustering(n_clusters=8) Agglo.fit(principalComponents) plt.figure(figsize=(20,11)) plt.scatter(tsne_[:, 0],tsne_[:, 1], c=Agglo.labels_,edgecolors='black') plt.gca().set_aspect('equal', 'datalim') plt.colorbar(boundaries=np.arange(11)-0.5).set_ticks(np.arange(8)) plt.title('Visualizing DDoS attacks after Agglomerative Clustering', fontsize=24); plt.show() 

obnaruzhenie ddos atak pri pomoshhi ai b4a9cb1 - Обнаружение DDos-атак при помощи AI

Что ж, похоже, наша модель обучения без учителя успешно нашла закономерности в данных и смогла до некоторой степени самостоятельно сегментировать нашу целевую переменную.

Замечание: Обучение без учителя дает вам подробное и проанализированное представление о форме и структуре данных. Кластеризация при обучении без учителя и прогнозирование целевой метки на основе данных будут меняться при изменении формы и структуры данных, поскольку целевые данные могут быть неизвестны. Насколько они точны, определить невозможно, а это делает машинное обучение с учителем более применимым к реальным проблемам. Это также одна из причин, почему обученные посредством обучения без учителя модели не подходят для развертывания в производственной среде.

Обучение с учителем для обнаружения угроз

Это прямо противоположно подходу с обучением без учителя. Здесь мы позволяем нашей модели учиться через целевую переменную. Это дает нашей модели дополнительную возможность извлекать закономерности из размеченных данных. Мы применяем ту же предварительную обработку данных, что и для моделей обучения без учителя. В данном случаем мы используем для обучения нашей модели методы глубокого обучения.

Структура нашей модели глубокого обучения

K.clear_session() def create_model():     Input_ = tf.keras.Input(shape=(84,))     model = tf.keras.layers.Dense(128, activation=tf.nn.relu)(Input_)     model = tf.keras.layers.Dropout(0.4)(model)     model = tf.keras.layers.BatchNormalization()(model)      model = tf.keras.layers.Dense(64, activation=tf.nn.relu)(model)     model = tf.keras.layers.Dropout(0.4)(model)     model = tf.keras.layers.BatchNormalization()(model)      model = tf.keras.layers.Dense(8, activation=tf.nn.softmax)(model)     return tf.keras.Model(inputs=Input_, outputs=model) 

obnaruzhenie ddos atak pri pomoshhi ai 78a34ae - Обнаружение DDos-атак при помощи AI

Так как наша целевая переменная несбалансированна, мы используем метод K-Fold для обучения и кроссвалидации наших данных из каждой выборки. Он балансирует обучение и валидацию для нашей несбалансированной переменной.

В качестве оптимайзера мы используем Adam, а в качестве метрики оценки качества — ROC_AUC. В данной метрике вычисляется площадь под кривой ошибок.

Мы обучили и проверили нашу модель на более чем 10 выборках. При этом мы достигли показателя ROC_AUC 96% и более по сравнению со средним значением для обнаружения угроз и достигли наивысшей точности 97% и более.

def auc(y_true, y_pred):     def fallback_auc(y_true, y_pred):         return metrics.roc_auc_score(y_true, y_pred)      return tf.py_function(fallback_auc, (y_true, y_pred), tf.double)  oof_preds = np.zeros((len(X_))) acc_ = [] i=0 skf = StratifiedKFold(n_splits=10) for train_index, test_index in skf.split(X_, y_):     i=i+1     X_train, X_test = X_.iloc[train_index, :], X_.iloc[test_index, :]     X_train = X_train.reset_index(drop=True)     X_test = X_test.reset_index(drop=True)     y_train, y_test = y_.iloc[train_index], y_.iloc[test_index]     y_train = y_train.reset_index(drop=True)     y_test = y_test.reset_index(drop=True)     model = create_model()     model.compile(optimizer=tf.keras.optimizers.Adam(),                   loss=tf.keras.losses.CategoricalCrossentropy(),                    metrics=[auc])     if i%3 == 0:         model.fit(x=X_train,                  y=utils.to_categorical(y_train),                  epochs=400,                  batch_size=1024,                 verbose=0,                 validation_data=(X_test, utils.to_categorical(y_test)),                  callbacks=[tensorboard_callback],                 )     else:         model.fit(x=X_train,                  y=utils.to_categorical(y_train),                  epochs=400,                  batch_size=1024,                 verbose=0,                 validation_data=(X_test, utils.to_categorical(y_test)),                  )     valid_fold_preds = model.predict(X_test)     #print(valid_fold_preds.shape,y_test.shape)     print("ROC accuracy: ")     #oof_preds[test_index] = valid_fold_preds.ravel()     acc = metrics.roc_auc_score(utils.to_categorical(y_test), valid_fold_preds,multi_class="ovr")     acc_.append(acc)     print(acc)     print(classification_report(y_test, np.argmax(valid_fold_preds,axis=1)))     cm = confusion_matrix(y_test, np.argmax(valid_fold_preds,axis=1))     cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]     print(cm.diagonal())     K.clear_session() 

obnaruzhenie ddos atak pri pomoshhi ai ef5d27b - Обнаружение DDos-атак при помощи AIobnaruzhenie ddos atak pri pomoshhi ai b272b13 - Обнаружение DDos-атак при помощи AI

Отчет о классификации в одной из 10 выборок

obnaruzhenie ddos atak pri pomoshhi ai d150ba5 - Обнаружение DDos-атак при помощи AI

Точность определения каждого класса в одной из 10 выборок

obnaruzhenie ddos atak pri pomoshhi ai d338e72 - Обнаружение DDos-атак при помощи AI

Выводы

Даже если у вас недостаточно размеченных данных и их намного меньше, чем неразмеченных, существуют методы машинного обучения с частичным привлечением учителя, которые позволяют получить отличные результаты.

В библиотеке TensorFlow есть индикаторы справедливости, с помощью которых можно оценить точность и производительность моделей машинного обучения.

Используемые инструменты и наборы данных

Данные были предоставлены Университетом Нью-Брансуика.

Для проведения исследований использовались библиотеки TensorFlow, Scikit Learn, Matplotlib, Seaborn.

  • 6 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close