Archiv verlassen und diese Seite im Standarddesign anzeigen : Neuer Schutz vor Exploits in Linux?
Hallo,
ich bin ziehmlich verwirrt:
Ich habe einen kleinen Exploit zu einem Demo Programm geschrieben, unter Linux.
Um die aktuelle Stack Adresse über ESP zu finden nutze ich die Methode:
movl %esp, %eax
Jedoch ist mir nun aufgefallen, dass sich diese bei jedem Aufruf ändert. Selbst wenn ich das Demo Programm debugge, ändert sich bei jedem Debug der Stack Beginn...
Wie kann das sein? Normalerweise bleibt er doch für jeden Programmaufruf gleich, sofern ich brav die Programme wieder schliesse...
Ist es möglich, dass der neue 2.6.14 Kernel einen entsprechenden Schutz eingebaut hat, so dass die Stackadresse ständig wechselt? Ich kann mich nämlich erinnern, dass vorher nicht so gehabt zu haben.
DKT
Seit 2.6.12 ist Address space randomization[1] implementiert. Bringt nicht unbedingt viel kann aber in "/proc/sys/kernel/randomize_va_space" deaktiviert werden.
[1] http://lwn.net/Articles/121845/
blue
Was macht dein Demo-Programm? Der ESP ändert sich jedes mal wenn du irgendwas an dem Stack machst (push, pop, call, leave, movl ?,%esp, sub usw.).
Wenn dein Programm also aus irgendwelchen Gründen auf verschiedenen Wegen zu deinem Code kommt, führt das natürlich zu anderen Ergebnissen.
Ansonsten kannst du mal nachsehen ab welcher Adresse der Stack (nicht der aktuelle Frame) anfängt. Der ist nämlich auch frei im Speicher positionierbar (auch wenn meist dieselbe Basis verwendet wird).
EDIT:
blue's Post erklärt das Problem.
Danke für den Link blue!
Sehr interessant. Das macht es zwar härter aber nicht sicherer. Dann muss ich doch mal mit der neuen Technik spielen, mal schauen wie oft sich etwas wiederholt.
nait, allein der vorhin erwähnte code brachte immer wieder eine andere adresse. Selbst wenn ich also ein Stück code an immer der gleichen Adresse überprüfe, darf sich normalerweise der Stackpointer nicht ändern, siehe alte Kernel Versionen, oder auch Windows!
Hat schonmal jemand damit gearbeitet, also Exploits trotz dieser Technik erstellt, und erfolgreich getestet?
DKT
Hat schonmal jemand damit gearbeitet, also Exploits trotz dieser Technik erstellt, und erfolgreich getestet?
Ja. Die Implementierung im Linux-Kernel stellt kein groszes Hindernis dar (Adressen im Stack und Heap Segment variieren ja nur um max. 64 Byte). Bruteforce hilft. :D
Entsprechenden Code hab ich auch noch. Kann den mal raussuchen, wenn Interesse besteht.
blue
Enchanter
30.11.2005, 13:23
@blue meld ... Arm weit oben ist........ *g
Ich wollte gerade erzählen das dir Glücksfaktor beim Exploiten doch nichts bringt.
64 Versuche höhrt sich aber glatt brauchbar an.
Hab mal etwas rumgespielt. Folgender Source als Test-Basis:
#include <stdio.h>
int main(void) {
unsigned sp;
asm("movl %%esp, %%eax" :: "a"(sp));
printf("0x%08X\n", sp);
return 0;
};
Anscheinend werden immer nur die 4. und 5. Hex-Stelle der Adresse geändert. Das ergibt 256 Möglichkeiten (0-255).
Wenn man den Source kompiliert und mal für ein paar Sekunden laufen lässt:
while true; do ./ex >> space; done
.., sieht man mit "uniq -d space" ganz gut, dass sich die Adressen doch schon relativ oft wiederholen. Ob das jetzt ein großes Risiko ist, weiß ich nicht. Zumindest Exploits, bei denen Adressen fest eingebaut sind sollten damit Probleme haben.
EDIT:
@blue meld ... Arm weit oben ist........ *g
Ich wollte gerade erzählen das dir Glücksfaktor beim Exploiten doch nichts bringt.
64 Versuche höhrt sich aber glatt brauchbar an.Das seh ich anders, zumindest bei Remote Exploits. Wenn du z.B. 'nen Server 63x abschießt, bevor dann der 64 (mit Glück - gibt ja keine Garantie, dass spätestens der 64. sitzt) passt, dürfte der Admin längst aufmerksam geworden sein. Außerdem (s.o.) denke ich doch, dass es 256 Möglichkeiten sind, oder hab ich was verpeilt?
Was ich meinte war etwas wie's in Rekursionen vorkommt. Da ändert sich der ESP mit der Rekursionstiefe. Allerdings hast du recht, dass mit denselben Einstellungen dieselbe Adresse rauskommt.
Wenn das ganze nur um 64 Byte variiert, kannst du, wenn du genug Platz hast, 'n NOP-Slope verwenden.
EDIT:
Boh, wat bin ich langsam. Ich sollte vielleicht das Valium absetzen. ;-)
Enchanter
30.11.2005, 13:31
*lizer zustimm, und auch unter 256^2 war Glück höchstens reine Suppe bei meinen Versuchen.
Ihren Code will ich trotzdem haben :-)
The patches, as posted, vary the stack base within a 64KB area and the mmap() base within a 1MB range.*räusper*
*räusper*
*hrhr*
Da haben sich meine Wurstfinger verheddert. :D
Werd mich auch die Suche nach dem Code machen. Kann allerdings etwas dauern bis ich das wiedergefunden hab.
Ok, zwei Möglichkeiten:
1. Hat man Platz, entsprechend NOPs einbinden
2. Nach welchem Random Verfahren werden die Adressen ermittelt? Ich kenne viele Random Funktionen, die gar nicht Random sind. Es ist eine einfache mathematische Funktion, die sich irgendwann wiederholt. Alles pseudo... Wobei ich das bei C nicht glaube...
DKT
Ich kenne viele Random Funktionen, die gar nicht Random sind
Das ist bei allen Zufallszahlengeneratoren zu, zumindest solange nur Algorithmen verwendet werden.
Ansonsten gibts noch ne Handvoll andere Methoden:
http://www.tty64.org/doc/smackthestack.txt
Wenn man lokalen Zugriff hat und nicht gerade irgendwelche bösen Kernelpatches aktiv sind, kann man auch per /proc/<pid>/maps sehen, wo der Speicher gemappt ist - bringt natürlich nur was, wenn man die Position nicht schon beim Programmstart wissen muss.
Ansonsten ist die Technik, in lokalen Exploits eine getesp()-Funktion zu benutzen, um eine ungefähre shellcodeadresse herauszubekommen, an die man dann noch nen fetten nopsled setzt, ziemlich veraltet - das hat sich seit aleph1 weiterentwickelt.
Wenn die Stackbase bekannt ist, kann man einfach den Shellcode ins env setzen, per execve() ausführen und dann elegant die exakte Position des Shellcodes ausrechnen.
Enchanter
30.11.2005, 14:24
http://lwn.net/Articles/120969/
könnte noch was bringen.
Abschliessend soll von meiner Seite kommen:
Ich glaube nicht das es sinn macht, für diese Architektur in Zukunft lauffähige
"Return into my wellplaced Bincode Exploits" zu schreiben.
Habt ihr gesehen, dass das auf unterschiedlichen Architekturen anders implementiert ist?
Hab den Source bis jetzt leider noch nicht gefunden. Ich werd dieses Wochenende noch ein paar andere Datentraeger durchsuchen. Wenn ich es nicht mehr finden sollte, werd ich mich mal nochmal ranmachen. Ich hab in letzter aber Zeit ziemlich viel um die Ohren wesshalb das dann etwas warten muss.
blue