GNU Bash exportiert Shell-Funktionen in Umgebungsvariablen, die die Funktionsdefinitionen enthalten:
$ function foo { echo bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { echo bar
}
Wenn eine neue Bash-Instanz erzeugt wird, sucht sie nach Umgebungsvariablen, die einem bestimmten Muster entsprechen. Der Inhalt dieser Variablen wird automatisch als Shell-Funktionen importiert. Wie Stéphane Chazelas erklärt , erfolgte der Import von Funktionen seit Einführung dieser Funktion in Bash 1.03 einfach durch Ersetzen =des entsprechenden Eintrags im Array der Umgebungsvariablen und Interpretieren des Ergebnisses als Funktionsdefinition. Vor dem Patch , mit dem CVE-2014-6271 behoben wurde , wurde die Umgebungsvariable vollständig interpretiert, einschließlich aller Befehle, die dem eigentlichen Funktionskörper folgen. Der Patch führt zwei spezielle Modi in die parse_and_execute()Funktion ein, SEVAL_FUNCDEFundSEVAL_ONECMD. Wenn die Funktion mit aufgerufen SEVAL_FUNCDEFwird, soll sie die Interpretation anderer Befehle als Funktionsdefinitionen verhindern. Das SEVAL_ONECMDFlag soll verhindern, dass die Funktion mehr als einen einzelnen Befehl auswertet.
Die speziell gestaltete Umgebungsvariable von Tavis Ormandy macht etwas subtil anderes. Es soll den Parser verwirren und den Puffer beschädigen, der zum Speichern der auszuwertenden Befehle verwendet wird. Reste der Umgebungsvariablen im Puffer ändern die Interpretation des nachfolgenden Befehls . Dieses verwandte Problem hat die CVE-Kennung CVE-2014-7169 erhalten .
Die Bestandteile der Definition von Umgebungsvariablen X='() { (a)=>\'sind:
() { Dies wird vom Parser als Beginn einer Funktionsdefinition interpretiert
(a)= soll den Parser verwirren und dazu führen, dass Reste der Umgebungsvariablen im Puffer verbleiben
>\ ist die tatsächliche Nutzlast, die im Puffer verbleibt
Der Zweck der Nutzdaten besteht darin, die Interpretation des Befehls zu ändern, der in der von aufgerufenen Subshell ausgeführt wird sh -c "echo date";. Dies setzt natürlich voraus, dass dies /bin/sheine symbolische Verbindung zu ist bash. Wenn die als Operand für angegebene Befehlszeichenfolge -cin den Puffer gestellt wird, lautet der Inhalt des Puffers:
>\[0xA]echo date
Das [0xA]ist ein ASCII-Zeilenumbruchzeichen, das normalerweise als Befehlstrennzeichen fungiert, jetzt jedoch \von der Nutzlast entfernt wird. Infolgedessen wird der Inhalt des Puffers als interpretiert
>echo date
Da mit Bash Umleitungsoperatoren Befehle vorangestellt werden können , entspricht dies
date > echo
Dies führt einfach dazu, dass der dateBefehl ausgeführt wird und seine Standardausgabe in eine aufgerufene Datei umgeleitet wird echo. Der Rest cat echoist nicht Teil des Exploits, sondern zeigt nur, dass jetzt eine Datei namens echomit der Ausgabe von dateexistiert.
In (a)=Bezug auf den Grund, warum die Zeichenfolge den Parser in diesem Fall verwirrt, scheint es, dass die damit verbundene Zeichenfolge als (fehlerhafte) verschachtelte Funktionsdefinition angezeigt wird. Die vereinfachte Variante des Exploits zeigt dies deutlicher:
$ X='() { function a a>\' bash -c echo
$ ls echo
echo