Login mit C
-
Bleibe in der Schleife, solange das (neu) gelesene Zeichen ungleich dem Zeilenende ist.
Es wird solange gelesen, solange das ZEichen von der Entertaste nicht gefunden wurde.
-
EOP schrieb:
Pwned:
Please enter your username:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Wie ist dein Passwort?
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hallo USER1.Shit happens.
(Tested and verified - VS 2005)
Bei meinem zuletzt geposteten Code ist das zumindest bei mir nicht mehr möglich.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char user[] = "USER1"; char pass[] = "PASS1"; char password[20]; char username[20]; printf("Please enter your username: \n"); scanf("%19s", username); printf("Wie ist dein Passwort?\n"); scanf("%19s", password); if (strcmp(user, username) == 0 && strcmp(pass, password) == 0) { printf("Hallo %s.", user); } else { printf("Hast du dein Passwort vergessen?"); } return 0; }
Wie siehts bei anderen aus?
-
Es sollte nicht mehr möglich sein. Aber EOPs Beitrag zeigt sehr schön, dass mein Einwand, dass dies möglich wäre, durchaus berechtigt und keine rein theoretische Panikmache war. Prüfungen (nicht nur der Länge) von Eingaben aller Art (also auch Daten aus Dateien usw.) sind extrem wichtig in C. Das war früher der Fehler schlechthin in Computersystemen, da viel mit C gearbeitet wurde und viele Programmierer diese Prüfungen nicht gemacht haben. Selbst heute noch sind viele schwere Sicherheitslücken auf diese Art von Fehler zurück zu führen. C vertraut blind auf den Programmierer und wenn der Programmierer dem Nutzer blind vertraut (oder der Programmierer es nicht besser kann), dann hat man ein ganz großes Problem, wenn der Nutzer böses will.
Das gilt prinzipiell natürlich auch in anderen Sprachen, wobei die Symptome aber oft andere sein können. Jedenfalls muss alles was irgendwie von außen in ein Programm kommt immer als ein mögliches Vehikel für einen Angriff angesehen werden und entsprechend kritisch behandelt werden.
-
CrispyTurtleAlligator schrieb:
Bei meinem zuletzt geposteten Code ist das zumindest bei mir nicht mehr möglich.
Ja, das war auf deine erste Version bezogen.
Nur eine Demo, was SeppJ und mir so auf Anhieb einfällt und dann auch noch funktioniert.
Hatte vorher keine Zeit dafür.EDIT:
Und jetzt kannst du dir überlegen wie ich USER1 wurde.
-
[quote="EOP"]
CrispyTurtleAlligator schrieb:
EDIT:
Und jetzt kannst du dir überlegen wie ich USER1 wurde.Ich habe ehrlich gesagt keinen blassen Schimmer.
-
CrispyTurtleAlligator schrieb:
Ich habe ehrlich gesagt keinen blassen Schimmer.
Versuch doch mal mit zu denken. Alles was du brauchst, wurde bereits mehrmals gesagt. Die Erklärung ist eine Kombination aus diesen beiden Antworten:
DirkB schrieb:
CrispyTurtleAlligator schrieb:
Warum genau kann man das Passwort selbst festlegen, wenn zu viele Zeichen eingegeben werden und wie?
Das liegt an der Anordnung der Variablen im Speicher.
Lokale Variablen liegen i.A. auf dem Stack und der wächst von oben (hohe Adresse) nach unten.
Neue Variablen liegen vor den Älteren.Bei wäre das dann
username[20] password[20] pass[]user[] uuuuuuuuuuuuuuuuuuuuppppppppppppppppppppPASS1_USER1_
u ist der Platz für username, p für password, die _ stehen für \0
Wie du siehst, kannst du durch schreiben über die Arraygrenzen hinaus, ganz einfach die anderen Variablen ändern.
DirkB schrieb:
In Zeile 18 solltest du den richtigen Namen (aus user) ausgeben. Dann geht das auch, wenn du den Namen mal änderst
In Zeile 20 solltest du den keinen Namen ausgeben. Sonnst kennt der Hacker nach dem ersten Fehlversuch den Namen.Dein Programm mal ein bisschen umgeschrieben, so dass es deutlicher wird:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char user[] = "USER1"; char pass[] = "PASS1"; char password[20]; char username[20]; printf("Please enter your username: \n"); scanf("%s", username); printf("Wie ist dein Passwort?\n"); scanf("%s", password); if (memcmp(user, username, sizeof(user)) == 0 && memcmp(pass, password, sizeof(pass))== 0) { printf("Hallo %s. Dein gespeichertes Passwort ist %s", user, pass); // Hier sollten ja eigentlich "USER1" und "PASS1" ausgegeben werden } else { printf("Anmeldung fehlgeschlagen.\n"); } return 0; }
GCC 4.8, 64 Bit (mit -fno-stack-protector, sonst funktioniert es nicht :p ):
Please enter your username: username12345678901234567890123456789012345678901234567890123456hackedpassword''username Wie ist dein Passwort? hackedpassword''username Hallo username. Dein gespeichertes Passwort ist hackedpassword''username
Nanu? Anscheinend steht in user gar nicht mehr "USER1" und in pass steht nicht mehr "PASS1". wie das bloß passiert ist?
(Man sieht auch, dass die genauen Details, was die Stackanordnung angeht, vom Compiler und System abhängig ist, aber nach ein paar Versuchen hat man es raus)
-
Soweit habe ich das jetzt verstanden.
Jedoch muss man den Code anscheinend mit GCC 4.8, 64 Bit mit -fno-stack-protector kompilieren. Unter Xcode bei meinem Macbook funktioniert das gezeigt von dir nämlich nicht. Wo ist dann der Bezug zur Realität, wenn "Hacker" gar nicht an den Quellcode rankommen?
-
CrispyTurtleAlligator schrieb:
Jedoch muss man den Code anscheinend mit GCC 4.8, 64 Bit mit -fno-stack-protector kompilieren. Unter Xcode bei meinem Macbook funktioniert das gezeigt von dir nämlich nicht. Wo ist dann der Bezug zur Realität, wenn "Hacker" gar nicht an den Quellcode rankommen?
Es gibt auch noch Debugger. Damit kann man Programme (auch ohne Quellcode) schrittweise ausführen und dann nachschauen was sich verändert.
Hacker haben einen großen Spieltrieb.
-
DirkB schrieb:
Hacker haben einen großen Spieltrieb.
Wie wahr. Ich bin in den späten 80ern bis zu 24 Stunden nur mit Kaffee und Zigaretten vor dem Debugger gesessen.
-
EOP schrieb:
DirkB schrieb:
Hacker haben einen großen Spieltrieb.
Wie wahr. Ich bin in den späten 80ern bis zu 24 Stunden nur mit Kaffee und Zigaretten vor dem Debugger gesessen.
Dann hoffe ich doch, dass du inzwischen die Zigarettensucht los geworden bist.