myGully.com

myGully.com (https://mygully.com/index.php)
-   Programmierung (https://mygully.com/forumdisplay.php?f=67)
-   -   Reihenfolge des allozierten Speichers auf dem Stack stimmt nicht? (https://mygully.com/showthread.php?t=2336288)

MaSydJun 12.06.11 20:18

Reihenfolge des allozierten Speichers auf dem Stack stimmt nicht?
 
Hallo,

bin Backfrisch hier im Forum.

Hab folgende Frage bzw. kuriose Feststellung:

Ich definiere 2 Variablen (in C):

Code:

char flag = 0;
char buffer[5];

Im Debugger bekomme ich folgende Infos:
Code:

(gdb) x/x &flag
0xbffff39f:        0xfff3b400
(gdb) x/s buffer
0xbffff39a:        "\374\267ȅ\004"

Nun, hier ist ja noch alles in Ordnung: `flag' ist vor `buffer' auf dem Stack

Wenn ich jetzt aber für den buffer mehr Speicher allozier wirds komisch:

Code:

char flag = 0;
char buffer[10];

GDB sagt:
Code:

(gdb) x/x &flag
0xbffff391:        0xd0bfff00
(gdb) x/s buffer
0xbffff392:        "\377\277\320j\353\267\340\204", <incomplete sequence \374\267>

Jetzt ist `buffer' vor `flag' auf dem Stack. Das erscheint mir extrem verrückt.

Ich will nämlich eigentlich einen Buffer Overflow erzeugen und so die Variable `flag' überschreiben.

Warum werden die beiden Variablen in verschiedenen Reihenfolgen auf den Stack gelegt?

Vielen Dank für Müh und Not ;)

slahn 12.06.11 22:03

Auch wenn ich selbst nur einfacher user hier bin, möchte ich dich trotzdem hier im Forum willkommen heißen: Hallo bei myGully :D

So, jetzt zu deiner Frage: Immerhin entscheidet hier immer noch der Compiler wie er deinen Code in Assembler umsetzt. Wie du selbst siehst, ist es ein bisschen übersichtlicher zuerst flag und dann erst buffer auf den Stack ab zu legen, da die Adressen gleich hintereinander liegen. Du muss jetzt auch nur +1 auf den SP wirken, um auf das erste Element von buffer zu kommen.

Wenn du dieses verhalten steuern willst musst du deinen Code schon in Assembler schreiben.

MaSydJun 13.06.11 04:32

Vielen Dank für die Antwort!
Das macht Sinn.

Ich lese zu Zeit das Buch "Hacking - Die Kunst des Exploits" (Ja, die deutsche Übersetzung ;))
In dem ist auch eben dieses Beispiel angegeben, in dem mit einem Bufferoverflow ein flag gesetzt wird und man damit quasi eine "Passwortabfrage" umgeht.
Und laut Buch sollte das so funktionieren…

Hier ist der im Buch beschriebene Code, falls es jemanden interessiert:
Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int check_authentication(char *password) {
        int auth_flag = 0;
        char password_buffer[16];

        strcpy(password_buffer, password);
       
        if(strcmp(password_buffer, "brillig") == 0)
                auth_flag = 1;
        if(strcmp(password_buffer, "outgrabe") == 0)
                auth_flag = 1;

        return auth_flag;
}

int main(int argc, char *argv[]) {
        if(argc < 2) {
                printf("Usage: %s <password>\n", argv[0]);
                exit(0);
        }
        if(check_authentication(argv[1])) {
                printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
                printf("      Access Granted.\n");
                printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
        } else {
                printf("\nAccess Denied.\n");
  }
}


mfg MaSydJun

slahn 13.06.11 13:51

Aber wie gesagt, der Compiler bestimmt die Reihenfolge (in allen höheren Sprachen).

Und bei heutigen Programmen wird dies nicht Funktionieren, da man entweder nur die Pufferlänge einliest (also eben nicht als Parameter, was ja eh wenig sinn macht, da es dann ja jeder lesen kann, der Zugriff auf die Logs hat), oder man ersetzt ganz einfach in der Funktion "check_authentication(char *password)" das "strcpy()" durch ein "strncpy()", wo dann die länge angegeben werden kann.

Epeos 14.06.11 10:15

Zitat:

Zitat von slahn (Beitrag 22385610)
Aber wie gesagt, der Compiler bestimmt die Reihenfolge (in allen höheren Sprachen).

Ich kenn mich mit den aktuellen C-Compilern nicht mehr so aus. Gibt's da keinen Parameter, mit dem man das Verhalten steuern kann? Ich meine, im Prinzip ist das ja schön, wenn der Compiler meinen Code optimiert, aber manchmal mache ich ja Dinge mit Absicht so, wie ich sie hingeschrieben habe (deswegen programmiere ich ja C und nicht smalltalk).

slahn 14.06.11 17:38

Mal eine geile Antwort :T Aber VORSICHT, es gibt in dem Border ein paar eingefleischte OOPler, die dich für so etwas verbal Lynchen würden ;).

Es gibt die Möglichkeit dies zu steuern, jedoch ist dies sehr Compiler spezifisch und für den Compiler noch immer keine Pflicht.

Was auch noch gehen sollte, wenn du die beiden Variablen in einen Struktur packst. Die werden nicht optimiert, da man dort oft auch Binärdaten strukturiert hinterlegt und die Optimierung würde die Funktion beeinflussen.

wenn du nicht weißt was eine Struktur ist, das Funktioniert so:
Code:

// deklariert den Strukturtyp
typedef struct authentication
{
  int flag;
  char password[16];
};

//deklariert Variable
authentication access;

//Struktur verwenden
access.flag = 0;
strcpy(access.password, "geheim");

Sieht doch schon ein wenig wie OOP aus ;)

Wenn du eh weißt was struct ist, habe ich mich hier gerade ein wenig zum Trottel gemacht, wenn du noch nix verstanden hast, kannst du ja noch nach fragen.

MaSydJun 14.06.11 17:42

Zitat:

Zitat von Epeos (Beitrag 22388936)
Ich kenn mich mit den aktuellen C-Compilern nicht mehr so aus. Gibt's da keinen Parameter, mit dem man das Verhalten steuern kann? Ich meine, im Prinzip ist das ja schön, wenn der Compiler meinen Code optimiert, aber manchmal mache ich ja Dinge mit Absicht so, wie ich sie hingeschrieben habe (deswegen programmiere ich ja C und nicht smalltalk).

Unter Umständen könnte es ja auch sein, dass ältere Versionen des GCC's standartmäßig keine optimierungen durchführen, denn bei dem Autor meines Buches, klappt alles so wie es soll.


mfg MaSydJun

[EDIT]

Ok, Jungs entwarnung!
Hab die Lösung gefunden: Mit dem Compilerschalter `-fno-stack-protector' wird die "richtige" Reihenfolge befolgt.

Quelle: [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]


mfg MaSydJun

kolodf 30.08.11 19:28

Problem mit Assemblercode
 
hi,

ich hab auch ein Problem mit Assemblercode:
ich hab mein Passwort für eine 7z-Datei verlohren:
das einzige was ich noch weiß, was mir aber nicht viel bringt ist, das Passwort ist nicht kompliziert

dann hatte ich die Idee "einfach" das Programm 7-zip mit Assemblercode zu ändern, so dass 7-zip die Passwortabfrage immer "bejaht" => sowas wie Assemblercode: "jne" in "je" ändern oder so

nur ich find die Stelle im Code nicht!!! Wer kann mir helfen?!

Mit freundlichen Grüßen
hedfd

Ccursed 31.08.11 01:51

^kolodf
1. Das Passwort gibt ja nicht einfach nur ein "ja" bei richtigem Passwort zurück, sondern hat die Daten im Archiv entsprechent dem Passwort gespeichert, also wird das ohne Passwort nicht klappen.
2. Das Programm decompilieren und verändern wird sich als äußerst .... schwierig gestalten.
3. Wenn du weißt, dass das Passwort "einfach" war, und mit einfach meine ich kurz, kannst du versuchen zu Bruteforcen.

kolodf 31.08.11 09:37

asdfg

kolodf 31.08.11 09:37

asdfg

kolodf 31.08.11 09:39

Nein, lustig ist das nicht!!!

Aber Bruteforce könnte ich probieren!


Vielen Dank für die Antwort!

PS: Warum kann meine Idee nicht funktionieren?
Das Programm vergleicht doch die Passwörter und macht dann eine Aktion: sperren, oder entpacken
und wenn ich das Programm so ändere, dass es immer in die Aktion "entpacken" springt, müsste das doch funktionieren, theoretisch?

7331 31.08.11 19:33

Die 7z Datei an sich ist extrem stark verschlüsselt und ohne Kennwort kann es nicht entschlüsselt werden. Bei der Eingabe eines Passworts versucht 7zip es zu entschlüsseln und zeigt einen Fehler an, wenns nicht geklappt hat. Diese MessageBox umpachtchen kann sehr leicht sein, aber nützt hier rein gar nicht. Nur bei reinen "Nerv-Abfragen", wie manche CD-Checks bei alten Spielen kann man so umgehen.

Wenns wirklcih kurz war, versuche einen Bruteforce oder Dictionary Angriff mit dem Passwort Recovery Tool von Elcom Soft. Diese Firma bietet in diesem Bereich das Beste.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 Uhr.

Powered by vBulletin® (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.