TL; DR
La vulnerabilità di shellshock è stata completamente risolta in
- Sul ramo bash-2.05b: 2.05b.10 e versioni successive (patch 10 inclusa)
- Sul ramo bash-3.0: 3.0.19 e versioni successive (patch 19 inclusa)
- Sul ramo bash-3.1: 3.1.20 e versioni successive (patch 20 inclusa)
- Sul ramo bash-3.2: 3.2.54 e versioni successive (patch 54 inclusa)
- Sul ramo bash-4.0: 4.0.41 e versioni successive (patch 41 inclusa)
- Sul ramo bash-4.1: 4.1.14 e versioni successive (patch 14 inclusa)
- Sul ramo bash-4.2: 4.2.50 e successivi (patch 50 inclusa)
- Sul ramo bash-4.3: 4.3.27 e versioni successive (patch 27 inclusa)
Se il tuo bash mostra una versione precedente, il tuo fornitore del sistema operativo potrebbe averlo ancora patchato da solo, quindi è meglio controllare.
Se:
env xx='() { echo vulnerable; }' bash -c xx
mostra "vulnerabile", sei ancora vulnerabile. Questo è l'unico test rilevante (se il parser bash è ancora esposto al codice in qualsiasi variabile d'ambiente).
Dettagli.
Il bug è stato nell'implementazione iniziale della funzione di esportazione / importazione introdotto sui 5 ° di agosto 1989 di Brian Fox, e in primo luogo liberato in bash-1.03 circa un mese più tardi in un momento in cui bash non era in tale uso diffuso, prima della sicurezza era così preoccupante e esisteva anche HTTP e il web o Linux.
Dal 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.
Alcune discussioni in gnu.bash.bug e comp.unix.questions in quel periodo menzionano anche la funzione.
È facile capire come ci sia arrivato.
bash esporta le funzioni in vari modi come
foo=() {
code
}
E all'importazione, tutto ciò che deve fare è interpretare ciò con il =
sostituito con uno spazio ... tranne che non dovrebbe interpretarlo ciecamente.
È anche rotto in questo bash
(contrariamente alla shell Bourne), le variabili e le funzioni scalari hanno uno spazio dei nomi diverso. In realtà se lo hai
foo() { echo bar; }; export -f foo
export foo=bar
bash
li inserirà felicemente nell'ambiente (sì voci con lo stesso nome di variabile) ma molti strumenti (incluse molte shell) non li propagheranno.
Si potrebbe anche sostenere che bash dovrebbe usare un BASH_
prefisso dello spazio dei nomi per questo dato che è solo rilevante da bash a bash. rc
utilizza un fn_
prefisso per una funzione simile.
Un modo migliore per implementarlo sarebbe stato quello di mettere la definizione di tutte le variabili esportate in una variabile come:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Ciò dovrebbe ancora essere disinfettato ma almeno non potrebbe essere più sfruttabile di $BASH_ENV
o $SHELLOPTS
...
C'è una patch che impedisce bash
di interpretare nient'altro che la definizione della funzione ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), ed è quella che ha stato applicato in tutti gli aggiornamenti di sicurezza delle varie distribuzioni Linux.
Tuttavia, bash interpreta ancora il codice presente e qualsiasi bug nell'interprete potrebbe essere sfruttato. Uno di questi bug è già stato trovato (CVE-2014-7169) sebbene il suo impatto sia molto più piccolo. Quindi presto arriverà un'altra patch.
Fino a quando una correzione avanzata che impedisce a bash di interpretare il codice in qualsiasi variabile (come usando l' BASH_FUNCDEFS
approccio sopra), non sapremo con certezza se non siamo vulnerabili a un bug nel parser bash. E credo che prima o poi uscirà una soluzione di questo tipo.
Modifica 28/09/2014
Sono stati trovati altri due bug nel parser (CVE-2014-718 {6,7}) (si noti che la maggior parte delle shell ha dei bug nel proprio parser per casi angolari, che non sarebbe stato un problema se quel parser non avesse non sono stati esposti a dati non attendibili).
Mentre tutti e 3 i bug 7169, 7186 e 7187 sono stati corretti nelle seguenti patch, Red Hat ha spinto per la correzione. Nella loro patch, hanno cambiato il comportamento in modo che le funzioni fossero esportate in variabili chiamate BASH_FUNC_myfunc()
più o meno anticipando la decisione di progettazione di Chet.
Chet ha successivamente pubblicato quella correzione come patch bash ufficiale per upstream .
Quella patch indurente o varianti di essa sono ora disponibili per la maggior parte delle principali distribuzioni Linux e alla fine sono arrivate su Apple OS / X.
Ciò ora attesta la preoccupazione per qualsiasi ambiente arbitrario che sfrutta il parser tramite quel vettore, incluse altre due vulnerabilità nel parser (CVE-2014-627 {7,8}) che sono state rivelate in seguito da Michał Zalewski (CVE-2014-6278 essendo quasi male come CVE-2014-6271) per fortuna dopo che molte persone avevano avuto il tempo di installare la patch di indurimento
Anche i bug nel parser verranno corretti, ma non rappresentano più un problema tanto che il parser non è più facilmente esposto a input non attendibili.
Si noti che mentre la vulnerabilità di sicurezza è stata risolta, è probabile che vedremo alcune modifiche in tale area. La correzione iniziale per CVE-2014-6271 ha interrotto la compatibilità all'indietro in quanto interrompe l'importazione delle funzioni con .
o :
o /
nel loro nome. Questi possono ancora essere dichiarati da bash, sebbene ciò comporti un comportamento incoerente. Poiché le funzioni con .
e :
nel loro nome sono comunemente utilizzate, è probabile che una patch ripristini accettando almeno quelle dall'ambiente.
Perché non è stato trovato prima?
Questo è anche qualcosa che mi chiedevo. Posso offrire alcune spiegazioni.
In primo luogo, penso che se un ricercatore di sicurezza (e io non sono un ricercatore di sicurezza professionale) fosse stato specificamente alla ricerca di vulnerabilità in Bash, probabilmente lo avrebbero trovato.
Ad esempio, se fossi un ricercatore di sicurezza, i miei approcci potrebbero essere:
- Guarda da dove
bash
viene ricevuto l'input e cosa ne fa. E l'ambiente è ovvio.
- Cerca in quali luoghi
bash
viene richiamato l' interprete e su quali dati. Ancora una volta, si distinguerebbe.
- L'importazione delle funzioni esportate è una delle funzionalità che è disabilitata quando
bash
è setuid / setgid, il che lo rende un luogo ancora più ovvio in cui cercare.
Ora, sospetto che nessuno pensasse di considerare bash
(l'interprete) come una minaccia, o che la minaccia avrebbe potuto arrivare in quel modo.
L' bash
interprete non intende elaborare input non attendibili.
Gli script di shell (non l'interprete) sono spesso esaminati da vicino dal punto di vista della sicurezza. La sintassi della shell è così imbarazzante e ci sono così tanti avvertimenti con la scrittura di script affidabili (mai visto me o altri che menzionano l'operatore split + glob o perché dovresti citare le variabili per esempio?) Che è abbastanza comune trovare vulnerabilità di sicurezza negli script che elaborano dati non attendibili.
Ecco perché spesso senti che non dovresti scrivere script shell CGI, o gli script setuid sono disabilitati sulla maggior parte degli Unices. O che dovresti stare molto attento quando elabori i file in directory scrivibili in tutto il mondo (vedi CVE-2011-0441 per esempio).
L'attenzione si concentra su questo, gli script di shell, non l'interprete.
È possibile esporre un interprete di shell a dati non attendibili (alimentando dati esterni come codice di shell da interpretare) tramite eval
o .
o chiamandolo su file forniti dall'utente, ma non è necessaria una vulnerabilità bash
per sfruttarlo. È abbastanza ovvio che se si stanno trasmettendo dati non autorizzati per l'interpretazione di una shell, li interpreterà.
Quindi la shell viene chiamata in contesti affidabili. Sono dati script fissi da interpretare e il più delle volte (perché è così difficile scrivere script affidabili) dati fissi da elaborare.
Ad esempio, in un contesto Web, una shell potrebbe essere invocata in qualcosa del tipo:
popen("sendmail -oi -t", "w");
Cosa può andare storto? Se è previsto qualcosa di sbagliato, si tratta dei dati inviati a quel sendmail, non del modo in cui viene analizzata quella riga di comando della shell stessa o di quali dati extra vengono inviati a quella shell. Non c'è motivo per cui si desideri prendere in considerazione le variabili di ambiente che vengono passate a quella shell. E se lo fai, ti rendi conto che è tutto env vars il cui nome inizia con "HTTP_" o sono noti come CGI env vars SERVER_PROTOCOL
o QUERYSTRING
nessuno dei quali la shell o sendmail hanno a che fare con.
In contesti di elevazione dei privilegi come quando si esegue setuid / setgid o via sudo, l'ambiente è generalmente considerato e ci sono state molte vulnerabilità in passato, di nuovo non contro la shell stessa ma contro le cose che elevano i privilegi come sudo
(vedi ad esempio CVE -2011-3628 ).
Ad esempio, bash
non si fida dell'ambiente quando setuid o viene chiamato da un comando setuid (pensate mount
ad esempio che invoca gli helper). In particolare, ignora le funzioni esportate.
sudo
fa pulire l'ambiente: tutto di default ad eccezione di una lista bianca, e se configurato non farlo, almeno liste nere alcuni che sono noti per influenzare una conchiglia o di un altro (come PS4
, BASH_ENV
, SHELLOPTS
...). Inoltre inserisce nella blacklist le variabili di ambiente il cui contenuto inizia ()
(motivo per cui CVE-2014-6271 non consente l'escalation dei privilegi tramite sudo
).
Ma ancora una volta, questo è per contesti in cui l'ambiente non può essere considerato attendibile: qualsiasi variabile con qualsiasi nome e valore può essere impostata da un utente malintenzionato in quel contesto. Ciò non si applica ai server Web / SSH o a tutti i vettori che sfruttano CVE-2014-6271 in cui l'ambiente è controllato (almeno il nome delle variabili di ambiente è controllato ...)
È importante bloccare una variabile come echo="() { evil; }"
, ma no HTTP_FOO="() { evil; }"
, perché HTTP_FOO
non verrà chiamata come comando da nessuno script di shell o riga di comando. E apache2 non ha mai intenzione di impostare una echo
o BASH_ENV
variabile.
È abbastanza ovvio che alcune variabili di ambiente dovrebbero essere inserite nella lista nera in alcuni contesti in base al loro nome , ma nessuno ha pensato che avrebbero dovuto essere nella lista nera in base al loro contenuto (tranne che per sudo
). O in altre parole, nessuno pensava che un ambiente arbitrario potesse essere un vettore per l'iniezione di codice.
Per quanto riguarda se i test approfonditi al momento dell'aggiunta della funzionalità avrebbero potuto colpirla, direi che è improbabile.
Quando si verifica la funzionalità , si verifica la funzionalità. La funzionalità funziona bene. Se esporti la funzione in una bash
chiamata, viene importata bene in un'altra. Un test molto approfondito potrebbe aver individuato problemi quando vengono esportate sia una variabile che una funzione con lo stesso nome o quando la funzione viene importata in una locale diversa da quella in cui è stata esportata.
Ma per essere in grado di individuare la vulnerabilità, non è un test di funzionalità che avresti dovuto fare. L'aspetto della sicurezza avrebbe dovuto essere l'obiettivo principale e non si sarebbe testare la funzionalità, ma il meccanismo e il modo in cui potrebbe essere abusato.
Non è qualcosa che gli sviluppatori (specialmente nel 1989) hanno spesso in mente, e uno sviluppatore di shell potrebbe essere scusato nel ritenere improbabile che il suo software sia sfruttabile in rete.