6.1 KiB
Prekoračenje steka
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite vašu kompaniju reklamiranu na HackTricks-u ili da preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRIJATELJSTVO!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte Porodicu PEASS, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @hacktricks_live.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Šta je prekoračenje steka
Prekoračenje steka je ranjivost koja se javlja kada program upisuje više podataka na stek nego što je alociran da drži. Ovi višak podataka će prepisati susedni memorijski prostor, što dovodi do korupcije validnih podataka, poremećaja kontrolnog toka i potencijalno izvršavanja zlonamernog koda. Ovaj problem često nastaje zbog korišćenja nesigurnih funkcija koje ne vrše proveru granica unosa.
Glavni problem ovog prepisivanja je što su sačuvani pokazivač instrukcija (EIP/RIP) i sačuvani bazni pokazivač (EBP/RBP) za povratak na prethodnu funkciju sačuvani na steku. Stoga, napadač će moći da prepisuje te vrednosti i kontroliše izvršavanje programa.
Ranjivost obično nastaje jer funkcija kopira unutar steka više bajtova nego što je alocirano za nju, te može prepisati druge delove steka.
Neke česte funkcije ranjive na ovo su: strcpy
, strcat
, sprintf
, gets
... Takođe, funkcije poput fgets
, read
& memcpy
koje uzimaju argument dužine, mogu biti korišćene na ranjiv način ako je navedena dužina veća od alocirane.
Na primer, sledeće funkcije mogu biti ranjive:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Pronalaženje ofseta preplavljivanja steka
Najčešći način pronalaženja preplavljivanja steka je unošenje vrlo velikog unosa A
(npr. python3 -c 'print("A"*1000)'
) i očekivanje Segmentation Fault
koji ukazuje da je pokušano pristupanje adresi 0x41414141
.
Osim toga, kada otkrijete da postoji ranjivost preplavljivanja steka, moraćete pronaći ofset dok je moguće prepisati povratnu adresu, za to se obično koristi De Bruijnov niz. Za dati alfabet veličine k i podnizove dužine n, De Bruijnov niz je ciklični niz u kojem se svaki mogući podniz dužine n pojavljuje tačno jednom kao kontinuirani podniz.
Na ovaj način, umesto potrebe da ručno odredite koji je ofset potreban za kontrolu EIP, moguće je koristiti jedan od ovih nizova kao punjenje, a zatim pronaći ofset bajtova koji su završili prepisivanjem.
Moguće je koristiti pwntools za ovo:
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}")
ili 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
Iskorišćavanje preplavljenosti steka
Tokom preplavljenosti (pretpostavljajući da je veličina preplavljenosti dovoljno velika) moći ćete da prepišete vrednosti lokalnih promenljivih unutar steka sve do dostizanja sačuvanog EBP/RBP i EIP/RIP (ili čak više).
Najčešći način zloupotrebe ovog tipa ranjivosti je menjanje adrese povratka tako da kada funkcija završi, tok kontrole će biti preusmeren gde god je korisnik odredio u ovom pokazivaču.
Međutim, u drugim scenarijima možda je dovoljno samo prepisati vrednosti nekih promenljivih u steku za eksploataciju (kao u jednostavnim CTF izazovima).
Ret2win
U ovom tipu CTF izazova, postoji funkcija unutar binarnog fajla koja nikada nije pozvana i koju morate pozvati da biste pobedili. Za ove izazove samo trebate pronaći pomeraj za prepisivanje adrese povratka i pronaći adresu funkcije koju treba pozvati (obično je ASLR onemogućen) tako da kada ranjiva funkcija završi, skrivena funkcija će biti pozvana:
{% content-ref url="ret2win.md" %} ret2win.md {% endcontent-ref %}
Shellkod u steku
U ovom scenariju napadač može postaviti shellkod u stek i zloupotrebiti kontrolisani EIP/RIP da skoči na shellkod i izvrši proizvoljni kod:
{% content-ref url="stack-shellcode.md" %} stack-shellcode.md {% endcontent-ref %}
ROP & Ret2... tehnike
Ova tehnika je osnovni okvir za zaobilaženje glavne zaštite prethodne tehnike: Neizvršivi stek (NX). I omogućava izvođenje nekoliko drugih tehnika (ret2lib, ret2syscall...) koje će na kraju izvršiti proizvoljne komande zloupotrebom postojećih instrukcija u binarnom fajlu:
{% content-ref url="../rop-return-oriented-programing/" %} rop-return-oriented-programing {% endcontent-ref %}
Vrste zaštita
Postoje nekoliko zaštita koje pokušavaju da spreče eksploataciju ranjivosti, proverite ih u:
{% content-ref url="../common-binary-protections-and-bypasses/" %} common-binary-protections-and-bypasses {% endcontent-ref %}