ASLR
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Randomizacja układu przestrzeni adresowej (ASLR) to technika zabezpieczeń stosowana w systemach operacyjnych do randomizacji adresów pamięci używanych przez procesy systemowe i aplikacyjne. Dzięki temu znacznie trudniej jest atakującemu przewidzieć lokalizację konkretnych procesów i danych, takich jak stos, sterta i biblioteki, co łagodzi niektóre rodzaje exploitów, szczególnie przepełnienia bufora.
Aby sprawdzić status ASLR w systemie Linux, możesz odczytać wartość z pliku /proc/sys/kernel/randomize_va_space
. Wartość przechowywana w tym pliku określa rodzaj stosowanej randomizacji ASLR:
0: Brak randomizacji. Wszystko jest statyczne.
1: Konserwatywna randomizacja. Biblioteki współdzielone, stos, mmap(), strona VDSO są randomizowane.
2: Pełna randomizacja. Oprócz elementów randomizowanych przez konserwatywną randomizację, pamięć zarządzana przez brk()
jest randomizowana.
Możesz sprawdzić status ASLR za pomocą następującego polecenia:
Aby wyłączyć ASLR, ustaw wartość /proc/sys/kernel/randomize_va_space
na 0. Wyłączanie ASLR jest ogólnie niezalecane poza scenariuszami testowymi lub debugowania. Oto jak możesz to wyłączyć:
Możesz również wyłączyć ASLR dla wykonania za pomocą:
Aby włączyć ASLR, możesz zapisać wartość 2 do pliku /proc/sys/kernel/randomize_va_space
. Zazwyczaj wymaga to uprawnień roota. Włączenie pełnej randomizacji można zrealizować za pomocą następującego polecenia:
Zmiany wprowadzone za pomocą poleceń echo
są tymczasowe i zostaną zresetowane po ponownym uruchomieniu. Aby zmiana była trwała, musisz edytować plik /etc/sysctl.conf
i dodać lub zmodyfikować następującą linię:
Po edytowaniu /etc/sysctl.conf
, zastosuj zmiany za pomocą:
To zapewni, że ustawienia ASLR pozostaną po ponownych uruchomieniach.
PaX dzieli przestrzeń adresową procesu na 3 grupy:
Kod i dane (zainicjowane i niezainicjowane): .text
, .data
i .bss
—> 16 bitów entropii w zmiennej delta_exec
. Ta zmienna jest losowo inicjowana z każdym procesem i dodawana do początkowych adresów.
Pamięć przydzielona przez mmap()
i biblioteki współdzielone —> 16 bitów, nazwane delta_mmap
.
Stos —> 24 bity, określane jako delta_stack
. Jednak efektywnie używa 11 bitów (od 10. do 20. bajtu włącznie), wyrównanych do 16 bajtów —> To skutkuje 524,288 możliwymi rzeczywistymi adresami stosu.
Powyższe dane dotyczą systemów 32-bitowych, a zmniejszona końcowa entropia umożliwia obejście ASLR poprzez wielokrotne próby wykonania, aż exploit zakończy się sukcesem.
Jeśli masz wystarczająco duży overflow, aby pomieścić duży NOP sled przed shellcode, możesz po prostu brute-forcować adresy na stosie, aż przepływ przeskoczy nad jakąś częścią NOP sled.
Inną opcją w przypadku, gdy overflow nie jest tak duży, a exploit może być uruchomiony lokalnie, jest możliwość dodania NOP sled i shellcode w zmiennej środowiskowej.
Jeśli exploit jest lokalny, możesz spróbować brute-forcować adres bazowy libc (przydatne dla systemów 32-bitowych):
Jeśli atakujesz zdalny serwer, możesz spróbować brute-forcować adres funkcji usleep
z libc
, przekazując jako argument 10 (na przykład). Jeśli w pewnym momencie serwer zajmuje dodatkowe 10s na odpowiedź, znalazłeś adres tej funkcji.
W systemach 64-bitowych entropia jest znacznie wyższa i to nie powinno być możliwe.
Możliwe jest zajęcie dużej części stosu zmiennymi środowiskowymi, a następnie próba nadużycia binarnego setki/tysiące razy lokalnie, aby go wykorzystać. Poniższy kod pokazuje, jak można po prostu wybrać adres na stosie i co kilkaset wykonania ten adres będzie zawierał instrukcję NOP:
/proc/[pid]/stat
)Plik /proc/[pid]/stat
procesu jest zawsze czytelny dla wszystkich i zawiera interesujące informacje, takie jak:
startcode & endcode: Adresy powyżej i poniżej z TEKSTEM binarnego
startstack: Adres początku stosu
start_data & end_data: Adresy powyżej i poniżej, gdzie znajduje się BSS
kstkesp & kstkeip: Aktualne adresy ESP i EIP
arg_start & arg_end: Adresy powyżej i poniżej, gdzie są argumenty cli.
env_start &env_end: Adresy powyżej i poniżej, gdzie są zmienne środowiskowe.
Dlatego, jeśli atakujący znajduje się na tym samym komputerze co binarny plik, który jest wykorzystywany, a ten plik binarny nie oczekuje przepełnienia z surowych argumentów, lecz z innego wejścia, które można skonstruować po odczytaniu tego pliku. Możliwe jest, aby atakujący uzyskał kilka adresów z tego pliku i skonstruował od nich przesunięcia dla exploita.
Aby uzyskać więcej informacji na temat tego pliku, sprawdź https://man7.org/linux/man-pages/man5/proc.5.html szukając /proc/pid/stat
Wyzwanie polega na uzyskaniu wycieku
Jeśli otrzymasz wyciek (łatwe wyzwania CTF), możesz obliczyć przesunięcia na jego podstawie (zakładając na przykład, że znasz dokładną wersję libc, która jest używana w systemie, który exploitujesz). Ten przykład exploita jest wyciągnięty z przykładu stąd (sprawdź tę stronę po więcej szczegółów):
ret2plt
Wykorzystując przepełnienie bufora, możliwe byłoby wykorzystanie ret2plt do wyeksportowania adresu funkcji z libc. Sprawdź:
Format Strings Arbitrary Read
Podobnie jak w ret2plt, jeśli masz dowolne odczyty przez lukę w formatach ciągów, możliwe jest wyeksportowanie adresu funkcji libc z GOT. Następujący przykład pochodzi stąd:
Możesz znaleźć więcej informacji na temat Format Strings arbitrary read w:
Spróbuj obejść ASLR, wykorzystując adresy w stosie:
Mechanizm vsyscall
służy do zwiększenia wydajności, umożliwiając wykonywanie niektórych wywołań systemowych w przestrzeni użytkownika, chociaż są one zasadniczo częścią jądra. Krytyczną zaletą vsyscalls są ich stałe adresy, które nie podlegają ASLR (Randomizacja Układu Przestrzeni Adresowej). Ta stała natura oznacza, że atakujący nie potrzebują luki w informacji, aby określić ich adresy i wykorzystać je w exploicie.
Jednak nie znajdziesz tutaj super interesujących gadżetów (chociaż na przykład możliwe jest uzyskanie odpowiednika ret;
)
(Następny przykład i kod są z tego opisu)
Na przykład, atakujący może użyć adresu 0xffffffffff600800
w exploicie. Próba bezpośredniego skoku do instrukcji ret
może prowadzić do niestabilności lub awarii po wykonaniu kilku gadżetów, skok do początku syscall
dostarczonego przez sekcję vsyscall może okazać się skuteczny. Starannie umieszczając gadżet ROP, który prowadzi wykonanie do tego adresu vsyscall, atakujący może osiągnąć wykonanie kodu bez potrzeby omijania ASLR dla tej części exploitu.
Zauważ więc, jak może być możliwe obejście ASLR przy użyciu vdso, jeśli jądro jest skompilowane z CONFIG_COMPAT_VDSO, ponieważ adres vdso nie będzie zrandomizowany. Po więcej informacji sprawdź:
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)