Leaking libc address with ROP
Brzi Rezime
Pronađite offset preplavljivanja
Pronađite
POP_RDI
gedžet,PUTS_PLT
iMAIN
gedžeteKoristite prethodne gedžete da procurete memorijsku adresu puts ili neke druge libc funkcije i pronađete verziju libc-a (preuzmite je)
Sa bibliotekom, izračunajte ROP i iskoristite je
Ostali tutorijali i binarni fajlovi za vežbanje
Ovaj tutorijal će iskoristiti kod/binarni fajl predložen u ovom tutorijalu: https://tasteofsecurity.com/security/ret2libc-unknown-libc/ Još korisnih tutorijala: https://made0x78.com/bseries-ret2libc/, https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
Kod
Ime fajla: vuln.c
ROP - Šablona za otkrivanje LIBC adrese
Preuzmite eksploataciju i smestite je u isti direktorijum kao i ranjivu binarnu datoteku i pružite potrebne podatke skripti:
1- Pronalaženje ofseta
Šablonu je potreban ofset pre nego što nastavi sa eksploatacijom. Ako nije pružen, izvršiće potreban kod za njegovo pronalaženje (podrazumevano OFFSET = ""
):
Izvršite python template.py
, otvoriće se GDB konzola sa programom koji je pao. Unutar te GDB konzole izvršite x/wx $rsp
da biste dobili bajtove koji će prepisati RIP. Na kraju dobijte ofset koristeći python konzolu:
Nakon što pronađete offset (u ovom slučaju 40), promenite promenljivu OFFSET unutar šablona koristeći tu vrednost.
OFFSET = "A" * 40
Još jedan način bio bi korišćenje: pattern create 1000
-- izvršiti do ret -- pattern seach $rsp
iz GEF-a.
2- Pronalaženje Gadgeta
Sada trebamo pronaći ROP gadžete unutar binarnog fajla. Ovi ROP gadžeti će biti korisni za pozivanje puts
kako bismo pronašli libc koji se koristi, a kasnije i za pokretanje konačnog napada.
PUTS_PLT
je potreban da bi se pozvala funkcija puts.
MAIN_PLT
je potreban da bi se pozvala glavna funkcija ponovo nakon jedne interakcije da bi se iskoristio preljev ponovo (beskonačne runde iskorišćavanja). Koristi se na kraju svakog ROP-a da bi se program pozvao ponovo.
POP_RDI je potreban da bi se prosledio parametar pozvanoj funkciji.
U ovom koraku ne morate izvršiti ništa jer će sve biti pronađeno pomoću pwntools tokom izvršavanja.
3- Pronalaženje libc biblioteke
Sada je vreme da se otkrije koja verzija libc biblioteke se koristi. Da bismo to uradili, procurećemo adresu u memoriji funkcije puts
, a zatim ćemo tražiti u kojoj verziji biblioteke se nalazi ta verzija puts funkcije na toj adresi.
Da biste to postigli, najvažnija linija izvršenog koda je:
Ovo će poslati nekoliko bajtova dok nije moguće prepisati RIP: OFFSET
.
Zatim će postaviti adresu gedžeta POP_RDI
tako da će sledeća adresa (FUNC_GOT
) biti sačuvana u registru RDI. To je zato što želimo pozvati puts prosljeđujući mu adresu PUTS_GOT
jer je adresa funkcije puts u memoriji sačuvana na adresi na koju pokazuje PUTS_GOT
.
Nakon toga, pozvaće se PUTS_PLT
(sa PUTS_GOT
unutar RDI) tako da će puts pročitati sadržaj unutar PUTS_GOT
(adresa funkcije puts u memoriji) i ispisati je.
Na kraju, ponovo se poziva glavna funkcija kako bismo ponovo iskoristili prekoračenje.
Na ovaj način smo prevarili funkciju puts da ispisuje adresu u memoriji funkcije puts (koja je unutar libc biblioteke). Sada kada imamo tu adresu, možemo proveriti koja verzija libc-a se koristi.
Kako iskorištavamo neki lokalni binarni fajl, nije potrebno otkriti koja verzija libc-a se koristi (samo pronađite biblioteku u /lib/x86_64-linux-gnu/libc.so.6
).
Međutim, u slučaju udaljenog napada objasniću kako to možete pronaći:
3.1- Pretraga verzije libc-a (1)
Možete pretražiti koja biblioteka se koristi na veb stranici: https://libc.blukat.me/ Takođe će vam omogućiti da preuzmete otkrivenu verziju libc-a
3.2- Pretraga verzije libc-a (2)
Takođe možete uraditi:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
Ovo će potrajati neko vreme, budite strpljivi. Da bi ovo radilo, potrebno nam je:
Ime simbola libc-a:
puts
Procurena adresa libc-a:
0x7ff629878690
Možemo saznati koja se libc najverovatnije koristi.
Dobijamo 2 podudaranja (trebalo bi da probate drugo ako prvo ne radi). Preuzmite prvo:
3.3- Druge funkcije za otkrivanje
4- Pronalaženje zasnovane adrese libc-a i eksploatacija
U ovom trenutku trebalo bi da znamo koju libc biblioteku koristimo. Budući da eksploatišemo lokalni binarni fajl, koristiću samo: /lib/x86_64-linux-gnu/libc.so.6
Dakle, na početku template.py
promenite libc promenljivu u: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Postavite putanju biblioteke kada je znate
Dajući putanju do libc biblioteke, ostatak eksploatacije će biti automatski izračunat.
Unutar funkcije get_addr
biće izračunata bazna adresa libc-a:
Imajte na umu da konačna adresa osnovne libc biblioteke mora završiti sa 00. Ako to nije slučaj, možda ste otkrili netačnu biblioteku.
Zatim će adresa funkcije system
i adresa stringa "/bin/sh" biti izračunati iz osnovne adrese libc i date libc biblioteke.
Konačno, eksploatacija izvršenja /bin/sh će biti pripremljena poslata:
Objasnićemo ovaj konačni ROP.
Poslednji ROP (rop1
) završio je ponovnim pozivom glavne funkcije, zatim možemo ponovo iskoristiti preplavljivanje (zato je ovde ponovo OFFSET
). Zatim želimo pozvati POP_RDI
koji pokazuje na adresu "/bin/sh" (BINSH
) i pozvati funkciju system (SYSTEM
) jer će adresa "/bin/sh" biti prosleđena kao parametar.
Na kraju se poziva adresa funkcije izlaza tako da se proces lepo završi i ne generiše se nikakvo upozorenje.
Na ovaj način eksploit će izvršiti _/bin/sh_** shell.**
4(2)- Korišćenje ONE_GADGET
Takođe možete koristiti ONE_GADGET da biste dobili shell umesto korišćenja system i "/bin/sh". ONE_GADGET će pronaći unutar libc biblioteke neki način da se dobije shell koristeći samo jednu ROP adresu.
Međutim, obično postoje neka ograničenja, najčešća i lako izbegnuta su poput [rsp+0x30] == NULL
. Pošto kontrolišete vrednosti unutar RSP, samo treba poslati još nekoliko NULL vrednosti kako bi se ograničenje izbeglo.
EXPLOIT FAJL
Ovde možete pronaći šablon za iskorišćavanje ove ranjivosti:
Česti problemi
MAIN_PLT = elf.symbols['main'] nije pronađen
Ako simbol "main" ne postoji. Tada možete pronaći gde se nalazi glavni kod:
i postavite adresu ručno:
Puts nije pronađen
Ako binarni fajl ne koristi Puts, trebalo bi da proverite da li koristi
sh: 1: %s%s%s%s%s%s%s%s: not found
sh: 1: %s%s%s%s%s%s%s%s: not found
Ako pronađete ovu grešku nakon što ste kreirali sve eksploate: sh: 1: %s%s%s%s%s%s%s%s: not found
Pokušajte da oduzmete 64 bajta od adrese "/bin/sh":
Last updated