Stack Overflow
Qu'est-ce qu'un débordement de pile
Un débordement de pile est une vulnérabilité qui se produit lorsqu'un programme écrit plus de données sur la pile qu'il n'est alloué pour en contenir. Ces données excédentaires vont écraser l'espace mémoire adjacent, entraînant la corruption de données valides, la perturbation du flux de contrôle et potentiellement l'exécution de code malveillant. Ce problème survient souvent en raison de l'utilisation de fonctions non sécurisées qui ne vérifient pas les limites des entrées.
Le principal problème de cet écrasement est que les pointeurs EIP et EBP pour revenir à la fonction précédente sont stockés dans la pile. Par conséquent, un attaquant pourra les écraser et contrôler le flux d'exécution du programme.
La vulnérabilité survient généralement parce qu'une fonction copie à l'intérieur de la pile plus d'octets que la quantité qui lui est allouée, ce qui lui permet d'écraser d'autres parties de la pile.
Certaines fonctions courantes vulnérables à cela sont : strcpy
, strcat
, sprintf
, gets
, fgets
...
Par exemple, les fonctions suivantes pourraient être vulnérables :
Trouver les débordements de pile
La manière la plus courante de trouver les débordements de pile est de fournir une entrée très grande de A
s (par exemple python3 -c 'print("A"*1000)'
) et d'attendre un Segmentation Fault
indiquant que l'adresse 0x41414141
a été tentée d'être accédée.
De plus, une fois que vous avez trouvé qu'il y a une vulnérabilité de débordement de pile, vous devrez trouver le décalage jusqu'à ce qu'il soit possible de écraser le pointeur EIP, pour cela on utilise généralement une séquence de De Bruijn. Qui, pour un alphabet donné de taille k et des sous-séquences de longueur n, est une séquence cyclique dans laquelle chaque sous-séquence possible de longueur _n_** apparaît exactement une fois** en tant que sous-séquence contiguë.
De cette manière, au lieu de devoir déterminer manuellement quel décalage écrase l'EIP, il est possible d'utiliser l'une de ces séquences comme rembourrage, puis de trouver le décalage des octets qui ont fini par l'écraser.
Il est possible d'utiliser pwntools pour cela:
ou GEF :
Exploiter les débordements de pile
Lors d'un débordement (en supposant que la taille du débordement est suffisamment grande), vous pourrez écraser les valeurs d'autres variables à l'intérieur de la pile jusqu'à atteindre l'EBP et l'EIP (ou même plus). La manière la plus courante d'exploiter ce type de vulnérabilité est en modifiant le pointeur EIP afin que lorsque la fonction se termine, le flux de contrôle soit redirigé où l'utilisateur l'a spécifié dans ce pointeur.
Cependant, dans d'autres scénarios, peut-être que simplement écraser les valeurs de certaines variables dans la pile pourrait suffire pour l'exploitation (comme dans les défis CTF faciles).
Ret2win
Dans ce type de défis CTF, il y a une fonction à l'intérieur du binaire qui n'est jamais appelée et que vous devez appeler pour gagner. Pour ces défis, vous devez simplement trouver le décalage pour écraser l'EIP et trouver l'adresse de la fonction à appeler (généralement ASLR serait désactivé) afin que lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
Ret2winShellcode de pile
Dans ce scénario, l'attaquant pourrait placer un shellcode dans la pile et exploiter l'EIP contrôlé pour aller au shellcode et exécuter le code de l'attaquant :
Stack ShellcodeROP
Cette technique est le cadre fondamental pour contourner la principale protection de la technique précédente : Pas de pile exécutable. Et elle permet d'exécuter plusieurs autres techniques (ret2lib, ret2syscall...) qui finiront par exécuter des commandes arbitraires en exploitant des instructions existantes dans le binaire :
ROP - Return Oriented ProgramingTypes de protections
Il existe plusieurs protections visant à empêcher l'exploitation des vulnérabilités, consultez-les ici :
Common Binary Protections & BypassesLast updated