Verständnisfrage Buffer overflow
-
Hi Leute,
hätte eine Frage bezüglich des Buffer (stack) overflows.
Auf wikipedia gibt es hier ein Beispiel http://en.wikipedia.org/wiki/Stack_buffer_overflowfloat My_Float = 10.5; // Addr = 0x0023FF4C char c[28]; // Addr = 0x0023FF30 // Will print 10.500000 printf("My Float value = %f\n", My_Float); memcpy(c, bar, strlen(bar)); // no bounds checking... // Will print 96.031372 printf("My Float value = %f\n", My_Float);
Hier wird nun offensichtlich my float überschrieben.
Dann gibt es hier wieder ein Beispiel
http://en.wikipedia.org/wiki/Buffer_overflowchar A[8] = {}; unsigned short B = 1979; strcpy(A, "excessive");
Hier wird nun B überschrieben?
Was ich nicht genau verstehe werden die Variablen über dem Buffer wie im ersten Beispiel oder die darunter wie im 2. Beispiel überschrieben
Eigentlich müssten die darüber ja überschrieben werden, da das letzte Array Element an der höchsten Addresse steht.
Danke im Voraus!
-
Was hat die Frage mit Assembler zu tun?
Wie genau ein Compiler die Variablen zueinander anordnet (sofern Variablen überhaupt noch irgendwie einer bestimmten Speicherposition zugeschrieben werden können, was oftmals nicht mehr der Fall ist) ist im C-Standard nicht vorgeschrieben. Es ist nicht einmal klar, ob überhaupt so etwas wie ein Stack existiert. Manche Compiler haben eine (für eben diesen speziellen Compiler) dokumentierte Anordnung im Falle von unoptimierten Code. Dieses Verhalten kann und wird sich daher von Fall zu Fall unterscheiden und die Beispielcodes auf Wikipedia sind daher hochgradig unportabel. Die sollen auch gar nicht wirklich ausgeführt werden, sondern bloß die Problemstellung verdeutlichen.
Ein kleines bisschen portabler geht es, wenn man die Daten in ein struct packt:
struct { char string[8]; float number; } foo;
Hier ist garantiert, dass &foo.string < &foo.number. Zumindest sofern man diese Adressen im Programm explizit benutzt*. Denn wie schon gesagt ist gar nicht klar, ob eine Instanz dieses structs im fertigen Maschinencode überhaupt noch irgendeine Repräsentation im Speicher des Computers hat. Ein C-Compiler hat sehr weitreichende Freiheiten bei der Erzeugung des Codes und wird diese auch großzügig nutzen, wenn er Optimierungen durchführt. Sofern das Programm am Ende sich so verhält als ob es dem C-Standard folgt, darf der Compiler so ziemlich alles machen. Und die Folgen eines Pufferüberlaufs sind im C-Standard explizit undefiniert, dass heißt der C-Compiler muss den Code nicht so erzeugen, dass bei einem Pufferüberlauf das Verhalten auftritt, von dem du denkst, dass es auftreten sollte. Wie schon gesagt existiert ein foo.string eventuell gar nicht mehr wirklich und es passiert wer weiß was, wenn du über dessen Grenzen schreibst.
*: Ein ganz cleverer Compiler könnte natürlich auch diesen Effekt irgendwie simulieren, um die Variablen weg zu optimieren, aber ich denke nicht, dass irgendein real existierender Compiler dies tut.
-
Hi,
alles klar, vielen Dank! Dachte die Frage passt hier ganz gut rein, da es so low level ist und entfernt was mit Assembler zu tun hat.
So schlimm ist ein Buffer overflow ja gar nicht, wenn man nicht voraussehen kann, wo die anderen Variablen liegen zum überschreiben. Aber die größere Gefahr ist wohl, dass Shellcode eingeschleust wird.Viele Grüße
Rafael
-
Rafael81 schrieb:
So schlimm ist ein Buffer overflow ja gar nicht, wenn man nicht voraussehen kann, wo die anderen Variablen liegen zum überschreiben.
Das macht die Sache doch noch viel schlimmer!
Dein Hacker weiß genau, was passiert, wenn er den Overflow verursacht. Er hat schließlich das fertig übersetzte Programm vorliegen (und wenn nicht, dann kann er leicht raten, was ungefähr passieren wird und ein bisschen ausprobieren). Zur Programmerstellungszeit kannst du nicht genau voraussagen, was passieren wird.
-
am besten du schaust dir das im Debugger an.
Dann siehst du wo welche Variablen im Speicher liegen.Habs z.B. mit deinem Programm kurz probiert.
Egal ob ich zuerst A und dann B definiere oder umgekehrt - der Compiler legt die Variablen immer in der gleichen Reihenfolge auf den Stack.
Das "oben" und "unten" korrespondiert also nicht mit "oben" oder "unten" am Stack!#include <string.h> #include <stdio.h> int main() { unsigned short B = 1979; char A[8] = {0}; printf("\nA=%p",A); printf("\nB=%p",&B); strcpy(A, "excessive"); return 0; }
; die Zuweisung unsigned short B = 1979 verrät die Position von B am Stack MOV ECX,7BB ; 7BB=1979 in ECX schreiben MOV WORD PTR SS:[EBP-0x4],CX ; und auf Stackposition EBP-4 schreiben ; und die Parameterübergabe am Stack für strcpy verrät die Position von A am Stack PUSH test.0040C010 ; Adresse von "excessive" auf Stack schreiben LEA ECX,DWORD PTR SS:[EBP-0x10] ; Adresse von char A[] laden und in ECX speichern PUSH ECX ; ECX auf Stack schreiben CALL test.00401070 ; strcpy aufrufen
Somit kennen wir das Stacklayout für deine Funktionsvariablen, 4byte pro Zeile:
EBP-0x10 | char A[8]: Byte 0 bis 3 EBP-0xC | char A[8]: Byte 4 bis 7 EBP-0x8 | nicht für Funktionsvariablen verwendet EBP-0x4 | unsigned short B (2byte) | nicht für Funktionsvariablen verwendet(2byte) EBP | nicht für Funktionsvariablen verwendet
Shellcode wird meist auf Programmfehler in bestimmten Versionen ausgerichtet - durchaus möglich dass der gleiche Shellcode nicht mehr funktioniert, wenn das angegriffene Programm mit einer anderen Compilerversion nochmal erstellt wird.
Außerdem bauen viele Compiler Code ins Programm ein, welcher checkt, ob der Stack überschrieben wurde.
-
okay danke, ist mir jetzt klar!
-
Hab ne frage:
Was tun bei dieser Fehlermeldung (hab gerade erst angefangen :))1>LINK : fatal error LNK1123: Fehler bei der Konvertierung in COFF: Datei ist ungültig oder beschädigt.
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========bitte um Antwort danke
-
Statt sich an einen anderen Thread anzuhängen wäre es besser gewesen. einen neuen Beitrag zu verfassen.
Wahrscheinlich ist dein Visual Studio falsch eingestellt. Ich habe vor etwas längerer Zeit eine Installationsanleitung auf Stackoverflow gepostet:
http://stackoverflow.com/questions/31037176/running-asm-procedure-in-cpp-file/31056748#31056748
und für 64 bit:
HTH
viele grüße
ralph