Apparentemente esiste una vulnerabilità (CVE-2014-6271) in bash:attacco di iniezione di codice con variabili di ambiente appositamente predisposto da Bash
Sto cercando di capire cosa sta succedendo, ma non sono del tutto sicuro di averlo capito. Come può l'echo
essere eseguito come è tra virgolette singole?
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test
MODIFICA 1 :Un sistema con patch si presenta così:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test
MODIFICA 2 :Esiste una vulnerabilità/patch correlata:CVE-2014-7169 che utilizza un test leggermente diverso:
$ env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"
output senza patch :
vulnerable
bash: BASH_FUNC_x(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_x(): line 0: `BASH_FUNC_x() () { :;}; echo vulnerable'
bash: error importing function definition for `BASH_FUNC_x'
test
output con patch parziale (versione precedente) :
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
bash: error importing function definition for `BASH_FUNC_x()'
test
output con patch fino a CVE-2014-7169 compreso:
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `BASH_FUNC_x'
test
MODIFICA 3 :la storia continua con:
- CVE-2014-7186
- CVE-2014-7187
- CVE-2014-6277
Risposta accettata:
bash memorizza le definizioni delle funzioni esportate come variabili di ambiente. Le funzioni esportate hanno il seguente aspetto:
$ foo() { bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { bar
}
Cioè, la variabile d'ambiente foo
ha il contenuto letterale:
() { bar
}
Quando una nuova istanza di bash viene avviata, cerca queste variabili di ambiente appositamente predisposte e le interpreta come definizioni di funzione. Puoi persino scriverne uno tu stesso e vedere che funziona ancora:
$ export foo='() { echo "Inside function"; }'
$ bash -c 'foo'
Inside function
Sfortunatamente, l'analisi delle definizioni delle funzioni dalle stringhe (le variabili di ambiente) può avere effetti più ampi del previsto. Nelle versioni senza patch, interpreta anche comandi arbitrari che si verificano dopo la fine della definizione della funzione. Ciò è dovuto a vincoli insufficienti nella determinazione di stringhe simili a funzioni accettabili nell'ambiente. Ad esempio:
$ export foo='() { echo "Inside function" ; }; echo "Executed echo"'
$ bash -c 'foo'
Executed echo
Inside function
Si noti che l'eco al di fuori della definizione della funzione è stata eseguita in modo imprevisto durante l'avvio di bash. La definizione della funzione è solo un passaggio per ottenere la valutazione e l'exploit, la definizione della funzione stessa e la variabile d'ambiente utilizzata sono arbitrarie. La shell esamina le variabili d'ambiente, vede foo
, che sembra soddisfare i vincoli che conosce sull'aspetto di una definizione di funzione e valuta la linea, eseguendo involontariamente anche l'eco (che potrebbe essere qualsiasi comando, dannoso o meno).
Questo è considerato non sicuro perché in genere non è consentito o previsto che le variabili causino direttamente l'invocazione di codice arbitrario in esse contenuto. Forse il tuo programma imposta le variabili di ambiente dall'input dell'utente non attendibile. Sarebbe del tutto inaspettato che tali variabili di ambiente potessero essere manipolate in modo tale che l'utente possa eseguire comandi arbitrari senza la tua intenzione esplicita di farlo utilizzando quella variabile di ambiente per tale motivo dichiarato nel codice.
Ecco un esempio di attacco praticabile. Esegui un server web che esegue una shell vulnerabile, da qualche parte, come parte della sua vita. Questo server Web passa le variabili di ambiente a uno script bash, ad esempio, se si utilizza CGI, le informazioni sulla richiesta HTTP sono spesso incluse come variabili di ambiente dal server Web. Ad esempio, HTTP_USER_AGENT
potrebbe essere impostato sul contenuto del tuo programma utente. Ciò significa che se falsifichi il tuo user agent in modo che sia qualcosa del tipo '() { :; }; echo foo', quando viene eseguito lo script della shell, echo foo
sarà eseguito. Di nuovo, echo foo
potrebbe essere qualsiasi cosa, dannosa o meno.