Home / Informatique / Administration système / Qu’est-ce que Snort et comment ça fonctionne ?

Qu’est-ce que Snort et comment ça fonctionne ?

Introduction

Snort est un NIDS (Network Intrusion Detection System) open source, créé en 1998 et distribué sous licence GNU 89. Il est actuellement maintenu par SourceFire qui est propriété de Cisco.

Un NDIS est un logiciel utilisé pour monitorer le trafic réseau. Pour cela, il va analyser tous les paquets qui passent par ce dernier. Les activités anormales peuvent être loggées, générer des alertes ou encore est rejetées. Pour les détecter, ce type de logiciel utilise une table de signatures. La machine qui hôte le NIDS est habituellement appelée un capteur ou une sonde. Elle peut être localisée à différents endroits du réseau selon l’objectif recherché (habituellement derrière le pare-feux). Il est possible d’utiliser le détecteur d’intrusions en mode lecture seule ou en mode interception. Dans le second cas seulement, il sera possible de rejeter les paquets. Snort est plus adapté pour les réseaux de petite taille [1] mais il est le NIDS le plus utilisé, en faisant, de facto, un standard.

Cet article explique comment est structuré Snort au niveau architectural et comment il fonctionne. La gestion des règles sera ensuite détaillée en s’appuyant sur plusieurs exemples de règles utilisant PCRE.

L’architecture de Snort

Figure 1: Fonctionnement de Snort [5]
Étant un NIDS, Snort est séparé en quatre parties distinctes, chacune était chargé d’exécuter des opérations spécifiques. Ces dernières sont : le décoder de paquets, les pré-processeurs, le moteur de détection et la système de logs/alertes. La Figure 1 montre comment elles interagissent entre-elles.

Le décodeur de paquets

Le décodeur de paquets est le premier à être appelé par Snort. Il reçoit les paquets bruts, fournis par la LibPcap. Puis, une chaine des trois décodeurs va analyser chaque paquet. Chacun de ces décodeurs est assigné à une couche précise du modèle TCP/IP (dans cet ordre : Liaison, Réseau, Transport). Pendant le processus, des structures de données sont remplies pour rendre l’usage futur du contenu des paquets plus facile.

Les Pré-Processeurs

Les pré-processeurs sont les seconds à être appelés par Snort, juste après le décodeur de paquets. Il y a deux type de processeurs. Le premier va seulement être chargé d’examiner les paquets. Le second, quand à lui va faire en sorte qu’ils soient plus facilement exploitables. Un certain nombre de pré-processeurs sont fournis dans la configuration de base mais il est également possible pour l’utilisateur d’en ajouter et de choisir lesquels activer ou non.

L’examinateur de paquets

Ce type de pré-processeur est utilisé pour détecter les activités suspicieuses. Par exemple, un header UDP plus petit que huit octets. Si une anomalie est détectée, alors, Snort arrête le traitement du paquet et notifie l’erreur au plugin de sortie (logs/alertes). L’examinateur de paquets permet d’améliorer la détection des attaques et détectant certaines d’entre elles qui ne pourrait pas l’être avec la correspondance des signatures [6]. Par exemple, le pré-processeur ARP spoof est utilisé pour détecter le trafic ARP anormal.

Le modificateur de paquets

Le modificateur de paquets va faire en sorte que le moteur de détection soit en mesure de lire les données contenues dans les paquets dans les meilleures conditions possible. Pour cela, il va par exemple défragmenter les données des paquets, remplacer les caractères hexadécimaux, assembler les paquets, … Ces opérations vont permettre de faire en sorte qu’il soit plus compliqué pour un pirate de tromper le moteur de détection d’une part mais aussi de normaliser les paquets pour rendre le travail du moteur de détection plus facile.

Le moteur de détection

Le moteur de détection est le cœur de Snort. Il est chargé de la détection des signatures. Snort est livré avec un certain nombre de règles et il est bien entendu possible d’en ajouter ou de modifier celles qui sont existantes. Les règles sont chargées au lancement du logiciel et stockées dans deux listes. La première contient les entêtes des règles (les conditions de base pour matcher et les actions à effectuer). La seconde contient les options des règles (filtres plus précis, priorité des règles, message à envoyé si la règle match, …). Une fois les règles chargées, Snort construit un arbre de décisions pour décider quelles règles opérer.

Dans la version 1.0, le moteur était programmé pour arrêter d’évaluer les règles à la première correspondance. Ce qui était bien entendu un problème : les règles avec une priorité faible pouvaient être vérifiées avant les règles plus importante. Cela pouvait conduire à logger uniquement une alerte peu importantes alors que des choses plus graves se passaient derrière. Ce problème de sécurité a été résolu dans la version 2.0 avec un réécriture complète du moteur. A présent, toutes les règles sont évaluées et la plus importante est loggée.

Cette partie est la plus critique en termes de performances. L’efficacité du programme peut déprendre du nombre de règles prises en comptes par le moteur, par la charge du réseau ou encore par la puissance de la machine.

Le plugin de sortie

Cette partie du programme est la dernière à être appelé. Elle permet de notifier l’administrateur qu’un problème a été rencontré. Il y a deux options. Il est possible de logger le paquet qui a matché avec la règle et/ou de générer une alerte.

Les alertes peuvent être envoyées de différentes manières. Il est possible de les faire apparaitre dans les logs du système, d’envoyer une alerte SMB pour Windows ou son équivalent Unix. Il est également possible pour l’utilisateur d’ajouter d’autres plugins pour mieux correspondre à ses besoins.

Les règles Snort

Structure

Les règles Snort utilisent un stucture simple mas efficace. Dans cette partie, je vais utiliser un exemple très simple pour monter leur fonctionnement. La règle va lancer une alerte si une IP en dehors du réseau 192.168.0.0/24 accède au port 21 (SSH) de n’importe quelle machine du réseau en utilisant le protocole TCP.

alert tcp !192.168.0.0/24 anyany 21 (msg:”SSH root…”;content: »root »; pcre: »/user\s+root/i »;)

Entête de la règle

La première partie de l’exemple (avant les parenthèses) contient les éléments généraux à propos du réseau et de l’action de la règle. Tous ces éléments seront toujours présent dans le même ordre. « alert » définit l’action à prendre si la règle match. Il y a d’autre possibilités offertes de base : « log », « pass », « activate » et « dynamic ». Il est également possible pour l’utilisateur de définir ses propres actions. Le protocole vient ensuite. Il peut être, par exemple « ip », « tcp » ou encore « udp ». Les parties en gras sont l’IP ou le network de la source et de la destination. Les parties soulignées sont les ports source et destination. Il est bien entendu possible de choisir plusieurs ports spécifiques ou un intervalle.

La flèche signifie que l’on surveille les paquets qui arrivent sur le réseau. Si elle était dans l’autre sens, ce serait les paquets qui en sortent. Il est également possible de surveiller les deux avec « <> ».

Options de la règle

La partie entre parenthèses contient les options de la règle. On pourra y trouver le message a mettre dans l’alerte mais aussi un certain nombre d’autres options pour rendre la détection plus précise ainsi que certaines options générales comme l’id de la règle.

Dans notre exemple, si une connexion arrive depuis l’extérieur du réseau sur le port 21, le contenu du paquet va être inspecté à la recherche du l’expression « user root ». Dans le cas où le contenu match, une alerte disant ‘SSH root » va être déclanchée. Dans le cas contraitre, rien ne se produira.

PCRE matching

PCRE est l’abbréviation de Pearl Compatible Regular Expression (RegEx). C’est une librairie qui permet d’utiliser les expressions régulières. et qui est connue pour être l’une des plus puissantes. Les RegEx sont utiles pour faire matcher des expressions avec des données. Par exemple, ils peuvent être utilisés pour détecter un numéro de téléphone ou un email.

Ajouter le support de PCRE dans snort est utile pour plusieurs raisons. Dans un premier temps il permet de détecter des patterns qui ne pourraient pas être détectés avec le simple match. Dans un second temps, cela permet de créer un expression qui pourra correspondre avec un certain nombre de chaines différentes, permettant ainsi de réduire le nombre de règles et donc de réduire le coût de traitement. Pour finir, cela peut être utilisé pour dététer si certaines données fuites en dehors du réseau ou certains évènements précis comme quelqu’un qui s’identifie avec succès en root par FTP.

Exemples avancés

Nous allons maintenant voir quatre exemples de règles Snort qui utilisent PCRE :

  1. alert ip any any <> any any (msg: »Alert message » ; pcre: »/(?i)SECURITY/ »; sid:42;)

  2. alert ip any any <> any any (msg: »Alert message » ; pcre: »/Hello([ ]+)world/ »; sid:42;)

  3. alert ip any any -> any 25 (msg: »Alert message » ; pcre: »/\ »[A-Z]([a-zA-Z]{3,6})\ »/ »; sid:42;)

  4. alert ip any any -> any [80, 443] (msg: »Alert message » ; pcre: »/(?i)(?!BG)(?!GB)(?!NK)(?!KN)(?!TN)(?!NT)(?!ZZ)[A-CEGHJ-PR-TW-Z]{2}(?:(\s{0,1}|[-])\d){6}(?:\s{0,1}|[-])[A-D]/ »; sid:42;)

Dans un premier temps, nous pouvons voir que les règles présentent plusieurs similarité. Toutes lancent une alerte disant « Alert message » si elles matchent avec le paquet. Dans un second temps, afin de monitorer à la fois le trafic tcp et udp, le protocole qui est surveillé est IP.

La première règle va chercher le mot « security » dans les paquets qui transitent sur le réseau. Pour être sir que la case n’interfère pas, « (?i) » qui permet de ne pas la prendre en compte a été utilisé. Ainsi, par exemple, « securitY » ou encore « SeCUrity » seront valides. Nous pouvons voir que la règle utilise any partout, elle surveillera donc tous les paquets qui transitent, et ce, dans les deux sens (grâce à « <> »).

La seconde règle va vérifier si les paquets qui transitent contiennent le mot « Hello world ». A l’aide de “([ ]+)”. Le contenu des crochets spécifie les caractères autorisés entre les deux mots. Dans notre cas, un espace. Afin d’autoriser un nombre d’espace supérieur à un, nous ajoutons un « + » après les crochets.

La troisième règle est un peu plus complexe. Elle va chercher un mot, encadré par des guillemets et qui commence par une majuscule et qui est suivi par trois à six lettres. Ce mot sera recherché dans les paquets qui sont envoyé à un serveur mail. Dans cet optique, nous utilisons une flèche pour ne récupérer le trafic que dans un sens. Le port utilisé par les mails et le port 25. Nous ne surveillons pas les autres puisqu’ils contiennent le trafic chiffré. Il y a quelques changements de syntaxe comparé à la règle précédente. Dans un premier temps, le backslash (caractère d’échappement) va être utilisé afin de pouvoir inclure les guillemets dans la règle.  Dans un second temps, nous allons réutiliser les crochets mais pour définir un intervalle. Ainsi, « [A-Z] » autorise toutes les lettres majuscules. Il est possible de les mettre à la suite. par exemple, « [A-Za-z] » va autoriser tout l’alphabet sans tenir compte de la case. Les accolades derrière permettent de dire combien de caractères correspondant à cette expression sont autorisé. Ici, entre 3 et 6.

La dernière règle va vérifier la présence d’un numéro de sécurité sociale anglais dans les paquets à destination d’un serveur web. Dans ce cas, nous capturons aussi le trafic vers le port 443 (SSL) car il est possible de mettre le numéro dans les metadata qui ne seront pas chiffrées. Les formes les plus courantes d’écritures de ce numéro seront vérifiées. Par exemple “AZ123456A” et “az 12 34 56 a” doivent tout deux être valides. Une fois encore, de nouvelles syntaxe ont été utilisées dans cette règle. Dans un premier temps, nous ne voulons pas que le numéro commence par certaines associations de lettres telles que « BG » ou « ZZ ». Les mettre sous la forme « (?!ZZ) » permet de refuser le fait qu’ils soient présents au début de la chaine. Cette syntaxe est appelée « negative hook ahead ». La syntaxe “(?:contenu)” permet de créer ce qui est appelé « un groupe de non capture » (différent de « (contenu) » qui un « groupe de capture »). Cela permet de ne pas sauver l’expression qui est matchée pour un usage futur. Par example, “(?:(\s{0,1}|[-])\d)” va matcher tout groupe qui commence avec un caractère vide (« \s » = espace, tabulations …) ou un tiret et a un nombre décimal (« \d » est équivalent à « [0-9] »). Finalement, la règle utilise un pipe qui correspond à une condition de type « ou ».

Conclusion

Snort est composé de quatre parties que sont le décodeur de paquets, les pré-processeurs, le moteur de détection et les plugins de sortie. Les deux premiers vont dans les grandes lignes reformater les paquets pour faciliter le travail du moteur de détection qui est la partie la plus importante du programme. Finalement, la plugin de sortie peut être appelé pour afficher des informations. Pour détecter les menaces, Snort va générer des signatures en parsant les règles. Les signatures seront ensuite comparées à chaque paquets et, si la signature match, différentes actions peuvent être prises. Les règles Snorts utilisent une syntaxe simple et efficace qui permet de choisir les adresses, ports, protocoles, contenu et état des paquets à vérifier. Il permet aussi d’utiliser les RegEx pour améliorer la fiabilité des règles ainsi que leur possibilités.

Même si Snort est un outils efficace pour améliorer la sécurité dans un réseau. Il souffre de quelques faiblesses. Dans un premier temps, il ne sera pas capable de détecter toutes les attaques qui n’ont pas de signature correspondante dans sa base de données (certains pré-processeurs sont utilisés pour cela mais le taux de succès n’est pas si haut que ça). Pour finir, les performances peuvent être un problème selon la puissance de la machine et la charge sur le réseau.

Références

  1. Martin Roesch (1999) . Snort – Lightweight Intrusion Detection for Networks. Available : https://www.usenix.org/legacy/event/lisa99/full_papers/roesch/roesch.pdf. Dernier accès : 02/16/2016.

  2. Cisco. Snort License. Available : https://www.snort.org/license. Dernier accès : 02/16/2016.

  3. Snort Team (2015). Snort User Manual. Available : https://www.snort.org/documents/snort-users-manual-html. Dernier accès 02/16/2016.

  4. Snort Team (2015). Snort FAQ. Available : https://www.snort.org/faq. Dernier accès : 02/16/2016.

  5. Jack Koziol (2003). Intrusion Detection with Snort. Indianapolis, Sams.

  6. Rafeeq Ur Rehman (2003). Intrusion Detection Systems with Snort. New Jersey, Pearson Education.

  7. Wikipedia. Available : http://en.wikipedia.org/wiki/National_Insurance_number. Dernier accès : 02/24/2016.

Voir aussi

Cable RJ45

Configurer son serveur DNS avec Bind

Dans ce tutoriel, nous allons voir comment configurer un serveur DNS. Comme c’est précisé dans …

Laisser un commentaire