Um ein paar zu beruhigen, ich habe den Fehler nicht gefunden, indem ich Exploits beobachtet habe. Ich habe keinen Grund zu der Annahme, dass er ausgenutzt wurde, bevor er veröffentlicht wurde (obwohl ich ihn natürlich nicht ausschließen kann). Ich habe es auch nicht anhand des bash
Codes gefunden.
Ich kann nicht sagen, dass ich mich genau an meine Gedankengänge zu dieser Zeit erinnere.
Dass mehr oder weniger aus einer Überlegung über einige Verhaltensweisen einer Software resultiert, finde ich gefährlich (die Verhaltensweisen, nicht die Software). Die Art von Verhalten, bei der man denkt: Das klingt nicht nach einer guten Idee .
In diesem Fall habe ich über die übliche Konfiguration von ssh nachgedacht, mit der Umgebungsvariablen vom Client unbeaufsichtigt weitergegeben werden können, vorausgesetzt, ihr Name beginnt mit LC_
. Die Idee ist, dass die Leute weiterhin ihre eigene Sprache verwenden können, wenn sie ssh
in andere Maschinen hineingehen. Eine gute Idee, bis Sie sich überlegen, wie komplex die Lokalisierungsbehandlung ist, insbesondere wenn UTF-8 in die Gleichung einbezogen wird (und zu sehen ist, wie schlecht es von vielen Anwendungen verarbeitet wird).
Bereits im Juli 2014 hatte ich eine Sicherheitslücke im Umgang mit der Glibc-Lokalisierung gemeldet, die zusammen mit dieser sshd
Konfiguration und zwei anderen gefährlichen Verhaltensweisen der bash
Shell
(authentifizierten) Angreifern erlaubte, sich in Git-Server zu hacken, vorausgesetzt, sie konnten dort Dateien hochladen und bash
wurden verwendet als Login-Shell des Git-Unix-Benutzers (CVE-2014-0475).
Ich dachte, es wäre wahrscheinlich eine schlechte Idee, bash
als Login-Shell für Benutzer zu fungieren, die Dienste über ssh anbieten, da es sich um eine recht komplexe Shell handelt (wenn Sie nur eine sehr einfache Befehlszeile parsen müssen), die die meisten Fehlentwicklungen geerbt hat von ksh. Da ich bereits einige Probleme bei bash
der Verwendung in diesem Kontext (zur Interpretation von sshs ForceCommand
) festgestellt hatte , fragte ich mich, ob möglicherweise mehr vorhanden sind.
AcceptEnv LC_*
Erlaubt jede Variable, deren Name mit beginnt LC_
und bei der ich die vage Erinnerung hatte, dass bash
exportierte Funktionen (eine gefährliche, wenn auch zeitlich nützliche Funktion) Umgebungsvariablen verwenden, deren Name
ungefährmyfunction()
so aussieht und die sich fragen, ob es dort nichts Interessantes gibt.
Ich wollte es mit der Begründung ablehnen, dass das Schlimmste, was man tun könnte, wäre, einen aufgerufenen Befehl neu zu definieren, LC_something
der kein wirkliches Problem darstellen könnte, da dies keine vorhandenen Befehlsnamen sind, aber dann begann ich mich zu fragen, wie diese Umgebungsvariablen bash
importiert wurden .
Was wäre, wenn die Variablen LC_foo;echo test; f()
zum Beispiel aufgerufen würden ? Also habe ich beschlossen, genauer hinzuschauen.
EIN:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
offenbarte, dass meine Erinnerung darin falsch war, dass die Variablen nicht aufgerufen wurden, myfunction()
aber myfunction
(und es ist der
Wert , der mit beginnt ()
).
Und ein kurzer Test:
$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for `true;echo test; f'
bestätigte meinen Verdacht, dass der Variablenname nicht bereinigt wurde und der Code beim Start ausgewertet wurde .
Schlimmer noch, der Wert wurde auch nicht bereinigt:
$ env 'foo=() { :;}; echo test' bash -c :
test
Das bedeutet, dass jede Umgebungsvariable ein Vektor sein kann.
Dann erkannte ich das Ausmaß des Problems, bestätigte, dass es auch über HTTP ( HTTP_xxx
/ QUERYSTRING
... env vars) ausnutzbar war, und berichtete (sorgfältig) über andere Probleme wie Mail-Verarbeitungsdienste, späteres DHCP (und wahrscheinlich eine lange Liste). .