Non è necessario utilizzare bash esplicitamente perché questo sia un problema. Il vero problema è consentire agli aggressori di avere voce in capitolo nel valore delle variabili d'ambiente. Dopo che l'ambiente è stato impostato, è solo questione di tempo prima che una shell venga eseguita (forse sconosciuta) con un ambiente per il quale non è stata preparata.
Ogni programma (bash, java, tcl, php, ...) ha questa firma:
int main (int argc, char ** argv, char ** arge);
Gli sviluppatori hanno l'abitudine di controllare la pulizia di argc e argv. La maggior parte ignorerà arge e non farà alcun tentativo di convalidarlo prima di generare subshell (esplicitamente o implicitamente). E in questo caso bash non si difende correttamente da input errati. Per collegare un'applicazione insieme, vengono generati sottoprocessi. In fondo, succede qualcosa del genere:
// Abbiamo codificato il binario e ripulito l'arg, quindi supponiamo che // non ci possa essere alcun input dannoso, ma l'ambiente corrente viene passato // in modo implicito.execl ("/ bin / bash", "bash", "-c", "/ opt / initTech / bin / dataScrape", cleanArg, NULL);
Nel tuo codice, potrebbero non esserci riferimenti a bash. Ma forse avvii tcl e qualcosa nel profondo del codice tcl lancia bash per te. Erediterà le variabili d'ambiente attualmente impostate.
Nel caso della versione vulnerabile di bash, sta accadendo qualcosa del genere:
int main (int argc, char ** argv, char ** arge) {// funzione principale di bash .... parseEnvironment (arge); // !!!! legge le definizioni delle funzioni e var definisce .... doArgv (argc, argv); ....}
Dove parseEnvironment vede un mucchio di definizioni di variabili d'ambiente che non necessariamente riconosce nemmeno. Ma supporrà che alcune di queste variabili d'ambiente siano definizioni di funzioni:
INITTECH_HOME = / opt / initTechHTTP_COOKIE = () {:; }; / usr / bin / eject
Bash non ha idea di cosa sia un HTTP_COOKIE. Ma inizia con (), quindi bash suppone che questa sia una definizione di funzione. Inoltre, consente utilmente di aggiungere del codice eseguito immediatamente dopo la definizione della funzione, perché forse è necessario inizializzare alcuni effetti collaterali con la definizione della funzione. La patch rimuove la possibilità di aggiungere effetti collaterali dopo la definizione della funzione.
Ma l'idea che una variabile d'ambiente possa rimanere inattiva con la definizione della funzione fornita dall'attaccante è ancora altamente inquietante!
recieve = '() {echo, intendevi ricevere lol; } '
Se l'attaccante può far sì che questo nome di variabile ottenga un valore fornito, e sa anche che può attendere che un sottoprocesso bash tenti di invocare una funzione con quel nome, allora questo sarebbe un altro vettore di attacco.
Questo è solo il vecchio ammonimento a convalidare i tuoi input . Poiché le shell possono essere generate come un dettaglio di implementazione sorprendente, mai impostare una variabile di ambiente su un valore che non sia strettamente convalidato. Ciò significa che qualsiasi possibile programma che legge questa variabile d'ambiente non farà qualcosa di inaspettato con il valore; come eseguirlo come codice.
Oggi è bash. Domani è java, sh, tcl o node. Tutti prendono un puntatore all'ambiente nella loro funzione principale; e tutti hanno limitazioni diverse su ciò che gestiranno in sicurezza (fino a quando non saranno patchati).