
Ich wurde verlinkt mitDas Handbuch für Unix-Hasserund stieß auf (Seite 149):
Betreff: Relevanter Unix-Fehler
11. Oktober 1991
Mitstudenten des W4115x—
Wenn wir schon beim Thema Aktivierungsdatensätze, Argumentübergabe und Aufrufkonventionen sind: Wussten Sie, dass die Eingabe von:
!xxx%s%s%s%s%s%s%s%s
zu einer C-Shell führt dazu, dass diese sofort abstürzt? Wissen Sie, warum?
Fragen zum Nachdenken:
- Was macht die Shell, wenn Sie eingeben
!xxx
?- Was muss es mit Ihrer Eingabe machen, wenn Sie tippen
!xxx%s%s%s%s%s%s%s%s
?- Warum stürzt die Shell dadurch ab?
- Wie könnten Sie den fehlerhaften Teil der Shell (relativ einfach) umschreiben, um dieses Problem zu vermeiden?
Nur aus Neugier: Kann mir jemand erklären, wo das Problem lag? Wenig überraschend hilft eine Google-Suche nach der Zeichenfolge nicht weiter. Die Suche nach anderen Zitaten aus der Nachricht lieferte mir nur weitere Kopien der Nachricht, aber keine Erklärung.
Antwort1
Ich habe keine Lust, nach den Quellen der 25 Jahre alten Muscheln zu suchen, aber
Es könnte einFormat-String-Sicherheitslücke.
Wenn die Shell Code wie diesen enthält
printf(str);
wobei str
eine Zeichenfolge aus der Benutzereingabe entnommen wird. Der Inhalt der Zeichenfolge ist die printf
verwendete Formatzeichenfolge. Die %s
's weisen an, printf
eine Zeichenfolge zu drucken, auf die ein Argument zeigt. Wenn die Argumente nicht angegeben sind (wie oben, es gibt nur die Formatzeichenfolge), liest die Funktion einige andere Daten vom Stapel und folgt ihnen als Zeiger. Wahrscheinlich greift sie auf nicht zugeordneten Speicher zu und bringt den Prozess zum Absturz.
In gewisser Weise deutet meiner Meinung nach auch der Wortlaut der Meldung auf eine solche Lösung hin. Wenn Sie eingeben !xxx
, gibt die Shell sichtbar eine Fehlermeldung wie aus !xxx: event not found
. Von dort ist es kein großer Schritt, auch zu versuchen, auszugeben !xxx%s%s%s%s%s%s%s%s: event not found
, was eine Sicherheitslücke in der Formatzeichenfolge impliziert.
Ich hätte es nicht tun sollen, aber ich habe einen Blick auf die Quelle geworfenHier( 4.3BSD-Tahoe/usr/src/bin/csh
, Daten stammen aus dem Jahr 1988).
findev(cp, anyarg)
Insh.lex.c
sieht aus, als ob es die Funktion zum Suchen eines passenden Verlaufsereignisses sein könnte: Sie durchläuft eine verknüpfte Liste von struct Hist
aufgerufenen Histlist
. Wenn sie nichts findet, ruft sie seterr2(cp, ": Event not found");
über auf noev()
. cp
hier scheint die Zeichenfolge zu sein, nach der im Verlauf gesucht wird.
seterr2()
setzt die Variable err
als Verkettung der Argumente und err
wird if (err) error(err);
an einigen Stellen in verwendet process()
, insh.c
. Schließlich error()
(insh.err.c
) enthält eine klassische Sicherheitslücke im Formatstring:if (s) printf(s, arg), printf(".\n");
An einigen anderen Stellen error()
wird mit einem Argument wie aufgerufen, error("Unknown user: %s", gpath + 1);
die Idee besteht also eindeutig darin, dass das erste Argument error()
eine Formatzeichenfolge sein kann.
Ich wäre nicht ehrlich, wenn ich sagen würde, dass ich die Funktionen zur Verlaufssubstitution vollständig verstanden habe. Es handelt sich praktisch um eine unkommentierte manuelle Zeichenfolgenbehandlung in C. %
Die Verlaufssubstitution hat zwar eine besondere Bedeutung, aber ich kann nur erkennen, dass sie speziell behandelt wird, wenn das erste Zeichen (wie in !%
) oder danach findev()
aufgerufen wird.