Sicherheitsanfälligkeit in C system () - Funktion

  • Angenommen, wir haben das folgende Programm:

     #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
            char *user = getenv("USER");
            char buffer[4096];
    
            if (user) {
                    snprintf(buffer, sizeof buffer, "/bin/echo %s", user);   
                    system(buffer);
            }
    
            return 0;
    }
     

    Ist es möglich für a Benutzer, damit dieses Programm beliebige Befehle ausführt?

    30 November 2011
4 answers
  • Wenn sich dieser Code tatsächlich irgendwo im Live-Code befindet, sollte derjenige, der ihn geschrieben hat, gezwungen sein, zu schreiben. Ich werde system nie wieder mit verdorbener Benutzereingabe 1 mal mit einem stumpfen Stift aufrufen . Ja. Wie geschrieben, enthält dieser Code einen Exploit. Hier ist ein einfaches Beispiel:

     tmp$ cat foo.c
    #include <stdlib.h>
    #include <stdio.h>
    
    int
    main() {
        char *user = getenv("USER");
        char buffer[4096];
        if (user) {
            snprintf(buffer, sizeof buffer, "/bin/echo %s", user);
            printf("running %s\n", buffer);
            system(buffer);
        }
        return 0;
    }
    tmp$ gcc foo.c
    tmp$ mkdir /tmp/xxx
    tmp$ ls -ld /tmp/xxx
    drwxr-xr-x  2 daveshawley  users  68 Nov 30 22:25 /tmp/xxx/
    tmp$ USER='foo; rm -fr /tmp/xxx' ./a.out
    running /bin/echo foo; rm -fr /tmp/xxx
    foo
    tmp$ ls -ld /tmp/xxx
    ls: /tmp/xxx: No such file or directory
    tmp$
     
    01 December 2011
    D.Shawley
  • Wenn Sie den Wert der Umgebungsvariablen USER ausdrucken möchten, können Sie Folgendes tun:

     fprintf(stderr, "%s", getenv("USER"));
     

    Sie müssen system(); nicht aufrufen.

    04 December 2011
    RoyiJohn Robertson
  • Andere haben Ihnen gesagt, wie Sie dies ausnutzen können. Im Sinne der Befürwortung der richtigen Art und Weise, Dinge zu tun, ist hier eine gute Möglichkeit, echo mit Benutzereingaben auszuführen und keine Schwachstellen zu haben (abgesehen von einigen Fehlern im Echo: -)):

     execlp("echo", string_from_user, NULL);
     

    Wenn Sie sich direkt mit der Systemfamilie exec beschäftigen, können Sie unverfälschte Zeichenfolgen direkt an das Programm übergeben ohne die Möglichkeit, dass die Shell sie falsch interpretiert, denn gibt es in diesem Fall keine Shell . Daher ist keine Flucht erforderlich.

    Es gibt weitere potenzielle Sicherheitsprobleme mit Code wie diesem. Hier sind einige, die mir einfallen:

    • Wenn ein nicht vertrauenswürdiger Benutzer /bin/echo ändern kann, ist es offensichtlich, dass ein nicht vertrauenswürdiger Benutzer diesen Run beliebig ausführen kann code.

    • Wenn ein nicht vertrauenswürdiger Benutzer die Umgebungsvariable PATH ändern kann, ist mein oben angeführtes Beispiel execlp anfällig. Eine Problemumgehung besteht darin, die - p -Varianten der Systemfamilie exec nicht zu verwenden, da diese PATH nicht prüfen.

    04 December 2011
    asveikau
  • Es ist nicht möglich. Sie müssten etwas schreiben, das den USER-Umgebungsparameter ändert, der die vorherigen Zeichen effektiv zurückstellt, und das System ("Zeichenfolge") verwendet tatsächlich keine Shell über ein Pseudo-Terminal, um die Ausführung auszuführen / p>

    editieren : Trotz der untenstehenden Kommentare und einer Ablehnung sind sie falsch.

    / bin / sh-Verarbeitung (oder was auch immer die Shell angibt) verarbeitet nur die Rücktaste & amp; andere Editierzeichen, wenn sie zur Eingabe an ein Endgerät angeschlossen sind.

    Außerdem beabsichtigt der ursprüngliche Autor, ein Programm zu unterlaufen, das nicht von ihm selbst erstellt wurde.

    01 December 2011
    Andy Finkenstadt