Hier ist der Befehl, mit dem ich meine Bash-Shell auf den Shellshock-Fehler überprüft habe:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Kann jemand bitte den Befehl im Detail erklären?
bash
shellshock
heemayl
quelle
quelle
Antworten:
Diese Antwort ist eine Ableitung eines Originalartikels im Fedora Magazine von Matthew Miller, lizenziert unter der Creative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 4.0 .
Lassen Sie mich erklären:
Dies gibt "OOPS" auf einem anfälligen System aus, beendet sich jedoch unbemerkt, wenn bash gepatcht wurde.
Dadurch wird "OOPS" auf einem anfälligen System gedruckt, es wird jedoch gedruckt,
“this is a test”
wenn bash gepatcht wurde.Und Sie haben wahrscheinlich gehört, dass es etwas mit Umgebungsvariablen zu tun hat. Aber warum wird Code in Umgebungsvariablen ausgeführt? Nun, das soll es nicht sein - aber aufgrund eines Merkmals, das ich in der Versuchung bin, es ein bisschen zu schlau zu nennen, gibt es etwas Raum für einen Fehler. Bash ist das, was Sie als Terminal-Eingabeaufforderung sehen, aber es ist auch eine Skriptsprache und kann Funktionen definieren. Das machst du so:
und dann hast du einen neuen befehl. Denken Sie daran, dass das
echo
hier noch nicht ausgeführt wird. Es wird nur gespeichert, was passieren wird, wenn wir unseren neuen Befehl ausführen. Dies wird in einer Minute wichtig sein!Sinnvoll! Aber lassen Sie uns aus irgendeinem Grund sagen, wir müssen eine neue Instanz von bash als Unterprozess ausführen und möchten meinen fantastischen neuen Befehl unter diesem ausführen. Die Anweisung
bash -c somecommand
macht genau das: Führt den angegebenen Befehl in einer neuen Shell aus:Oh. Traurig. Das Kind hat die Funktionsdefinition nicht geerbt. Die Umgebung ist jedoch inhärent - eine Sammlung von Schlüssel-Wert-Paaren, die aus der Shell exportiert wurden. (Dies ist ein komplettes Konzept. Wenn Sie damit nicht vertraut sind, vertrauen Sie mir jetzt.) Und wie sich herausstellt, kann bash auch Funktionen exportieren. So:
Was alles gut und schön ist - außer dass der Mechanismus, durch den dies erreicht wird, ein bisschen zweifelhaft ist . Da es für die Ausführung von Funktionen in Umgebungsvariablen keine Linux / Unix-Magie gibt, erstellt die Exportfunktion im Grunde genommen nur eine reguläre Umgebungsvariable, die die Funktionsdefinition enthält. Wenn dann die zweite Shell die "eingehende" Umgebung liest und auf eine Variable mit Inhalten stößt, die wie eine Funktion aussehen, wertet sie diese aus.
Theoretisch ist dies absolut sicher , da das Definieren einer Funktion sie nicht tatsächlich ausführt . Außer - und aus diesem Grund sind wir hier - gab es einen Fehler im Code, bei dem die Auswertung nicht gestoppt wurde, als das Ende der Funktionsdefinition erreicht wurde. Es läuft einfach.
Das würde niemals passieren, wenn die in einer Umgebungsvariablen gespeicherte Funktion mit legitim gemacht wird
export -f
. Aber warum echt sein? Ein Angreifer kann einfach eine alte Umgebungsvariable erfinden, und wenn es wie eine Funktion aussieht, werden neue Bash-Shells denken, dass dies der Fall ist!Also, in unserem ersten Beispiel:
Der
env
Befehl führt einen Befehl mit einem bestimmten Variablensatz aus. In diesem Fall stellen wirx
etwas ein, das wie eine Funktion aussieht. Die Funktion ist nur eine einzige:
, was eigentlich ein einfacher Befehl ist, der definiert ist, nichts zu tun. Aber dann, nach dem,semi-colon
was das Ende der Funktionsdefinition signalisiert, gibt es einenecho
Befehl. Das sollte nicht da sein, aber es hindert uns nichts daran, es zu tun.Dann ist der Befehl, der zum Ausführen mit dieser neuen Umgebung gegeben wird, eine neue Bash-Shell, wiederum mit einem "
echo this is a test
" oder "nichts tun":
" enthält. sie völlig harmlos beendet.Aber - hoppla! Wenn diese neue Shell gestartet wird und die Umgebung liest, gelangt sie zur
x
Variablen, und da sie wie eine Funktion aussieht, wertet sie sie aus. Die Funktionsdefinition ist harmlos geladen - und dann wird auch unsere schädliche Nutzlast ausgelöst. Wenn Sie die oben genannten Schritte auf einem anfälligen System ausführen, werden Sie darauf hingewiesen“OOPS”
. Oder ein Angreifer kann viel Schlimmeres tun, als nur Dinge zu drucken.quelle
env
nicht erforderlich ist. Sie können das gleiche Ergebnis (bestanden / nicht bestanden , je nachdem ob Bash aktualisiert wurde) , indem Sie den Befehl ohne es:x='() { :;}; echo OOPS' bash -c "echo this is a test"
. Dies liegt daran, dass vor einem Befehl mit einer Variablenzuweisung diese Variable und ihr Wert an diebash -c "..."
Umgebung des Befehls ( in diesem Fall) übergeben werden.env
erforderlich ist oder nicht , hängt von der Shell ab, von der aus der Test ausgeführt wird, nicht von der zu testenden Shell. (Diese können identisch sein. Selbst dann testen wir, wie bash seine eigene Umgebung verarbeitet.) Shells im Borowski-Stil akzeptierenNAME=value command
Syntax. C-Stil Schalen (zBcsh
,tcsh
) nicht. Daher ist der Test etwas portablerenv
(auf Kosten von Verwirrung, wie er manchmal funktioniert).In der ungepatchten Version
bash
werden exportierte Funktionsdefinitionen als Umgebungsvariablen gespeichert.Speichern Sie eine Funktion
x
als,Und überprüfen Sie seine Definition als,
Man könnte dies also ausnutzen, indem man seine eigenen Umgebungsvariablen definiert und sie als Funktionsdefinitionen interpretiert. Zum Beispiel
env x='() { :;}'
würde als behandelt werdenWas bewirkt der Befehl zum Überprüfen von Shellshock?
Von
man env
,env
- Führen Sie ein Programm in einer geänderten Umgebung aus.:
Mach nichts anderes als Exits mit Exit-Status0
. sehen mehrWenn eine neue Instanz von Bash ohne Patch gestartet wird
bash -c "echo this is a test"
, wird die gestaltete Umgebungsvariable als Funktion behandelt und geladen. Dementsprechend bekommt man die Ausgabequelle
env test='() { echo "anything"; }' bash -c "echo otherthing"
, werden Sie am Ausgang sehenotherthing
. Das ist im Patch korrigiert. Fühlen Sie sich frei, wenn ich noch nicht klar bin.unpatched bash
die Funktion aufrufen können, wie sie definiert ist, aber in einem gepatchtenbash
die Definition selbst nicht vorhanden ist.echo vulnerable
) folgt, nicht ausgeführt wird. Beachten Sie, dass in den neuesten Patches die übergebene Funktion ein bestimmtes Präfix (env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test"
) haben muss. Einige neuere Patches können%%
anstelle des ersten verwendet werden()
.