5 Pluspunkte 0 Minuspunkte
Ich lese immer wieder man soll die Funktion gets() nicht benutzen weil sie unsicher ist und zu Pufferüberlauf führen kann. Aber wie funktioniert das? Was ist ein Beispiel für einen Buffer Overflow?
von  

1 Antwort

4 Pluspunkte 0 Minuspunkte

Ein Buffer Overflow (Speicherüberlauf) tritt auf wenn mehr Daten in einen Puffer (eine temporäre Speicherregion) geschrieben werden, als er aufnehmen kann. Dadurch werden benachbarte Speicherbereiche überschrieben. Nehmen wir an du hast ein Programm das den Benutzer um ein Passwort fragt und die Eingabe vergleicht.

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

int main(){

    char realPassword[] = "s3cr3t";
    char givenPassword[10];

    printf("Password: ");
    gets(givenPassword);
    
    if (0 == strncmp(givenPassword, realPassword, 10)){
    
        printf("SUCCESS!\n");
        
    } else {
    
        printf("FAILURE!\n");
        
    }  

    printf("givenPassword: %s\n", givenPassword);
    printf("realPassword: %s\n", realPassword);
    
    return 0;
    
}

Die Eingabe wird mit gets() gelesen, was unsicher ist weil die Funktion keine Prüfung auf die Länge der Eingabe vornimmt. Erst scheint alles zu funktionieren.

C:\dev>test
Password: s3cr3t
SUCCESS!
givenPassword: s3cr3t
realPassword: s3cr3t

Zum Speichern der Benutzereingabe wurden 10 Byte reserviert.

char givenPassword[10];

Wenn du jetzt eine Eingabe machst die 9 Zeichen hat funktioniert es.

C:\dev>test
Password: aaaaaaaaa
FAILURE!
givenPassword: aaaaaaaaa
realPassword: s3cr3t

Jetzt geben wir genau 10 Zeichen ein, soviel wie Speicher reserviert wurde.

C:\dev>test
Password: aaaaaaaaaa
FAILURE!
givenPassword: aaaaaaaaaa
realPassword:

Du merkst das "realPassword" plötzlich leer ist. Eigentlich nicht leer, sondern ein "\0" Byte steht an der ersten Stelle. Ein String in C wird mit einem "\0" Byte beendet. Da wir genau 10 Buchstaben eingegeben haben steht das "\0" Byte am Ende unserer Eingabe jetzt an der ersten Stelle des überschriebenen Puffer von "realPassword". Das Programm liest den String, findet ein "\0" Byte und denkt der String ist zu Ende. Jetzt geben wir 11 Zeichen ein.

C:\dev>test
Password: aaaaaaaaaaa
FAILURE!
givenPassword: aaaaaaaaaaa
realPassword: a

Der Puffer fängt an sich mit den "a" aus unserer Eingabe zu füllen. Wir können also den Buffer von "realPassword" durch unsere Eingabe überschreiben. Wieso ist das gefährlich? Geben wir jetzt 20 Zeichen ein passiert folgendes.

C:\dev>test
Password: aaaaaaaaaaaaaaaaaaaa
SUCCESS!
givenPassword: aaaaaaaaaaaaaaaaaaaa
realPassword: aaaaaaaaaa

Der gesamte Buffer (10 Byte) von "realPassword" wurden durch unsere Eingabe mit "a" überschrieben. Da unsere Eingabe "givenPassword" jetzt auch aus lauter "a" besteht sind beide Strings gleich und wir wären eingeloggt.

von (716 Punkte)