2014-12-30 5 views

Antwort

29

Der Code, den Sie sprechen von wie folgt aussieht:

ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
while(c=nargv[0][i]) { 
    ncom[9+i++] = c; 
} 
ncom[9+i] = '\0'; 

diejenigen Akt All x als Puffer, werden sie durch die folgende Schleife außer Kraft gesetzt. Daher fügt der Code "/ usr/bin /" effektiv zum Befehl in nargv[0] hinzu.

Mit etwas mehr Kontext der Code dies tut:

execv(nargv[0], nargv, np); 
execv(ncom+4, nargv, np); 
execv(ncom, nargv, np); 

Wenn der gegebene Befehl in nargv[0] ist "foo" es wird zuerst versuchen, "foo" dann "/bin/foo" und schließlich "/usr/bin/foo" zu laufen.


Beachten Sie, dass über ein gutes Beispiel dafür ist, wie man nicht solche Dinge tun:

Wenn die Zeichenfolge in nargv[0] länger als die Anzahl von x ist passiert sein, weiterhin wird der Code glücklich Kopieren von Daten . Dies überschreibt andere Teile des Stapels. Das Ergebnis ist ein gutes Beispiel für einen Pufferüberlauf. (Sie einen Puffer mit einer gewissen Größe zuweisen und mehr Daten schreiben als zugewiesen.)

Dieses Beispiel wird das Problem zeigen:

#include <stdio.h> 
int main(){ 
    char s[]="abcde"; 
    int i; 
    for(i=0;i<100;i++){ 
    printf("position %2d contains value %3d\n",i,s[i]); 
    s[i]=0; 
    } 
    puts(s); 
    return 0; 
} 

Wenn Sie es ausführen wird es (wahrscheinlich) Ausgang dieses:

position 0 contains value 97 
position 1 contains value 98 
position 2 contains value 99 
position 3 contains value 100 
position 4 contains value 101 
position 5 contains value 0 
position 6 contains value 0 
position 7 contains value 0 
position 8 contains value 0 
position 9 contains value 0 
position 10 contains value 0 
position 11 contains value 0 
position 12 contains value 12 
position 1 contains value 0 
position 2 contains value 0 
position 3 contains value 0 
position 4 contains value 0 
position 5 contains value 0 
position 6 contains value 0 
position 7 contains value 0 
[...] 

Es wird die Zeichenfolge (die die ASCII-Werte 97 bis 101 enthält) mit Nullen gefüllt und wird fortfahren, den Speicher zu schreiben, wo es die Position der Variablen i finden wird, wird es auch auf Null gesetzt. Jetzt i ist Null und daher beginnt die Schleife erneut, überschreiben die bereits überschriebene Zeichenfolge immer wieder.

Nicht nur lokale Variablen können überschrieben werden, auch die Rückgabeadresse einer Funktion kann überschrieben werden, was entweder zu einem "Segmentierungsfehler" oder zur Ausführung von beliebigem Code führt, der häufig von Malware verwendet wird.

+2

Warum +9 und +4? Danke michas :) – Joey

+4

Die Zahlen sind Positionen in der Zeichenfolge: "/ usr" sind 4 Zeichen. "/ usr/bin /" sind 9 Zeichen. – michas

+1

Ah jetzt sehe ich es :) Danke nochmal Michas! – Joey