Buffer Overflow für Login bei C-Programm

Guten Tag,
ich würde mich gerne bei folgendem Programm mit einem Buffer overflow einloggen können als Übung. Das password kenne ich dabei nicht. Nun habe ich bereits vieles versucht, beispielsweise username mit vielen Zeichen zu überladen, das userPassword zu überladen. Jedoch habe ich wahrscheinlich einen Denkfehler wie der Stack aufgebaut ist. Mir fehlt im Moment jeder Ansatz für die Lösung.

Code:
#include <stdio.h>
#include <stdlib.h>

int main() {
    int password = 12341234;
    char username[10];
    char userPassword[10];

    printf("Enter username:");
    gets(username);
    printf("Enter password:");
    gets(userPassword);

    int inputCode = atoi(userPassword);

    if (inputCode == password) {
        printf("Logged in.\n");
    } else {
        printf("Wrong passcode.\n");
    }
}

Unter Linux habe ich bereits mit gdb mir den Assembler Code angesehen, und ich vermute, dass ich irgendwie die Rücksprungadresse verändern muss oder so. Aber wie gesagt, mir fehlt selbst der Ansatz zu einer richtigen Lösung.
Kann mir da bitte jemand helfen?
 
Ich vermute, dass in deinem Test-System ein Stack-Protector aktiviert ist, wenn du keinen Overflow auslösen kannst.

Code:
527 bitmuncher@mbp2.bitmuncher.de:~/test [23:59] [2] [227] [12213240]
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int main() {
  int password = 12341234;
  char username[10];
  char userPassword[10];

  printf("Enter username:");
  gets(username);
  printf("Enter password:");
  gets(userPassword);

  int inputCode = atoi(userPassword);

  if (inputCode == password) {
    printf("Logged in.\n");
  } else {
    printf("Wrong passcode.\n");
  }
}
528 bitmuncher@mbp2.bitmuncher.de:~/test [23:59] [2] [227] [12213240]
$ gcc -o test test.c
529 bitmuncher@mbp2.bitmuncher.de:~/test [23:59] [2] [227] [12213240]
$ ./test
warning: this program uses gets(), which is unsafe.
Enter username:foobar
Enter password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Wrong passcode.
Segmentation fault: 11
 
Ich glaube selbst Linux lässt sich so nicht mehr austricksen. Du brauchst da eine entsprechende Version.

Davon abgesehen davon ist eine Vorstellung vom "einloggen" falsch. Der Klassiker wäre in deinem Fall, Bytecode einzuschleusen, der eine lokale Shell springen lässt. Den Bytecode muss du entweder selbst via gcc erzeugen oder irgendwo anders besorgen. Wobei man den bytecode besser nicht einfach irgendwo herunterlädt. Das Prinzip ist jedenfalls recht simpel, aber ohne gediegene Kenntnisse in C wirst du da nicht weit kommen.

Als Sprache für die "Angriffe" würde ich python oder perl empfehlen .. die sind für Anfänger etwas leichter zu handlen..ausserdem lernste was sinnvolles :)

Für dich wären wohl die verfügbaren "hack-me" sinnvoll um mal reinzukommen. Und dann natürlich einschlägige Literatur. Das kann man sich aber draufschaffen!
 
Ich möchte mithilfe des Buffer Overflows einen Login erzeugen.
Ich will eine unbekannte Zeichenfolge bei Username eingeben, dann eine unbekannte Zeichenfolge bei Passwort, und dann soll "Logged in." da stehen.
Ein script in perl oder Phyton hatte ich nicht erwartet, ich hätte eher gedacht, ich könnte via Buffer Overflow den RAM beschreiben, damit dann die einsprungadresse verändern oder das passwort selbst und so dann das Programm dazu zwingen, einen Login auszuspucken.
 
Ich will eine unbekannte Zeichenfolge bei Username eingeben, dann eine unbekannte Zeichenfolge bei Passwort, und dann soll "Logged in." da stehen.

dann müsstest du lernen wie man gezielt Speicherslots und werte ermittelt und genau an dieser Stelle platziert ... Aber diese Zeiten sind vorbei und Prozessoren und Betriebsystem haben seit den 90ern einiges an Arbeit geleistet.

Es gibt ein "outdated" Buch von Tobias Klein. Das wäre ein guter Einstieg, denn ohne den ganzen Speicher und Stack Kram wirst du das niemals selbst in einem eigenen Programm her/nachstellen können.. Und darüber sind wir alle froh ;)
 
Für einen historischen Überblick ist das OK.
Aber die Anwendungsbeispiele sind veraltet.

Da hat sich seit '96 nen bisschen was getan ;)

Gönn dir "Buffer Overflows" von Foster, das ist 10 Jahre "jünger".

Ansonsten EFNET und Bugtraq/FD zum mitlesen.
 
In den Puffer von 'username' passen 11 bytes.
+ int password ist auf 32bit linux warscheinlich 4 bytes
=> du musst 15 bytes als username eingeben
die letzten 4 bytes sind das was overfowt damit kannst du quasi das passwort selbst setzen, dass du dann wenn nach dem passwort gefragt wird eingeben kannst.


So hätte ich das früher gelöst aber jetzt gibt es stack carnarys, (beim compilierne mit dem gcc -fno-stack-protector dazu und dann ist es zum üben erst einmal ausgeschaltet.) die zumindest die rücksprung adresse beschützen (einfach googeln für mehr info). Ich weis nicht ob mittlerweile auch die einzelnen varriablen beschützt werden. Das war als ich dass letzte mal einen BOF exploit geschrieben habe meine ich noch nicht so (ist aber auch schon ein weilchen her).

hoffe das hats so ungefair beantwortet :) viel Spaß... :wink:

PS: wenn du noch was zum lesen brauchst: Buffer Overflows für Jedermann
fand ich damals ganz gut und ist nicht so n ganzer batzen...
 
Zuletzt bearbeitet:
=> du musst 15 bytes als passwort eingeben
die letzten 4 bytes sind das was overfowt damit kannst du quasi das passwort selbst setzen, dass du dann wenn nach dem passwort geefragt wird eingeben kannst.

Diese Technik müsstest du jetzt mal im Detail erklären...
 
entschuldigung ich meinte als usename. bei dem passwort müssten es denke ich 11 mehr sein. Bin in letzter zeit ein wenig matschig im Kopf...
 
Zuletzt bearbeitet:
entschuldigung ich meinte als usename. bei dem passwort müssten es denke ich 11 mehr sein. Bin in letzter zeit ein wenig matschig im Kopf...

Und woher weiß der Prozessor in deinem exploit wo dein eingeschleuster Username + Passwort im Speicher stehen, bzw. das diese Daten nun verglichen werden sollen?
 
Und woher weiß der Prozessor in deinem exploit wo dein eingeschleuster Username + Passwort im Speicher stehen, bzw. das diese Daten nun verglichen werden sollen?
Ich verstehe die Frage nicht ganz. Das wird doch ohnehin von dem Program geleistet und dass macht das Program auch immernoch wenn ich die einzelnen Varriablen überschreibe.
 
aber das eip register wird in meiner version doch garnicht manipuliert. Oder bin ich da jetzt komplett auf dem falschen Dampfer?
 
Ich verstehe die Frage nicht ganz. Das wird doch ohnehin von dem Program geleistet und dass macht das Program auch immernoch wenn ich die einzelnen Varriablen überschreibe.

Du behauptest, es würde reichen den Variablenspeicher zu überschreiben + noch ein paar Bytes dranzuhängen, die dann den neuen Wert erhalten. Woher soll deine CPU wissen dass sich die Werte, die jetzt als User-Pass ausgewertet werden sollen - ein paar Bytes hinter der dem Speicherbereich liegen, der von den entsprechenden Registerzeigern referenziert werden?

Wie willst du ausserdem einen 16 Byte string (zb 9999999999999999) durch atoi schicken, welches nur einen maximalen Dezimalwert von 4294967295 zurückgeben könnte? Oder - wie würdest du diesen Programmteil überspringen? Der Code vergleicht ja als Passwort eine Zahl, keinen String (wie mit gets eingelesen)... ?
 
Gdb

Hallo, ich melde mich nun auch wieder zu Wort.
Also, ich habe mit GDB das Programm schrittweise analysiert, mir immer wieder den Stack angeschaut. Zu Anfang habe ich mir einen einfach zu erkennenden Buchstaben ('U' in ASCII => '55') rausgesucht und dann vor der eingabe des Benutzernamens den stack angeschaut und dann noch einmal nach Eingabe des Benutzernamens (also eines einzelnen 'U'). Dadurch wusste ich, wo im Stack der Benutzername gespeichert wird. Nun habe ich mir noch angeschaut, wo das Passwort in Hexcode gespeichert wurde, und habe herausgefunden, dass ich 28 Zeichen schreiben muss, bis ich in das Passwort überschreiben kann. Dadruch ist es dann möglich, als Benutzername "UUUUUUUUUUUUUUUUUUUUUUUUUUUU12345678" und als Passwort dann "12345678" einzugeben und vom Programm die Antwort zu bekommen, ich sei eingeloggt. Das kommt daher, weil bei der Überprüfung bzw. jeder weiteren verwendung der variable "password" der Wert, der im Stack steht, herausgezogen wird. Diesen haben wir überschrieben. Daher ist das so möglich.
 
Zurück
Oben