ROP - Return Oriented Programing
Osnovne informacije
Return-Oriented Programming (ROP) je napredna tehnika eksploatacije koja se koristi za zaobilaženje sigurnosnih mera poput No-Execute (NX) ili Data Execution Prevention (DEP). Umesto ubacivanja i izvršavanja shell koda, napadač koristi delove koda već prisutne u binarnom fajlu ili u učitanim bibliotekama, poznate kao "gadgeti". Svaki gadget obično završava sa ret
instrukcijom i obavlja malu operaciju, poput premeštanja podataka između registara ili izvođenja aritmetičkih operacija. Spajanjem ovih gadgeta, napadač može konstruisati payload za obavljanje proizvoljnih operacija, efikasno zaobilazeći NX/DEP zaštite.
Kako ROP funkcioniše
Preuzimanje kontrole toka: Prvo, napadač mora preuzeti kontrolu toka programa, obično iskorišćavanjem prelivanja bafera da bi prepisao sačuvanu adresu povratka na steku.
Spajanje Gadgeta: Napadač zatim pažljivo bira i spaja gadgete da bi izvršio željene akcije. To može uključivati postavljanje argumenata za poziv funkcije, pozivanje funkcije (npr.
system("/bin/sh")
), i rukovanje neophodnim čišćenjem ili dodatnim operacijama.Izvršavanje Payloada: Kada ranjiva funkcija završi, umesto povratka na legitimnu lokaciju, počinje izvršavanje lanca gadgeta.
Alati
Gadgeti se obično mogu pronaći korišćenjem ROPgadget, ropper ili direktno iz pwntools (ROP).
ROP Lanac u x86 Primeru
x86 (32-bit) Konvencije pozivanja
cdecl: Pozivaoc čisti stek. Argumenti funkcije se guraju na stek u obrnutom redosledu (sa desna na levo). Argumenti se guraju na stek s desna na levo.
stdcall: Slično cdecl-u, ali je callee odgovoran za čišćenje steka.
Pronalaženje Gadgeta
Prvo, pretpostavimo da smo identifikovali potrebne gadgete unutar binarnog fajla ili njegovih učitanih biblioteka. Gadgeti koji nas zanimaju su:
pop eax; ret
: Ovaj gadget skida vrh vrednosti sa steka u registarEAX
i zatim se vraća, omogućavajući nam kontrolu nadEAX
.pop ebx; ret
: Slično kao prethodno, ali za registarEBX
, omogućavajući kontrolu nadEBX
.mov [ebx], eax; ret
: Premešta vrednost izEAX
u memorijsku lokaciju na koju pokazujeEBX
i zatim se vraća. Ovo se često naziva write-what-where gadget.Dodatno, imamo adresu funkcije
system()
dostupnu.
ROP Lanac
Koristeći pwntools, pripremamo stek za izvršavanje ROP lanca kako bismo izvršili system('/bin/sh')
, obratite pažnju kako lanac počinje sa:
ret
instrukcijom radi poravnanja (opciono)Adresa funkcije
system
(pretpostavljajući da je ASLR isključen i poznata libc, više informacija u Ret2lib)Rezervisano mesto za adresu povratka iz
system()
Adresa stringa
"/bin/sh"
(parametar za funkciju system)
Primer ROP lanac u x64
x64 (64-bit) Konvencije pozivanja
Koristi System V AMD64 ABI konvenciju pozivanja na sistemima sličnim Unix-u, gde se prva šest celobrojnih ili pokazivačkih argumenata prosleđuje u registre
RDI
,RSI
,RDX
,RCX
,R8
, iR9
. Dodatni argumenti se prosleđuju na steku. Povratna vrednost se smešta uRAX
.Windows x64 konvencija pozivanja koristi
RCX
,RDX
,R8
, iR9
za prva četiri celobrojna ili pokazivačka argumenta, sa dodatnim argumentima prosleđenim na steku. Povratna vrednost se smešta uRAX
.Registri: 64-bitni registri uključuju
RAX
,RBX
,RCX
,RDX
,RSI
,RDI
,RBP
,RSP
, iR8
doR15
.
Pronalaženje Gadgeta
Za našu svrhu, fokusiraćemo se na gedžete koji će nam omogućiti postavljanje registra RDI (kako bismo prosledili string "/bin/sh" kao argument funkciji system()) i zatim pozvali funkciju system(). Pretpostavićemo da smo identifikovali sledeće gedžete:
pop rdi; ret: Skida vrh vrednosti sa steka u registar RDI i zatim se vraća. Neophodno za postavljanje argumenta za system().
ret: Jednostavan povratak, koristan za poravnanje steka u nekim scenarijima.
I znamo adresu funkcije system().
ROP Lanac
U nastavku je primer korišćenja pwntools za postavljanje i izvršavanje ROP lanca sa ciljem izvršavanja system('/bin/sh') na x64:
U ovom primeru:
Koristimo
pop rdi; ret
gedžet da postavimoRDI
na adresu"/bin/sh"
.Direktno skačemo na
system()
nakon postavljanjaRDI
, sa adresom system() funkcije u lancu.ret_gadget
se koristi za poravnanje ako ciljano okruženje zahteva, što je češće u x64 da bi se osiguralo pravilno poravnanje steka pre pozivanja funkcija.
Poravnanje Staka
x86-64 ABI osigurava da je stek poravnan na 16 bajtova kada se izvrši call instrukcija. LIBC, radi optimizacije performansi, koristi SSE instrukcije (kao što su movaps) koje zahtevaju ovo poravnanje. Ako stek nije pravilno poravnan (što znači da RSP nije višekratnik broja 16), pozivi funkcija poput system će neuspeti u ROP lancu. Da biste to rešili, jednostavno dodajte ret gedžet pre pozivanja system u vašem ROP lancu.
x86 vs x64 glavna razlika
Pošto x64 koristi registre za prvih nekoliko argumenata, često zahteva manje gedžeta od x86 za jednostavne pozive funkcija, ali pronalaženje i povezivanje pravih gedžeta može biti složenije zbog povećanog broja registara i većeg adresnog prostora. Povećani broj registara i veći adresni prostor u x64 arhitekturi pružaju i mogućnosti i izazove za razvoj eksploatacija, posebno u kontekstu Return-Oriented Programming (ROP).
ROP lanac u ARM64 Primeru
ARM64 Osnove & Konvencije pozivanja
Proverite sledeću stranicu za ove informacije:
Introduction to ARM64v8Zaštite Protiv ROP
Stack Canaries: U slučaju BOF-a, potrebno je zaobići čuvare steka kako bi se prepisali povratni pokazivači i iskoristio ROP lanac.
Nedostatak Gedžeta: Ako nema dovoljno gedžeta, neće biti moguće generisati ROP lanac.
Tehnike Bazirane na ROP-u
Primetite da je ROP samo tehnika za izvršavanje proizvoljnog koda. Bazirano na ROP-u, razvijeno je mnogo Ret2XXX tehnika:
Ret2lib: Koristi ROP za pozivanje proizvoljnih funkcija iz učitane biblioteke sa proizvoljnim parametrima (obično nešto poput
system('/bin/sh')
.
Ret2Syscall: Koristi ROP za pripremu poziva syscall-a, npr.
execve
, i izvršava proizvoljne komande.
EBP2Ret & EBP Chaining: Prvi će zloupotrebiti EBP umesto EIP-a za kontrolu toka, a drugi je sličan Ret2lib-u, ali u ovom slučaju tok je kontrolisan uglavnom sa EBP adresama (mada je takođe potrebno kontrolisati i EIP).
Ostali Primeri & Reference
64 bita, Pie i nx omogućeno, bez čuvara, prepisivanje RIP-a sa adresom
vsyscall
sa jedinim ciljem povratka na sledeću adresu na steku koja će biti delimično prepisivanje adrese kako bi se dobio deo funkcije koji otkriva zastavuarm64, bez ASLR-a, ROP gedžet za omogućavanje izvršavanja steka i skakanje na shellcode u steku
Last updated