Aggiorna bash e questo problema specifico scompare.
Ma se vuoi sapere se sei vulnerabile prima di questo, ci saranno percorsi specifici per le applicazioni da aggiungere alle vulnerabilità generiche (fino a quando bash viene corretto), quindi potrebbero esserci nuove vulnerabilità non bash scoperte successivamente con lo stesso modello).
Il problema specifico è consentire le variabili d'ambiente controllate dall'hacker . Se l'utente malintenzionato è in grado di ottenere in remoto una variabile di ambiente impostata su una definizione di funzione seguita da un comando immediato; l'attaccante potrebbe aspettare un comando totalmente non correlato per ottenere l'esecuzione di bash. Non importa quale programma bash è, o se gli argomenti sono stati validati (o hardcoded, ecc.).
In particolare, bash ha un punto di ingresso principale come qualsiasi altro programma, e ha questa firma:
int main(int argc, char** argv, char** arge); //bash's main entry point
Questa funzione principale viene invocata come dettaglio interno di richiamo di un exec. Se arge non è stato pulito in precedenza, il principale di bash farà doverosamente ciò che dovrebbe fare la shell bash. Una di queste cose sta analizzando l'ambiente.
Abbiamo tutti l'abitudine di strofinare argc e argv per la pulizia. Ma la maggior parte delle persone ignora completamente ciò che è in arge. Quindi se un socket remoto ha detto un processo per impostare una variabile di ambiente (es .: HTTP_COOOKIE) allora qualche voce di arge ha quel valore. Supponi che arge [42] abbia un valore:
HTTP_COOKIE=() { :; }; /usr/bin/eject
Quindi il principale di bash vede che il valore della stringa ha la parentesi aperta / chiusa e indovina che questa deve essere una definizione di funzione. Quindi definisce doverosamente HTTP_COOKIE come una funzione, ed esegue anche il comando immediato dopo di esso.
Quindi, se l'ambiente ha questa variabile, non è ancora successo niente di male. Ma potresti facilmente chiamare codice innocuo di Python che ovviamente non sta eseguendo bash. Questo è tutto ciò che vedi:
Licensing().check()
Forse c'è un binario che la tua azienda usa che controlla una licenza e tu chiami questa funzione (non sai cosa fa). Ma diciamo che in definitiva ciò che fa è questo (risolto nell'implementazione C):
//There are no arguments to this program so this is "safe"
execl("/bin/bash", "bash", "-c", "licensingWrapper", (char*)0);
Quindi bash si avvia ...
//This is bash's main function
int main(int argc, char** argv, char** arge) {
....
parseEnvironment(arge); //!!!!
....
}
Quindi in parseEnvironment, in arge [42] vede una variabile chiamata 'HTTP_COOKIE' e la analizza. bash non ha la più pallida idea di cosa sia questa variabile, ma vede che è una definizione di funzione con un comando immediatamente eseguito; e lo fa Questo parse dell'ambiente è solo un prerequisito standard per mettere la shell pronta ad eseguire qualsiasi cosa argv dice di eseguire.
Se ci pensi un po 'più a fondo, è solo un altro caso di input non purificante. Nessuno pulisce l'input ambientale. A peggiorare le cose, le variabili di ambiente vengono interpretate in modo diverso in base a ciò a cui vengono inoltrate (bash, sh, java, ...). Quindi se avessi una funzione generica per ripulire l'ambiente, sarebbe specifico per i tipi di exec che ti aspetti di eseguire più tardi.
int main(int argc, char** argv, char** arge) {
BOOL isClean = TRUE;
isClean &= cleanseEnvironment(arge, BASIC_SANITY);
isClean &= cleanseEnvironment(arge, BASH_RULES);
if(isClean) {
parseEnvironment(arge);
}
else {
return -EBADENVIRONMENT;
}
...
}
Quindi sarei molto sospettoso che le variabili di ambiente siano impostate su valori corrotti da un attaccante. Quindi semplicemente presume che qualche shell che non avresti pensato verrà eseguito successivamente con quell'ambiente. Hai un evidente problema se puoi dimostrare che bash è eventualmente eseguito. Ma potrebbe facilmente essere un percorso indiretto, come quando viene eseguito tcl, quindi tcl fa in modo che bash venga richiamato.