GNU/Linux >> Linux Esercitazione >  >> Linux

Quando è stato introdotto il bug Shellshock (cve-2014-6271/7169) e qual è la patch che lo risolve completamente?

Un po' di contesto sul bug:CVE-2014-6271

Bash supporta l'esportazione non solo di variabili di shell, ma anche di funzioni di shell
in altre istanze di bash, tramite l'ambiente di processo in processi figlio
(indiretti). Le attuali versioni di bash utilizzano una variabile di ambiente
denominata dal nome della funzione e una definizione di funzione
che inizia con "() {" nel valore della variabile per propagare le definizioni di funzione
nell'ambiente. La vulnerabilità si verifica perché
bash non si interrompe dopo l'elaborazione della definizione della funzione; it
continua ad analizzare ed eseguire i comandi della shell seguendo la definizione della funzione
. Ad esempio, un'impostazione di una variabile di ambiente di

  VAR=() { ignored; }; /bin/id

eseguirà /bin/id quando l'ambiente viene importato nel processo bash
.

Fonte:http://seclists.org/oss-sec/2014/q3/650

Quando è stato introdotto il bug e qual è la patch che lo risolve completamente? (Vedi CVE-2014-7169)

Quali sono le versioni vulnerabili oltre a quelle indicate nel CVE (inizialmente) (3.{0..2} e 4.{0..3})?

Il codice sorgente difettoso è stato riutilizzato in altri progetti?

Sono necessarie ulteriori informazioni.

Correlati:cosa significa env x='() { :;}; command' bash do e perché non è sicuro?

Risposta accettata:

TL;DR

La vulnerabilità shellshock è stata completamente risolta in

  • Nel ramo bash-2.05b:2.05b.10 e versioni successive (patch 10 inclusa)
  • Nel ramo bash-3.0:3.0.19 e versioni successive (patch 19 inclusa)
  • Nel ramo bash-3.1:3.1.20 e versioni successive (patch 20 inclusa)
  • Nel ramo bash-3.2:3.2.54 e versioni successive (patch 54 inclusa)
  • Nel ramo bash-4.0:4.0.41 e versioni successive (patch 41 inclusa)
  • Nel ramo bash-4.1:4.1.14 e versioni successive (patch 14 inclusa)
  • Nel ramo bash-4.2:4.2.50 e versioni successive (patch 50 inclusa)
  • Nel ramo bash-4.3:4.3.27 e versioni successive (patch 27 inclusa)

Se il tuo bash mostra una versione precedente, il fornitore del tuo sistema operativo potrebbe averlo ancora corretto 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 di ambiente).

Dettagli.

Il bug era nell'implementazione iniziale della funzione di esportazione/importazione introdotta il 5 agosto 1989 da Brian Fox, e rilasciata per la prima volta in bash-1.03 circa un mese dopo, in un momento in cui bash non era così diffuso, prima che la sicurezza fosse una tale preoccupazione ed esistevano persino 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.

Anche alcune discussioni in gnu.bash.bug e comp.unix.questions in quel periodo menzionano la funzione.

È facile capire come ci sia arrivato.

bash esporta le funzioni in env vars come

foo=() {
  code
}

E durante l'importazione, tutto ciò che deve fare è interpretarlo con = sostituito con uno spazio... solo che non dovrebbe interpretarlo ciecamente.

È anche rotto in bash (contrariamente alla shell Bourne), le variabili e le funzioni scalari hanno uno spazio dei nomi diverso. In realtà se hai

foo() { echo bar; }; export -f foo
export foo=bar

bash inserirà felicemente entrambi 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 quello poiché è env vars rilevante solo da bash a bash. rc usa un fn_ prefisso per una funzione simile.

Un modo migliore per implementarlo sarebbe stato inserire la definizione di tutte le variabili esportate in una variabile come:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

Dovrebbe ancora essere disinfettato, ma almeno non potrebbe essere più sfruttabile di $BASH_ENV o $SHELLOPTS

C'è una patch che impedisce bash dall'interpretare nient'altro che la definizione della funzione lì (https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html), ed è quella che è stata applicata in tutta la sicurezza aggiornamenti dalle varie distribuzioni Linux.

Tuttavia, bash interpreta ancora il codice e qualsiasi bug nell'interprete potrebbe essere sfruttato. Uno di questi bug è già stato trovato (CVE-2014-7169) anche se il suo impatto è molto minore. Quindi presto ci sarà un'altra patch.

Fino a una correzione rafforzata che impedisce a bash di interpretare il codice in qualsiasi variabile (come l'utilizzo di BASH_FUNCDEFS approccio sopra), non sapremo con certezza se non siamo vulnerabili a causa di un bug nel parser bash. E credo che prima o poi verrà rilasciata una tale correzione per l'indurimento.

Correlati:come trovare i file con un determinato sottopercorso?

Modifica 28-09-2014

Sono stati trovati due bug aggiuntivi nel parser (CVE-2014-718{6,7}) (nota che la maggior parte delle shell è destinata ad avere bug nel parser per i casi d'angolo, questo non sarebbe stato un problema se quel parser avesse non è stato esposto a dati non attendibili).

Mentre tutti e 3 i bug 7169, 7186 e 7187 sono stati corretti nelle patch successive, Red Hat ha spinto per la correzione del rafforzamento. 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 progettuale di Chet.

Chet ha successivamente pubblicato quella correzione come patch bash upstream ufficiale.

Quella patch di rafforzamento, o le sue varianti, sono ora disponibili per la maggior parte delle principali distribuzioni Linux e alla fine sono arrivate ad Apple OS/X.

Ciò ora elimina la preoccupazione per qualsiasi env var arbitrario che sfrutti il ​​parser tramite quel vettore, comprese altre due vulnerabilità nel parser (CVE-2014-627{7,8}) che sono state divulgate in seguito da Michał Zalewski (CVE-2014-6278 quasi pessimo come CVE-2014-6271) fortunatamente dopo che la maggior parte delle persone ha avuto il tempo di installare la patch di rafforzamento

Anche i bug nel parser verranno risolti, ma non sono più un grosso problema ora che il parser non è più così facilmente esposto a input non attendibili.

Tieni presente che mentre la vulnerabilità della sicurezza è stata corretta, è probabile che vedremo alcuni cambiamenti in quell'area. La correzione iniziale per CVE-2014-6271 ha interrotto la compatibilità con le versioni precedenti in quanto interrompe l'importazione di funzioni con . o : o / a loro nome. Questi possono ancora essere dichiarati da bash, il che rende il comportamento incoerente. Perché funziona con . e : nel loro nome sono comunemente usati, è probabile che una patch si ripristinerà accettando almeno quelli dall'ambiente.

Perché non è stato trovato prima?

È anche qualcosa che mi chiedevo. Posso offrire alcune spiegazioni.

Innanzitutto, penso che se un ricercatore di sicurezza (e io non sono un ricercatore di sicurezza professionista) avesse cercato specificamente delle vulnerabilità in bash, probabilmente l'avrebbero trovato.

Ad esempio, se fossi un ricercatore di sicurezza, i miei approcci potrebbero essere:

  1. Guarda dove bash riceve input da e cosa fa con esso. E l'ambiente è ovvio.
  2. Guarda in quali posizioni bash viene invocato l'interprete e su quali dati. Ancora una volta, risalterà.
  3. L'importazione di funzioni esportate è una delle funzionalità che viene disabilitata quando bash è setuid/setgid, il che lo rende un posto ancora più ovvio in cui cercare.

Ora, sospetto che nessuno abbia pensato di prendere in considerazione bash (l'interprete) come una minaccia, o che la minaccia potrebbe essere arrivata in quel modo.

Il bash interprete non è pensato per elaborare input non attendibili.

Shell script (non l'interprete) sono spesso guardati da vicino da un 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 menzionare l'operatore split+glob o perché dovresti citare le variabili, ad esempio?) che è abbastanza comune trovare vulnerabilità di sicurezza negli script che elaborano dati non attendibili.

Ecco perché spesso senti dire che non dovresti scrivere script di shell CGI o che gli script setuid sono disabilitati sulla maggior parte degli Unice. O che dovresti prestare molta attenzione durante l'elaborazione di file in directory scrivibili da tutto il mondo (vedi CVE-2011-0441 per esempio).

L'obiettivo è quello, gli script della shell, non l'interprete.

Puoi esporre un interprete di shell a dati non attendibili (alimentando dati estranei come codice shell da interpretare) tramite eval o . o chiamandolo su file forniti dall'utente, ma non hai bisogno di una vulnerabilità in bash per sfruttarlo. È abbastanza ovvio che se stai passando dati non disinfettati per l'interpretazione di una shell, li interpreterà.

Quindi la shell viene chiamata in contesti attendibili. Gli vengono forniti 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 in questo? Se si prevede qualcosa di sbagliato, si tratta dei dati inviati a quella sendmail, non di come viene analizzata la riga di comando della shell stessa o di quali dati extra vengono inviati a quella shell. Non c'è motivo per cui vorresti considerare le variabili di ambiente che vengono passate a quella shell. E se lo fai, ti rendi conto che sono tutte env vars il cui nome inizia con "HTTP_" o sono ben note env vars CGI come SERVER_PROTOCOL o QUERYSTRING nessuno dei quali shell o sendmail hanno a che fare con.

Correlati:utilizzare un transistor per illuminare "completamente" una lampada?

In contesti di elevazione dei privilegi come quando si esegue setuid/setgid o tramite sudo, l'ambiente è generalmente considerato e ci sono state molte vulnerabilità in passato, ancora non contro la shell stessa ma contro cose che elevano i privilegi come sudo (vedi ad esempio CVE-2011-3628).

Ad esempio, bash non si fida dell'ambiente quando setuid o chiamato da un comando setuid (pensa a mount per esempio che invoca gli helper). In particolare, ignora le funzioni esportate.

sudo pulisce l'ambiente:tutto per impostazione predefinita tranne una white list e, se configurato per non farlo, almeno black list alcuni che sono noti per influenzare una shell o un'altra (come PS4 , BASH_ENV , SHELLOPTS …). Inoltre inserisce nella lista nera le variabili di ambiente il cui contenuto inizia con () (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 oa 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 non HTTP_FOO="() { evil; }" , perché HTTP_FOO non verrà chiamato come comando da alcuno script di shell o riga di comando. E apache2 non imposterà mai un echo o BASH_ENV variabile.

È abbastanza ovvio alcuni le variabili di ambiente dovrebbero essere inserite nella lista nera in alcuni contesti in base al loro nome , ma nessuno pensava che dovessero essere inseriti nella lista nera in base al loro contenuto (tranne sudo ). O in altre parole, nessuno pensava che env vars arbitrario potesse essere un vettore per l'iniezione di codice.

Per quanto riguarda il fatto che test approfonditi quando è stata aggiunta la funzionalità avrebbero potuto rilevarlo, direi che è improbabile.

Quando esegui il test per la funzione , si verifica la funzionalità. La funzionalità funziona bene. Se esporti la funzione in un bash invocazione, è importato bene in un altro. Un test molto approfondito potrebbe aver individuato problemi durante l'esportazione di una variabile e di 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 avresti testato la funzionalità, ma il meccanismo e come si potrebbe abusarne.

Non è qualcosa che gli sviluppatori (soprattutto nel 1989) hanno spesso in fondo alla loro mente, e uno sviluppatore di shell potrebbe essere scusato per pensare che è improbabile che il suo software sia sfruttabile in rete.


Linux
  1. In Bash, quando alias, quando script e quando scrivere una funzione?

  2. Quando si digita "ls -a", qual è il significato di "." E ".."?

  3. Monitoraggio e correzione di un bug di installazione

  4. Qual è la differenza tra #!/usr/bin/env bash e #!/usr/bin/bash?

  5. Cosa c'è di sbagliato nel mio script bash per mantenere gli ultimi file x ed eliminare il resto?

Qual è la differenza tra Linux e Unix?

Qual è il significato di caddr_t e quando viene utilizzato?

Qual è l'uso di $# in Bash

Qual era il metodo di compressione SquashFS?

Quali sono i contenuti di /bin/bash e cosa devo fare se li ho accidentalmente sovrascritti

Qual è la differenza tra unlink e rm?