Obejście ASLR z wyciekiem informacji

https://chacker.pl/

Randomizacja układu przestrzeni adresowej (ASLR) to kontrola ochrony pamięci, która losowo wybiera lokalizacje pamięci segmentu kodu, segmentu stosu, segmentów sterty i obiektów współdzielonych, a także losowo wybiera mapowania mmap(). W naszym exploicie używaliśmy stałego adresu bazowego libc, ale to już nie zadziała, ponieważ nie będziemy w stanie znaleźć adresu dup2, system i /bin/sh. Najpierw włączmy ASLR i skopiujmy exploit2.py do exploit3.py:

Możemy pokonać ASLR, tworząc dwuetapowy exploit.

Etap 1

W etapie 1 exploita wykonamy następujące czynności:

  1. Wyciek stosu kanarka.
  2. Zbudujemy łańcuch ROP, który wywoła funkcję write PLT z dwoma argumentami:
  • Pierwszy argument to liczba 4 (deskryptor pliku accept), aby odczytać dane wyjściowe od naszego klienta. Pamiętaj, że na tym etapie nie możemy użyć dup2, ponieważ nie znamy jeszcze jego adresu.
  • Drugi argument to adres write GOT.

Co to są PLT i GOT? Procedure Linkage Table (PLT) to sekcja tylko do odczytu pliku ELF generowana w czasie kompilacji, w której przechowywane są wszystkie symbole wymagające rozwiązania. Jest ona głównie odpowiedzialna za wywoływanie dynamicznego linkera w czasie wykonywania w celu rozwiązania adresów żądanych funkcji (leniwe linkowanie). Global Offset Table (GOT) jest wypełniana adresami funkcji libc przez dynamiczny linker w czasie wykonywania. Na przykład, gdy budujemy program vuln.c, funkcja write jest kompilowana jako write@plt, a gdy program wywołuje write@plt, wykonuje następujące czynności:

  1. Szuka wpisu GOT dla adresu write.
  2. Jeśli wpis nie istnieje, koordynuje się z dynamicznym linkerem, aby uzyskać adres funkcji i zapisać go w GOT.
  3. Rozwiązuje i przechodzi do adresu zapisanego w write@got.

Krótko mówiąc, wywołamy write@plt, aby wydrukować adres write@got. Poprzez wyciek tego adresu libc możemy obliczyć bazę libc, odejmując <wyciekły adres> od <adresu symbolu write>, jak pokazano tutaj:

Możemy pokonać ASLR, tworząc dwuetapowy exploit.

Etap 1

W etapie 1 exploita wykonamy następujące czynności:

  1. Wyciek stosu kanarka.
  2. Zbudujemy łańcuch ROP, który wywoła funkcję write PLT z dwoma argumentami:
  • Pierwszy argument to liczba 4 (deskryptor pliku accept), aby odczytać dane wyjściowe od naszego klienta. Pamiętaj, że na tym etapie nie możemy użyć dup2, ponieważ nie znamy jeszcze jego adresu.
  • Drugi argument to adres write GOT.

Co to są PLT i GOT? Procedure Linkage Table (PLT) to sekcja tylko do odczytu pliku ELF generowana w czasie kompilacji, w której przechowywane są wszystkie symbole wymagające rozwiązania. Jest ona głównie odpowiedzialna za wywoływanie dynamicznego linkera w czasie wykonywania w celu rozwiązania adresów żądanych funkcji (leniwe linkowanie). Global Offset Table (GOT) jest wypełniana adresami funkcji libc przez dynamiczny linker w czasie wykonywania. Na przykład, gdy budujemy program vuln.c, funkcja write jest kompilowana jako write@plt, a gdy program wywołuje write@plt, wykonuje następujące czynności:

  1. Szuka wpisu GOT dla adresu write.
  2. Jeśli wpis nie istnieje, koordynuje się z dynamicznym linkerem, aby uzyskać adres funkcji i zapisać go w GOT.
  3. Rozwiązuje i przechodzi do adresu zapisanego w write@got.

Krótko mówiąc, wywołamy write@plt, aby wydrukować adres write@got. Poprzez wyciek tego adresu libc możemy obliczyć bazę libc, odejmując <wyciekły adres> od <adresu symbolu write>, jak pokazano tutaj:

W (1) używamy narzędzia ROP Pwntools, aby uprościć budowę naszego łańcucha ROP do wywołania write(4, write@got). W (2) po zwróceniu przez funkcję exploit() naszego wyciekłego write@got obliczamy bazę libc i kontynuujemy budowę/wykonywanie naszego ładunku drugiego etapu:

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *