Suivant: La piste des applets Monter: Solutions et résultats

La piste des compteurs


Nous avons tout d'abord décidé de comptabiliser les erreurs 404 comme expliqué ci-dessus. Cependant, Snort ne propose pas de compteur par défaut, il a donc fallu développer un préprocesseur dédicacé.

Notre préprocesseur a été conçu de façon à pouvoir s'adapter aussi bien à un client qu'à un serveur. C'est pourquoi, il nécessite certains paramètres lors de son initialisation :

Initialisation

Lorsque le préprocesseur est déclaré dans "snort.conf", il analyse les arguments qui lui sont passés et reconnait:


La ligne de snort.conf ressemble donc à ceci:

preprocessor http_404: -src -to:60 -nb:10 -ti:60


Remarques :

  1. Les options -src et -dest ne peuvent êtres utilisées en même temps;
  2. Pour détecter les floods côté client et surtout serveur, il est préférable d'utiliser -dest. L'option -src était en fait surtout utile pour tester plusieurs adresses IP avec un seule machine.
  3. [to] et [ti] sont exprimés en secondes.
  4. Les paramètres [nb] et [ti] sont des ordres de grandeurs. Etant donné la nature des compteurs, il est impossible de garantir que [nb] erreurs en [ti]+1 secondes ne seront pas alertées.


Détection


Le préprocesseur commence par vérifier qu'il s'agit d'un paquet de traffic TCP (donc que la session TCP est ouverte). Si ce n'est pas le cas, il quitte directement.

Il vérifie ensuite qu'il s'agit d'une réponse HTTP, c'est-à-dire que les 4 premiers bytes de données du paquet sont 'HTTP'. Etant donné que 4 'char' = 1 'int', il suffit de considérer que les données sont un tableau de 'int' et de vérifier que le premier est 'PTTH' (car la machine sur laquelle nous avons testé est little endian).

Le début d'un paquet de réponse HTTP ressemble toujours à ceci (car c'est le serveur qui l'envoie) :

HTTP/1.1 404 [...]


Si on le découpe en 'int', on obtient:

|HTTP| |/1.1| | 404| [...]


Il suffit donc pour détecter une erreur 404 de comparer le 3eme int à '404_' (c'est à dire '_404' inversé). La vérification qu'un paquet TCP est bien une erreur HTTP 404 est donc très rapide.

Remarque :
On ne peut pas optimiser la détection de cette manière si on teste les 'GET' sur les pages 'html' car dans ce cas, le 'GET' est envoyé par l'attaquant, et peut donc être 'gEt' si ca l'amuse.


Comptage


Une fois l'erreur détectée, il faut l'ajouter à un compteur pour ne lancer une alerte que quand un certain seuil est dépassé. De plus, pour que la détection soit efficace, il faut qu'il y ait un compteur par adresse IP.

Pour cela, le préprocesseur insère chaque compteur dans une liste doublement liée circulaire ordonnée par adresse IP croissante. La liste des champs d'une cellule de la liste est :


Pour simplifier la gestion de la liste, on y insère par défaut une cellule avec l'adresse IP égale à 0 de sorte que la liste ne soit jamais vide.
Il y a aussi un pointeur global qui pointe vers la cellule courante dans la liste.

Lorsque l'erreur 404 est détectée, le préprocesseur parcours la liste depuis la cellule courante jusqu'à ce qu'il tombe sur la bonne adresse IP, ou qu'il dépasse l'endroit où elle aurait du se trouver (ce qui est faisable vu que la liste est ordonnée par IP croissante). Vu que la liste est doublement liée, on peut choisir le sens de parcours pour minimiser la distance entre l'adresse IP recherchée et celle se trouvant dans la cellule courante.

Lors de cette recherche, si le préprocesseur tombe sur une cellule dont l'adresse IP ne correspond pas et dont le champ 'Time' est inférieur à l'heure actuelle - [to], il retire la cellule de la liste (sauf s'il s'agit de l'adresse IP 0). Cela permet d'élaguer la liste pour ne garder en mémoire que les adresses IP actives, sans pour autant faire un tour complet de la liste à chaque fois.

Une fois la cellule trouvée (ou créée), le préprocesseur met à jour la valeur du compteur par la formule suivante :

Count=Count*exp(K1*(Now-Time))+K2;


Ensuite, il la compare à K3 et si elle plus grande, il lance une alerte et retire la cellule de la liste.

Les valeurs de K1,K2 et K3 sont calculées à partir des paramètres [nb] et [ti].
Le préprocesseur retire la cellule de la liste pour limiter le nombre d'alertes lancées. On pourrait toutefois envisager une autre stratégie, du style remettre le compteur à 0, ou désactiver cette adresse pendant un certain temps, ...

Remarque :
Le calcul de K1,K2 et K3 est basé sur le fait qu'on peut calculer K1 et K2 pour que C ne dépasse jamais une certaine constante si (Now-Time) est constant. En calculant ces valeurs avec Cmax=[ti] et (Now-Time) = [ti]/[nb], on arrive a faire un compteur qui ne dépassera [ti] que si le nombre d'erreurs moyen sur un temps [ti] est plus grand que [nb].
Le problème, c'est que si le nombre d'erreurs moyen est légèrement supérieur à [nb], le nombre d'erreurs nécessaires pour dépasser [ti] peut être très grand. C'est pour cela que pour calculer K1 et K2, on utilise un certain pourcentage de [nb].


Suivant: La piste des applets Monter: Solutions et résultats