Hier ist der Befehl, den ich verwendet habe, um meine Bash-Shell auf den Shellshock-Bug zu überprüfen:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Kann jemand den Befehl bitte genauer erklären?
Antwort1
Diese Antwort ist eine Ableitung einerOriginalartikel im Fedora Magazinevon Matthew Miller, lizenziert unter derCreative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 4.0Lizenz.
Lassen Sie mich erklären:
env x='() { :;}; echo OOPS' bash -c :
Dies gibt auf einem anfälligen System „OOPS“ aus, wird jedoch stillschweigend beendet, wenn Bash gepatcht wurde.
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Auf einem anfälligen System wird „OOPS“ gedruckt, aber nur “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 sollte er nicht – aber aufgrund einer Funktion, die ich als etwas zu clever für ihr eigenes Wohl bezeichnen würde, besteht die Möglichkeit eines Fehlers. Bash ist das, was Sie als Terminal-Eingabeaufforderung sehen, aber es ist auch eine Skriptsprache und kann Funktionen definieren. Das machen Sie so:
$ Ubuntu() { echo "Ubuntu is awesome."; }
und dann haben Sie einen neuen Befehl. Denken Sie daran, dass das echo
hier noch nicht wirklich ausgeführt wird; es wird nur gespeichert, was passieren wird, wenn wir unseren neuen Befehl ausführen. Das wird gleich wichtig sein!
$ Ubuntu
Ubuntu is awesome.
Nützlich! Aber nehmen wir an, wir müssen aus irgendeinem Grund eine neue Instanz von Bash als Unterprozess ausführen und möchten meinen tollen neuen Befehl darunter ausführen. Die Anweisung bash -c somecommand
macht genau das: Sie führt den angegebenen Befehl in einer neuen Shell aus:
$ bash -c Ubuntu
bash: Ubuntu: command not found
Oh. Traurig. Das Kind hat die Funktionsdefinition nicht geerbt. Aber es hat die Umgebung übernommen – eine Sammlung von Schlüssel-Wert-Paaren, die aus der Shell exportiert wurden. (Das ist ein ganz anderes Konzept; wenn Sie damit nicht vertraut sind, vertrauen Sie mir erstmal.) Und wie sich herausstellt, kann Bash auch Funktionen exportieren. Also:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
Das ist alles schön und gut – außer dass der Mechanismus, mit dem dies erreicht wird,irgendwie zwielichtig. Da es unter Linux/Unix keine magische Methode gibt, Funktionen in Umgebungsvariablen auszuführen, erstellt die Exportfunktion eigentlich nur eine normale Umgebungsvariable, die die Funktionsdefinition enthält. Wenn dann die zweite Shell die „eingehende“ Umgebung liest und auf eine Variable mit Inhalt stößt, der wie eine Funktion aussieht, wertet sie diese aus.
Theoretisch ist diesabsolut sicher, denn, denken Sie daran, das Definieren einer Funktion bedeutet nicht wirklichFühr es aus. Außer – und deshalb sind wir hier – gab es einen Fehler im Code, bei dem die Auswertung nicht stoppte, wenn das Ende der Funktionsdefinition erreicht war. Sie lief einfach weiter.
Das würde nie passieren, wenn die in einer Umgebungsvariable gespeicherte Funktion legitim erstellt wird, mit export -f
. Aber warum legitim sein? Ein Angreifer kann einfach irgendeine alte Umgebungsvariable erstellen, und wenn sie wie eine Funktion aussieht, werden neue Bash-Shells denken, dass sie eine ist!
In unserem ersten Beispiel gilt also:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Der env
Befehl führt einen Befehl mit einem bestimmten Variablensatz aus. In diesem Fall legen wir x
etwas fest, das wie eine Funktion aussieht. Die Funktion ist nur ein einzelnes :
, was eigentlich ein einfacher Befehl ist, der so definiert ist, dass er nichts tut. Aber dann, nach dem , semi-colon
das das Ende der Funktionsdefinition signalisiert, gibt es einen echo
Befehl. Der sollte nicht dort sein, aber nichts hindert uns daran, ihn auszuführen.
Der Befehl zum Ausführen dieser neuen Umgebung ist dann eine neue Bash-Shell, wiederum mit einem „ echo this is a test
“- oder „Nichts tun :
“-Befehl, wonach sie völlig harmlos beendet wird.
Aber – hoppla! Wenn diese neue Shell startet und die Umgebung liest, gelangt sie zur x
Variable, und da sie wie eine Funktion aussieht, wertet sie sie aus. Die Funktionsdefinition wird harmlos geladen – und dann wird auch unsere bösartige Nutzlast ausgelöst. Wenn Sie also das Obige auf einem anfälligen System ausführen, wird es “OOPS”
Ihnen ausgedruckt. Oder ein Angreifer könnte viel Schlimmeres tun, als nur Dinge auszudrucken.
Antwort2
Inungepatchte Version vonbash
Es speichert exportierte Funktionsdefinitionen als Umgebungsvariablen.
Speichern Sie eine Funktion x
als:
$ x() { bar; }
$ export -f x
Und überprüfen Sie die Definition wie folgt:
$ env | grep -A1 x
x=() { bar
}
Man könnte dies also ausnutzen, indem man seine eigenen Umgebungsvariablen definiert und diese als Funktionsdefinitionen interpretiert. Beispielsweise env x='() { :;}'
würde behandelt werden als
x() { :;
}
Was bewirkt der Befehl zur Überprüfung des Shellshocks?
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Aus man env
,
env
- Führen Sie ein Programm in einer geänderten Umgebung aus.:
nichts tun, außer mit exit status beenden0
. siehemehrWenn eine neue Instanz der ungepatchten Bash als gestartet wird
bash -c "echo this is a test"
, wird die erstellte Umgebungsvariable als Funktion behandelt und geladen. Entsprechend erhält man die Ausgabe
verletzlich das ist ein Test
Notiz:Das Echo außerhalb der Funktionsdefinition wurde beim Start von Bash unerwartet ausgeführt. Die Funktionsdefinition ist nur ein Schritt, um die Auswertung und Ausnutzung zu ermöglichen. Die Funktionsdefinition selbst und die verwendete Umgebungsvariable sind beliebig. Die Shell betrachtet die Umgebungsvariablen, sieht x, das die ihr bekannten Einschränkungen hinsichtlich des Aussehens einer Funktionsdefinition zu erfüllen scheint, und wertet die Zeile aus, wobei unbeabsichtigt auch das Echo ausgeführt wird (das ein beliebiger Befehl sein könnte, ob bösartig oder nicht). Siehe auchDas