Non è necessario utilizzare bash esplicitamente perché questo sia un problema. Il vero problema è consentire agli aggressori di avere voce in capitolo sul valore delle variabili di ambiente. Dopo aver impostato l'ambiente, è solo questione di tempo prima che qualche shell venga eseguita (forse sconosciuta) con un ambiente per il quale non è stato preparato.
Ogni programma (bash, java, tcl, php, ...) ha questa firma:
int main(int argc, char** argv, char** arge);
Gli sviluppatori hanno l'abitudine di controllare argc e argv per la pulizia. La maggior parte ignorerà l'arge e non tenterà di convalidarlo prima di generare subshell (esplicitamente o implicitamente). E in questo caso bash non si difende correttamente da input sbagliati. Per collegare un'applicazione, i processi secondari vengono generati. In fondo, succede qualcosa di simile:
//We hardcoded the binary, and cleaned the arg, so we assume that
//there can be no malicious input - but the current environment is passed
//in implicitly.
execl("/bin/bash", "bash", "-c", "/opt/initTech/bin/dataScrape", cleanedArg, NULL);
Nel tuo codice, potrebbero non esserci riferimenti a bash. Ma forse lanciate tcl, e qualcosa di profondo nel codice tcl lancia la bash per voi. Avrebbe ereditato le variabili di ambiente che sono attualmente impostate.
Nel caso della versione vulnerabile di bash, qualcosa di simile sta succedendo:
int main(int argc, char** argv, char** arge) { //bash's main function
....
parseEnvironment(arge); //!!!! read function definitions and var defines
....
doArgv(argc, argv);
....
}
Dove parseEnvironment vede una serie di definizioni di variabili d'ambiente che non necessariamente nemmeno riconosce. Ma indovina che alcune di queste variabili d'ambiente sono definizioni di funzioni:
INITTECH_HOME=/opt/initTech
HTTP_COOKIE=() { :; }; /usr/bin/eject
Bash non ha idea di cosa sia un HTTP_COOKIE. Ma inizia con (), quindi bash indovina che questa è una definizione di funzione. Ti aiuta anche ad aggiungere del codice immediatamente eseguito dopo la definizione della funzione, perché forse hai bisogno di inizializzare alcuni effetti collaterali con la definizione della funzione. La patch rimuove la capacità di aggiungere effetti collaterali dopo la definizione della funzione.
Ma l'idea che una variabile d'ambiente possa rimanere addormentata con la definizione della funzione fornita da un attaccante è ancora molto inquietante!
recieve='() { echo you meant receive lol; }'
Se l'autore dell'attacco può far sì che questo nome di variabile ottenga un valore fornito, e sa anche che può aspettare che un processo di bash provi a richiamare una funzione con quel nome, allora questo sarebbe un altro vettore di attacco.
Questa è solo la vecchia ammonizione di convalidare i tuoi input . Poiché le shell possono essere generate come un sorprendente dettaglio di implementazione, mai imposta una variabile di ambiente su un valore che non è strettamente validato. Ciò significa che qualsiasi programma possibile 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 ambientale nella loro funzione principale; e hanno tutti diverse limitazioni su ciò che gestiranno in modo sicuro (fino a quando non saranno riparati).