ROP - Return Oriented Programing
Last updated
Last updated
Leer en oefen AWS-hacking:HackTricks Training AWS Red Team Expert (ARTE) Leer en oefen GCP-hacking: HackTricks Training GCP Red Team Expert (GRTE)
Return-Oriented Programming (ROP) is 'n gevorderde uitbuitingstegniek wat gebruik word om sekuriteitsmaatreëls soos No-Execute (NX) of Data Execution Prevention (DEP) te omseil. In plaas van om shellcode in te spuit en uit te voer, maak 'n aanvaller gebruik van stukke kode wat reeds teenwoordig is in die binêre lêer of in gelaai biblioteke, bekend as "gadgets". Elke gadget eindig tipies met 'n ret
instruksie en voer 'n klein operasie uit, soos die skuif van data tussen registre of die uitvoer van rekenkundige operasies. Deur hierdie gadgets aan mekaar te koppel, kan 'n aanvaller 'n lading bou om arbitrêre operasies uit te voer, wat effektief NX/DEP-beskerming omseil.
Beheerstroomkaping: Eerstens moet 'n aanvaller die beheerstroom van 'n program kap, tipies deur 'n buffer-oorvloei te benut om 'n gestoorde terugkeeradres op die stok oor te skryf.
Gadget-ketting: Die aanvaller kies dan sorgvuldig gadgets en koppel hulle aan mekaar om die gewenste aksies uit te voer. Dit kan die opstel van argumente vir 'n funksieoproep behels, die roep van die funksie (bv., system("/bin/sh")
), en die hanteer van enige nodige skoonmaak of bykomende operasies.
Ladinguitvoering: Wanneer die kwesbare funksie terugkeer, begin dit in plaas van om na 'n wettige plek terug te keer, die ketting van gadgets uitvoer.
Gewoonlik kan gadgets gevind word met behulp van ROPgadget, ropper of direk vanuit pwntools (ROP).
cdecl: Die oproeper maak die stok skoon. Funksie-argumente word in omgekeerde volgorde op die stok gedruk (van regs na links). Argumente word van regs na links op die stok gedruk.
stdcall: Soortgelyk aan cdecl, maar die ontvanger is verantwoordelik vir die skoonmaak van die stok.
Eerstens, laat ons aanneem dat ons die nodige gadgets binne die binêre lêer of sy gelaai biblioteke geïdentifiseer het. Die gadgets waarin ons belangstel, is:
pop eax; ret
: Hierdie gadget skuif die boonste waarde van die stok in die EAX
-register en keer dan terug, wat ons in staat stel om EAX
te beheer.
pop ebx; ret
: Soortgelyk aan die bogenoemde, maar vir die EBX
-register, wat beheer oor EBX
moontlik maak.
mov [ebx], eax; ret
: Skuif die waarde in EAX
na die geheueplek wat deur EBX
aangedui word en keer dan terug. Dit word dikwels 'n write-what-where gadget genoem.
Daarbenewens het ons die adres van die system()
-funksie beskikbaar.
Met behulp van pwntools berei ons die stok voor vir die uitvoering van die ROP-ketting soos hieronder gemik om system('/bin/sh')
uit te voer, let op hoe die ketting begin met:
'n ret
instruksie vir uitlyn doeleindes (opsioneel)
Adres van system
-funksie (onder die veronderstelling dat ASLR uitgeskakel is en bekende libc, meer inligting in Ret2lib)
Plekhouer vir die terugkeeradres van system()
"/bin/sh"
string-adres (parameter vir stelsel funksie)
Gebruik die System V AMD64 ABI oproepkonvensie op Unix-soortgelyke stelsels, waar die eerste ses heelgetal- of wysaanwysingsargumente in die register RDI
, RSI
, RDX
, RCX
, R8
, en R9
oorgedra word. Addisionele argumente word op die stok oorgedra. Die terugvoerwaarde word in RAX
geplaas.
Die Windows x64 oproepkonvensie gebruik RCX
, RDX
, R8
, en R9
vir die eerste vier heelgetal- of wysaanwysingsargumente, met addisionele argumente wat op die stok oorgedra word. Die terugvoerwaarde word in RAX
geplaas.
Register: 64-bis register sluit in RAX
, RBX
, RCX
, RDX
, RSI
, RDI
, RBP
, RSP
, en R8
tot R15
.
Vir ons doel, laat ons fokus op gadgets wat ons sal toelaat om die RDI register in te stel (om die "/bin/sh" string as 'n argument aan system() oor te dra) en dan die system() funksie aan te roep. Ons aanvaar dat ons die volgende gadgets geïdentifiseer het:
pop rdi; ret: Haal die boonste waarde van die stok uit in RDI en keer dan terug. Essensieel vir die instelling van ons argument vir system().
ret: 'n Eenvoudige terugkeer, nuttig vir stokuitlyn in sommige scenarios.
En ons weet die adres van die system() funksie.
Hieronder is 'n voorbeeld wat pwntools gebruik om 'n ROP-reeks op te stel en uit te voer met die doel om system('/bin/sh') uit te voer op x64:
In hierdie voorbeeld:
Ons maak gebruik van die pop rdi; ret
instrument om RDI
in te stel op die adres van "/bin/sh"
.
Ons spring direk na system()
nadat ons RDI
ingestel het, met system() se adres in die ketting.
ret_gadget
word gebruik vir belyn as die teikenomgewing dit vereis, wat meer algemeen is in x64 om behoorlike stakingsbelyn te verseker voordat funksies geroep word.
Die x86-64 ABI verseker dat die stapel 16-byte gebelyn is wanneer 'n oproepinstruksie uitgevoer word. LIBC, om prestasie te optimaliseer, gebruik SSE-instruksies (soos movaps) wat hierdie belyn vereis. As die stapel nie behoorlik gebelyn is nie (wat beteken dat RSP nie 'n veelvoud van 16 is nie), sal oproepe na funksies soos system misluk in 'n ROP-ketting. Om dit reg te stel, voeg eenvoudig 'n ret gadget by voordat jy system in jou ROP-ketting aanroep.
Aangesien x64 registers gebruik vir die eerste paar argumente, benodig dit dikwels minder gadgets as x86 vir eenvoudige funksie-oproepe, maar die vind en koppel van die regte gadgets kan meer kompleks wees as gevolg van die verhoogde aantal registers en die groter adresruimte. Die verhoogde aantal registers en die groter adresruimte in x64-argitektuur bied beide geleenthede en uitdagings vir uitbuitontwikkeling, veral in die konteks van Return-Oriented Programming (ROP).
Kyk na die volgende bladsy vir hierdie inligting:
Introduction to ARM64v8Stapelkanaries: In geval van 'n BOF, is dit nodig om die stapelkanarie te omseil om terugkeerpunte te oorskryf om 'n ROP-ketting te misbruik.
Gebrek aan Gadgets: As daar nie genoeg gadgets is nie, sal dit nie moontlik wees om 'n ROP-ketting te genereer nie.
Let daarop dat ROP net 'n tegniek is om arbitrêre kode uit te voer. Gebaseer op ROP is baie Ret2XXX-tegnieke ontwikkel:
Ret2lib: Gebruik ROP om arbitrêre funksies van 'n gelaai biblioteek met arbitrêre parameters aan te roep (gewoonlik iets soos system('/bin/sh')
.
Ret2Syscall: Gebruik ROP om 'n oproep na 'n syscall voor te berei, bv. execve
, en maak dit moontlik om arbitrêre bevele uit te voer.
EBP2Ret & EBP Chaining: Die eerste sal EBP misbruik in plaas van EIP om die vloei te beheer en die tweede is soortgelyk aan Ret2lib, maar in hierdie geval word die vloei hoofsaaklik met EBP-adresse beheer (alhoewel dit ook nodig is om EIP te beheer).
64 bit, Pie en nx geaktiveer, geen kanarie, oorskryf RIP met 'n vsyscall
-adres met die enigste doel om terug te keer na die volgende adres in die stapel wat 'n gedeeltelike oorskrywing van die adres sal wees om die deel van die funksie te kry wat die vlag lek
arm64, geen ASLR, ROP-gadget om stapel uitvoerbaar te maak en te spring na shellcode in stapel
Leer & oefen AWS-hacking:HackTricks Opleiding AWS Red Team Expert (ARTE) Leer & oefen GCP-hacking: HackTricks Opleiding GCP Red Team Expert (GRTE)