L'écriture de règles Snort

version originale par Martin Roesch
traduction française par Denis Ducamp

24 janvier 2001 - version 1.7 / traduction française 29 avril 2001


Comment écrire des règles Snort et garder son équilibre mental

1. Les bases

Snort utilise un langage simple et léger de description de règles qui est flexible et assez puissant. Il y a nombre d'indications simples à se souvenir en développant des règles Snort.

La première est que les règles Snort doivent être complètement contenues sur une seule ligne, l'analyseur de règles de Snort ne sait pas comment traiter des règles sur plusieurs lignes.

Les règles Snort sont divisées en deux sections logiques, l'entête de la règle et les options de la règle. L'entête de règle contient comme informations l'action de la règle, le protocole, les adresses IP source et destination et les masques réseau, et les ports source et destination. La section options de la règle contient les messages d'alerte et les informations sur les parties du paquet qui doivent être inspectées pour déterminer si l'action de la règle doit être acceptée.

Voici une règle d'exemple :


alert tcp any any -> 192.168.1.0/24 111 (content:"|00 01 86 a5|"; msg: "mountd access";)

Figure 1 - Exemple de règle Snort

Le texte jusqu'à la première parenthèse est l'entête de règle et la section entourée par les parenthèses est les options de la règle. Les mots avant les deux-points dans la section des options de la règle sont appelés les mots clés des options. Notez que la section des options de la règle n'est spécifiquement requise par aucune règle, elles sont juste utilisées pour le bien de rendre plus strictes les définitions des paquets à collecter ou à alarmer (ou à ignorer, d'ailleurs). Tous les éléments dans cette composition de règle doivent être vrais pour que l'action de règle indiquée soit acceptée. En les prenant ensembles, les éléments peuvent être considérés comme formant la déclaration d'un ET logique. En même temps, les diverses règles dans un fichier bibliothèque de règles Snort peuvent être considérées comme formant une large déclaration d'un OU logique. Commençons par parler à propos de la section d'entête de règle.

1.1 Les inclusions

Le mot clé include permet à d'autres fichiers de règles d'être inclus dans le fichier de règles indiqué sur la ligne de commande de Snort. Il fonctionne beaucoup comme un "#include" du langage de programmation C, lisant le contenu de fichier nommé et les mettant en place dans le fichier à la place où l'include apparaît.

Format :

include: <répertoire/nom du fichier include>

Notez qu'il n'y a pas de point-virgule à la fin de la ligne. Les fichiers inclus substitueront toute valeur de variable prédéfinie dans le fichier de règles de Snort.

1.2 Les variables

Des variables peuvent être définies dans Snort. Ce sont de simples substitutions des variables fixées avec le mot clé var comme dans la Figure 2.

Format :

var: <nom> <valeur>


var MY_NET [192.168.1.0/24,10.1.1.0/24]
alert tcp any any -> $MY_NET any (flags: S; msg: "SYN packet";)

Figure 2 - Exemple de définition et d'utilisation de variable

Les noms de variables de règles peuvent être modifiées de plusieurs façons. Vous pouvez définir des méta-variables en utilisant l'opérateur "$". Celles-ci peuvent être utilisées avec les opérateurs de modification de variables, "?" et "-".

Voir Figure 3 pour un exemple de ces modificateurs de règles en action.


var MY_NET $(MY_NET:-192.168.1.0/24)
log tcp any any -> $(MY_NET:?MY_NET is undefined!) 23

Figure 3 - Exemple d'utilisation avancée de variable

2. Les entêtes de règle

2.1 L'action de règle

L'entête de règle contient l'information qui défini le "qui, où, et quoi" d'un paquet, ainsi que quoi faire dans l'événement où le paquet avec tous les attributs indiqués dans la règle devrait se présenter. Le premier élément dans une règle est l'action de règle. L'action de règle dit à Snort quoi faire quand il trouve un paquet qui correspond aux critères de la règle. Il y a cinq actions accessibles par défaut dans Snort, alert, log, pass, activate, et dynamic.

Vous pouvez aussi définir vos propres types de règles et associer un ou plusieurs plugins de sortie avec eux. Vous pouvez alors utiliser le type de règle comme action dans les règles Snort.

Cet exemple créera un type qui journalisera juste vers tcpdump :

            ruletype suspicious 
            { 
                type log 
                output log_tcpdump: suspicious.log 
            }

Cet exemple créera un type de règle qui journalisera vers syslog et une base de données mysql :

            ruletype redalert 
            { 
                type alert 
                output alert_syslog: LOG_AUTH LOG_ALERT 
                output database: log, mysql, user=snort dbname=snort host=localhost 
            } 

2.2 Les protocoles

Le champ suivant dans une règle est le protocole. Il y a trois protocoles IP que Snort analyse actuellement pour des comportements suspicieux, tcp, udp, et icmp. Dans le futur il pourra y en avoir plus, tels que ARP, IGRP, GRE, OSPF, RIP, IPX, etc.

2.3 Les adresses IP

La section suivante de l'entête de règle s'occupe comme information de l'adresse IP et du port pour une règle donnée. Le mot clé "any" peut être utilisé pour définir n'importe quelle adresse. Snort n'a pas de mécanisme pour fournir de la résolution de nom pour le champ de l'adresse IP dans le fichier de règles. Les adresses sont formées par une simple adresse IP numérique et un bloc CIDR. Le bloc CIDR indique le masque réseau qui doit être appliqué à l'adresse de la règle et à tout paquet qui est testé par rapport à la règle. Un masque de bloc CIDR de /24 indique un réseau de classe C, /16 un réseau de classe B, et /32 indique l'adresse spécifique d'une machine. Par exemple, la combinaison d'adresse/CIDR 192.168.1.0/24 devrait signifier le bloc d'adresses de 192.168.1.1 à 192.168.1.255. Toute règle qui utilise cette désignation pour, disons, l'adresse destination devrait correspondre à toute adresse dans cet intervalle. Les désignations CIDR nous donne une façon rapide de désigner de larges espaces d'adresses avec juste quelques caractères.

Dans la Figure 1, l'adresse IP source était fixée pour correspondre à tout ordinateur parlant, et l'adresse destination était fixée pour correspondre au réseau de classe C 192.168.1.0 .

Il y a un opérateur qui peut être appliqué aux adresses IP, l'opérateur de négation. Cet opérateur dit à Snort de correspondre à toute adresse IP sauf celles indiquées par la liste d'adresses IP. L'opérateur de négation est indiqué par un "!". Par exemple, une modification facile à l'exemple initial est de le faire alerter sur tout trafic qui provient de l'extérieur du réseau local avec l'opérateur de négation comme montré dans la Figure 4.


alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 111 (content: "|00 01 86 a5|"; msg: "external mountd access";)

Figure 4 - Un exemple de règle avec négation d'adresse IP

Ces adresses IP de la règle indiquent "tout paquet tcp avec une adresse source ne provenant pas du réseau interne et à destination du réseau interne".

Vous pouvez aussi spécifier des listes d'adresses IP. Une liste IP spécifiée en entourant une liste d'adresses IP et de blocs CIDR séparés par des virgules entre crochets. Pour le moment, une liste IP ne peut pas inclure d'espaces entre les adresses. Voir la Figure 3 pour un exemple de liste IP en action.


alert tcp ![192.168.1.0/24,10.1.1.0/24] any -> [192.168.1.0/24,10.1.1.0/24] 111 (content: "|00 01 86 a5|"; msg: "external mountd access";)

2.4 Les numéros de ports

Les numéros de ports peuvent être spécifiés de nombre de façons, incluant "any" (ndt : tous les ports), des définitions de ports statiques, des intervalles et des négations. Les ports "any" sont les valeurs génériques, signifiant littéralement tous les ports. Les ports statiques sont indiqués par un seul numéro de port, tel que 111 pour portmapper, 23 pour telnet, ou 80 pour http, etc. Les intervalles de ports sont indiqués avec l'opérateur d'intervalle ":". L'opérateur d'intervalle peut être appliqué dans nombre de façons pour prendre différentes significations, tel que dans la Figure 5.


log udp any any -> 192.168.1.0/24 1:1024
journalise le trafic udp provenant de tout port et à destination de ports dans l'intervalle de 1 à 1024
log tcp any any -> 192.168.1.0/24 :6000
journalise le trafic tcp depuis tout port et allant vers les ports inférieurs ou égaux à 6000
log tcp any :1024 -> 192.168.1.0/24 500:
journalise le trafic tcp depuis les ports privilégiés inférieurs ou égaux à 1024 allant vers les ports supérieurs ou égaux à 500

Figure 5 - Exemples d'intervalles de ports

La négation de port est indiquée en utilisant l'opérateur de négation "!". L'opérateur de négation peut être appliqué à tous les autres types de règles (excepté "any", qui se traduirait en aucun, combien ce serait Zen...). Par exemple, si pour quelque raison tordue vous voulez tout journaliser sauf les ports X Windows, vous pourriez faire quelque chose comme la règle dans la Figure 6.


log tcp any any -> 192.168.1.0/24 !6000:6010

Figure 6 - Exemple de négation de port

2.5 L'opérateur de direction

L'opérateur de direction "->" indique l'orientation, ou la "direction", du trafic auquel la règle s'applique. L'adresse IP et les numéros de ports du côté gauche de l'opérateur de direction est considéré comme le trafic provenant du système source, et les informations d'adresse et de port du côté droit de l'opérateur est le système destination. Il y a aussi un opérateur bidirectionel, qui est indiqué par le symbole "<>". Ceci dit à Snort de considérer les paires adresse/port ou bien en source ou bien en destination de l'orientation. C'est utile pour enregistrer/analyser les deux côtés d'une conversation, tel que des sessions telnet ou POP3. Un exemple de l'opérateur bidirectionel étant utilisé pour enregistrer les deux côtés d'une session telnet est montré en Figure 7.


log !192.168.1.0/24 any <> 192.168.1.0/24 23

Figure 7 - Une règle Snort utilisant l'opérateur bidirectionel

2.6 Les règles activate/dynamic

Les paires de règles activate/dynamic donnent à Snort une capacité puissante. Vous pouvez maintenant avoir une règle qui en active une autre pour un nombre fixé de paquets quand son action est accomplie. Ceci est très utile si vous voulez configurer Snort pour effectuer l'enregistrement de ce qui suit quand une règle spécifique "se désactive". Les règles d'activation se comportent juste comme les règles alert, excepté qu'elles ont un champ d'option *obligatoire* : "activates". Les règles dynamiques se comportent juste comme les règles log, mais elles ont un champ d'option différent : "activated_by". Les règles dynamiques ont également un second champ obligatoire, "count". Quand la règle "activate" se désactive, elle active la règle dynamique qui lui est liée (indiquée par les numéros d'option activates/activated_by) pour "count" paquets (50 dans ce cas).

Mettez les ensembles et elles ressemblent à ceci :


activate tcp !$HOME_NET any -> $HOME_NET 143 (flags: PA; content: "|E8C0FFFFFF|\bin|; activates: 1; msg: "IMAP buffer overflow!";)

dynamic tcp !$HOME_NET any -> $HOME_NET 143 (activated_by: 1; count: 50;)

Figure 8 - exemple de règles activate/dynamic

Ces règles disent à Snort d'alerter quand il détecte un débordement de tampon dans IMAP et collecte les 50 prochains paquets destinés au port 143 provenant de l'extérieur de $HOME_NET et destinés à $HOME_NET. Si le débordement de tampon arrive et a réussi, il y a de très bonnes possibilités que des données utiles seront contenues dans les prochains 50 (ou quel que soit) paquets allant au même port de service sur le réseau, ainsi il y a avantage à collecter ces paquets pour une analyse ultérieure.

3. Les options de règle

Les options de règle forment le coeur du moteur de détection d'intrusion de Snort, combinant facilité d'utilisation, puissance et flexibilité. Toutes les options de règle de Snort sont séparées les unes des autres par un caractère point virgule ";". Les mots clés des options de règle sont séparés de leurs arguments avec un caractère deux points ":". Au moment de la rédaction, il y a 15 mots clé d'option de règle disponibles dans Snort :

3.1 Msg

L'option de règle msg dit au moteur de journalisation et d'alerte le message à imprimer avec une sauvegarde du paquet ou une alerte. C'est une simple chaîne texte qui utilise "\" comme caractère d'échappement pour indiquer un caractère discret qui pourrait autrement rendre confus l'analyseur de règles de Snort (tel que le caractère point virgule ";").

Format :

msg: "<message texte>";

3.2 Logto

L'option logto dit à Snort de journaliser tous les paquets qui déclenchent cette règle vers un fichier journal de sortie spécial. C'est spécialement pratique pour combiner les données de choses comme les activités NMAP, les scans CGI HTTP, etc. Il doit être noté que cette option ne marche pas quand Snort est en mode de journalisation binaire.

Format :

logto: "<nom de fichier>";

3.3 TTL

Cette règle d'option est utilisée pour fixer la valeur time-to-live à tester. Le test qu'il effectué est réussi seulement sur une correspondance exacte. Ce mot de clé d'option était destiné à être utilisé pour détecter les tentatives de traceroute.

Format :

ttl: "<nombre>";

3.4 TOS

Le mot clé "tos" vous permet de vérifier le champ TOS de l'entête IP pour une valeur spécifique. Le test effectué est réussi seulement sur une correspondance exacte.

Format :

tos: "<nombre>";

3.5 ID

Ce mot clé d'option est utilisé pour tester une correspondance exacte dans le champ ID de fragment de l'entête IP. Quelques programmes de pirates (et d'autres programmes) fixent ce champ spécifiquement pour différents besoins, par exemple la valeur 31337 est très populaire avec certains pirates. Ceci peut être retourné contre eux en mettant en place une simple règle pour tester ceci et quelques autres "nombres de pirates".

Format :

id: "<nombre>";

3.6 Ipoption

Si des options IP sont présentes dans un paquet, cette option va chercher l'utilisation d'une option spécifique, tel que le routage par la source. Les arguments valides de cette option sont :

Les options IP les plus fréquemment regardées sont les routages vague et stricte par la source qui ne sont utilisés dans aucune application Internet. Seulement une seule option peut être spécifiée par règle.

Format :

ipopts: <option>;

3.7 Fragbits

Cette règle inspecte les bits de fragment et le bit réservé dans l'entête IP. Il y a trois bits qui peuvent être vérifiés, le bit Reserved Bit (RB), le bit More Fragments (MF) et le bit Dont Fragment (DF). Ces bits peuvent être vérifiés pour une variété de combinaisons. Utilisez les valeurs suivantes pour indiquer les bits spécifiques :

Vous pouvez également utiliser des modificateurs pour indiquer des critères logiques de correspondance pour les bits spécifiés :

Format :

fragbits: <valeurs des bits>;


alert tcp !$HOME_NET any -> $HOME_NET any (fragbits: R+; msg: "Reserved IP bit set!";)

Figure 9 - Exemple d'utilisation de la détection par fragbits

3.8 Dsize

L'option dsize est utilisée pour tester la taille de la charge du paquet. Il peut être fixé à toute valeur, utilise en plus les signes supérieur/inférieur pour indiquer des intervalles et des limites. Par exemple, si vous savez qu'un certain service a un tampon d'une certaine taille, vous pouvez fixer cette option pour regarder les tentatives de débordement de tampons. Cela a l'avantage supplémentaire d'être une façon bien plus rapide de tester contre les débordements de tampons qu'une vérification de contenu de la charge.

Format :

dsize: [>|<] <nombre>;

Note : Les opérateurs > et < sont optionnels !

3.9 Content

Le mot clé content est une des fonctionnalités les plus importantes de Snort. Il autorise l'utilisateur de fixer des règles qui recherchent un contenu spécifique dans la charge du paquet et déclencher une réponse basée sur les données. A chaque fois que l'option content de correspondance de motif est exécutée, la fonction de correspondance de motif de Boyer-Moore est appelée et le test (plutôt cher en temps de calcul) est effectué contre le contenu du paquet. Si une donnée correspondant exactement à la chaîne de donnée en argument est contenue n'importe où dans la charge de paquet, le test est réussi et le reste des options de la règle est exécutée. Sachez que ce test fait la différence entre majuscules et minuscules.

La donnée d'option pour le mot clé content est quelque peu complexe; il peut contenir du texte et des données binaires mélangées. Les données binaires sont généralement entourées dans des caractères barre verticale ("|") et représentées en tant que bytecode. Un bytecode représente une donnée binaire comme des nombres hexadécimaux et c'est une bonne méthode de raccourci pour décrire des données binaires complexes. La Figure 7 contient un exemple de mélange de textes et de données binaires dans une règle Snort.


alert tcp any any -> 192.168.1.0/24 143 (content: "|90C8 C0FF FFFF|/bin/sh"; msg: "IMAP buffer overflow!";)

Figure 10 - Mélange de bytecode binaire et de texte dans une option de règle content

Format :

content: "<chaîne de contenu>";

3.10 Offset

L'option de règle offset est utilisée comme un modificateur des règles utilisant le mot clé d'option content. Ce mot clé modifie la position de début de recherche pour la fonction de correspondance de motif depuis le début de la charge du paquet. Il est très utile pour des choses comme des règles de détection de scans CGI où la chaîne de recherche de contenu n'est jamais trouvée dans les quatre premiers octets de la charge. Soin doit être pris à ne pas fixer la valeur offset trop strictement sous peine de manquer potentiellement une attaque ! Ce mot clé d'option de règle ne peut pas être utilisé sans spécifier également l'option de règle content.

Format :

offset: <nombre>;

3.11 Depth

Depth est une autre modification de l'option de règle content. Ceci fixe la profondeur maximale de recherche dans la fonction content de correspondance de motif de recherche depuis le début de sa région de recherche. Il est utile pour limiter la fonction de correspondance de motif d'exécuter des recherches inefficaces une fois que la région de recherche probable pour un ensemble de contenus donné a été dépassée. (C'est à dire que si vous recherchez "cgi-bin/phf" dans un paquet relatif au web, vous n'avez probablement pas besoin de perdre du temps à rechercher dans la charge après les 20 premiers octets!) Voir la Figure 8 pour un exemple de règle de recherche combinant content, offset et depth.

Format :

depth: <nombre>;


alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf"; offset: 3; depth: 22; msg: "CGI-PHF access";)

Figure 11 - Règle combinant content, offset et depth

3.12 Nocase

L'option nocase est utilisée pour désactiver la différence majuscules/minuscules dans une règle "content". Elle est spécifiée seule dans une règle et tout caractère ASCII qui est comparé à la charge du paquet est traité comme si il était soit en majuscule soit en minuscule.

Format :

nocase;


alert tcp any any -> 192.168.1.0/24 21 (content: "USER root"; nocase; msg: "FTP root user access attempt";)

Figure 12 - Règle content avec le modificateur nocase

3.13 Flags

Cette règle teste les drapeaux TCP pour une correspondance. Il y a actuellement 8 drapeaux variables qui sont disponibles dans Snort :

Il y a aussi des opérateurs logiques qui peuvent être utilisés pour spécifier des critères de correspondance pour les drapeaux indiqués :

Les bits réservés peuvent être utilisés pour détecter des comportements non usuels, tels que des tentatives d'empreintes digitales de piles IP ou d'autres activités suspicieuses. La Figure 13 montre un règle de détection d'un scan SYN-FIN .

Format :

flags: <valeurs de drapeaux>;


alert any any -> 192.168.1.0/24 any (flags: SF; msg: "Possible SYN FIN scan";)

Figure 13 - Exemple de spécification de drapeaux TCP

3.14 Seq

Cette option de règle se réfère aux numéros de séquence TCP. Essentiellement, il détecte si le paquet a un numéro de séquence statique fixé, et donc plutôt peu utilisé. Elle a été incluse pour le bien de l'exhaustivité.

Format :

seq: <nombre>;

3.15 Ack

Le mot clé ack d'option de règle se réfère au champ d'acquittement de l'entête TCP. Cette règle a un propos pratique jusqu'ici : détecter les pings TCP NMAP. Un ping TCP NMAP fixe ce champ à zéro et envoie un paquet avec le drapeau ACK TCP pour déterminer si un système réseau est actif. La règle pour détecter l'activité est montrée dans la Figure 14.

Format :

ack: <nombre>;


alert any any -> 192.168.1.0/24 any (flags: A; ack: 0; msg: "NMAP TCP ping";)

Figure 14 - Utilisation du champ ACK TCP

3.16 Itype

Cette règle teste la valeur du champ type ICMP. Il est fixé en utilisant la valeur numérique du champ. Pour une liste des valeurs disponibles, regardez dans le fichier decode.h inclus avec Snort ou dans toute référence ICMP. Il doit être noté que les valeurs peuvent être fixées en dehors de l'intervalle pour détecter des valeurs de type ICMP invalides qui sont quelques fois utilisées dans des dénis de services et des attaques en inondations.

Format :

itype: <nombre>;

3.17 Icode

Le mot clé d'option de règle icode est plutôt identique à la règle itype, fixez juste une valeur numérique ici et Snort va détecter tout trafic en utilisant cette valeur de code ICMP. Les valeurs hors intervalle peut également être fixé pour détecter le trafic suspicieux.

Format :

icode: <nombre>;

3.18 Session

Le mot clé session est nouveau depuis la version 1.3.1.1 et est utilisé pour extraire les données utilisateurs depuis les sessions TCP. Il est extrêmement utile pour voir ce que les utilisateurs tapent dans telnet, rlogin, ftp et même les sessions web. Il y a deux mots clé disponibles en argument pour l'option de règle session, printable ou all. Le mot clé printable affiche seulement les données que l'utilisateur verrait normalement ou serait capable de taper. Le mot clé all substitue les caractères non imprimables avec leurs équivalents hexadécimaux. Cette fonction peut ralentir considérablement Snort, donc elle ne devrait pas être utilisée dans des situations de charge importante, et est probablement mieux adaptée au post-traitement de fichiers journaux binaires (format tcpdump). Voir la Figure 15 pour un bon exemple de règle de session telnet.

Format :

session: [printable|all];


log tcp any any <> 192.168.1.0/24 23 (session: printable;)

Figure 15 - Journalisation des données imprimables d'une session telnet

3.19 Icmp_id

L'option icmp_id examine le numéro ICMP ID d'un paquet ECHO ICMP pour une valeur spécifique. C'est utile car quelques programmes de canaux cachés utilisent des champs ICMP statiques quand ils communiquent. Ce plugin particulier a été développé pour activer la règle de détection de stacheldraht écrite par Max Vision, mais c'est certainement utile pour détecter un nombre potentiel d'attaques.

Format :

icmp_id: <nombre>;

3.20 Icmp_seq

L'option Icmp_seq examine le champ séquence ICMP d'un paquet ECHO ICMP pour une valeur spécifique. C'est utile car quelques programmes de canaux cachés utilisent des champs ICMP statiques quand ils communiquent. Ce plugin particulier a été développé pour activer la règle de détection de stacheldraht écrite par Max Vision, mais c'est certainement utile pour détecter un nombre potentiel d'attaques. (Et oui, je sais que l'information pour ce champ est presque identique à la description de icmp_id, c'est pratiquement la même fichue chose!)

Format :

icmp_seq: <nombre>;

3.21 Rpc

Cette option regarde les requêtes RPC et décode automatiquement l'application, la procédure et la version de programme, en indiquant un succès quand les trois variables correspondent toutes. Le format de l'option d'appel est "application,procédure,version". Les caractères génériques sont valides pour la procédure et les numéros de version et sont indiquées par une "*".

Format :

icmp_seq: <nombre,[nombre|*],[nombre|*]>;


alert tcp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC getport (TCP)";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC getport (UDP)";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100083,*,*; msg:"RPC ttdb";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100232,10,*; msg:"RPC sadmin";)

Figure 16 - Diverses alertes d'appels RPC

3.22 Resp

Le mot clé resp met en oeuvre les réponses flexibles (FlexResp) au trafic qui correspond à une règle Snort. Le code FlexResp permet à Snort de fermer activement les connexions en infraction. Les arguments suivants sont valides pour ce module :

Les options peuvent être combinées pour envoyer des réponses multiples au système cible. Les arguments multiples sont séparés par des virgules.

Format :

resp: <resp_modifier[, resp_modifier...]>;


alert tcp any any -> 192.168.1.0/24 1524 (flags: S; resp: rst_all; msg: "Root shell backdoor attempt";)
alert udp any any -> 192.168.1.0/24 31 (resp: icmp_port,icmp_host; msg: "Hacker's Paradise access attempt";)

Figure 17 - Exemples d'utilisation de FlexResp

3.23 Content-list

Le mot clé content-list permet à de multiples chaînes de contenu d'être spécifiées à la place d'une unique option de contenu. Les motifs qui seront recherchés doivent pour chacun être spécifiés sur une seule ligne du fichier content-file comme montré dans la Figure 1, mais sinon ils sont traités identiquement aux chaînes de contenue spécifiées comme un argument à la directive standard content. Cette option est la base pour le mot clé react.


# adult sites
porn
adults
hard core
www.pornsite.com
# ...

Figure 18 - fichier d'exemple de content-list pour adultes

Format :

content-list: "<nom de fichier>";

3.24 React

Le mot clé react basé sur les réponses flexibles (FlexResp) met en oeuvre la réaction flexible au trafic qui correspond à une règle Snort. La réaction de base est de bloquer les sites intéressants que les utilisateurs veulent accéder : New York Times, slashdot, ou quelque chose de vraiment important - napster et les sites pornos. Le code Flex Resp permet à Snort de fermer activement les connexions en infraction et/ou d'envoyer un message visible au navigateur (modificateur d'avertissement disponible bientôt). Le message peut inclure votre propre commentaire. Les argument suivants (modificateurs de base) sont valides pour cette option :

Des arguments additionnels multiples sont séparés par une virgule. Le mot clé react doit être placé en dernier dans la liste des options.

Format :

react: <react_basic_modifier[, react_additional_modifier...]>;


alert tcp any any <> 192.168.1.0/24 80 (content-list: "adults"; msg: "Not for children!"; react: block, msg;)
alert tcp any any <> 192.168.1.0/24 any (content-list: "adults"; msg: "Adults list access attempt"; react: block;)

Figure 19 - Exemples d'utilisation de React

4. Les préprocesseurs

4.1 Vue d'ensemble des préprocesseurs

Les préprocesseurs ont été introduits dans la version 1.5 de Snort. Ils permettent à snort la fonctionnalité d'être étendu en permettant aux utilisateurs et aux programmeurs d'insérer assez facilement dans Snort des "plugins" modulaires. Le code du préprocesseur est exécuté avant que le moteur de détection soit appelé, mais après que le paquet ait été décodé. Le paquet peut être modifié ou analysé de manière non classique au travers de ce mécanisme.

Les préprocesseurs sont chargés et configurés en utilisant le mot clé preprocessor. Le format de la directive preprocessor dans les règles de Snort est :

preprocessor <nom>: <options>


preprocessor minfrag: 128

Figure 20 - Exemple de Format de la Directive Preprocessor

4.2 Les modules préprocesseurs accessibles

Minfrag

Le préprocesseur minfrag examine les paquets fragmentés pour une valeur limite de taille spécifiée. Quand les paquets sont fragmentés, c'est généralement causé par des routeurs entre la source et la destination. Généralement, il n'y a pas d'équipement réseau commercial qui fragmente les paquets en tailles plus petites que 512 octets, donc nous pouvons utiliser ce fait pour activer la surveillance du réseau pour de petits fragments qui sont généralement indicatifs de quelqu'un essayant de cacher son trafic derrière la fragmentation.

Format :

minfrag: <valeur limite>

HTTP Decode

HTTP Decode est utilisé pour traiter les chaînes HTTP URI et convertir leurs données en chaînes ASCII non obscurcies. Ceci est fait pour vaincre les scanners évasifs d'URL web et les attaques hostiles qui pourraient autrement échapper aux chaînes d'analyse de contenu utilisées pour examiner dans le trafic HTTP des activités suspicieuses. Le module préprocesseur prend des numéros de ports HTTP (séparés par des espaces) pour être normalisés en arguments (typiquement 80 et 8080).

Format :

http_decode: <liste de ports>


preprocessor http_decode: 80 8080

Figure 21 - Exemple de Format de la Directive HTTP Decode

Portscan Detector

Le préprocesseur de scans de ports de Snort est développé par Patrick Mullen et (beaucoup) d'autres informations sont disponibles sur sa page web.

Ce que le préprocesseur de scans de ports de Snort fait :

Journaliser le début et la fin de scans de ports depuis une unique IP source vers la facilité de journalisation standard.

Si un fichier journal est spécifié, il journalise les IP destinations et les ports scannés ainsi que le type de scan.

Un scan de ports est défini comme des tentatives de connexion TCP vers plus de P ports en T secondes ou des paquets UDP envoyés à plus de P ports en T secondes. Les ports peuvent être répartis au travers de tout nombre d'adresses IP destinations, et peuvent tous être le même port si ils sont répartis au travers de multiples IP. Cette version fait les scans de ports unique->unique et unique->plusieurs. La prochaine version majeure fera les scans de ports distribués (multiple->unique ou multiple->multiple). Un scan de ports est également défini comme un unique paquet de "scan furtif", tel que NULL, FIN, SYNFIN, XMAS, etc. Ceci signifie que dans scan-lib dans la distribution standard de snort vous devez commenter la section pour les paquets de scans furtifs. Le bénéfice est qu'avec le module de scans de ports ces alertes ne devraient apparaître qu'une fois, plutôt qu'une fois pour chaque paquet. Si vous utilisez la fonctionnalité de journalisation externe vous pouvez voir la technique et le type dans le fichier journal.

Les arguments de ce module sont :

Format :

portscan: <réseau à surveiller> <nombre de ports> <période de détection> <répertoire/fichier>


preprocessor portscan: 192.168.1.0/24 5 7 /var/log/portscan.log

Figure 22 - Exemple de configuration du module de scans de ports

Portscan Ignorehosts

Un autre module de Patrick Mullen qui modifie le fonctionnement du système de détection de scans de ports. Si vous avez des serveurs qui tendent à activer le détecteur de scans de ports (tels que des serveurs NTP, NFS et DNS), vous pouvez dire au module d'ignorer les SYN TCP et les scans de ports UDP de certains systèmes. Les arguments de ce module sont une liste de blocs IP/CIDR à ignorer.

Format :

portscan-ignorehosts: <liste de systèmes>


preprocessor portscan-ignorehosts: 192.168.1.5/32 192.168.3.0/24

Figure 23 - Exemple de configuration du module Portscan Ignorehosts

Defrag

Le module defrag (de Dragos Ruiu) permet à Snort d'effectuer de la défragmentation IP, rendant plus difficile pour les pirates de contourner simplement les capacités de détection du système. Il est très simple dans son usage, requérant simplement l'addition d'une directive préprocesseur au fichier de configuration sans aucun argument. Ce module ***supercedes*** généralement la fonctionnalité du module minfrag (c.-à-d. vous n'avez pas besoin d'utiliser minfrag si vous utilisez defrag).

Format :

defrag


preprocessor defrag

Figure 24 - Exemple de configuration du préprocesseur defrag

Stream

Ce module est toujours en BETA test, utilisez avec précautions

Le plugin stream fournit la fonctionnalité de réassemblage de sessions TCP à Snort. Les sessions TCP sur les ports configurés avec de petits segments seront réassemblés en un flux de données que Snort peut évaluer proprement pour des activités suspicieuses. Ce plugin prend plusieurs arguments :

Format :

stream: timeout <temps maximal>, ports <ports>, maxbytes <maximum d'octets>


preprocessor stream: timeout 5, ports 21 23 80 8080, maxbytes 16384

Figure 25 - Exemple de configuration du réassembleur de sessions TCP

Spade : the Statistical Packet Anomaly Detection Engine

Dans l'intéret de l'opportunité et du bon sens, je suggérerais de consulter le fichier README.Spade dans la distribution Snort ainsi que de consulter http://www.silicondefense.com/spice/

Ce module permet à Snort d'être capable d'effectuer de la détection statistique d'anomalies sur votre réseau, et il est essentiellement un nouveau moteur de détection pour Snort. Si vous êtes intéressé dans ce genre de capacité, vous devriez réellement lire la documentation dans la distribution Snort ainsi que celle sur le site SiliconDefense

5. Les modules de sortie

5.1 Vue d'ensemble des modules de sortie

Les modules de sortie sont une nouveauté de la version 1.6. Ils permettent à Snort d'être bien plus flexible dans le formatage et la présentation des sorties à ses utilisateurs. Les modules de sortie son exécutés quand les sous-systèmes d'alerte ou de journalisation de Snort sont appelés, après les préprocesseurs et le moteur de détection. Le format des directives dans le fichier de règles est très similaire à celui des préprocesseurs.

Plusieurs plugins de sortie peuvent être spécifiés dans le fichier de configuration de Snort. Quand plusieurs plugins du même type (journal, alert) sont spécifiés, ils sont "empilés" et appelés en séquence quand un événement se produit. Comme avec les systèmes standards de journalisation et d'alerte, les plugins de sortie envoient leurs données à /var/log/snort par défaut ou vers un répertoire désigné par un utilisateur (en utilisant l'option de la ligne de commande "-l").

Les modules de sortie sont chargés au moment de l'exécution en spécifiant le mot clé output dans le fichier de règles :

output <nom>: <options>


output alert_syslog: LOG_AUTH LOG_ALERT

Figure 26 - Exemple de Configuration de Module de Sortie

5.2 Les modules de sortie accessibles

Alert_syslog

Ce module envoie les alertes à la facilité syslog (comme l'option -s de la ligne de commande). Ce module permet également à l'utilisateur de spécifier la facilité de journalisation et la priorité dans le fichier de règles de Snort, en donnant aux utilisateurs une plus grande flexibilité dans la journalisation des alertes.

Mots clés disponibles :

Format :

alert_syslog: <facilité> <priorité> <options>

Alert_fast

Ceci imprimera les alertes de Snort dans un format rapide d'une ligne vers un fichier de sortie spécifié. C'est une méthode d'alerte plus rapide que les alertes full car elle n'a pas besoin d'afficher toutes les entêtes des paquets vers le fichier de sortie.

Format :

alert_fast: <nom du fichier de sortie>


output alert_fast: alert.fast

Figure 27 - Configuration des alertes "fast"

Alert_full

Affiche les messages d'alerte de Snort avec l'intégralité des entêtes des paquets. Cette facilité d'alerte est généralement plutôt lente car elle requière que le programme fasse beaucoup plus d'analyse de données pour formater les données à être imprimées. Les alertes seront écrites dans le répertoire de journalisation par défaut (/var/log/snort) ou le répertoire de journalisation spécifié sur la ligne de commande.

Format :

alert_full: <nom du fichier de sortie>


output alert_full: alert.full

Figure 28 - configuration des alertes "full"

Alert_smb

Ce plugin envoie des messages d'alerte WinPopup aux noms de machines NETBIOS indiqués dans le fichier spécifié comme argument à ce plugin de sortie. Il doit être noté que l'utilisation de ce plugin n'est pas encouragé puisqu'il exécute un exécutable binaire externe (smbclient) au même niveau de privilèges que Snort, communément root. Le format du fichier des stations de travail est une liste de noms NETBIOS des systèmes qui souhaitent recevoir les alertes, un par ligne dans ce fichier.

Format :

alert_smb: <nom du fichier des stations de travail à alerter>


output alert_smb: workstation.list

Figure 29 - Configuration des alertes "smb"

Alert_unixsock

Configure une socket du domaine UNIX et y envoie les rapports d'alertes. Des programmes / processus externes peuvent écouter cette socket et recevoir les alertes Snort et les données des paquets en temps réel. C'est actuellement une interface expérimentale.

Format :

alert_unixsock


output alert_unixsock

Figure 30 - Configuration des alertes "unixsock"

Log_tcpdump

Le module log_tcpdump enregistre les paquets vers un fichier au format tcpdump. Ceci est utile pour effectuer des analyses post traitement sur le trafic collecté avec le grand nombre d'outils qui sont disponibles pour examiner des fichiers au format tcpdump. Ce module ne prend qu'un seul argument, le nom du fichier de sortie.

Format :

log_tcpdump: <nom du fichier de sortie>


output log_tcpdump: snort.log

Figure 31 - Exemple de configuration du module de sortie "tcpdump"

Xml

Le plugin XML active la journalisation de snort en SNML - simple network markup language alias (snort markup language) vers un fichier ou au travers du réseau. La DTD est disponible dans le répertoire contrib de la distribution de snort et à : http://www.cert.org/DTD/snml-1.0.dtd. Vous pouvez utiliser ce plugin avec une ou plusieurs sondes snort pour journaliser vers une base de données centrale et créer des infrastructures de détection d'intrusion hautement configurables dans votre réseau. Le plugin vous permettra également de rapporter automatiquement les alertes au Centre de Coordination du CERT, votre équipe de réponse, ou votre fournisseur de gestion d'IDS.

Ce plugin a été développé par Jed Pickel et Roman Danyliw du Centre de Coordination du CERT comme partie du projet AIRCERT.

Soyez conscient que la DTD SNML est dans sa phase précoce de développement et il est probable qu'elle soit modifiée pendant que l'examen public se déroule.

Voyez http://www.cert.org/kb/snortxml pour les informations et documentations les plus à jour à propos de ce plugin.

La ligne de configuration sera au format suivant :

output xml: [log | alert], [liste de paramètres]

Arguments :

[log | alert] - spécifiez log ou alert pour connecter le plugin xml à la facilité de journalisation ou d'alerte.

[liste de paramètres] - La liste de paramètres consiste en paires de clés valeurs. Le format correct est une liste de paires clé=valeur chacune séparée par un espace.


file
quand c'est le seul paramètre il journalisera vers un fichier sur la machine locale. Autrement, si http ou https est employé (voir protocole), c'est le script qui est exécuté sur le système distant.
protocol Les valeurs possibles pour ce champ sont

http - envoie un POST dans HTTP à un serveur web (requis : un paramètre [file])
https - juste comme http mais chiffré et mutuellement authentifié par ssl. (requis : les paramètres [file], [cert], [key])
tcp - une simple connexion tcp. Vous avez besoin d'utiliser une quelconque sorte de récepteur (requis : un paramètre [port])
iap - une mise en oeuvre de Intrusion Alert Protocol (ndt : Protocole d'Alertes d'Intrusion) (ceci ne marche pas encore).
host système distant où les journaux doivent être envoyés
port le numéro de port auquel se connecter (les ports par défaut sont)

http 80
https 443
tcp 9000
iap 9000
cert le certificat X.509 client à utiliser avec https (au format PEM)
key la clé privée cliente à utiliser avec https (au format PEM)
ca le certificat CA utilisé pour valider le certificat du serveur https (au format PEM)
server le fichier contenant une liste de serveurs valides avec lesquels communiquer. Il est utilisé pour que Snort puisse authentifier le serveur. Chaque serveur est identifié par une chaîne formée par le sujet du certificat X.509 du serveur. Cette chaîne peut être créée par :

% openssl x509 -subject -in <server certificate>.

Typiquement seulement quelqu'un déployant le serveur HTTPS aura à effectuer cette tâche (puisqu'ils ont accès au certificat du serveur). Cette entité doit publier cette chaîne sujet pour configuration dans chaque sonde snort.
sanatize L'argument est une combinaison réseau/masque pour un intervalle d'IP que vous souhaitez être nettoyés. Toute adresse IP dans l'intervalle que vous spécifiez sera représenté par "xxx.xxx.xxx.xxx". Également, pour les alertes nettoyées, aucune charge de paquet ne sera journalisé. Vous pouvez utiliser le paramètre sanitize plusieurs fois pour représenter plusieurs intervalles IP.
encoding La charge des paquets et les options des données sont binaires et il n'y a pas une façon standard de les représenter en texte ASCII. Vous pouvez choisir l'option de codage binaire qui convient le mieux à votre environnement. Chacun a ses propres avantages et désavantages.

hex : (défaut) représente les données binaires comme une chaîne hexadécimale.
besoins de stockage... - 2x la taille du binaire
recherches... - très bonnes
lisibilité humaine... - non lisible à moins que vous ne soyez un véritable intello requière du traitement ultérieur

base64 : représente les données binaires comme une chaîne en base 64.
besoins de stockage... - ~1.3x la taille du binaire
recherches... - impossible sans traitement ultérieur
lisibilité humaine... - non lisible nécessite du traitement ultérieur

ascii : représente les données binaires comme une chaîne ascii. C'est la seule option où vous perdrez effectivement des données. Les données non ascii sont représentées en tant qu'un ".". Si vous choisissez cette option alors les données pour les IP et les options tcp seront toujours représentées comme "hex" car cela n'a pas de sens pour ces données d'être en ascii.
besoins de stockage... - Bien plus large que les données binaires car quelques caractères ont besoin d'être échappés (&, <, >)
recherches... - très bonne pour rechercher uns chaîne de texte impossible si vous voulez rechercher du binaire
lisibilité humaine... - très bonne
detail Combien de données détaillées voulez-vous enregistrer ? Les optionssont :

full : (défaut) journalise tous les détails d'un paquet qui a causé une alerte (en incluant les options ip et tcp et la charge)

fast: journalise seulement une quantité minimale de données. Vous limitez sévèrement le potentiel de quelques application d'analyse si vous choisissez cette option, mais ceci est toujours le meilleur choix pour quelques applications. Les champs suivants sont journalisés (horaire, signature, ip source, ip destination, port source, port destination, drapeaux tcp et protocole)

Format :

xml: <facilité de sortie>


output xml: log, file=output
output xml: log, protocol=https host=air.cert.org file=alert.snort cert=mycert.crt key=mykey.pem ca=ca.crt server=srv_list.lst

Figure 32 - exemples de configuration du plugin de sortie XML

Database

Ce module de Jed Pickel envoie les données de Snort à une variété de bases de données SQL. Plus d'informations sur l'installation et la configuration de ce module peuvent être trouvées sur la page web d'Incident.org. Les arguments de ce plugin sont le nom de la base de données vers laquelle journaliser et une liste de paramètres. Les paramètres sont spécifiés avec le format paramètre = argument. Les paramètres suivants sont disponibles.


host
Le système auquel se connecter. Si une chaîne de longueur non nulle est spécifiée, une communication TCP/IP est utilisée. Sans un nom de machine, il se connectera en utilisant une socket du domaine Unix local.
port Le numéro de port auquel se connecter au système serveur, ou une extension de nom de fichier de socket pour les connexions de domaine Unix.
dbname Le nom de la base de données
user Le nom de l'utilisateur de la base de donnée pour l'authentification
password Le mot de passe utilisé si la base de données demande une authentification par mot de passe
sensor_name Spécifie votre propre nom pour cette sonde snort. Si vous ne spécifiez pas de nom un sera généré automatiquement
encoding Parce que la charge du paquet et les options des données sontbinaires, il n'y a pas une façon simple et portable de les enregistrer dansune base de données. BLOBS ne sont pas utilisés car ils ne sont pas portableentre les bases de données. Donc je vous laisse l'option de codage. Vouspouvez choisir parmi les options suivantes. Chacune a ses propres avantageset des désavantages :

hex : (défaut) représente les données binaires comme une chaîne hexadécimale.
besoins de stockage... - 2x la taille du binaire
recherches... - très bonnes
lisibilité humaine... - non lisible à moins que vous ne soyez un véritable intello requière du traitement ultérieur

base64 : représente les données binaires comme une chaîne en base 64.
besoins de stockage... - ~1.3x la taille du binaire
recherches... - impossible sans traitement ultérieur
lisibilité humaine... - non lisible nécessite du traitement ultérieur

ascii : représente les données binaires comme une chaîne ascii. C'est la seule option où vous perdrez effectivement des données. Les données non ascii sont représentées en tant qu'un ".". Si vous choisissez cette option alors les données pour les IP et les options tcp seront toujours représentées comme "hex" car cela n'a pas de sens pour ces données d'être en ascii.
besoins de stockage... - Bien plus large que les données binaires car quelques caractères ont besoin d'être échappés (&, <, >)
recherches... - très bonne pour rechercher uns chaîne de texte impossible si vous voulez rechercher du binaire
lisibilité humaine... - très bonne
detail Combien de données détaillées voulez-vous enregistrer ? Les optionssont :

full : (défaut) journalise tous les détails d'un paquet qui a causé une alerte (en incluant les options ip et tcp et la charge)

fast: journalise seulement une quantité minimale de données. Vous limitez sévèrement le potentiel de quelques application d'analyse si vous choisissez cette option, mais ceci est toujours le meilleur choix pour quelques applications. Les champs suivants sont journalisés (horaire, signature, ip source, ip destination, port source, port destination, drapeaux tcp et protocole)

De plus, il y a une méthode de journalisation et un type de base de données qui doivent être définis. Il y a deux types de journalisation disponibles, log et alert. Fixer le type à log attache la fonctionnalité de journalisation de database à la facilité de journalisation dans le programme. Si vous fixez le type à log, le plugin sera appelé dans la chaîne de sortie log. Fixer le type à alert attache le plugin à la chaîne de sortie alert dans le programme.

Il y a quatre bases de données disponibles dans la version courante du plugin qui sont MySQL, PostgreSQL, Oracle et les bases de données compatibles unixODBC. Fixez le type pour correspondre à la base de données que vous utilisez.

Format :

database: <log | alert>, <type de base de données>, <liste de paramètres>


output database: log, mysql, dbname=snortuser=snort host=localhost password=xyz

Figure 33 - Configuration du plugin de sortie "database"

6. Construire de bonnes règles

Il y a quelques concepts généraux à garder à l'esprit en développant des règles Snort pour maximiser l'efficacité et la vitesse. Je ferai des rajouts à cette section quand ma muse le voudra. :)

6.1 Les règles de contenus différencient majuscules et minuscules (à moins que vous n'utilisiez l'option "nocase")

N'oubliez pas que les règles content font la différence entre majuscules et minuscules et que beaucoup de programmes utilisent typiquement les lettres majuscules pour indiquer les commandes. FTP en est un bon exemple. Considérez les deux règles suivantes :

alert tcp any any -> 192.168.1.0/24 21 (content: "user root"; msg: "FTP root login";)

alert tcp any any -> 192.168.1.0/24 21 (content: "USER root"; msg: "FTP root login";)

La seconde de ces deux règles va capturer la plupart des tentatives de connexion root automatiques, mais aucune qui utilise les caractères minuscules pour "user".

6.2 Accélérer les règles qui ont des options de contenus

L'ordre dans lequel les règles sont testées par le moteur de détection est complètement indépendant de l'ordre dans lequel elles sont écrites dans une règle. Le dernier test de règle qui est effectué (quand nécessaire) est toujours l'option de règle content. Prenez avantage de ce fait en utilisant d'autres options de règles plus rapides qui peuvent détecter si oui ou non le contenu a besoin d'être vérifié. Par exemple, la plupart du temps quand des données sont envoyées du client au serveur après qu'une session TCP soit établie, les drapeaux PSH et ACK sont fixés sur le paquet contenant les données. Ce fait peut être utilisé avantageusement par les règles qui ont besoin de tester le contenu de la charge provenant du client vers le serveur avec un simple test de drapeaux TCP qui nécessite bien moins de ressources en calculs que l'algorithme de correspondance de motifs. En sachant cela, une façon simple d'accélérer les règles qui utilisent l'option content est d'effectuer également un test flag, comme dans la Figure 23. L'idée de base est que lorsque les drapeaux PSH et ACK ne sont pas fixés, il n'y a pas besoin de tester la charge du paquet pour la règle donnée. Si les drapeaux sont fixés, la puissance de calcul additionnelle nécessaire pour effectuer le test est négligeable.


alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf"; flags: PA; msg: "CGI-PHF probe";)

Figure 34 - Utilisation des tests de drapeaux TCP pour accélérer les règles de contenu


Version 1.2, Tous droits réservés, © Copyright 1999-2001 Martin Roesch
traduction française © Copyright 2001 Denis Ducamp