2012-04-09 15 views
1

Warum ist dieser Code ungesichert?Warum ist dieser Code ausnutzbar?

#include <stdio.h> 
int main(int argc, char *argv[]) 
    { 
     printf(argv[1]); 
     printf("\n"); 
     return 0; 
    } 
+12

Warum sollten wir Ihre Hausaufgaben für Sie tun? –

+3

http://en.wikipedia.org/wiki/Uncontrolled_format_string –

Antwort

5

printf wird seinen ersten Parameter, auf der Suche nach Dingen wie %d und %s verarbeiten.

Basierend auf diesen Werten werden mehr Daten vom Stapel abgerufen und ausgedruckt.

Also, wenn jemand Ihr Programm mit dem Namen:

a.out "%d %d %d %d %d %d %d %d %d %d %d %d" 

Sie konnten einen Teil Ihres Computers Aufrufliste anzuzeigen.

Wenn sie mit dem Formatbezeichner noch kreativer werden, könnten sie vielleicht etwas Wichtiges wie eine Kreditkartennummer oder ein Passwort ablegen.

+1

mit '% n' können Sie sogar irgendwo im Speicher schreiben – ouah

+0

Ja, das, was ich dachte, aber es druckt nur die%, weil es argv [1] druckt, das ist es. – 0x90

+0

Dies ist relativ gutartig; '% n' kann aktiven Schaden verursachen (z. B. den Kontrollfluss modifizieren). –

4

Überlegen Sie, was das erste Argument von printf Kontrollen (Hinweis: printf nicht nur seine Eingabeargumente lesen).

1

Seit Plakate für ein Beispiel gefragt, was %n tut:

Die Art und Weise eines printf Format-String kann Änderung Speicher sind durch die %n Option; Ein bestimmter zu schreibender Wert kann erhalten werden, indem Formatbreiten-Spezifikatoren "weise" verwendet werden. Als Test:

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int *q = (int *)argv[0]; 
    printf("%1$300000d%5$n", 
     123,   // %1 - 1st param (formatted as '300000d') 
     0,   // %2 - 2nd param (unused) 
     0,   // %3 - 3rd param (unused) 
     0,   // %4 - 4th param (unused) 
     argv[0]); // %5 - 5th param (written to via 'n') 

    printf("\nNow *q == %d\n", *q); 

    return 0; 
} 

Wenn Sie dies ausführen und eine die letzte Zeile der Ausgabe aussehen, wird es Now *q == 300000 (getestet auf Linux) drucken.

Ich bin mit der eher unbekannten Positionsformat Syntax (% <pos> $ <fmt>) für printf() hier, um zu zeigen, wie man Argumente überspringen kann zu wählen, welche, ohne zu ändern, dass zu verwenden von den "uninteressanten".

Ich werde es den Lesern Experimente überlassen, um herauszufinden, was printf() als "Argumente" für einen Anruf wie printf(argv[1]) behandelt. Die Antwort darauf hängt von der calling conventions (oder verwandten, die ABI für Ihr System), und ist für 32/64bit Windows/Linux/MacOSX etc.