TL; DR
Die Shellshock-Schwachstelle ist vollständig in behoben
- Auf dem bash-2.05b-Zweig: 2.05b.10 und höher (Patch 10 enthalten)
- Auf dem Bash-3.0-Zweig: 3.0.19 und höher (Patch 19 enthalten)
- Auf dem Bash-3.1-Zweig: 3.1.20 und höher (Patch 20 enthalten)
- Auf dem bash-3.2-Zweig: 3.2.54 und höher (Patch 54 enthalten)
- Auf dem Bash-4.0-Zweig: 4.0.41 und höher (Patch 41 enthalten)
- Auf dem bash-4.1-Zweig: 4.1.14 und höher (Patch 14 enthalten)
- Auf dem bash-4.2-Zweig: 4.2.50 und höher (Patch 50 enthalten)
- Auf dem Bash-4.3-Zweig: 4.3.27 und höher (Patch 27 enthalten)
Wenn Ihre Bash eine ältere Version zeigt, hat Ihr Betriebssystemhersteller diese möglicherweise noch selbst gepatcht. Am besten überprüfen Sie dies.
Wenn:
env xx='() { echo vulnerable; }' bash -c xx
zeigt "verwundbar", du bist immer noch verwundbar. Dies ist der einzige relevante Test (ob der Bash-Parser noch Code in einer Umgebungsvariablen enthält).
Einzelheiten.
Der Fehler in der anfänglichen Implementierung der Funktion war Export / auf den 5 eingeführt Importieren th August 1989 von Brian Fox und ersten später zu einer Zeit , in bash-1.03 etwa einem Monat veröffentlicht , wo bash war nicht so weit verbreitet, vor dem Sicherheits War das ein großes Problem und HTTP und das Web oder Linux existierten sogar.
Aus dem ChangeLog in 1.05 :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Einige Diskussionen in gnu.bash.bug und comp.unix.questions zu dieser Zeit erwähnen diese Funktion ebenfalls.
Es ist leicht zu verstehen, wie es dort ankam.
bash exportiert die Funktionen in env vars wie
foo=() {
code
}
Und beim Import muss es nur interpretieren, dass =
durch ein Leerzeichen ersetzt wird ... außer, dass es nicht blind interpretiert werden soll.
Es ist auch darin aufgeschlüsselt, dass bash
skalare Variablen und Funktionen (im Gegensatz zur Bourne-Shell) einen anderen Namensraum haben. Eigentlich, wenn Sie haben
foo() { echo bar; }; export -f foo
export foo=bar
bash
wird beide gerne in die Umgebung stellen (ja Einträge mit demselben Variablennamen), aber viele Werkzeuge (einschließlich vieler Shells) werden sie nicht verbreiten.
Man würde auch argumentieren, dass bash ein BASH_
Namespace-Präfix dafür verwenden sollte, da dies env-Variablen sind, die nur von bash zu bash relevant sind. rc
verwendet ein fn_
Präfix für eine ähnliche Funktion.
Eine bessere Möglichkeit zur Implementierung wäre gewesen, die Definition aller exportierten Variablen in eine Variable wie die folgende zu setzen:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Das müsste noch saniert werden, aber zumindest könnte das nicht besser ausgenutzt werden als $BASH_ENV
oder $SHELLOPTS
...
Es gibt einen Patch, der verhindert, dass bash
etwas anderes als die darin enthaltene Funktionsdefinition interpretiert wird ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ) wurde in allen Sicherheitsupdates der verschiedenen Linux-Distributionen angewendet.
Bash interpretiert den darin enthaltenen Code jedoch immer noch und jeder Fehler im Interpreter könnte ausgenutzt werden. Ein solcher Fehler wurde bereits gefunden (CVE-2014-7169), obwohl seine Auswirkungen viel geringer sind. Es wird also bald einen weiteren Patch geben.
Bis zu einem Fix, der verhindert, dass Bash Code in einer Variablen interpretiert (wie BASH_FUNCDEFS
oben beschrieben), werden wir nicht genau wissen, ob wir nicht anfällig für einen Fehler im Bash-Parser sind. Und ich glaube, es wird früher oder später einen solchen Fix geben.
Bearbeiten Sie den 28.09.2014
Es wurden zwei zusätzliche Fehler im Parser gefunden (CVE-2014-718 {6,7}) (Beachten Sie, dass die meisten Shells in Eckfällen Fehler im Parser enthalten müssen, die ohne diesen Parser kein Problem gewesen wären nicht vertrauenswürdigen Daten ausgesetzt waren).
Während alle 3 Fehler 7169, 7186 und 7187 in den folgenden Patches behoben wurden, hat Red Hat auf die Behebung des Problems gedrängt. In ihrem Patch haben sie das Verhalten dahingehend geändert, dass Funktionen in Variablen exportiert wurden, die BASH_FUNC_myfunc()
mehr oder weniger Chets Entwurfsentscheidung vorwegnahmen.
Chet veröffentlichte diesen Fix später als offiziellen Upstream-Bash-Patch .
Dieser Hardening-Patch oder Varianten davon sind jetzt für die meisten großen Linux-Distributionen verfügbar und haben es schließlich auf Apple OS / X geschafft.
Das schließt nun die Sorge um beliebige Umgebungsvariablen aus, die den Parser über diesen Vektor ausnutzen, einschließlich zweier weiterer Schwachstellen im Parser (CVE-2014-627 {7,8}), die später von Michał Zalewski (CVE-2014-6278 ) offengelegt wurden so schlimm wie CVE-2014-6271), zum Glück, nachdem die meisten Leute Zeit hatten, das Härtungs-Patch zu installieren
Fehler im Parser werden ebenfalls behoben, sind jedoch nicht mehr so problematisch, da der Parser nicht mehr so leicht nicht vertrauenswürdigen Eingaben ausgesetzt ist.
Beachten Sie, dass die Sicherheitsanfälligkeit zwar behoben wurde, in diesem Bereich jedoch wahrscheinlich einige Änderungen vorgenommen werden. Das anfängliche Update für CVE-2014-6271 hat die Abwärtskompatibilität insofern beeinträchtigt, als das Importieren von Funktionen mit .
oder :
oder /
in deren Namen gestoppt wird . Diese können jedoch immer noch durch Bash deklariert werden, was zu einem inkonsistenten Verhalten führt. Da Funktionen mit .
und :
in ihrem Namen häufig verwendet werden, wird wahrscheinlich ein Patch wiederhergestellt, der mindestens die Funktionen aus der Umgebung akzeptiert.
Warum wurde es nicht früher gefunden?
Darüber habe ich mich auch gewundert. Ich kann ein paar Erklärungen anbieten.
Erstens denke ich, dass ein Sicherheitsforscher (und ich bin kein professioneller Sicherheitsforscher), der gezielt nach Schwachstellen in Bash gesucht hat, diese wahrscheinlich gefunden hätte.
Wenn ich zum Beispiel ein Sicherheitsforscher wäre, könnten meine Ansätze sein:
- Schau dir an, woher
bash
der Input kommt und was es damit macht. Und die Umgebung ist offensichtlich.
- Überprüfen Sie, an welchen Stellen der
bash
Interpreter aufgerufen wird und auf welchen Daten. Auch hier würde es auffallen.
- Das Importieren von exportierten Funktionen ist eine der Funktionen, die deaktiviert sind, wenn
bash
setuid / setgid aktiviert ist, wodurch es noch offensichtlicher wird, darauf zu achten.
Ich vermute, niemand hat gedacht, dass er bash
(den Dolmetscher) als Bedrohung ansieht oder dass die Bedrohung auf diese Weise entstanden sein könnte.
Der bash
Interpreter ist nicht dazu gedacht, nicht vertrauenswürdige Eingaben zu verarbeiten.
Shell- Skripte (nicht der Interpreter) werden aus Sicherheitsgründen häufig genau betrachtet. Die Shell-Syntax ist so umständlich und es gibt so viele Einschränkungen beim Schreiben zuverlässiger Skripte (ich oder andere haben den split + glob-Operator schon einmal erwähnt oder warum sollten Sie beispielsweise Variablen zitieren?), Dass es durchaus üblich ist, Sicherheitslücken in Skripten zu finden, die diese verarbeiten nicht vertrauenswürdigen Daten.
Aus diesem Grund hören Sie oft, dass Sie keine CGI-Shell-Skripte schreiben sollten, oder setuid-Skripte sind auf den meisten Unices deaktiviert. Oder dass Sie besonders vorsichtig sein sollten, wenn Sie Dateien in von der Welt beschreibbaren Verzeichnissen verarbeiten (siehe beispielsweise CVE-2011-0441 ).
Der Fokus liegt darauf, auf den Shell-Skripten, nicht auf dem Interpreter.
Sie können einen Shell-Interpreter nicht vertrauenswürdigen Daten aussetzen (fremde Daten als zu interpretierenden Shell-Code einspeisen), indem Sie über eval
oder .
auf von Benutzern bereitgestellte Dateien zugreifen. In diesem Fall benötigen Sie jedoch keine Sicherheitsanfälligkeit bash
, um diese auszunutzen. Es ist ziemlich offensichtlich, dass nicht bereinigte Daten, die von einer Shell interpretiert werden sollen, interpretiert werden.
Die Shell wird also in vertrauenswürdigen Kontexten aufgerufen. Es gibt feste Skripte zum Interpretieren und oft feste Daten zum Verarbeiten (weil es so schwierig ist, zuverlässige Skripte zu schreiben).
In einem Webkontext kann eine Shell beispielsweise folgendermaßen aufgerufen werden:
popen("sendmail -oi -t", "w");
Was kann damit möglicherweise schief gehen? Wenn etwas nicht in Ordnung ist, geht es um die Daten, die an diese sendmail gesendet werden, nicht darum, wie diese Shell-Befehlszeile selbst analysiert wird oder welche zusätzlichen Daten an diese Shell gesendet werden. Es gibt keinen Grund, die Umgebungsvariablen zu berücksichtigen, die an diese Shell übergeben werden. Und wenn Sie dies tun, stellen Sie fest, dass es sich um alle Env-Vars handelt, deren Name mit "HTTP_" beginnt oder die bekannte CGI-Env-Vars sind SERVER_PROTOCOL
oder QUERYSTRING
mit denen die Shell oder Sendmail nichts zu tun haben.
In Privilegienerhöhungskontexten wie bei der Ausführung von setuid / setgid oder über sudo wird die Umgebung im Allgemeinen berücksichtigt. In der Vergangenheit gab es zahlreiche Schwachstellen, auch hier nicht gegenüber der Shell selbst, sondern gegenüber Dingen, die die Privilegien erhöhen sudo
(siehe z. B. CVE) -2011-3628 ).
Vertraut beispielsweise bash
der Umgebung nicht, wenn setuid oder durch einen setuid-Befehl aufgerufen wird (denken Sie mount
beispielsweise, dass er Helfer aufruft). Insbesondere werden exportierte Funktionen ignoriert.
sudo
Bereinigt die Umgebung: Alle standardmäßig mit Ausnahme einer weißen Liste und, falls nicht konfiguriert, zumindest einige schwarze Listen, von denen bekannt ist, dass sie eine Shell oder eine andere betreffen (z. B PS4
. BASH_ENV
,, SHELLOPTS
...). Außerdem werden die Umgebungsvariablen auf eine schwarze Liste gesetzt, deren Inhalt mit beginnt ()
(weshalb CVE-2014-6271 die Eskalation von Berechtigungen über nicht zulässt sudo
).
Dies gilt jedoch auch für Kontexte, in denen der Umgebung nicht vertraut werden kann: Jede Variable mit einem beliebigen Namen und Wert kann von einem böswilligen Benutzer in diesem Kontext festgelegt werden. Dies gilt nicht für Webserver / ssh oder alle Vektoren, die CVE-2014-6271 ausnutzen, bei denen die Umgebung gesteuert wird (zumindest der Name der Umgebungsvariablen wird gesteuert ...).
Es ist wichtig, eine Variable wie echo="() { evil; }"
, aber nicht zu blockieren HTTP_FOO="() { evil; }"
, da sie HTTP_FOO
nicht von einem Shell-Skript oder einer Befehlszeile als Befehl aufgerufen wird. Und Apache2 wird niemals eine echo
oder BASH_ENV
Variable setzen.
Es ist ziemlich offensichtlich, dass einige Umgebungsvariablen in einigen Kontexten aufgrund ihres Namens auf der schwarzen Liste stehen sollten, aber niemand dachte, dass sie aufgrund ihres Inhalts auf der schwarzen Liste stehen sollten (außer sudo
). Mit anderen Worten, niemand glaubte, dass beliebige Umgebungsvariablen ein Vektor für die Code-Injektion sein könnten.
Ich würde sagen, dass es unwahrscheinlich ist, ob umfangreiche Tests, als das Feature hinzugefügt wurde, es abgefangen haben könnten.
Wenn Sie das Feature testen, testen Sie die Funktionalität. Die Funktionalität funktioniert gut. Wenn Sie die Funktion in einem bash
Aufruf exportieren , wird sie in einem anderen Aufruf ordnungsgemäß importiert. Bei einem sehr gründlichen Test konnten Probleme festgestellt werden, wenn sowohl eine Variable als auch eine Funktion mit demselben Namen exportiert wurden oder wenn die Funktion in einem Gebietsschema importiert wurde, das von dem Gebietsschema abweicht, in dem sie exportiert wurde.
Um die Sicherheitsanfälligkeit erkennen zu können, ist dies jedoch kein Funktionstest, den Sie hätten durchführen müssen. Der Sicherheitsaspekt hätte im Vordergrund stehen müssen, und Sie würden nicht die Funktionalität testen, sondern den Mechanismus und wie er missbraucht werden könnte.
Es ist nicht etwas, was Entwickler (besonders 1989) oft im Hinterkopf haben, und ein Shell-Entwickler könnte entschuldigt werden, zu glauben, dass seine Software wahrscheinlich nicht netzwerkfähig ist.