No es necesario que uses bash explícitamente para que esto sea un problema. El problema real es permitir que los atacantes tengan voz en el valor de las variables de entorno. Una vez que se establece el entorno, solo es cuestión de tiempo antes de que se ejecute un shell (quizás desconocido para usted) con un entorno para el que no estaba preparado.
Cada programa (bash, java, tcl, php, ...) tiene esta firma:
int main(int argc, char** argv, char** arge);
Los desarrolladores tienen la costumbre de verificar argc y argv para la limpieza. La mayoría ignorará arge y no intentará validarlo antes de generar subshells (explícita o implícitamente). Y en este caso, bash no se está defendiendo correctamente de una entrada incorrecta. Para conectar una aplicación, se generan subprocesos. En el fondo, algo como esto sucede:
//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);
En su propio código, puede que no haya referencias a bash. Pero tal vez lanzas tcl, y algo dentro del código tcl se lanza bash para ti. Heredaría las variables de entorno que están configuradas actualmente.
En el caso de la versión vulnerable de bash, algo como esto está sucediendo:
int main(int argc, char** argv, char** arge) { //bash's main function
....
parseEnvironment(arge); //!!!! read function definitions and var defines
....
doArgv(argc, argv);
....
}
Donde parseEnvironment ve un montón de definiciones de variables de entorno que no necesariamente reconoce. Pero supondrá que algunas de estas variables de entorno son definiciones de funciones:
INITTECH_HOME=/opt/initTech
HTTP_COOKIE=() { :; }; /usr/bin/eject
Bash no tiene idea de lo que es un HTTP_COOKIE. Pero comienza con (), así que bash adivina que esta es una definición de función. También le permite agregar algunos códigos ejecutados inmediatamente después de la definición de la función, porque quizás necesite inicializar algunos efectos secundarios con la definición de la función. El parche elimina la capacidad de agregar efectos secundarios después de la definición de la función.
¡Pero la idea general de que una variable de entorno puede permanecer inactiva con la definición de la función suministrada por el atacante sigue siendo muy inquietante!
recieve='() { echo you meant receive lol; }'
Si el atacante puede hacer que este nombre de variable obtenga un valor que proporcionó, y también sabe que puede esperar a que un subproceso de bash intente invocar una función con ese nombre, entonces este sería otro vector de ataque.
Esta es solo la vieja advertencia para validar sus entradas . Como los shells se pueden generar como un detalle de implementación sorprendente, nunca establece una variable de entorno en un valor que no esté ajustado validado. Eso significa que cualquier programa posible que lea esta variable de entorno no hará algo inesperado con el valor; como ejecutarlo como codigo.
Hoy es bash. Mañana es java, sh, tcl, o nodo. Todos ellos tienen un indicador de entorno en su función principal; y todos ellos tienen limitaciones diferentes sobre lo que manejarán de manera segura (hasta que estén parcheados).