Ist das Verhalten hinter der Shellshock-Schwachstelle in Bash dokumentiert oder überhaupt gewollt?
Eine aktuelle Sicherheitslücke, CVE-2014-6271, wie Bash interpretiert Umgebungsvariablen bekannt war. Der exploit beruht auf der Bash Parsen einige environment-Variablen-Deklarationen, wie Funktionsdefinitionen, aber dann weiterhin das ausführen von code nach der definition:
$ x='() { echo i do nothing; }; echo vulnerable' bash -c ':'
vulnerable
Aber ich verstehe es nicht. Es gibt nichts, was ich in der Lage gewesen, zu finden in der Bash-Dokumentation über die Interpretation von environment-Variablen als Funktionen überhaupt (außer für Erben-Funktionen, das ist unterschiedlich). In der Tat, eine ordnungsgemäße benannte definition einer Funktion wird nur behandelt wie ein Wert:
$ x='y() { :; }' bash -c 'echo $x'
y() { :; }
Aber eine korrupte man druckt nichts:
$ x='() { :; }' bash -c 'echo $x'
$ # Nothing but newline
Den korrupten Funktion ist Unbenannt, und so kann ich nicht nur es nennen. Steht diese Sicherheitsanfälligkeit in einem reinen Umsetzung bug, oder ist es eine beabsichtigte Funktion hier, dass ich einfach nicht sehen kann?
Update
Pro Barmar Kommentar, habe ich die Hypothese aufgestellt der name der Funktion wurde der parameter name:
$ n='() { echo wat; }' bash -c 'n'
wat
Konnte ich schwöre, ich versuchte vor, aber ich denke, dass ich nicht hart genug versuchen. Es ist wiederholbar jetzt. Hier ist ein wenig mehr testen:
$ env n='() { echo wat; }; echo vuln' bash -c 'n'
vuln
wat
$ env n='() { echo wat; }; echo $1' bash -c 'n 2' 3 -- 4
wat
...also scheinbar die Argumente sind nicht festgelegt auf die Zeit der exploit ausgeführt wird.
Trotzdem, die grundsätzliche Antwort auf meine Frage ist, ja, das ist wie Bash implementiert geerbt Funktionen.
- Wie denken Sie Erben funktioniert in den ersten Platz? Die einzige Art der Vererbung zwischen Prozessen ist die Umwelt. So exportierten Funktionen müssen codiert sein, die in der Umgebung irgendwie.
- der Beispiel-code in den link, den Sie enthalten, beginnt mit
env
wie inenv x='...
. Nicht sicher, wie das einen Unterschied macht, entweder. FYIksh
emittiert keine Ergebnisse dieser tests nach dem ändern von Referenzen ausbash -c
zuksh -c
. - Das dauerte bash 4.3.25-1 geschlossen wird die Ausführung des Befehls nach der seltsamen definition einer Funktion, aber die Funktion ist noch erhalten, definiert...
- Es gibt eine neue Sicherheitslücke kommen unten das Rohr als auch access.redhat.com/security/cve/CVE-2014-7169
- Definition einer Funktion auf diese Weise ist eine beabsichtigte Funktion; der bug ist mit dem extra-code nach der definition einer Funktion wird ausgeführt.
- Zu get this straight, können wir immer noch dieses:
export ls='(){ /bin/ls $@; echo "Caught you";}'
? - Fast. Die Zeichenfolge beginnen muss explizit mit
() {
(beachten Sie das Leerzeichen). Ansonsten, ja,bash
drehen, die in eine Funktion namensls
wenn er sieht, dass Strings in seiner Umgebung auf Start. Die schließende geschweifte Klammer, es stellt sich heraus, ist etwas optional. - in meiner Verteidigung, ich konnte ja nicht wissen, was Erben bedeutet. Bedenken Sie, dass Sie setzen x=3 und es in einer subshell:
$(echo $x)
, aber das ist etwas anders vom Exportx
. Bis dieser bug zum Vorschein kam, wusste ich nicht einmal, Sie könnten export-Funktionen. - Siehe Was bedeutet env x='() { :;}; Befehl' bash zu tun und warum ist es unsicher?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das scheint eine Umsetzung bug.
Anscheinend, die Art und Weise exportierten Funktionen arbeiten in
bash
ist, dass Sie speziell formatierte Umgebungsvariablen. Wenn Sie eine Funktion exportieren:es definiert eine Umgebungsvariable wie:
Was wahrscheinlich geschieht, ist, dass, wenn die neue shell sieht eine Umgebungsvariable, deren Wert beginnt mit
()
es stellt den Namen der Variablen und führt die resultierende Zeichenkette. Der bug ist, dass diese Ausführung etwas nach die definition der Funktion als gut.Beschriebene Korrektur ist offenbar zu analysieren, das Ergebnis zu sehen, wenn Sie eine gültige Funktionsdefinition. Wenn nicht, druckt es die Warnung über das ungültige Funktion definition versuchen.
Dieser Artikel bestätigt meine Erklärung für die Ursache des Fehlers. Es geht auch ein bisschen mehr ins detail darüber, wie das Update behebt es: nicht nur, dass Sie analysieren die Werte genauer an, aber die Variablen, die verwendet werden, um pass exportierten Funktionen einer bestimmten Namenskonvention. Diese Namenskonvention unterscheidet sich von verwendet, die für die Umgebungsvariablen erstellt für CGI-Skripte, so dass ein HTTP-client sollte nie in der Lage, um den Fuß in dieser Tür.
Folgende:
Drucke
scheint, als Bash, nachdem er analysiert die
x=...
entdeckt, das es da eine Funktion, mit der Sie ausgeführt hat, sah derdeclare -fx x
und erlaubt die Ausführung des Befehls nach der Erklärung.echo vulnerable
Drucke:
und ausführen der
x
Drucke
segfaults - unendliche rekursive Aufrufe
Es nicht überschreibt, die bereits definierte Funktion
Drucke:
z.B. die x -, bleibt die bisher (korrekt) definierte Funktion.
Für die Bash
4.3.25(1)-release
die Sicherheitslücke geschlossen ist, soDrucke
aber - was ist seltsam (zumindest für mich)
TROTZDEM GEDRUCKT
und die
speicherzugriffsverletzungen zu, so dass es NOCH akzeptieren das seltsame definition einer Funktion...
x
nicht überschrieben wird, sieht tatsächlich aus wie ein bug als gut. Ich würde erwarten, dass der Befehl environment override Vorrang; es ist, zumindest für "normale" Umgebungsvariablen". Betrachtendeclare -x foo=5; bash -c 'echo $foo'; foo=9 bash -c 'echo $foo'
. Die ersten Ausgänge 5; die zweiten Ausgänge 9.x
ist die definition einer Funktion und nichts mehr, so dass es exportiert wird.bash
erbt ein solcher Wert wird "instanziieren" es als ausführbare Funktion. Das ist, mitexport foo='() { echo 5; }'
,foo
bleibt eine normale string-parameter in der aktuellen shell, sondern ein Kindbash
wird es eine Funktion (echo $foo
würde nichts drucken, zum Beispiel, weil es keinen parameter mit dem Namenfoo
im Kind, nur eine Funktion).bash
Tat: es bewertet die Zeichenfolge in der Umgebung, deren prefix war eine gültige definition einer Funktion, die ohne Rücksicht auf was auch immer nachfolgende code ausgewertet wurde zusammen mit ihm.Ich denke, es lohnt ein Blick auf das Bash-code selbst. Der patch gibt ein wenig Einsicht in das problem. Insbesondere
Beim Bash exportiert eine Funktion, zeigt es sich als eine Umgebungsvariable, zum Beispiel:
Wenn Sie einen neuen Bash-Prozess findet eine Funktion definiert auf diese Weise in seine Umgebung, es evalutes den code in die variable mit
parse_and_execute()
. Für normale, nicht-bösartigen code ausführen es definiert lediglich die Funktion in der Bash und bewegt sich auf. Jedoch, weil es an eine generische Ausführung-Funktion der Bash wird korrekt Parsen und ausführen zusätzlichen code definiert, dass die variable nach der definition der Funktion.Können Sie sehen, dass in den neuen code ein flag namens
SEVAL_ONECMD
Hinzugefügt wurde erzählt, dass Bash nur bewerten, der erste Befehl (das heißt, die definition der Funktion) undSEVAL_FUNCDEF
nur functio0n Definitionen.In Bezug auf Ihre Frage über die Dokumentation, bemerkt, dass hier in der commandline Dokumentation für die
env
Befehl, dass eine Untersuchung der syntax zeigt, dassenv
funktioniert wie beschrieben.-i
(für die Abwärtskompatibilität nehme ich an)