Vers une détection d’intrusion dynamique et continue en utilisant les réseaux de neurones

MISC HS n° 018 | novembre 2018 | Charles Mure - Félix Molina - Mustafizur Shahid - Gregory Blanc
Creative Commons
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
La détection d’intrusion suppose souvent que l’on connaisse ce qu’est une intrusion (détection par signature) ou ce qui relève d’une activité normale (détection d’anomalie). Cependant, le volume de données à traiter dans un réseau et leur complexité brouillent souvent la frontière entre ces deux principales catégories de flux réseau. Les techniques d’apprentissage profond portent la promesse d’une découverte facilitée des caractéristiques qui permettraient de distinguer flux réseau légitimes et intrusions. Cet article se propose d’aborder de manière pratique des résultats de recherche récents en utilisant des outils libres comme Keras et TensorFlow.

À ce jour, de nombreux travaux de recherches, notamment concernant des NIDS (Network Intrusion Detection System, i.e. des systèmes de détection d’intrusion réseau), ont été conduits dans des conditions spécifiques en termes de systèmes, algorithmes, jeux de données utilisés, limitant l’extrapolation des résultats à une cible plus large de systèmes. Ces recherches se basent sur des méthodes d’apprentissage statistique permettant de concevoir des algorithmes encore jamais implémentés dans un système réel, permettant de détecter de nouvelles attaques et de répondre aux problématiques dues au retard constant des outils de sécurité sur les menaces auxquelles les entreprises doivent faire face (vol de données, espionnage, etc.).

Dans cet article, nous nous proposons d’implémenter un système de détection complet basé sur des méthodes d’apprentissage profond et à partir de résultats de recherches parus récemment. Les travaux auxquels nous faisons référence décrivent la manière théorique d’implémenter un tel système. Nous nous proposons de mettre en œuvre les modèles issus de ces travaux, en y apportant les modifications nécessaires au bon fonctionnement et à la déployabilité du système.

Notre objectif est donc la mise en application de résultats de recherches dans un système capable de fonctionner en temps réel sur le réseau. La partie d’apprentissage profond (Deep Learning) du système sera implémentée en suivant les indications des différents articles de recherche et en utilisant le framework TensorFlow ainsi que la bibliothèque Keras permettant d’implémenter rapidement des algorithmes d’apprentissage automatique (Machine Learning). Nous nous intéresserons aux problématiques de gestion des différentes entrées du système de détection, et à celle de la continuité de la surveillance réseau au travers de la mise en place d’un système de traitement de flux de données.

Les données analysées par un IDS proviennent soit des données de paquets entiers, soit des flux de paquets. Dans notre cas, l’IDS considère uniquement les flux, ce qui réduit la quantité de données à analyser. L’implémentation du système a été réalisée en Python et utilise la bibliothèque scikit-learn, très facile à prendre en main et à installer [17].

1. Motivation

Les réseaux gagnant toujours plus en taille et en complexité, il devient dès lors difficile pour un administrateur, voire un opérateur, de surveiller les activités qui s’y produisent et de détecter des anomalies, des incidents ou des activités malveillantes. La quantité de données à traiter, et leur provenance parfois imprécise, pourraient bien se résumer au fameux adage « chercher une aiguille dans une botte de foin ». Dans ce contexte, les algorithmes de Machine Learning peuvent aider à traiter l’immense quantité de données générées par le réseau afin de détecter les attaques. De nombreux travaux ont été réalisés pour mettre au point des systèmes de détection d’attaques en utilisant le Machine Learning [1]. Pouvoir décider qu’une donnée représente un comportement malveillant ou est indicatrice d’un comportement légitime relève de certaines caractéristiques (features) de celle-ci qui vont être traitées par l’algorithme de Machine Learning. Déterminer quelles sont les caractéristiques à utiliser est une étape souvent cruciale lors du développement d’un système de détection basé sur des algorithmes de Machine Learning.

Fig. 1 : Exemple de réseau de neurones simple consistant en une couche d’entrée, une couche de sortie, et entre les deux, une couche de neurones convolutionnels (couche cachée), voir aussi l’article de A. Bouchekif.

Les travaux présentés dans cet article tirent profit des algorithmes de Deep Learning, notamment les réseaux de neurones convolutionnels ou CNN (Convolutional Neural Network). Les réseaux de neurones sont des modèles d’apprentissage automatique inspirés du fonctionnement des neurones biologiques [2]. Un réseau de neurones (voir figure 1) est constitué de plusieurs couches: une couche d’entrée (input layer) constituée des caractéristiques décrivant la donnée (par exemple pour du trafic réseau, taille des paquets, nombre de paquets), une ou plusieurs couches cachées (hidden layer),  et une couche de sortie (output layer) qui émet le résultat de la classification (malveillant ou légitime dans le cas de la détection d’intrusion). Chaque couche prend ses entrées de la sortie de la couche précédente. Chaque neurone d’une couche est ainsi connecté à tous les neurones de la couche précédente. Au niveau d’un neurone, un poids différent est associé à chaque entrée. Les données fournies à l’entrée traversent ainsi le réseau de neurones de couche en couche jusqu’à la couche de sortie où le résultat est émis. Le Deep Learning est un sous-domaine du Machine Learning et fait référence aux réseaux de neurones profonds, c’est-à-dire, les réseaux de neurones constitués d’au moins deux couches cachées [3].

Les algorithmes de Deep Learning permettent d’obtenir de meilleurs résultats que les algorithmes de Machine Learning classiques. En effet, les réseaux de neurones profonds sont capables de détecter des motifs beaucoup plus complexes permettant ainsi de réduire le taux de faux positifs dans le cas d’un IDS. L’autre avantage du Deep Learning est qu’il n’est plus nécessaire de déterminer les features à l’avance. En effet, les réseaux de neurones profonds peuvent à partir d’une représentation très complexe de la donnée sélectionner automatiquement, lors de la phase d’apprentissage, les features les plus pertinentes, ce qui leur permet de trouver des « motifs » afin de classifier la donnée. Les CNN ont premièrement été conçus pour résoudre des problèmes de reconnaissance visuelle par ordinateur et peuvent être optimisés pour résoudre des tâches de classification d’images [4]. En effet, résoudre un problème aussi simple que la détection d’un chat sur une image en utilisant une architecture classique de réseau de neurones artificiels nécessiterait beaucoup trop de calculs et de ressources rendant l’opération impossible à réaliser en pratique. Les CNN constituent un bon point de départ dans le développement d’algorithmes de détection d’attaques. En effet, les CNN ont connu un succès dans de nombreuses applications telles que la reconnaissance faciale, la reconnaissance vocale ou encore le traitement automatisé du langage.

2. Architecture

Dans le domaine de la sécurité des réseaux, deux types de réseaux neuronaux sont majoritairement utilisés, comme en attestent les recherches menées sur le sujet [5] : l'architecture convolutive (CNN) et le perceptron multicouche (MLP - MultiLayer Perceptron). L’avantage majeur des réseaux convolutifs par rapport au MLP est l’utilisation d’un seul poids associé aux entrées de tous les neurones d’une même couche de convolution. Ce qui entraîne une performance globale du système accrue et le traitement par translation reste invariant tout au long du processus [6].

Le modèle CNN que nous avons choisi d’implémenter est composé de plusieurs couches convolutionnelles avec trois étapes de mise en commun (Pooling) – où les neurones d’entrée sont réduits à un nombre moindre de neurones en sortie ; classiquement, nous avons retenu la valeur maximale des neurones en entrée (maximisation) – puis suivi par trois couches entièrement connectés comme dans un réseau neuronal multicouche classique. Nous avons construit une architecture CNN pour extraire finalement 10 catégories correspondant aux classes du jeu de données : soit 9 types d’attaques et une catégorie pour les flux sans danger pour le réseau. Les données pré-traitées sont transmises à travers la couche d'entrée comprenant 16 neurones correspondant aux 16 features décrites dans la section 3 (Jeux de données).

Le modèle (voir figure 2) utilise des filtres de taille 64, 128 et 256 (respectivement 12x64, 4x128 et 2x256 sorties). Les couches de convolution reçoivent donc en entrée plusieurs flux, et calculent la convolution de chacun d'entre eux avec chaque filtre. Les filtres correspondent exactement aux features que l'on souhaite retrouver dans les flux.

Chacun de ces groupes convolutifs est entièrement connecté par l'intermédiaire d’une couche de maximisation (MaxPooling). Ces étapes permettent de réduire la taille des données en entrée de ces couches pour extraire une maximisation de chaque feature en entrée. Cela augmente sa fiabilité en réduisant l’impact d’un écart de valeur des features. La couche dite d'aplatissement (Flatten) permet de réduire le réseau à une seule dimension précédemment créée par les couches convolutives. À la suite de la couche d’aplatissement, nous insérons un réseau neuronal dense connecté à 3 couches avec respectivement 100, 20 et 10 unités. La couche la plus élevée du groupe est entièrement connectée avec 100 sorties vers la couche intermédiaire ayant 20 sorties entièrement connectées à la couche de sortie possédant 10 neurones correspondant aux 10 catégories que nous considérons dans notre étude. Voir pour plus d’explications [3,21].

Fig. 2 : Architecture de notre réseau de neurones convolutionnels permettant de traiter 16 features en entrée via une série de couches de neurones convolutionnels cachés, entrecoupés de couches de mise en commun par maximisation, et d’obtenir en sortie une classification parmi 10 catégories (9 types d’attaques et 1 catégorie bénigne).

3. Jeux de données

Actuellement, il existe peu de jeux de données en accès libre suffisamment récents et complets (diversité et nouveauté des exemples d’attaques) pour permettre un apprentissage performant sur notre réseau de neurones, eu égard à la diversité et à la réalité des flux réseau. Le jeu de données UNSW-NB15 [7] fourni par l’université de Nouvelle-Galles du Sud à Sydney (University of New South Wales, UNSW) fait usage des outils Argus [8] et Bro [9] pour générer 35 features. Une autre partie des features (12) a été calculée manuellement en prenant en compte la séquence chronologique des flux, ce qui permet ainsi d’introduire une notion de temporalité des attaques (par exemple, une attaque par déni de service sera détectée par un ensemble de flux et non par un unique flux anormal). Argus et Bro IDS pouvant fonctionner en temps réel, il est donc plus simple de mettre en place la collecte et le pré-traitement des données dans notre prototype. Nous avons donc préféré tester et réaliser l’apprentissage de notre modèle sur ce jeu de données.

Les données de l'UNSW-NB15 ont été créées par l'outil IXIA PerfectStorm fourni par le Centre Australien de Cybersécurité (Australian Centre for Cyber Security, ACCS). Le jeu de données ainsi créé représente 100 Go de trafic et 2 540 044 enregistrements. Il comprend neuf types d’attaques détaillées dans le tableau ci-dessous.

Une partie de ce jeu de données a été configuré en tant que jeu d'apprentissage et d'essai pour le rendre plus efficace pour la phase d’apprentissage en réduisant par exemple la surreprésentation de certaines classes comme la classe Normal (2 218 761 enregistrements). Le jeu de données d'entraînement contient 175 341 enregistrements et le jeu de données de test contient 82 332 enregistrements. Le tableau ci-dessous contient la distribution pour chaque classe du jeu de données d'entraînement (voir [22]) :

Type Nb d’enregistrements Description
Normal 56 000 Données normales
Fuzzers 18 184 Tentative de suspendre un programme ou un réseau en lui fournissant des données générées au hasard.
Analysis 2 000 Contient différentes attaques de scan de ports, spam et fichiers html des pénétrations.
Backdoors 1 746 Porte dérobée : dans un logiciel, fonctionnalité inconnue de l'utilisateur légitime, qui donne un accès secret au logiciel.
DoS 12 264 Déni de service : tentative malveillante de rendre un serveur ou une ressource réseau inaccessible aux utilisateurs, généralement en interrompant ou en suspendant temporairement les services d'un hôte connecté à Internet.
Exploits 33 393 L'attaquant connaît un problème de sécurité au sein d'un système d'exploitation ou d'un logiciel et exploite cette connaissance en exploitant la vulnérabilité.
Generic 40 000 Une technique qui fonctionne contre tous les block-ciphers (avec un bloc et une taille de clé donnés), sans considération de la structure du block-cipher.
Reconnaissance 10 491 Contient tous les flux qui peuvent simuler des attaques qui recueillent de l'information.
Shellcode 1 133 Un petit morceau de code utilisé comme charge utile dans l'exploitation de la vulnérabilité des logiciels.
Worms 130 Attaquant qui se réplique afin de se propager à d'autres ordinateurs. Souvent, il utilise un réseau informatique pour se répandre, en s'appuyant sur les défaillances de sécurité de l'ordinateur cible pour y accéder.

Afin de réduire la complexité de notre prototype, nous avons suivi une implémentation proposée par A. Valero dans son IDS INsIDES [11]. Sa proposition est d’utiliser uniquement les features provenant d’Argus afin de réduire le temps de traitement (mise en corrélation des données des 2 logiciels) et de prouver que l’on peut créer une solution qui fonctionne uniquement avec des flux de données en temps réel. Ensuite, en utilisant la méthode InfoGainAttributeEval proposée dans le logiciel Weka [11], nous pouvons réduire notre espace de départ en sélectionnant uniquement les features les plus pertinentes et trouver un compromis acceptable entre précision et coût de calcul. Cela nous permet d’extraire 16 features du jeu de données que notre prototype utilisera. La liste des features sélectionnées est détaillée dans le tableau ci-dessous. Les 5 dernières features doivent être implémentées manuellement.

Caractéristique (nom) Description de la caractéristique
dur Durée totale de l’enregistrement
dpkts Nombre de paquets envoyés de la destination à la source
sbytes Nombre d’octets envoyés de la source à la destination
dbytes Nombre d’octets envoyés de la destination à la source
rate Nombre de paquets par seconde
sttl TTL de la source à la destination
dttl TTL de la destination à la source
sload Nombre de bits par seconde pour la source
dload Nombre de bits par seconde pour la destination
smean Moyenne de la taille des paquets de flux transmis par l’adresse IP source
dmean Moyenne de la taille des paquets de flux transmis par l’adresse IP destination
ct_dst_ltm Ratio de connexions vers une même adresse IP destination parmi 100 connexions
ct_src_dport_ltm Ratio de connexions depuis une même adresse IP source vers un même port destination parmi 100 connexions
ct_dst_sport_ltm Ratio de connexions vers une même adresse IP destination depuis un même port source parmi 100 connexions
ct_dst_src_ltm Ratio de connexion depuis une même adresse IP source vers une même adresse IP destination parmi 100 connexions
ct_state_ttl Index fonction de l’état de la connexion et du TTL à la source et/ou à la destination

4. Implémentation

L’implémentation du système se décompose en 2 parties distinctes (voir figure 3). La première permet d’effectuer la phase d’apprentissage et la seconde permet de réaliser la catégorisation des flux réels sur un réseau local.

Fig. 3 : Implémentation du système comprenant une phase d’apprentissage à partir du jeu de données UNSW-NB15, et une phase de test en production à partir des flux capturés dans un réseau local.

Nous avons utilisé Python pour mettre en place notre système de Machine Learning, associé au framework TensorFlow [12] et à la bibliothèque Keras [13]. TensorFlow est un framework open source développé par Google pour le calcul numérique haute performance. Il facilite le déploiement de tâches de calcul sur une variété de plateformes (CPU, GPU, ou le Tensor Processing Unit, TPU de Google), allant des ordinateurs de bureau aux clusters de serveurs, en passant par les périphériques mobiles et terminaux. À l’origine, un framework pour la programmation de flux de données, il est aussi couramment utilisé pour des applications de Machine Learning, telles que des réseaux de neurones. Keras est une API de haut niveau pour la conception et la programmation de réseaux de neurones, écrite en Python et capable de fonctionner au-dessus de TensorFlow, CNTK ou Theano. Elle a été développée dans le but de permettre une expérimentation rapide par un prototypage facile des réseaux de neurones.

4.1 Partie apprentissage

Dans cette partie, la bibliothèque Keras simplifie grandement la mise en place d’un réseau convolutionnel et la réalisation de la phase d’apprentissage. Pour créer un réseau, il faut dans un premier temps déclarer sa forme (quelles sont les différentes couches, leur taille, leur fonction d’activation, etc.). Le CNN est déclaré de la manière suivante :

model = Sequential()

model.add(Conv2D(64, (3, 1), activation='relu', input_shape=(shape, 1, 1)))  # entrée

model.add(Conv2D(64, (3, 1), activation='relu')) # type de couche / taille / fonction d’activation

model.add(MaxPooling2D(pool_size=(2, 1)))

model.add(Conv2D(128, (3, 1), activation='relu'))

model.add(Conv2D(128, (3, 1), activation='relu', padding="same"))

model.add(Conv2D(128, (3, 1), activation='relu', padding="same"))

model.add(MaxPooling2D(pool_size=(2, 1)))

model.add(Conv2D(256, (3, 1), activation='relu', padding="same"))

model.add(Conv2D(256, (3, 1), activation='relu', padding="same"))

model.add(Conv2D(256, (3, 1), activation='relu', padding="same"))

model.add(MaxPooling2D(pool_size=(2, 1)))

model.add(Flatten())

model.add(Dense(100, kernel_initializer='normal', activation='relu'))

model.add(Dropout(0.5))

model.add(Dense(20, kernel_initializer='normal', activation='relu', name='output'))

return model

Chaque ligne permet d’ajouter une nouvelle couche (layer) à notre réseau. Les 11 premières lignes constituent les niveaux convolutionnels (suite de couches Conv2D et MaxPooling2D) qui permet au réseau d’extraire ses propres features. Nous utilisons la fonction d’activation ReLu (Rectified Linear Unit) dans notre modèle. Cette fonction d’activation est la plus utilisée dans les modèles CNN et Deep Learning à l’heure actuelle, car ses propriétés mathématiques permettent d'accélérer la phase d’apprentissage et d’obtenir de meilleurs résultats [14]. Les couches suivantes sont plus classiques et suivent le modèle du perceptron, il s’agit de la partie du réseau agissant comme classifieur.

Ensuite, il suffit de compiler le modèle déclaré puis de réaliser l'apprentissage à partir du jeu de données que vous lui fournissez. Cela s’effectue en 3 lignes de code Python :

model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(lr=0.001), metrics=['categorical_accuracy'])

stopper = EarlyStopping(monitor='categorical_accuracy', patience=2, mode='auto')

model.fit(x_train, y_train, epochs=4, batch_size=50, validation_data=(x_validation, y_validation), callbacks=[stopper])

Quand nous compilons le modèle, nous précisons dans un premier temps la fonction de perte que nous allons utiliser, ici categorical_crossentropy qui est efficace pour les problèmes de classification multiple [15]. Ensuite, nous déclarons l’optimiseur que nous utilisons : Adam [16] ainsi que la valeur du paramètre de taux d’apprentissage (lr pour learning rate). Enfin, nous précisons la métrique que nous souhaitons utiliser pour observer les résultats de notre modèle. L’apprentissage est réalisé à l’aide de la fonction fit, à laquelle nous donnons en paramètres les données d’apprentissage et de validation, ainsi que les valeurs de répétition de l’apprentissage (epochs) et de taille d’échantillon (batch_size). L’utilisation de la bibliothèque scikit-learn [17] permet aussi d'automatiser la recherche des paramètres optimaux pour le modèle, mais nous ne rentrerons pas dans les détails de son utilisation dans cet article.

Cela semble pour l’instant déconcertant de simplicité (si on connaît scikit-learn), mais la partie la plus complexe dans le Machine Learning est généralement la phase de pré-traitement des données pour générer les tableaux x_train, y_train, x_validation et y_validation, qui correspondent aux données d’entrée et de sortie des phases d’apprentissage et de validation. Notre application n’échappe pas à cette règle !

Dans notre jeu de données, les données brutes sont au format CSV et sont composées de chaînes de caractères (string), d’entiers (integer) et de réels (float). Or, le réseau utilise obligatoirement des réels en entrée.

Les pré-traitements à effectuer sont les suivants :

  • isoler les features souhaitées ;
  • encoder les strings à l’aide d’un dictionnaire ;
  • convertir le tableau en floats ;
  • réadapter l’échelle de chaque feature pour ne pas biaiser le système (MinMaxScalar) ;
  • découper de manière aléatoire notre jeu de données pour le séparer en jeux d’apprentissage (train), de validation et de test.

La phase de pré-traitement est généralement propre à chaque jeu de données et par conséquent cette partie du programme doit être ajustée à chaque fois que vous souhaitez tester votre système avec un nouveau jeu de données. Le pré-traitement s’effectue en utilisant la bibliothèque scikit-learn qui contient tout ce qu’il nous faut.

Une fois la phase d’apprentissage réalisée, nous pouvons enregistrer notre modèle ainsi que les poids associés pour le réutiliser dans la seconde phase de notre système : la prédiction/classification.

model_json = model.to_json()

with open("model.json", "w") as json_file:

 json_file.write(model_json)

model.save_weights("model.h5")

4.2 Partie prédiction

La catégorisation d’un flux de données s’effectue simplement à l’aide de Keras en utilisant le modèle extrait lors de la phase d’apprentissage. Cela s’effectue en quelques lignes de code Python, vous pouvez ensuite réécrire la sortie de la prédiction dans un fichier de log pour la réutiliser dans un autre système.

json_file = open('model.json', 'r')

loaded_model_json = json_file.read()

loaded_model = keras.models.model_from_json(loaded_model_json) # chargement du modèle

loaded_model.load_weights("model.h5") # chargement des poids

# compilation

loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

res = loaded_model.predict(data_log) # prédiction à partir de data_log

# écriture dans un fichier de log

Cependant, nous devons maintenant construire correctement notre tableau data_log sur lequel notre réseau va effectuer une prédiction. Pour cela, il faut arriver à extraire les mêmes features depuis le réseau que celles constituant notre jeu de données d’apprentissage.

Pour l’extraction des features depuis les flux collectés par les sondes, nous avons utilisé Argus, qui est un outil open source d’audit de réseau et qui permet de générer des fichiers de log avec des features pré-calculés utiles à la détection de comportements malveillants. Cela nous permet d’extraire directement 11 features que nous utilisons dans notre modèle. Pour les 5 features restantes qui calculent des statistiques basées sur les 100 derniers flux, il est nécessaire de les recalculer à la volée à l’aide d’un script en Python à partir des logs générés par Argus. En utilisant des principes de files d’attente FIFO et de recherche sur des condensats (hashs), nous pouvons exécuter de manière efficace la recherche d’éléments dans les 100 derniers flux.

Ci-dessous, nous présentons un exemple de calcul de la caractéristique ct_dst_sport_ltm.

# pour chaque nouvelle ligne de log

ct_dst_sport_ltm_hash = hash(logline[1] + logline[2]) # IP destination + port source

ct_dst_sport_ltm_list.pop()

ct_dst_sport_ltm_list.insert(0, ct_dst_sport_ltm_hash) # insertion nouveau condensat

# calcul des 4 autres features
...

data_log = log_line + str(ct_dst_sport_ltm_list.count(ct_dst_sport_ltm_hash))] + ...

...

# pré-traitement puis prédiction sur le flux

5. Résultats

Notre modèle CNN nous permet de classer les flux parmi 9 types d’attaques aux caractéristiques significatives. Il y a donc 9 classes d’attaques et une classe pour les flux dits normaux. L’histogramme (voir figure 4) représente les taux de précision, de rappel et de mesure F1 calculés lors de nos tests.

Note

- Précision = nombre de flux correctement classés dans la catégorie i / nombre de flux classés dans la catégorie i
- Rappel = nombre de flux correctement classés dans la catégorie i/nombre de flux de la catégorie i
- Mesure F1 = 2*(Rappel * Précision) / (Rappel + Précision)

Certains types d’attaques comme les attaques par déni de service (DoS) ou les attaques par porte dérobée (backdoor) se sont avérées compliquées à classer par le modèle. L’une des raisons est que pour obtenir un modèle bien entraîné et donc, a priori performant, il faut des jeux de données avec un grand nombre d’éléments de tous types afin de catégoriser la majorité des cas de figure d’attaque. Or la table du nombre d’enregistrements montre que certaines classes ne sont pas très bien représentées dans le jeu de données, car d’autres sont surreprésentées.

Nous pouvons aussi remarquer que le taux de précision de certaines classes est très faible. Ceci est dû au fait que dans ces classes nous trouvons beaucoup de faux positifs au regard des vrais positifs découverts. Les faux positifs proviennent pour la plupart des erreurs de catégorisation. Par exemple, certains flux d’un scan (Reconnaisance) peuvent être catégorisés, par erreur, comme une tentative d’analyse (Analysis). Cela va donc induire des faux positifs dans la catégorie Analysis et réduire sa précision.

Fig. 4 : Résultats de l’évaluation de notre modèle de Deep Learning pour la classification des flux réseau.

De manière générale, nous observons que notre modèle permet de détecter une très grande partie des vrais positifs de chaque classe, à l’exception des classes Backdoor et DoS. En effet, pour que l’IDS soit performant dans la catégorisation des flux de ces classes, il serait peut-être utile de réaliser une inspection profonde des paquets (Deep Packet Inspection ou DPI) ou d’analyser uniquement les en-têtes des paquets, ce qui donnerait des informations sur le type d’application visé.

Cependant, pour mieux percevoir l’intérêt du Machine Learning dans un IDS, nous pouvons effectuer une comparaison avec un IDS plus classique. Nous avons choisi de comparer notre modèle à l’IDS open source Snort [18]. Pour cela, nous avons réalisé la phase d’apprentissage de notre modèle sur 175 341 flux, puis effectué la phase de test sur l’ensemble du jeu de données UNSW-NB15, c’est-à-dire sur les 2 540 047 flux. Concernant le test de Snort, nous nous appuyons sur le résultat d’une précédente étude [10] sur le même jeu de données UNSW-NB15, nous avons utilisé le même jeu de signatures, les matrices de confusion nous confirment que le nombre total de flux est identique. Ce test a été réalisé à l’aide des données brutes (pcap) et de l’outil tcpreplay pour rejouer l’ensemble des échanges sur le réseau. Nous avons montré dans la partie précédente qu’il nous était possible d’extraire les features d’un flux réseau, nous pouvons donc utiliser indifféremment les .pcap ou les .csv pour notre test.

  Prédiction par Snort (précision : 60,87%)
  2 540 047 Attaque Légitime
Catégorie réelle Attaque 7808 313 475
Légitime 680 365 1 538 399
  Prédiction par notre modèle Deep Learning (précision : 97,99%)
  2 540 047 Attaque Légitime
Catégorie réelle Attaque 315 326 5957
Légitime 45 174 2 173 590

Le Machine Learning et plus spécifiquement le Deep Learning est donc capable de surpasser les méthodes plus classiques dans la détection d’intrusion et semble extrêmement prometteur pour développer les prochaines générations d’IDS.

6. Discussion

Néanmoins, nos résultats expérimentaux nous montrent que ces méthodes sont encore perfectibles. Les articles traitant de ce sujet sont aussi très critiquables de part les métriques qu’ils utilisent, mais aussi par le fait qu’ils utilisent des jeux de données peu représentatifs de l’état actuel des réseaux. En effet, bien que le jeu de données NSL-KDD [19] soit correctement construit pour tester un modèle, il est trop éloigné du trafic actuel d’un réseau et représente mal la complexité des attaques actuelles qui génèrent de moins en moins de signaux forts. Notre étude nous a aussi permis de faire le constat que trop peu de jeux de données sont disponibles pour pouvoir entraîner et mettre en place des modèles suffisamment précis. À l’inverse d’un système de détection d’anomalies, un modèle basé sur le Deep Learning nécessite d’avoir une répartition équilibrée entre les différentes classes : 130 flux d’attaques par vers et 56 000 flux de trafic normal ne permettent pas de construire un modèle de classification correct. Cela a pour conséquence de biaiser le système dans la phase d’apprentissage, car les flux normaux auront plus d’impact que les flux d’attaques de vers.

De plus, les jeux de données nous limitent à un nombre réduit de features qui nous empêche d’exploiter d’autres indicateurs dans la détection d’attaques. Par exemple, nous souhaitions mieux prendre en compte la notion de temporalité des attaques dans notre modèle en utilisant des systèmes proches de l’analyse de texte (modèle Long Short Term Memory [20]) qui sont actuellement mis en place dans les chatbots ou encore la prédiction de cours boursier. En effet, les attaques complexes peuvent être réparties entre plusieurs flux et s’étaler sur la durée (attaques APT), ou encore un trafic important la nuit ou le week-end dans une entreprise doit être considéré comme suspect. Les jeux de données n’étant pas horodatés, nous n’avons pas pu exploiter cette notion dans notre modèle.

Conclusion

Nous avons montré qu’il est possible d’utiliser des méthodes de classification basées sur le Deep Learning pour la détection d’intrusion sur un réseau et celles-ci montrent un véritable potentiel par rapport aux méthodes de détection d’anomalies ou bien par rapport aux méthodes basées sur les signatures. Elles permettent de détecter des attaques inconnues et comblent la principale lacune de la détection d’anomalies qui est le manque d’information sur l’attaque (savoir que le trafic est anormal permet difficilement de choisir l’action à mener pour contrer l’attaque potentielle).

Cependant, le modèle proposé ne possède pas une précision suffisamment élevée dans certaines classes pour être utilisé tel quel dans un système en entreprise, mais il est possible de construire un IDS hybride qui reposerait sur un système de détection par signature et par Machine Learning.

Pour que la détection d’intrusion à l’aide du Deep Learning se développe, nous avons besoin d’un grand volume de données catégorisées et d’exemples d’attaques. Or, la plupart des jeux de données disponibles publiquement sont soit trop vieux, soit trop restreints. À l’heure actuelle, la disponibilité de données d’apprentissage reste le plus grand frein au développement de cette technologie en open source.

Enfin, nous avons pu constater qu’il ne s’agit pas d’une simple application du Machine Learning à la sécurité informatique, mais que ce domaine nécessite une compréhension approfondie des diverses attaques d’un point de vue technique (pour définir les features des jeux de données) mais aussi des modèles de ML. Une forte coopération entre les experts en sécurité et en science des données est donc nécessaire pour développer le potentiel de ces méthodes de détection.

Remerciements

Les auteurs souhaitent remercier Télécom SudParis, une école de l’IMT, pour leur avoir permis de conduire ces travaux. L’ensemble du code et des résultats peut être consulté sur le dépôt suivant : https://github.com/CharlesMure/cassiope-NIDS.

Références

[1] A. L. Buczak and E. Guven, A Survey of Data Mining and Machine Learning Methods for Cyber Security Intrusion Detection, IEEE Communications Surveys & Tutorials, vol. 18, no. 2, pp. 1153-1176, 2016.

[2] https://en.wikipedia.org/wiki/Artificial_neural_network

[3] A. Géron, Hands-On Machine Learning with Scikit-Learn and Tensorflow: Concepts, Tools, and Techniques to Build Intelligent Systems (1st ed.). O'Reilly Media, Inc, 2017

[4] V. Tata, Simple Image Classification using Convolutional Neural Network – Deep Learning in python. Medium, décembre 2017. Disponible en ligne : https://becominghuman.ai/building-an-image-classifier-using-deep-learning-in-python-totally-from-a-beginners-perspective-be8dbaf22dd8

[5] M. M. U. Chowdhury, F. Hammond, G. Konowicz, C. Xin, H. Wu and J. Li, A Few-shot Deep Learning Approach for Improved Intrusion Detection. 8th Annual Ubiquitous Computing, Electronics and Mobile Communication Conference (UEMCON). IEEE, 2017

[6] https://fr.wikipedia.org/wiki/R%C3%A9seau_neuronal_convolutif

[7] N. Moustafa and J. Slay, UNSW-NB15: a comprehensive data set for network intrusion detection systems (UNSW-NB15 network data set), Military Communications and Information Systems Conference (MilCIS), 2015. Disponible en ligne : https://www.unsw.adfa.edu.au/unsw-canberra-cyber/cybersecurity/ADFA-NB15-Datasets/

[8] Argus. Disponible en ligne : https://qosient.com/argus/

[9] Bro. Disponible en ligne : https://www.bro.org/

[10] A. Valero León, INsIDES: A new machine learning-based intrusion detection system. Universitat Pompeu Fabra, 2017

[11] Weka. Disponible en ligne : https://www.cs.waikato.ac.nz/ml/weka/

[12] TensorFlow. Disponible en ligne : https://www.tensorflow.org/

[13] Keras. Disponible en ligne : https://keras.io/

[14] P. Ramachandran, B. Zoph, and Q. V. Le, Searching for activation functions, 2017. Disponible en ligne : https://arxiv.org/pdf/1710.05941

[15] Cross-Entropy. Disponible en ligne : http://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html#cross-entropy

[16] D. P. Kingma and J. Ba, Adam: A method for stochastic optimization, 2014. Disponible en ligne : https://arxiv.org/pdf/1412.6980

[17] Scikit-learn. Disponible en ligne : http://scikit-learn.org/stable/

[18] Snort. Disponible en ligne : https://www.snort.org

[19] M. Tavallaee, E. Bagheri, W. Lu, and A. Ghorbani, A Detailed Analysis of the KDD CUP 99 Data Set, Second IEEE Symposium on Computational Intelligence for Security and Defense Applications (CISDA), 2009. Disponible en ligne : https://www.unb.ca/cic/datasets/nsl.html

[20] J. Schmidhuber, Long Short-Term Memory. Disponible en ligne : http://people.idsia.ch/~juergen/rnn.html

[21] F. Chollet, Deep learning with Python, Manning Publications Co., 2018.

[22] N. Mustapha et J. Slay, UNSW-NB15: a comprehensive data set for network intrusion detection systems (UNSW-NB15 network data set), Military Communications and Information Systems Conference (MilCIS), 2015