Darum hat man ja auch W^X erfunden, bzw. für die 386 Architektur entwickelt!
Für alle nochmal, die das jetzt noch nicht ganz verstanden haben:
Ich habe 2 Variablen: A und B
in A steht "1234567890"
in B steht "0C5B:5FF2"
A beinhaltet jetzt die Informationen über der ID-Tag und B die Sprungadresse, zu der (z.B.) gesprungen wird nach dem A verarbeitet wurde.
Im RAM steht dann: "12345678900C5B:5FF2"
Der PC/das Programm weiß ja wo was endet und was beginnt.
Wenn jetzt aber ein manipulierter (und zu langer) Tag geladen wird, steht dann im Speicher z.B.: "1234567890ABCD:EF00"
Somit wird nach der Auswertung des ID-Tags an die falsche Adresse gesprungen und folgerichtig der falsche Code ausgeführt.
Dagegen gibt es 3 Möglichkeiten:
1) Immer vor dem schreiben abfragen, ob der Wert NICHT länger ist als die Variable dimensioniert wurde,
2) Den Ausführbaren code schreibgeschützt laden, bzw Variablen mit einem Kennzeichen versehen, dass das Betriebssystem daran hindert den Code (Sprungadressen) auszuführen (was W^X beschreibt) oder
3) Den Speicherbereich nicht linear verwenden, sondern einfach zufälligen Adressen des freien RAM-Speichers verwenden. somit wird bei einem Bufferoverflow mit 99,99% Sicherheit an die Falsche Stelle (quasi ins Nichts) gesprungen.
Das Problem bei 1) ist, dass jede schreibende Aktion verlangsamen würde, so dass dies nicht jeder implementieren will. Dazu kommen noch die ganzen unwissenden Programmierer die dies schlicht und einfach nicht begreifen.
Zu 2) fallen mir keine Nachteile ein und zu 3) KANN es keine nachteile geben - abgesehen von den Page misses, die ich dabei riskiere - was mich vieleicht einige Nanosekunden ausbremst . . .
Aber M$ hat ja nicht einmal gezeigt, dass Sicherheit ein anscheinen unnützer Luxus ist. Hat ja immerhin (fast) jeder.
Die Linux-Scene ist sicherlich auch nicht perfekt, doch wenigstens glänzen die nicht so mit Fehler . . .
MfG James
|