Dans cet article, nous vous proposons de revoir les attaques par corruption de mémoire en observant les différentes utilisations, attaques et mitigations. Nous allons notamment nous focaliser sur les débordements de pile (ou stack overflow) qui étaient les plus communs à vers la fin des années 90, début 2000.
Par ailleurs, il est important de spécifier que cette revue, non exhaustive, aborde uniquement le périmètre et la vision occidentale. Elle ne tient pas compte de la vision russe ou chinoise.
Rappel sur l’allocation mémoire
Sur un système linux x86, chaque programme quand il est exécuté obtient un espace mémoire entièrement isolé à l’aide du principe de mémoire virtuelle. La mémoire est adressée par mots (4 octets) et couvre l’espace d’adresse de 0x00000000 - 0xffffffff soit 4 Giga-octets adressables.
L’espace virtuel est divisé en deux zones : l’espace utilisateur (0x00000000 - 0xbfffffff) et l’espace kernel (0xc0000000 - 0xffffffff). Un processus utilisateur ne peut pas accéder à l’espace kernel mais l’inverse est possible. Un exécutable ELF est transformé en une image processus par le program loader.
Pour créer cette image en mémoire, le program loader va mapper en mémoire tous les loadable segments de l’exécutables et des librairies requises au moyen de l’appel système mmap()
. Les exécutables sont chargés à l’adresse mémoire fixe 0x08048000 appelée “adresse de base”.
La figure (ci-dessus) montre les sections principales d’un programme en mémoire. La section .text
de la figure correspond au code du programme, c’est-à-dire aux instructions. Dans la section .data
sont placées les données globales initialisées (dont les valeurs sont connues à la compilation) et dans la section .bss
les données globales non initialisées. Ces deux zones sont réservées et connues dès la compilation. Une variable locale statique initialisée se retrouve dans la section .data
et une variable locale statique non initialisée se retrouve dans la section .bss
.
La pile quant à elle contient les variables locales. Elle fonctionne selon le principe LIFO (Last in First Out), premier entré premier sorti et croît vers les adresses basses de la mémoire. A l’exécution d’un programme, ses arguments (argc et argv) ainsi que les variables d’environnement sont aussi stockés dans la pile. Les variables allouées dynamiquement par la fonction malloc()
sont stockées dans le heap.
Lors de l’appel d’une fonction, un nouveau cadre de pile est créé au-dessus du précédent pour désigner l’espace mémoire de la fonction.
Il contient donc :
- les variables locales,
- une sauvegarde du pointeur de base de la fonction appelante,
- ainsi qu’une adresse de retour EIP sauvegardée qui indique où continuer l’exécution après la fonction.
Dépassement de tampon ou buffer overflow
Un dépassement de tampon se produit lorsque les données écrites dans un tampon corrompent également les adresses mémoire adjacentes au tampon de destination en raison d’une vérification insuffisante des limites. Cela peut se produire lorsque l’on copie des données d’un tampon à un autre sans vérifier au préalable que les données tiennent dans le tampon de destination.
Ce débordement permet de réécrire le pointeur EIP sauvegardé qui provoquera une redirection de l’exécution lors du retour de la fonction et, en conséquence, une potentielle prise de contrôle de l’exécution du programme.
Pourquoi ? L’architecture de von Neumann, utilisée dans la plupart des ordinateurs modernes, utilise le même matériel pour les instructions et les données.
Architecture de von Neumann
Architecture contraire au type Harvard qui sépare physiquement les instructions et les données.
Architecture de Harvard
Nous allons explorer l’histoire de ce type d’exploitation, les différentes techniques utilisées ainsi que les remédiations apportées au fil des années.
1972
- Le problème est connu depuis au moins 1972 dans “Computer Security Technology Planning Study” :
The code performing this function does not check the source and destination addresses properly, permitting portions of the monitor to be overlaid by the user. This can be used to inject code into the monitor that will permit the user to seize control of the machine. (Page 61)
1988
- Première exploitation de masse en 1988 par le ver Morris créé par un étudiant de l’université Cornell exploitant, entre autres, le service fingerd. C’est également le premier ver à se propager par internet.
I had heard of the potential for exploits via overflow of the data segment buffers overwriting the next variable. That is, people were worried about code like this:
char buf[512];
int is_authorized; main(){
...;
gets(buf);
The idea of using buffer overflow to inject code into a program and cause it to jump to that code occured to me while reading fingerd.c
En réponse au ver, le premier CERT est créé par la Carnegie Mellon University.
1989
-
ZARDOZ Security-Digest list est créer où plusieurs personnes discutent des différentes vulnérabilités source
-
Le CERT publie une alerte de vulnérabilité à propos d’un overflow dans 4.3BSD bin/passwd.c source
1993
- Bugtraq est créé en réponse au CERT qui ne publie pas les vulnérabilités et aux vendeurs qui ne patchent pas leurs programmes. C’est le début du mouvement full disclosure. Bugtraq était une liste de diffusion électronique consacrée aux questions de sécurité informatique. Les sujets abordés sont les nouvelles discussions sur les vulnérabilités, les annonces des fournisseurs relatives à la sécurité, les méthodes d’exploitation et la façon de les corriger. C’était une liste de diffusion à fort volume, avec jusqu’à 776 messages par mois, et presque toutes les nouvelles vulnérabilités de sécurité étaient discutées sur la liste à ses débuts. Le forum permettait à quiconque de divulguer et de discuter des vulnérabilités informatiques, y compris les chercheurs en sécurité et les vendeurs de produits.
1995
- Thomas Lopatic poste sur Bugtraq un buffer overflow de NCSA httpd 1.3. Le post détaille les étapes nécessaires pour exploiter le service ainsi qu’un POC (Proof Of Concept) qui créer le fichier
/tmp/GOTCHA
Actually, this bug is similar to the bug in fingerd exploited by the internet worm. The HTTPD reads a maximum of 8192 characters when accepting a request from port 80. When parsing the URL part of the request a buffer with a size of 256 characters is used to prepend the document root (function strsubfirst(), called from translate_name()). Thus we are able to overwrite the data after the buffer. Since the stack grows towards higher addresses on the HP-PA, we are able to overwrite the return pointer which is used to return from the strcpy() call in strsubfirst(). The strcpy() overwrites its own return pointer. On systems with a stack growing the other direction, we’d have to overwrite the return pointer of strsubfirst().
-
Le CERT publie une alerte de vulnérabilité dans syslogd source
-
Mudge du l0pht écrit un papier sur “How to write Buffer Overflows”. Ce sont des notes sur le dépassement de tampon avec une introduction aux shellcodes et contenant un exploit du bug de syslogd rendu publique plus tôt. Ce document circule en interne et ne sera connu du grand public que des années plus tard. source
-
DaveG et VicM d’Avalon Research publient sur Bugtraq une alerte et un exploit pour splitvt sur Linux 2-3.x. La vulnérabilité est due à l’utilisation d’un
sprintf()
non borné exploité à l’aide d’une longue variable d’environnement. source
1996
- Aleph1 publie dans Phrack #49 “Smashing The Stack For Fun And Profit”, probablement un des articles les plus cités sur le sujet. Il eut un impact énorme lors de sa publication et fut la première introduction publique de haute qualité, étape par étape, aux vulnérabilités de débordement de tampon de pile (stack overflow) et à leur exploitation. source
En 1996, les dépassements de tampon sont connus et leur exploitation consiste en général à prendre le contrôle du pointeur de retour sauvegardé et retourner dans son code. Le code malicieux peut être inséré n’importe où en mémoire du moment qu’il est possible de pointer l’exécution dessus. Par exemple DaveG et VicM, dans leur exploit pour splitvt, placent leur shellcode dans une variable d’environnement qui se situe vers la fin de la pile. Aleph1 lui, dans son article, retourne dans son propre buffer après avoir réécrit le pointeur d’exécution.
1997
-
Solar Designer publie un exploit pour Superprobe. Ici, c’est un pointeur de fonction qui est réécrit pour pointer vers une variable d’environnement et non le pointeur d’exécution. source
-
Quelque mois plus tard, Solar Designer propose une remédiation contre les exploits qui retourne et exécute du code depuis la pile en le rendant non exécutable. (nx stack) Il publie en même temps un moyen de contourner son propre patch en retournant dans la mémoire partagée qui est, elle, toujours exécutable, ici la fonction system() de la libc. (ret-to-libc) Enfin, il propose un patch contre ce contournement qui modifie la façon dont les fonctions des librairies partagées sont adressées en mémoire en s’assurant que les adresses de ces dernières contiennent toujours un octet nul. source
-
En fin d’année, StackGuard est annoncé sur Bugtrack. C’est un patch pour gcc qui insère un canari avant l’adresse de retour de la fonction et provoque un arrêt du programme si celui-ci est modifié. source
1997 voit déjà arriver des remédiations contre le dépassement de tampon. En effet, le principe jusqu’ici est de prendre le contrôle du pointeur de retour et de retourner à un endroit de la pile qui contient notre code. La solution proposée par StackGuard est de placer, avant les pointeurs de frame et de retour, une valeur appelée canari qui sera comparée à une copie ailleurs en mémoire avant que la fonction ne retourne. Si les deux valeurs ne correspondent pas, le programme s’arrête.
Solar Designer, lui, propose de rendre la pile non exécutable. De ce fait, il devient impossible de retourner dans un shellcode placé dans la pile. Une pile non exécutable est maintenant considérée comme standard et nous pouvons voir dans un binaire actuel que la pile est non exécutable par défaut. (le stack est rw-)
Pour contrer sa propre idée, Solar Designer propose de retourner dans la bibliothèque standard C libc qui fournit des macros, des définitions de types et des fonctions pour des tâches telles que la manipulation des chaînes de caractères, les calculs mathématiques, le traitement des entrées/sorties, la gestion de la mémoire et plusieurs autres services du système d’exploitation. Elle est également mappée en mémoire lors du lancement du binaire comme nous pouvons le voir sur la capture précédente. Il commence par rechercher la chaîne de caractères “/bin/sh” dans l’espace mémoire de la libc afin de passer un pointeur vers cette chaine en argument à la fonction system(). Lors de l’exécution de la fonction, l’état de la pile est le suivant :
1998
-
Après un premier exploit pour Internet explorer 4 sur Windows 95 fin 97, Dildog du l0pht récidive avec un nouvel exploit utilisant cette fois un heap overflow. source
-
Dans son poste sur Bugtraq intitulé “Defeating Solar Designer non-executable stack patch”, Andy Church décrit une attaque où un écrasement est utilisé pour écraser les paramètres de snprintf afin de créer le premier exemple connu d’attaque de type format string. source
-
Quelques mois plus tard, Dildog de nouveau, publie “The Tao of Windows Buffer Overflow” qui devient la bible de l’exploitation sous Windows. source
1998 voit l'arrivée publique de deux nouveaux types d’attaque, le heap overflow que nous verrons plus en détails dans la deuxième partie de l’article, ainsi que les attaques de type “format string” détaillées plus loin.
1999
-
sh0k de w00w00 publie “w00w00 on Heap Overflows” qui revient sur le travail de ses prédécesseurs et les différentes étapes qui l’ont amené à ce point. source
-
Dark spyrit AKA Barnaby Jack publie dans phrack #55 “Win32 Buffer Overflows (Location, Exploitation and Prevention)”. Utilisant une vulnérabilité dans SLMail 3.2.3113 divulgué publiquement, il démontre comment localiser le bug en utilisant PE Dump et SoftIce et explique ensuite les problèmes liés au shellcode sur Win32 pour finalement couvrir l’utilisation d’appels trampoline qui permettent de retourner de manière fiable au début du stack en utilisant des gadgets dans les DLL ayant un adressage fixe. C’est également un des premiers signes de distanciation de Bugtraq accusé de ne plus être 100% full disclosure.
Seattle Labs were contacted about this in a previous version but did not bother to remedy the situation, instead they just changed the default port from 27 to 8376.
Bad move.
The vulnerabilities were made public by the way, so please, Russ, don’t send me nasty emails.
-
Dans le même numéro de phrack, klog publie “The Frame Pointer Overwrite”. Il démontre que dans certaines circonstances, réécrire un seul octet du pointeur de frame sauvegardé permet de faire récupérer, lorsque la fonction retourne, le pointeur d’instruction depuis un emplacement défini par l’attaquant. Il indique également que d’autres techniques ésotériques sont possibles notamment lors de pertes de privilèges. source
-
Tymm Twillman publie sur bugtraq un exploit pour proftpd 1.2.0pre6 utilisant un bug de format strings découvert en 1989 par l’Université du Wisconsin. Les exploit format string utilisent le spécificateur de format
%n
pour écrire dans la mémoire lorsqu’une variable contrôlée par l’attaquant est passée directement à une fonction de typeprintf
source -
Taeho Oh publie “Advanced buffer overflow exploit” ou il démontre des techniques de shellcode avancé pour contourner certains filtres, contourner
seteuid(getuid())
, s’évader dechroot()
, ou bien ouvrir un socket. source
1999 voit le premier exemple d’exploitation format string “moderne”. Le problème provient de l’utilisation d’une entrée utilisateur non vérifiée comme paramètre de la chaîne de format dans certaines fonctions C qui effectuent un formatage, comme printf(). Un utilisateur malveillant peut utiliser les jetons de format %s et %x, entre autres, pour imprimer des données de la pile d’appels ou d’autres emplacements de la mémoire. Il peut également écrire des données arbitraires à des emplacements arbitraires en utilisant le jeton de format %n, qui commande à printf() et aux fonctions similaires d’écrire le nombre d’octets formatés à une adresse stockée sur la pile.
2000
-
Trois articles intéressants sortent dans phrack #56 :
- Bulba et Kil3r démontrent comment contourner StackGuard et StackShield de manière fiable en écrivant dans la Global Offset Table. source (Bypassing StackGuard and StackShield)
- Rix met en évidence la possibilité de prendre le contrôle de l’exécution en réécrivant un pointeur virtuel de la table des méthodes virtuelles lors de dépassement de tampon en C++. source (Smashing C++ VPTRs)
- Twitch explique la possibilité d’exploiter le fait que certaines fonctions considérées comme sûres (ici
strncpy()
) ne terminent pas les chaînes de caractères par un octet nul si la taille du buffer est égale au nombre d’octet copié.
The essence of the issue is that many functions that a programmer may take to be safe and/or ‘magic bullets’ against buffer overflows do not automatically terminate strings/buffers with a NULL. That in actuality, the buffer size argument provided to these functions is an absolute size not the size of the string.
source (Exploiting Non-adjacent Memory Spaces)
-
Tf8 publie son exploit pour WU-FTPD 2.6.0 “WuFTPD: Providing remote root since at least1994” développé l’année précédente attirant enfin l’attention sur les bugs format strings. source
-
Lamagra publie un papier couvrant l’essentiel des informations disponibles sur les bugs de type format strings “Format Bugs: What are they, Where did they come from?”. source
-
Solar Designer publie “JPEG Com Marker vulnerability in Netscape” démontrant comment élaborer un fichier image qui écrasera le tas lorsqu’il sera décodé par Netscape. Cet article fut le premier connu parlant de bugs de format de fichier qui continuent d’être pertinents de nos jours. Solar Designer explique également comment parvenir à exécuter du code lors de dépassement du tas de manière fiable à l’aide de
free()
etunlink()
. source
L’image servant de POC provoquant le crash du programme
- Tim Newsham sort son papier “Format String Attacks”, le plus complet quant à la nature du problème et son exploitation.
—-[ INTRODUCTION
I know it has happened to you. It has happened to all of us, at one point or another. You’re at a trendy dinner party, and amidst the frenzied voices of your companions you hear the words “format string attack.” “Format string attack? What is a format string attack?” you ask. Afraid of having your ignorance exposed among your peers you decide instead to break an uncomfortable smile and nod in hopes of appearing to be in the know. If all goes well, a few cocktails will pass and the conversation will move on, and no one will be the wiser. Well fear no more! This paper will cover everything you wanted to know about format string attacks but were afraid to ask!
- En octobre sort PaX, un correctif (patch) de sécurité pour le noyau Linux qui fournit des pages mémoire non exécutables. La première version utilise uniquement la méthode
PAGEEXEC
PAGEEXEC est la première implémentation proposée pour implémenter le bit NX sur les architectures i386. Le bit supervisor surchargé pour émuler le comportement du bit NX. Cette implémentation repose sur le translation lookaside buffer (TLB), le cache utilisé par l’unité de gestion mémoire. Lors d’une tentative d’accès à une page protégée qui n’est pas encore dans le TLB, en exécution, une faute de protection est levée. Comme sur les processeurs récents le TLB est séparé en un cache pour les exécutions (ITLB) et un cache pour les données (DTLB), PaX peut déterminer s’il s’agit d’une instruction, qui doit alors être interdite.
-
En novembre, PaX ajoute la méthode
MPROTECT
qui empêche l’introduction de nouveau code exécutable dans l’espace mémoire d’une tâche en restreignant l’accès aux interfacesmmap()
etmprotect()
. -
Juan M. Bello Rivas publie “Overwriting ELF .dtors section to modify program execution” et explique comment prendre le contrôle de l’exécution d’un programme en réécrivant le constructeur (
.ctors
) ou destructeur (.dtors
) d’une fonction (icimain()
). Le code injecté est alors exécuté respectivement avant ou après un appel à la fonction. source -
En fin d’année, Brad Spengler sort grsecurity, une modification (patch) augmentant la sécurité pour le noyau Linux. Il inclut différents éléments, dont PaX, un système de contrôle d’accès à base de rôles et différents moyens de renforcer la sécurité générale du noyau.
2001
-
eEye Digital Security publie une alerte de sécurité à propos d’un dépassement de tampon dans une extension ISAPI. L’exploit utilise une technique de spraying du tas pour exécuter du code sur Windows 2000 et NT4. source
-
La même entreprise découvre le “Code Red worm” qui utilise le bug IIS du dessus (MS01-033). Après analyse, le ver réécrit un gestionnaire d’exception SEH sur la pile. Le payload envoyé par le ver pouvait ressembler à cela :
GET /default.ida?NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u9090%u8190%u00c3%u0003%u8b00%u531b%u53ff%u0078%u0000%u00=a HTTP/1.0
- PaX introduit la distribution aléatoire de l’espace d’adressage (ASLR) permettant de changer l’adressage à chaque démarrage du programme. L’attaquant ne sait donc plus dans quelle région retourner lorsqu’il contrôle le pointeur d’exécution.
The goal of Address Space Layout Randomization is to introduce randomness into addresses used by a given task. This will make a class of exploit techniques fail with a quantifiable probability and also allow their detection since failed attempts will most likely crash the attacked task.
-
Au 10ème USENIX symposium sur la sécurité, StackGhost et FormatGuard sont présentés. Remédiant respectivement à la réécriture du pointeur de retour et aux attaques de type format string. source | source
-
Dans Prack #57, deux articles reviennent sur les précédentes découvertes de Solar Designer.
-
“Once upon a free()…” est une introduction au dépassement de tas (heap overflow). source
-
Dans “Vudo malloc tricks”, MaXX commence par documenter de manière très détaillé l’implémentation de
malloc()
par Doug Lea ainsi que les différentes techniques d’exploitation possibles. Il termine l’article en démontrant un exploit utilisant la techniqueunlink()
contre sudo-1.6.1-1 sous RedHat 6.2.
The present paper could probably have been entitled “Smashing The Heap For Fun And Profit”… indeed, the memory allocator used by the GNU C Library (Doug Lea’s Malloc) and the associated heap corruption techniques are presented. However, it was entitled « Vudo , An object superstitiously believed to embody magical powers » since a recent Sudo vulnerability and the associated Vudo exploit are presented as well.
-
Scut de TESO publie “Exploiting Format String Vulnerabilities” un guide complet sur la recherche et l’exploitation des bugs de type format strings. source
-
Nergal publie dans Prack #58 “Advanced return-into-lib(c) exploits (PaX case study)”. La première partie couvre les attaques simples et avancées de type return-to-libc dont certaines étaient déjà ce que nous appelons aujourd’hui Return Oriented Programming (ROP). La deuxième partie se concentre sur les moyens de contournement de PaX. source
2001 voit l’apparition de l’ASLR qui organise de manière aléatoire les positions de l’espace d’adressage des zones de données clés d’un processus, y compris la base de l’exécutable et les positions de la pile, du tas et des bibliothèques. Dès lors, si un attaquant arrive à prendre le contrôle de pointeur de retour sauvegardé, il lui est impossible de savoir ou retourner sans avoir au préalable une fuite d’information sur l’organisation mémoire du processus.
C’est également la sortie de la première publication parlant de Return Oriented Programming (ROP) qui permet d’exécuter des séquences d’instructions machine soigneusement choisies et déjà présentes dans la mémoire de la machine, appelées “gadgets”. Chaque gadget se termine généralement par une instruction de retour et se trouve dans une sous-routine du programme existant et/ou du code de la bibliothèque partagée. Enchaînés ensemble, ces gadgets permettent à un attaquant d’effectuer des opérations arbitraires sur une machine employant des défenses tel que NX.
2002
- Halvar Flake, créateur de TESO, présente “Third Generation Exploits on NT/Win2k Platforms” à Blackhat Briefings Windows 2002. Il reprend l’exploit de Solar Designer (4 octets unlink()) en l’adaptant à Windows. Il documente ensuite une attaque contre l’allocateur de tas de Borland et finit en expliquant le fonctionnement des attaques SEH sur Windows. C’est également le début de la fin du mouvement full disclosure.
Some bug-hunters see bugs as a natural resource which is slowly being depleted – thus the “save the bugs movements” and more push in the underground to keep bugs secret
-
Microsoft sort la protection de pile /GS pour Visual C++ 7. Tout comme StackGuard, /GS place un cookie sur la pile avant l’adresse de retour et appel ensuite
__security_check_cookie()
à la fin de la fonction pour valider la non modification de ce cookie. source -
mnemonix (David Litchfield) publie “Non-stack Based Exploitation of Buffer Overrun Vulnerabilities on Windows NT/2000/XP” qui documente les attaques de type return-to-libc sous Windows. source
-
Tyler Durden publie dans Phrack #59 “Bypassing PaX ASLR protection” ou il démontre comment obtenir une fuite d’information à l’aide d’une réécriture partielle.
We may want to return-into-write or return-into-any_output_function if there is no printf and no send somewhere near the original return address, but depending on the output function, it would be quite hard to perform the attack since we would have to control many of the vulnerable function parameters.
- Dans le même numéro de Phrack, riq et gera publient “Advances in format string exploitation”
This text deals with 2 different subjects. The first is about different tiny tricks that may help speeding up bruteforcing when exploiting format strings bugs, and the second is about exploiting heap based format strings bugs.
-
Maximiliano Caceres publie “Syscall Proxying - Simulating remote execution” démontre d’autre façon de militariser les exploits, en redéfinissant les shellcodes, par exemple pour de l’élévation de privilèges, ou pour pivoter. source
-
Grsecurity reçoit un mode d’apprentissage, qui génère automatiquement des règles individuelles à partir du fonctionnement normal du système.
-
Gera publie “Four different tricks to bypass StackShield and StackGuard protection” démontre comment contourner les protections au niveau compilateur. (StackGuard, StackShield et Microsoft /GS) source
-
Le ver Slapper utilise une fuite mémoire pour exploiter un dépassement de tas de manière fiable à l’aide d’un bug OpenSSL rendu publique quelques mois plus tôt. source
-
PaX introduit SEGMEXEC pour implémenter la fonctionnalité de page de mémoire non exécutable et RANDKSTACK qui introduit de l’aléatoire dans la pile du kernel.
SEGMEXEC émule le fonctionnement du bit NX sur les processeurs IA-32. Cela fonctionne en segmentant la mémoire en deux zones de 1.5 Go chacune. La zone basse (de 0 à 1.5 Go) contient les données non exécutables, c’est-à-dire les données mais aussi instructions (qui peuvent en effet vouloir être lues). La seconde zone, exécutable, en revanche ne contient que les instructions. Les mappings des deux segments pointent vers les mêmes zones de la mémoire physique, ainsi la mémoire vive utilisée n’est pas doublée. Lorsqu’une adresse mémoire doit être exécutée, elle est traduite dans la zone contenant le code exécutable. Si le code n’est pas présent à l’adresse traduite, il s’agit alors d’une tentative d’exécution de code interdite, le programme est alors tué.
-
Grsecurity ajoute des protections pour
/dev/mem
et/dev/kmem
pour empêcher l’écriture dans la mémoire du kernel. Attaque connue depuis au moins Novembre 1998. source -
Blexim publie “Basic Integer Overflows” où il discute et démontre le dépassement d’entier. source
En 2002 les premiers papiers publics concernant les attaques SEH sous Windows sortent. Un enregistrement SEH comporte deux parties : un pointeur vers l’enregistrement SEH suivant et un pointeur vers le gestionnaire d’exception de l’enregistrement SEH actuel. Ainsi, lorsque l’on écrase le pointeur vers le gestionnaire d’exception actuel, il faut également écraser le pointeur vers le gestionnaire d’exception suivant, car ce dernier se trouve directement avant le pointeur vers le gestionnaire d’exception actuel sur la pile. Lorsqu’une exception se produit, l’application se rend à l’enregistrement SEH actuel et exécute le gestionnaire. Ainsi, lorsque nous écrasons le gestionnaire, nous devons placer un pointeur vers quelque chose qui nous mènera à notre shellcode.
2003
-
Sortie de “pax-future.txt”. Ce document, souvent négligé, détaille de nombreuses attaques et préventions qui ont été redécouvertes des années plus tard ou qui n’avaient pas encore été mises en œuvre de manière logicielle. Le document avait pour but de décrire les faiblesses actuelles d’un système mettant correctement en œuvre NX/ASLR et leurs solutions futures. Les notes de conception de la section 1 classent toutes les attaques contre NX/ASLR qui ont été publiées et celles qui doivent encore l’être. La section c.1 traite des variantes des techniques de retour dans le code (y compris les instructions jmp). Plusieurs méthodes permettant de prévenir toutes les formes de ces techniques sont décrites. Elle présente également pour la première fois (dans la section b.1) le concept de ce qui sera appelé plus tard KERNEXEC. source
-
Sortie de grsecurity 2.0, un système de contrôle d’accès basé sur les rôles (RBAC) a été ajouté. Le système ACL précédent avait des abstractions sujet/objet, et le nouveau système RBAC a ajouté une hiérarchie utilisateur/groupe/rôle spécial derrière ces abstractions. C’est une réécriture complète, tant du côté du noyau que du côté de l’utilisateur.
-
Le site metasploit.com ouvre au public en juin et la version 1.0 du framework libre et open-source sort en octobre avec 9 exploits inclus.
-
PaX introduit les pages kernel non exécutables.
-
David Litchfield publie “Variations in Exploit methods between Linux and Windows”. Il fait référence à une “technique connue depuis longtemps” consistant à écraser l’enregistrement SEH de la pile sous Windows (c’est en fait la première documentation connue de cette attaque). source
-
Lord YuP de Sec-Labs sort “Win32 Device Drivers Communication Vulnerabilities” concernant la corruption de mémoire dans les pilotes de périphérique ainsi qu’un exploit pour Norton Antivirus.
-
David Litchfield publie “Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server” où il contourne la protection des SEH enregistrés en remarquant que les gestionnaires d’exception non enregistrés qui sont hors de la portée des DLLs chargés étaient considérés comme valides. source
-
Microsoft introduit /SAFESEH dans Visual Studio 2003 pour tenter de limiter l’exploitation des gestionnaires SEH écrasés. /GS réorganise la pile pour limiter les effets des dépassements.
2004
-
Matt Conover et Oded Horovitz présentent “Reliable Windows Heap Exploits” donnant une vue d’ensemble des techniques d’exploitation fiables disponibles et exposent les protections du prochaine Windows XP-SP2. (PEB randomization, security cookies on chunks header, safe unlink from doubly linked list)
-
David Litchfield présente “Windows Heap Overflows” à la BlackHat USA 2004 sur l’attaque free qui permet d’écrire 4 octets n’importe où et les potentiels cibles d’écriture.
-
Microsoft livre XP-SP2. Windows lui-même est maintenant compilé avec /GS et /SAFESEH. DEP est supporté par le matériel et les logiciels. La validation des cookies de tas et le Safe Unlinking sont maintenant inclus. PEB et TEB sont randomisés. Les pointeurs sont codés. La pile et le tas sont tous deux marqués comme non exécutables.
-
Des chercheurs de Stanford publient “On the effectiveness of address-space randomization”. Ils démontrent que l’utilité de l’ASLR sur les plates-formes 32 bits est limitée en raison du nombre de bits disponibles pour la randomisation. Ils présentent une attaque qui est capable d’utiliser la force brute pour déterminer la disposition de la pile (en retournant dans sleep()) avant de lancer un exploit return-2-libc sur les systèmes avec PaX ou W^X. source
-
Barend-Jan Wever (SkyLined) publie un exploit “Internet Exploiter” pour le débordement du paramètre IFRAME src et name d’Internet Explorer. Son exploit utilise du “Heap Spraying” comme vecteur d’attaque, remplissant la mémoire avec son code dans le but de retourner dessus. source
2005
-
Alexander Anisimov publie “Defeating Microsoft Windows XP SP2 Heap protection and DEP bypass” abusant l’absence de vérification sur les listes lookaside et obtient de l’exécution de code. source
-
Barnaby Jack publie un article intitulé “Remote Windows Kernel Exploitation, Step into the Ring 0”, dans lequel il utilise, à des fins d’illustration, un bug précédemment divulgué dans la gamme de pare-feu personnels Symantec. Son exemple de shellcode est un enregistreur de frappe à distance et un chargeur de noyau qui permet d’exécuter n’importe quel shellcode userland. source
-
L’auteur de PaX (pageexec) publie un bug d’escalade de privilèges dans PaX. Il qualifie ce bug de “spectaculaire ratage” qui “détruit pratiquement tout ce que PaX a toujours représenté et pour lequel on avait confiance” et tente de quitter le projet. (il donne une explication approfondie du bug sur la DailyDave Mailing List). source
-
Nicolas Falliere de Symantec publie “Critical Section Heap Exploit Technique” détaillant une nouvelle technique d’exploitation contre les mécanismes de protection du tas de XP-SP2. Il exploite un écrasement de la liste doublement liée de la section critique. source
-
Sebastian Krahmer publie “Borrowed Code Chunk Exploitation Technique” qui vise spécifiquement les systèmes x86-64. L’article décrit efficacement ce qui sera appelé plus tard le return oriented programming (ROP) pour contourner DEP/NX/AVP. source
-
Dans Uninformed Journal 2, Matt Miller (skape) et Ken Johnson (skywing) publient une technique pour contourner le DEP matériel en utilisant une attaque de type return-2-libc pour retourner dans des fonctions qui désactivent le DEP. (ZwProtectVirtualMemory ou NtSetInformationProcess) source
-
Visual Studio 2005 est livré avec le pragma GS strict. /GS est maintenant en version 2 et fait une copie cachée des paramètres des arguments. Il introduit également la détection de débordement d’entier C++ operator::new.
-
Steve Christey publie “Format String Vulnerabilities in Perl Programs”. Il couvre les problèmes de bugs format string dans l’interpréteur Perl et les programmes Perl, ainsi qu’une chronologie de ce type d’attaques. source
-
Brett Moore publie une technique pour exploiter les débordements dans Freelist[0] sur XP-SP2. Elle tire partie du fait que les processus continuent de s’exécuter malgré la corruption du tas détectée. source
Conclusion
Les erreurs de mémoire sont présentes dans les logiciels depuis plus de trois décennies maintenant, ce qui entraîne de nombreux problèmes de sécurité. Les langages de bas niveau comme C et C++, qui sont sujets à cette catégorie d’erreurs, sont largement utilisés. Cela signifie qu’un grand nombre de systèmes actuels sont sensibles aux attaques qui ciblent les vulnérabilités de corruption de mémoire. Par conséquent, le durcissement des programmes et la protection contre ce type d’attaques sont de la plus haute importance pour construire des systèmes sûrs.
Bibliographie
https://thinkst.com/resources/papers/BlackHat-USA-2010-Meer-History-of-Memory-Corruption-Attacks-wp.pdf
https://www.youtube.com/watch?v=oz7UWCbSMU0vz
https://www.isg.rhul.ac.uk/sullivan/pubs/tr/technicalreport-ir-cs-73.pdf
À propos : Le blog d'AlgoSecure est un espace sur lequel notre équipe toute entière peut s'exprimer. Notre personnel marketing et commercial vous donne des informations sur la vie et l'évolution de notre société spécialisée en sécurité sur Lyon. Nos consultants techniques, entre deux tests d'intrusion ou analyses de risque, vous donnent leur avis ainsi que des détails techniques sur l'exploitation d'une faille de sécurité informatique. Ils vous expliqueront également comment sécuriser votre système d'informations ou vos usages informatiques particuliers, avec autant de méthodologie et de pédagogie que possible. Vous souhaitez retrouver sur ce blog des informations spécifiques sur certains sujets techniques ? N'hésitez pas à nous en faire part via notre formulaire de contact, nous lirons vos idées avec attention. Laissez-vous guider par nos rédacteurs : Alexandre, Amine, Antonin, Arnaud, Benjamin, Damien, Enzo, Eugénie, Fabien, Françoise, Gilles, Jean-Charles, Jean-Philippe, Jonathan, Joël, Joëlie, Julien, Jéromine, Lucas, Ludovic, Lyse, Nancy, Natacha, Nicolas, Pierre, PierreG, Sébastien, Tristan, Yann, et bonne visite !