4.8.14.1 Tester les débordements de tas

From OWASP
Jump to: navigation, search
This article is part of the new OWASP Testing Guide v4.
Back to the OWASP Testing Guide v4 ToC: https://www.owasp.org/index.php/OWASP_Testing_Guide_v4_Table_of_Contents Back to the OWASP Testing Guide Project: https://www.owasp.org/index.php/OWASP_Testing_Project

Sommaire

Dans ce test, le testeur vérifie s'il est possible de cause un débordement de tas (Heap overflow) exploitant un segment de mémoire.


Le tas est un segment de mémoire utilisé pour stocker des données allouées dynamiquement ainsi que les variables globales. Chaque block de mémoire du tas consiste en balises limites contenant des informations de gestion de la mémoire.


Quand un tampon dans le tas est débordé, les informations de contrôle de ces balises sont écrasées. Quand la routine de gestion du tas libère le tampon, un dépassement d'écriture a lieu, entraînant une violation d'accès. Quand le dépassement est effectué de façon contrôlée, la vulnérabilité permet à un attaquant d'écraser la zone mémoire voulue par une valeur déterminée. En pratique, un attaquant peut remplacer des pointeurs de fonctions et diverses adresses stockées dans des structures comme GET, .dtors, ou TEB avec l'adresse d'une charge utile malicieuse.


Il y a un grand nombre de variante de vulnérabilités de débordement (ou corruption) de tas, qui peuvent permettre l'écrasement de pointeurs de fonctions, ou d'exploiter les structures de gestionde la mémoire pour exécuter du code arbitrairement. La découverte des débordements de tas requiert une étude plus détaillée que celle des débordements de pile, puisque certaines conditions doivent être remplies pour qu'il soient exploitables.

Comment tester

Test en boite noire

Les principes de test en boite noire pour les débordements de tas sont les mêmes que pour les débordements de pile. La clef est de fournir des chaînes d'entrées plus longues qu'attendu. Bien que le processus reste le même, les résultats visibles dans un débogueur sont significativement différents. Alors que dans le as d'un débordement de pile, l'écrasement du pointeur d'instruction ou SEH apparaîtrait, cela n'est pas le cas pour un débordement de tas. Quand on débogue sous Windows, un débordement de tas peut avoir différentes formes, la plus commune étant un échange de pointeur après que la routine de gestion du tas soit entrée en action. Le scenario suivant illustre une vulnérabilité de débordement de tas.


Heap overflow vulnerability.gif


Les deux registres affichés, EAX et ECX, peuvent être affectés avec des adresses fournies par l'utilisateur qui font partie des données utilisées pour déborder le tas. Une des adresse peut pointer sur un pointeur de fonction à écraser, par exemple UEF (Unhandled Exception filter), et l'autre peut être l'adresse du code à exécuter.


Quand les instructions MOV affichée dans le panneau de gauche sont exécutées, l'écrasement a lieu, et quand la fonction est appelée, le code fourni par l'utilisateur est exécuté. Comme mentionné plus haut, d'autres méthodes pour tester de telle vulnérabilités incluent l'ingénierie inverse des binaires de l'application, qui est un processus long et complexe, et le les techniques de fuzzing.


Test en boite grise

Quand on fait uen revue de code, on doit savoir qu'il y a différentes manières dont les débordement de tas peuvent survenir. Du code en apparence inoffensif à première vue peut en fait être vulnérable dans certaines conditions. Comme il y a plusieurs variantes de cette vulnérabilité, nous allons voir seulement les plus fréquentes.


La plupart du temps, le tas est considéré comme sûr par beaucoup de développeurs qui n'hésitent pas à utiliser des fonctions non sécurisées comme strcpy(). Le mythe prétendant que les débordement de pile et l'écrasement du pointeur d'instruction sont les seuls moyen d'exécuter du code arbitraire est en fait hasardeux dans le cas du code suivant :

int main(int argc, char *argv[])
	{
		……

		vulnerable(argv[1]);		                                 
		return 0;
	}


	int vulnerable(char *buf)
	{
		
		HANDLE hp = HeapCreate(0, 0, 0);		
		
		HLOCAL chunk = HeapAlloc(hp, 0, 260);

		strcpy(chunk, buf);  ''' Vulnerability''' 
                         
                          …….. 

		return 0;
	}


Dans ce cas, si buf est plus grand que 200 octets, il va écraser les pointeurs de la balise de limite voisine, facilitant la réécriture d'une zone de mémoire arbitraire avec 4 octets une fois que la routine de gestion du tas se lance.


Récemment, plusieurs produits, notamment des bibliothèques anti-virus, ont été impactés par des variantes qui sont uen combinaison de débordement d'entier et d'opérations de copie vers un tampon du tas. Par exemple, considérons un morceau de code vulnérable, composant de code traîtant les fichiers de type TNEF, de Clam Anti Virus 0.86.1 (fichier source tnef.c et fonction tnef_message() ) :

string = cli_malloc(length + 1); ''' Vulnerability'''
if(fread(string, 1, length, fp) != length) {''' Vulnerability'''
free(string);
return -1;
}


Le malloc de la ligne 1 alloue une quantité de mémoire basée sur la valeur de length, qui est un entier 32 bits. Dans cet exemple, length est contrôlable par l'utilisateur et un fichier TNEF malicieux peut être construit pour affecter '-1' à length, ce qui donnerait un malloc( 0 ). Donc ce malloc allourait un petit tampon dans le tas, qui ferait 16 octets sur la plupart des plateformes 32 bits (comme indiqué dans malloc.h).


Ensuite à la ligne 2, un débordement de tas lors de l'appelle à fread(à. Le 3e argument, dans ce cas length, devrait être une variable size_t. Mais comme il est égal à '-1', il est converti en 0xFFFFFFFF, copiant ainsi 0xFFFFFFFF octets dans le tampon de 16 octets.


Les outils d'analyse de code statiques peuvent aussi aider pour repérer les vulnérabilités en rapport, comme les "double free", etc. Divers outils comme RATS, Flwfinder et ITS4 sont disponiblres pour analyser les langages C et dérivés.


Outils


Références

Whitepapers