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

122

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 Umgebungsvariable, die nach dem Funktionsnamen benannt ist, und eine Funktionsdefinition, die mit „() {“ im Variablenwert beginnt, um Funktionsdefinitionen in der Umgebung zu verbreiten. Die Sicherheitsanfälligkeit tritt auf, weil bash nach der Verarbeitung der Funktionsdefinition nicht beendet wird. Es werden weiterhin Shell-Befehle analysiert und ausgeführt, die der Funktionsdefinition folgen. Zum Beispiel eine Umgebungsvariableneinstellung von

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

wird / bin / id ausführen, 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 weiteren gefährdeten Versionen sind (ursprünglich) im CVE angegeben (3. {0..2} und 4. {0..3})?

Wurde der fehlerhafte Quellcode in anderen Projekten wiederverwendet?

Zusätzliche Informationen sind wünschenswert.


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

Hirschjäger
quelle
Ein weiteres gutes Schreiben an: access.redhat.com/articles/1200223
Greg Bray

Antworten:

206

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 bashskalare 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. rcverwendet 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_ENVoder $SHELLOPTS...

Es gibt einen Patch, der verhindert, dass bashetwas 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_FUNCDEFSoben 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:

  1. Schau dir an, woher bashder Input kommt und was es damit macht. Und die Umgebung ist offensichtlich.
  2. Überprüfen Sie, an welchen Stellen der bashInterpreter aufgerufen wird und auf welchen Daten. Auch hier würde es auffallen.
  3. Das Importieren von exportierten Funktionen ist eine der Funktionen, die deaktiviert sind, wenn bashsetuid / 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 bashInterpreter 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 evaloder .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_PROTOCOLoder QUERYSTRINGmit 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 bashder Umgebung nicht, wenn setuid oder durch einen setuid-Befehl aufgerufen wird (denken Sie mountbeispielsweise, dass er Helfer aufruft). Insbesondere werden exportierte Funktionen ignoriert.

sudoBereinigt 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_FOOnicht von einem Shell-Skript oder einer Befehlszeile als Befehl aufgerufen wird. Und Apache2 wird niemals eine echooder BASH_ENVVariable 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 bashAufruf 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.

Stéphane Chazelas
quelle
128
PS: Diese Antwort stammt von der Person, die den Fehler ursprünglich entdeckt hat :)
Ramesh
6
@Ben Ist das nicht die Antwort auf die entgegengesetzte Frage?
Türknauf
31
Darf ich fragen ... sind Sie zufällig auf den Fehler gestoßen oder haben Sie aktiv nach Fehlern in Bash gesucht?
200_success
7
@gerrit Weil der Fehler unter normalen Bedingungen kein schlechtes Verhalten verursacht. Da nichts schief geht, schaut niemand auf den Code außer Sicherheitsforschern und schwarzen Hüten.
Loren Pechtel
4
@JacekSzymanski stimmt, aber was ist mit anderen Headern? besonders benutzerdefinierte Header? (Ein Angreifer kann einfach einen X-Exploit-Payload-Header hinzufügen, der als HTTP_X_EXPORT_PAYLOAD festgelegt werden sollte.)
immibis
19

Laut der NVD-Datenbank unter NIST ( http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271 ) sind ALLE VERSIONEN von bash ab 1.14.0 anfällig.

RedHat hat am 14. September Wind von der Wanze bekommen .

Der von Mr.Ramey (Bash-Betreuer) am 26.09.2014 veröffentlichte Patch behebt den CVE-2014-7169-Fehler .

Wenden Sie diese und alle vorherigen Patches auf die entsprechenden Bash-Quellen an:


Zusätzliche Sicherheitslücken in bash


Ein bisschen mehr über die Geschichte des Fehlers (mit freundlicher Genehmigung von mikeserv )

Quelle: http://www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm

1994 beschrieb es Chet Ramey als älter als die alte POSIX 2-Spezifikation, die exportierte Funktionen spezifizierte. Oder zumindest beschrieb er den Bash-Mechanismus so - ob er damals so fehlerhaft war wie heute, weiß ich nicht. Er bespricht auch die Funktionsexporte von rc in diesem Thread.

Deer Hunter
quelle