ASLR
Last updated
Lernen Sie und üben Sie AWS-Hacking: HackTricks Training AWS Red Team Expert (ARTE) Lernen Sie und üben Sie GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Address Space Layout Randomization (ASLR) ist eine Sicherheitstechnik, die in Betriebssystemen verwendet wird, um die Speicheradressen zu randomisieren, die von System- und Anwendungsprozessen verwendet werden. Dadurch wird es für einen Angreifer erheblich schwieriger, den Ort bestimmter Prozesse und Daten vorherzusagen, wie z.B. den Stack, den Heap und Bibliotheken, wodurch bestimmte Arten von Exploits, insbesondere Pufferüberläufe, abgemildert werden.
Um den ASLR-Status auf einem Linux-System zu überprüfen, können Sie den Wert aus der Datei /proc/sys/kernel/randomize_va_space
lesen. Der in dieser Datei gespeicherte Wert bestimmt den Typ des angewendeten ASLR:
0: Keine Randomisierung. Alles ist statisch.
1: Konservative Randomisierung. Gemeinsam genutzte Bibliotheken, Stack, mmap(), VDSO-Seite werden randomisiert.
2: Vollständige Randomisierung. Zusätzlich zu den Elementen, die durch konservative Randomisierung randomisiert werden, wird der durch brk()
verwaltete Speicher randomisiert.
Sie können den ASLR-Status mit folgendem Befehl überprüfen:
Um ASLR zu deaktivieren, setzen Sie den Wert von /proc/sys/kernel/randomize_va_space
auf 0. Das Deaktivieren von ASLR wird im Allgemeinen außerhalb von Test- oder Debugging-Szenarien nicht empfohlen. So können Sie es deaktivieren:
Sie können ASLR auch für eine Ausführung deaktivieren mit:
Um ASLR zu aktivieren, können Sie einen Wert von 2 in die Datei /proc/sys/kernel/randomize_va_space
schreiben. Dies erfordert in der Regel Root-Berechtigungen. Die vollständige Zufallsauswahl kann mit dem folgenden Befehl durchgeführt werden:
Änderungen, die mit den echo
-Befehlen vorgenommen werden, sind vorübergehend und werden beim Neustart zurückgesetzt. Um die Änderung dauerhaft zu machen, müssen Sie die Datei /etc/sysctl.conf
bearbeiten und die folgende Zeile hinzufügen oder ändern:
Nachdem du /etc/sysctl.conf
bearbeitet hast, wende die Änderungen mit an:
Dies stellt sicher, dass Ihre ASLR-Einstellungen über Neustarts hinweg bestehen bleiben.
PaX teilt den Prozess-Adressraum in 3 Gruppen auf:
Code und Daten (initialisiert und nicht initialisiert): .text
, .data
und .bss
—> 16 Bits Entropie in der Variablen delta_exec
. Diese Variable wird mit jedem Prozess zufällig initialisiert und den Anfangsadressen hinzugefügt.
Speicher allokiert durch mmap()
und gemeinsam genutzte Bibliotheken —> 16 Bits, genannt delta_mmap
.
Der Stack —> 24 Bits, bezeichnet als delta_stack
. Es werden jedoch effektiv 11 Bits verwendet (vom 10. bis zum 20. Byte einschließlich), ausgerichtet auf 16 Bytes —> Dies ergibt 524.288 mögliche reale Stack-Adressen.
Die vorherigen Daten gelten für 32-Bit-Systeme und die reduzierte endgültige Entropie ermöglicht es, ASLR zu umgehen, indem der Angriff so oft wiederholt wird, bis er erfolgreich abgeschlossen ist.
Wenn Sie genügend Platz für ein großes NOP-Schlitten vor dem Shellcode haben, könnten Sie einfach Adressen im Stack brute-forcen, bis der Fluss über einen Teil des NOP-Schlittens springt.
Eine weitere Option dafür, falls der Überlauf nicht so groß ist und der Angriff lokal ausgeführt werden kann, besteht darin, den NOP-Schlitten und den Shellcode in einer Umgebungsvariablen hinzuzufügen.
Wenn der Angriff lokal ist, können Sie versuchen, die Basisadresse von libc per Brute-Force zu ermitteln (nützlich für 32-Bit-Systeme):
Wenn Sie einen Remote-Server angreifen, könnten Sie versuchen, die Adresse der libc
-Funktion usleep
durch Brute-Force zu ermitteln und dabei 10 als Argument zu übergeben. Wenn der Server zu einem bestimmten Zeitpunkt 10 Sekunden länger braucht, um zu antworten, haben Sie die Adresse dieser Funktion gefunden.
Bei 64-Bit-Systemen ist die Entropie viel höher und dies sollte nicht möglich sein.
Es ist möglich, einen großen Teil des Stacks mit Umgebungsvariablen zu belegen und dann versuchen, den Binärcode hunderte/tausende Male lokal zu missbrauchen, um ihn auszunutzen. Der folgende Code zeigt, wie es möglich ist, einfach eine Adresse im Stack auszuwählen und bei jeder Ausführung alle paar hundert Male wird diese Adresse die NOP-Anweisung enthalten:
/proc/[pid]/stat
)Die Datei /proc/[pid]/stat
eines Prozesses ist immer von jedem lesbar und enthält interessante Informationen wie:
startcode & endcode: Adressen über und unter dem TEXT des Binärdatei
startstack: Die Adresse des Starts des Stacks
start_data & end_data: Adressen über und unter denen sich der BSS befindet
kstkesp & kstkeip: Aktuelle ESP und EIP-Adressen
arg_start & arg_end: Adressen über und unter denen sich die CLI-Argumente befinden.
env_start & env_end: Adressen über und unter denen sich die Umgebungsvariablen befinden.
Daher kann ein Angreifer, der sich auf demselben Computer wie das ausgebeutete Binärprogramm befindet und dieses Binärprogramm keinen Überlauf von Rohargumenten erwartet, sondern von einer anderen Eingabe, die nach dem Lesen dieser Datei erstellt werden kann. Es ist für einen Angreifer möglich, einige Adressen aus dieser Datei zu erhalten und Offset daraus für den Exploit zu konstruieren.
Für weitere Informationen zu dieser Datei siehe https://man7.org/linux/man-pages/man5/proc.5.html und suche nach /proc/pid/stat
Die Herausforderung besteht darin, ein Leck zu haben
Wenn Ihnen ein Leck gegeben wird (einfache CTF-Herausforderungen), können Sie Offset daraus berechnen (angenommen, Sie kennen beispielsweise die genaue libc-Version, die im System verwendet wird, das Sie ausnutzen). Dieses Beispiel-Exploit wird aus dem Beispiel von hier extrahiert (überprüfen Sie diese Seite für weitere Details):
ret2plt
Durch Ausnutzen eines Pufferüberlaufs wäre es möglich, ein ret2plt zu manipulieren, um die Adresse einer Funktion aus der libc zu exfiltrieren. Überprüfen Sie:
Format Strings Arbitrary Read
Genau wie bei ret2plt, wenn Sie über eine Schwachstelle bei Formatzeichenfolgen einen beliebigen Lesezugriff haben, ist es möglich, die Adresse einer libc-Funktion aus dem GOT zu exfiltrieren. Das folgende Beispiel stammt von hier:
Sie können weitere Informationen zum willkürlichen Lesen von Formatzeichenfolgen finden unter:
Versuchen Sie, ASLR zu umgehen, indem Sie Adressen im Stack missbrauchen:
Der vsyscall
-Mechanismus dient dazu, die Leistung zu verbessern, indem bestimmte Systemaufrufe im Benutzerbereich ausgeführt werden können, obwohl sie grundsätzlich Teil des Kernels sind. Der entscheidende Vorteil von vsyscalls liegt in ihren festen Adressen, die nicht der ASLR (Adressraumlayout-Zufälligkeitsanordnung) unterliegen. Diese feste Natur bedeutet, dass Angreifer keine Informationsleckschwachstelle benötigen, um ihre Adressen zu bestimmen und sie in einem Exploit zu verwenden.
Es werden jedoch keine besonders interessanten Gadgets hier gefunden (obwohl es zum Beispiel möglich ist, ein ret;
-Äquivalent zu erhalten)
(Das folgende Beispiel und der Code stammen aus diesem Writeup)
Ein Angreifer könnte beispielsweise die Adresse 0xffffffffff600800
in einem Exploit verwenden. Während der Versuch, direkt zu einer ret
-Anweisung zu springen, nach der Ausführung einiger Gadgets zu Instabilität oder Abstürzen führen könnte, kann das Springen zum Beginn eines syscall
aus dem vsyscall-Abschnitt erfolgreich sein. Durch sorgfältiges Platzieren eines ROP-Gadgets, das die Ausführung zu dieser vsyscall-Adresse führt, kann ein Angreifer eine Codeausführung erreichen, ohne ASLR für diesen Teil des Exploits umgehen zu müssen.
Beachten Sie daher, wie es möglich sein könnte, ASLR zu umgehen, indem das vdso missbraucht wird, wenn der Kernel mit CONFIG_COMPAT_VDSO kompiliert ist, da die vdso-Adresse nicht zufällig ist. Weitere Informationen finden Sie unter: