GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wann wurde der Shellshock-Fehler (cve-2014-6271/7169) eingeführt und welcher Patch behebt ihn vollständig?

Ein wenig Kontext zum Fehler:CVE-2014-6271

Bash unterstützt den Export nicht nur von Shell-Variablen, sondern auch von Shell-
-Funktionen in andere Bash-Instanzen über die Prozessumgebung in
(indirekte) untergeordnete Prozesse. Aktuelle Bash-Versionen verwenden eine nach dem Funktionsnamen benannte Umgebungsvariable
und eine Funktionsdefinition
beginnend mit „() {“ im Variablenwert, um Funktionsdefinitionen
durch die Umgebung zu verbreiten. Die Schwachstelle tritt auf, weil
bash nach der Verarbeitung der Funktionsdefinition nicht stoppt; es
fährt damit fort, Shell-Befehle zu parsen und auszuführen, die der Funktionsdefinition
folgen. Beispielsweise eine Umgebungsvariableneinstellung von

  VAR=() { ignored; }; /bin/id

führt /bin/id aus, wenn die Umgebung in den bash
-Prozess importiert wird.

Quelle:http://seclists.org/oss-sec/2014/q3/650

Wann wurde der Fehler eingeführt und welcher Patch behebt ihn vollständig? (Siehe CVE-2014-7169)

Welche anfälligen Versionen sind darüber hinaus im CVE (ursprünglich) (3.{0..2} und 4.{0..3}) aufgeführt?

Wurde der fehlerhafte Quellcode in anderen Projekten wiederverwendet?

Zusätzliche Informationen sind erwünscht.

Verwandte:Was bedeutet env x='() { :;}; command’ bash tun und warum ist es unsicher?

Akzeptierte Antwort:

TL;DR

Die Shellshock-Schwachstelle wurde vollständig behoben in

  • 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 anzeigt, hat Ihr Betriebssystemanbieter diese möglicherweise noch selbst gepatcht, also prüfen Sie am besten nach.

Wenn:

env xx='() { echo vulnerable; }' bash -c xx

„verwundbar“ anzeigt, sind Sie immer noch verwundbar. Das ist der einzige Test, der relevant ist (ob der Bash-Parser immer noch Code in beliebigen ausgesetzt ist Umgebungsvariable).

Einzelheiten.

Der Fehler lag in der anfänglichen Implementierung der Funktion Exportieren/Importieren, die am 5. August 1989 von Brian Fox eingeführt und erstmals in Bash-1.03 etwa einen Monat später veröffentlicht wurde, zu einer Zeit, als Bash noch nicht so weit verbreitet war, bevor es Sicherheit gab so besorgniserregend 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 aus dieser Zeit erwähnen dieses Feature ebenfalls.

Es ist leicht zu verstehen, wie es dorthin kam.

bash exportiert die Funktionen in Umgebungsvariablen wie

foo=() {
  code
}

Und beim Importieren muss es das nur mit = interpretieren durch ein Leerzeichen ersetzt… außer dass es nicht blind interpretiert werden sollte.

Das ist auch in bash eingebrochen (im Gegensatz zur Bourne-Shell) haben skalare Variablen und Funktionen einen anderen Namensraum. Eigentlich, wenn Sie

foo() { echo bar; }; export -f foo
export foo=bar

bash wird gerne beides in die Umgebung stellen (ja, Einträge mit demselben Variablennamen), aber viele Tools (einschließlich vieler Shells) werden sie nicht weitergeben.

Man würde auch argumentieren, dass Bash einen BASH_ verwenden sollte Namespace-Präfix dafür, da dies env vars ist, die nur von Bash zu Bash relevant sind. rc verwendet ein fn_ Präfix für eine ähnliche Funktion.

Ein besserer Weg, dies zu implementieren, wäre gewesen, die Definition aller exportierten Variablen in eine Variable wie diese zu schreiben:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

Das müsste noch bereinigt werden, aber zumindest könnte es nicht ausnutzbarer sein als $BASH_ENV oder $SHELLOPTS

Es gibt einen Patch, der bash verhindert davon abhalten, irgendetwas anderes als die darin enthaltene Funktionsdefinition zu interpretieren (https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html), und das ist diejenige, die in der gesamten Sicherheit angewendet wurde Updates von den verschiedenen Linux-Distributionen.

Bash interpretiert jedoch immer noch den darin enthaltenen Code, 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 Hardening-Fix, der Bash daran hindert, Code in einer beliebigen Variable zu interpretieren (wie die Verwendung von BASH_FUNCDEFS Ansatz oben), wissen wir nicht genau, ob wir nicht durch einen Fehler im Bash-Parser anfällig sind. Und ich glaube, dass es früher oder später einen solchen Hardening-Fix geben wird.

Verwandte:Wie finde ich Dateien mit einem bestimmten Unterpfad?

Bearbeitet am 28.09.2014

Zwei zusätzliche Fehler im Parser wurden gefunden (CVE-2014-718{6,7}) (beachten Sie, dass die meisten Shells zwangsläufig Fehler in ihrem Parser für Eckfälle haben, das wäre kein Problem gewesen, wenn dieser Parser nicht gewesen wäre nicht vertrauenswürdigen Daten ausgesetzt waren).

Während alle 3 Fehler 7169, 7186 und 7187 in den folgenden Patches behoben wurden, drängte Red Hat auf die Härtung. In ihrem Patch änderten sie das Verhalten so, dass Funktionen in Variablen namens BASH_FUNC_myfunc() exportiert wurden Chets Designentscheidung mehr oder weniger vorwegnehmen.

Chet veröffentlichte diesen Fix später als offiziellen Upstream-Bash-Patch.

Dieser Härtungspatch oder Varianten davon sind jetzt für die meisten großen Linux-Distributionen verfügbar und haben es schließlich bis zu Apple OS/X geschafft.

Das beseitigt nun die Bedenken hinsichtlich einer beliebigen env-Variablen, die den Parser über diesen Vektor ausnutzt, einschließlich zweier weiterer Sicherheitslücken im Parser (CVE-2014-627{7,8}), die später von Michał Zalewski (CVE-2014-6278 ist fast so schlimm wie CVE-2014-6271), zum Glück, nachdem die meisten Leute Zeit hatten, den Hardening-Patch zu installieren

Fehler im Parser werden ebenfalls behoben, aber sie sind nicht mehr so ​​ein großes Problem, da der Parser nicht mehr so ​​leicht unzuverlässigen Eingaben ausgesetzt ist.

Beachten Sie, dass die Sicherheitslücke zwar behoben wurde, es jedoch wahrscheinlich ist, dass wir einige Änderungen in diesem Bereich sehen werden. Der anfängliche Fix für CVE-2014-6271 hat die Abwärtskompatibilität beeinträchtigt, indem er den Import von Funktionen mit . stoppt oder : oder / in ihrem Namen. Diese können jedoch immer noch von bash deklariert werden, was zu einem inkonsistenten Verhalten führt. Denn funktioniert mit . und : in ihrem Namen häufig verwendet werden, ist es wahrscheinlich, dass ein Patch wiederhergestellt wird, der zumindest die aus der Umgebung akzeptiert.

Warum wurde es nicht früher gefunden?

Das habe ich mich auch gefragt. Ich kann ein paar Erklärungen anbieten.

Erstens denke ich, wenn ein Sicherheitsforscher (und ich bin kein professioneller Sicherheitsforscher) speziell nach Schwachstellen in Bash gesucht hätte, hätte er sie wahrscheinlich gefunden.

Wenn ich beispielsweise Sicherheitsforscher wäre, könnten meine Ansätze wie folgt aussehen:

  1. Schau dir an, wo bash bekommt Input von und was es damit macht. Und das Umfeld liegt auf der Hand.
  2. Sehen Sie, an welchen Stellen die bash Interpreter aufgerufen wird und auf welchen Daten. Auch hier würde es auffallen.
  3. Der Import von exportierten Funktionen ist eine der Funktionen, die beim bash deaktiviert wird ist setuid/setgid, was es zu einem noch offensichtlicheren Ort zum Suchen macht.

Nun, ich vermute, niemand hat daran gedacht, bash in Betracht zu ziehen (der Dolmetscher) als Drohung, oder dass die Drohung so kommen könnte.

Die bash Der Interpreter ist nicht dazu gedacht, nicht vertrauenswürdige Eingaben zu verarbeiten.

Shell-Skripte (nicht der Dolmetscher) werden oft unter Sicherheitsgesichtspunkten genau betrachtet. Die Shell-Syntax ist so umständlich und es gibt so viele Vorbehalte beim Schreiben zuverlässiger Skripte (jemals gesehen, wie ich oder andere den Split+Glob-Operator erwähnt haben oder warum Sie zum Beispiel Variablen zitieren sollten?), dass es ziemlich üblich ist, Sicherheitslücken in Skripten zu finden, die verarbeiten nicht vertrauenswürdige Daten.

Deshalb hört man oft, man solle keine CGI-Shell-Skripte schreiben, oder setuid-Skripte seien auf den meisten Unices deaktiviert. Oder dass Sie besonders vorsichtig sein sollten, wenn Sie Dateien in weltweit beschreibbaren Verzeichnissen verarbeiten (siehe zum Beispiel CVE-2011-0441).

Der Fokus liegt darauf, die Shell-Skripte, nicht der Interpreter.

Sie können einen Shell-Interpreter über eval nicht vertrauenswürdigen Daten (Fremddaten als Shell-Code zum Interpretieren zuführen) aussetzen oder . oder es auf vom Benutzer bereitgestellte Dateien aufrufen, aber dann brauchen Sie keine Schwachstelle in bash es auszunutzen. Es ist ziemlich offensichtlich, dass, wenn Sie nicht bereinigte Daten zur Interpretation an eine Shell weitergeben, diese sie interpretieren wird.

Die Shell wird also in vertrauenswürdigen Kontexten aufgerufen. Es erhält festgelegte Skripte zum Interpretieren und meistens (weil es so schwierig ist, zuverlässige Skripte zu schreiben) festgelegte Daten zum Verarbeiten.

In einem Web-Kontext könnte eine Shell beispielsweise folgendermaßen aufgerufen werden:

popen("sendmail -oi -t", "w");

Was kann daran schief gehen? Wenn etwas falsch ins Auge gefasst wird, geht es um die Daten, die dieser Sendmail zugeführt werden, nicht darum, wie diese Shell-Befehlszeile selbst geparst wird oder welche zusätzlichen Daten dieser Shell zugeführt werden. Es gibt keinen Grund, warum Sie die Umgebungsvariablen berücksichtigen sollten, die an diese Shell übergeben werden. Und wenn Sie dies tun, stellen Sie fest, dass es sich um Env-Variablen handelt, deren Namen mit „HTTP_“ beginnen, oder um bekannte CGI-Env-Variablen wie SERVER_PROTOCOL oder QUERYSTRING mit nichts davon haben die Shell oder sendmail etwas zu tun.

Siehe auch:Verwenden eines Transistors, um eine Lampe „vollständig“ zu beleuchten?

In Privilegienerhöhungskontexten wie beim Ausführen von setuid/setgid oder über sudo wird die Umgebung im Allgemeinen berücksichtigt, und es gab in der Vergangenheit viele Schwachstellen, wiederum nicht gegen die Shell selbst, sondern gegen Dinge, die die Privilegien erhöhen, wie sudo (siehe zum Beispiel CVE-2011-3628).

Zum Beispiel bash vertraut der Umgebung nicht, wenn setuid oder von einem setuid-Befehl aufgerufen wird (denken Sie an mount zum Beispiel, das Helfer aufruft). Insbesondere werden exportierte Funktionen ignoriert.

sudo reinigt die Umgebung:alles standardmäßig außer einer weißen Liste, und wenn dies nicht konfiguriert ist, werden zumindest einige auf die schwarze Liste gesetzt, von denen bekannt ist, dass sie eine Shell oder eine andere betreffen (wie PS4 , BASH_ENV , SHELLOPTS …). Es führt auch die Umgebungsvariablen auf die schwarze Liste, deren Inhalt beginnt mit () (weshalb CVE-2014-6271 keine Rechteausweitung über sudo zulässt ).

Aber auch das gilt für Kontexte, in denen der Umgebung nicht vertraut werden kann:Jede Variable mit beliebigem Namen und Wert kann von einem böswilligen Benutzer in diesem Kontext festgelegt werden. Das gilt nicht für Webserver/ssh oder alle Vektoren, die CVE-2014-6271 ausnutzen, wo die Umgebung kontrolliert wird (zumindest der Name der Umgebungsvariablen wird kontrolliert …)

Es ist wichtig, eine Variable wie echo="() { evil; }" zu blockieren , aber nicht HTTP_FOO="() { evil; }" , weil HTTP_FOO wird nicht als Befehl von einem Shell-Skript oder einer Befehlszeile aufgerufen. Und Apache2 wird niemals ein echo setzen oder BASH_ENV Variable.

Es ist ziemlich offensichtlich einige Umgebungsvariablen sollten in einigen Kontexten basierend auf ihrem Namen auf die schwarze Liste gesetzt werden , aber niemand dachte, dass sie aufgrund ihres Inhalts auf die schwarze Liste gesetzt werden sollten (außer sudo ). Oder anders gesagt, niemand dachte, dass beliebige env-Variablen ein Vektor für die Code-Injektion sein könnten.

Ich würde sagen, ob umfangreiche Tests, als das Feature hinzugefügt wurde, es hätten erkennen können.

Wenn Sie die Funktion testen , testen Sie auf Funktionalität. Die Funktionalität funktioniert einwandfrei. Wenn Sie die Funktion in einer bash exportieren Aufruf, es ist in Ordnung in einem anderen importiert. Ein sehr gründlicher Test hätte Probleme erkennen können, wenn sowohl eine Variable als auch eine Funktion mit demselben Namen exportiert wurden oder wenn die Funktion in einem anderen Gebietsschema importiert wurde als dem, in das sie exportiert wurde.

Aber um die Schwachstelle erkennen zu können, ist es 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 (insbesondere im Jahr 1989) oft im Hinterkopf haben, und ein Shell-Entwickler könnte entschuldigt werden, wenn er denkt, dass seine Software wahrscheinlich nicht über das Netzwerk ausnutzbar ist.


Linux
  1. Wenn Sie „ls -a“ eingeben, was ist die Bedeutung von „.“ Und ".."?

  2. Verfolgen und Beheben eines Installationsfehlers

  3. Was ist der Unterschied zwischen #!/usr/bin/env bash und #!/usr/bin/bash?

  4. Was ist die Verwendung von $ # in Bash

  5. Was ist der Unterschied zwischen &> und >&in bash?

Was ist der Unterschied zwischen InnoDB und MyISAM?

Was ist der Unterschied zwischen Linux und Unix?

Was ist falsch an meinem Bash-Skript, um die letzten x Dateien zu behalten und den Rest zu löschen?

Was war die SquashFS-Komprimierungsmethode?

Was sind die Inhalte von /bin/bash und was mache ich, wenn ich sie versehentlich überschrieben habe?

Was ist der Unterschied zwischen unlink und rm?