Leaking libc address with ROP
Last updated
Last updated
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Vind overflow offset
Vind POP_RDI
gadget, PUTS_PLT
en MAIN
gadgets
Gebruik vorige gadgets om die geheue adres van puts of 'n ander libc funksie te lek en vind die libc weergawe (aflaai dit)
Met die biblioteek, bereken die ROP en exploiteer dit
Hierdie tutorial gaan die kode/binary wat in hierdie tutorial voorgestel word, exploiteer: https://tasteofsecurity.com/security/ret2libc-unknown-libc/ Ander nuttige tutorials: https://made0x78.com/bseries-ret2libc/, https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
Filename: vuln.c
Laai die exploit af en plaas dit in dieselfde gids as die kwesbare binêre en gee die nodige data aan die skrip:
Die sjabloon benodig 'n offset voordat dit met die exploit voortgaan. As enige verskaf word, sal dit die nodige kode uitvoer om dit te vind (standaard OFFSET = ""
):
Voer python template.py
uit, 'n GDB-konsol sal geopen word met die program wat gecrash het. Binne daardie GDB-konsol voer x/wx $rsp
uit om die bytes te kry wat die RIP sou oorskryf. Laastens kry die offset met 'n python-konsol:
Nadat die offset gevind is (in hierdie geval 40), verander die OFFSET veranderlike binne die sjabloon met daardie waarde.
OFFSET = "A" * 40
'n Ander manier sou wees om: pattern create 1000
-- voer uit tot ret -- pattern seach $rsp
van GEF te gebruik.
Nou moet ons ROP gadgets binne die binêre vind. Hierdie ROP gadgets sal nuttig wees om puts
aan te roep om die libc wat gebruik word te vind, en later om die finale exploit te lanseer.
Die PUTS_PLT
is nodig om die funksie puts aan te roep.
Die MAIN_PLT
is nodig om die hoof funksie weer aan te roep na een interaksie om die overflow weer te ontgin (oneindige rondes van ontginning). Dit word aan die einde van elke ROP gebruik om die program weer aan te roep.
Die POP_RDI is nodig om 'n parameter aan die aangeroepde funksie te gee.
In hierdie stap hoef jy niks uit te voer nie, aangesien alles deur pwntools tydens die uitvoering gevind sal word.
Nou is dit tyd om te vind watter weergawe van die libc biblioteek gebruik word. Om dit te doen, gaan ons die adres in geheue van die funksie puts
lek en dan gaan ons soek in watter biblioteek weergawe die puts weergawe in daardie adres is.
Om dit te doen, is die belangrikste lyn van die uitgevoerde kode:
Dit sal 'n paar bytes stuur totdat oorskrywing van die RIP moontlik is: OFFSET
.
Dan sal dit die adres van die gadget POP_RDI
stel sodat die volgende adres (FUNC_GOT
) in die RDI register gestoor sal word. Dit is omdat ons wil oproep puts deur dit die adres van die PUTS_GOT
te gee, aangesien die adres in geheue van die puts-funksie in die adres wat deur PUTS_GOT
aangedui word, gestoor is.
Daarna sal PUTS_PLT
aangeroep word (met PUTS_GOT
binne die RDI) sodat puts die inhoud binne PUTS_GOT
(die adres van die puts-funksie in geheue) sal lees en dit sal uitdruk.
Laastens, word die hoof funksie weer aangeroep sodat ons die oorskrywing weer kan benut.
Op hierdie manier het ons die puts-funksie bedrieg om die adres in geheue van die funksie puts (wat binne die libc biblioteek is) te druk. Nou dat ons daardie adres het, kan ons soek watter libc weergawe gebruik word.
Aangesien ons 'n paar lokale binêre benut, is dit nie nodig om uit te vind watter weergawe van libc gebruik word nie (vind net die biblioteek in /lib/x86_64-linux-gnu/libc.so.6
).
Maar, in 'n afstandsbenutting geval sal ek hier verduidelik hoe jy dit kan vind:
Jy kan soek watter biblioteek op die webblad gebruik word: https://libc.blukat.me/ Dit sal jou ook toelaat om die ontdekte weergawe van libc af te laai.
Jy kan ook doen:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
Dit sal 'n rukkie neem, wees geduldig. Vir dit om te werk, het ons nodig:
Libc simbool naam: puts
Gelekte libc adres: 0x7ff629878690
Ons kan uitvind watter libc waarskynlik gebruik word.
We kry 2 ooreenkomste (jy moet die tweede een probeer as die eerste een nie werk nie). Laai die eerste een af:
Kopieer die libc van libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
na ons werksgids.
Op hierdie punt behoort ons die libc biblioteek te ken wat gebruik word. Aangesien ons 'n plaaslike binêre uitbuit, sal ek net gebruik: /lib/x86_64-linux-gnu/libc.so.6
So, aan die begin van template.py
verander die libc veranderlike na: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Stel biblioteek pad in wanneer dit bekend is
Deur die pad aan die libc biblioteek te gee, gaan die res van die uitbuiting outomaties bereken word.
Binne die get_addr
funksie gaan die basis adres van libc bereken word:
Let op dat die finale libc basisadres moet eindig op 00. As dit nie jou geval is nie, het jy dalk 'n verkeerde biblioteek gelekt.
Dan gaan die adres na die funksie system
en die adres na die string "/bin/sh" bereken word vanaf die basisadres van libc en gegee aan die libc biblioteek.
Uiteindelik gaan die /bin/sh uitvoeringsuitbuiting voorberei word en gestuur:
Laten ons hierdie finale ROP verduidelik.
Die laaste ROP (rop1
) het weer die hooffunksie aangeroep, dan kan ons weer die oortolligheid benut (dit is hoekom die OFFSET
hier weer is). Dan wil ons POP_RDI
aanroep wat na die adres van "/bin/sh" (BINSH
) wys en die system funksie (SYSTEM
) aanroep omdat die adres van "/bin/sh" as 'n parameter oorgedra sal word.
Laastens, die adres van die uitgang funksie word aangeroep sodat die proses netjies bestaan en enige waarskuwing gegenereer word.
Op hierdie manier sal die exploit 'n _/bin/sh_** shell uitvoer.**
Jy kan ook ONE_GADGET gebruik om 'n shell te verkry in plaas van om system en "/bin/sh" te gebruik. ONE_GADGET sal binne die libc biblioteek 'n manier vind om 'n shell te verkry met net een ROP adres.
E however, normaalweg is daar 'n paar beperkings, die mees algemene en maklik om te vermy is soos [rsp+0x30] == NULL
Aangesien jy die waardes binne die RSP beheer, hoef jy net 'n paar meer NULL waardes te stuur sodat die beperking vermy word.
Jy kan 'n sjabloon vind om hierdie kwesbaarheid te benut hier:
As die "main" simbool nie bestaan nie. Dan kan jy vind waar die hoofkode is:
en stel die adres handmatig:
As die binêre nie Puts gebruik nie, moet jy kyk of dit gebruik
sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie
As jy hierdie fout vind nadat jy alle die exploits geskep het: sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie
Probeer om 64 bytes van die adres van "/bin/sh" af te trek:
Leer & oefen AWS Hacking:HackTricks Opleiding AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Opleiding GCP Red Team Expert (GRTE)