Warum variiert die Position von Umgebungsvariablen so stark?

9

Beim Lesen des Buches Hacking: The Art of Exploitation von Jon Erickson versuche ich, die Adresse einer Umgebungsvariablen zu approximieren SHELLCODE, um ein Programm auszunutzen.

Jedes Mal, wenn ich renne getenv("SHELLCODE");, um den Ort zu finden, ist das Ergebnis völlig anders.

Auszug aus meiner Muschel:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

Ich verstehe, dass die Position etwas anders wäre, wenn der Programmname geändert oder neue Umgebungsvariablen hinzugefügt würden, aber warum variiert der Speicherort so stark?

Janman
quelle
Das getenvHandbuch gibt an, dass ein Zeiger auf eine Zeichenfolge zurückgegeben wird, die den Wert der Variablen enthält. Alles andere ist nicht spezifiziert, so dass Ihr Kernel und / oder Compiler den Wert behalten können, wo immer sie wollen, solange dieses Zeigerversprechen wahr bleibt. Ich vermute, dass die genaue Antwort darauf eine schwere Zauberei sein kann und von verschiedenen Details der Implementierung der Speicherzuordnung und der Mondphase abhängt. (Ich bin nicht Zauberer genug, um Ihnen die genaue Antwort zu geben.)
Anko
"Ich verstehe, dass die Position etwas anders wäre, wenn der Programmname geändert oder neue Umgebungsvariablen hinzugefügt würden, aber warum variiert der Speicherort so stark?" Das stimmt in der einfachsten aller möglichen Implementierungen, ist aber sicherlich nicht erforderlich.
dmckee --- Ex-Moderator Kätzchen

Antworten:

13

Was Sie beschreiben, ist eine Anti-Exploitation-Funktion namens Address Space Layout Randomization (ASLR). Grundsätzlich setzt der Kernel die oberste Adresse des Funktionsaufrufstapels eines Programms jedes Mal, wenn der Kernel die ELF-Datei des Programms von der Festplatte lädt, auf eine etwas andere ("zufällige") Adresse. Die Adressen in argvund die Umgebungsvariablen, von denen Ihr Shellcode eine ist, landen bei jedem Programmaufruf an einer variierenden Adresse.

ASLR soll es schwieriger machen, Pufferüberläufe und andere stapelbezogene Schwachstellen auszunutzen. Der Exploiter muss Code schreiben oder etwas tun, um die unterschiedlichen Adressen von Variablen und Werten auf dem Funktionsaufrufstapel zu berücksichtigen.

Sieht so aus, als könnten Sie ASLR deaktivieren, indem Sie Folgendes tun:

echo 0 > /proc/sys/kernel/randomize_va_space

als Root-Benutzer. Da Sie Ubuntu explizit zitieren, ist der obige Befehl anders:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Bruce Ediger
quelle
Ja, das hat den Trick gemacht. Ich habe festgestellt, dass der Buchautor Ubuntu 10.04 verwendet, das noch keine ASLR hatte.
Janman