Para tranquilizar a algunos, no encontré el error al observar exploits, no tengo ninguna razón para creer que haya sido explotado antes de ser revelado (aunque, por supuesto, no puedo descartarlo). Tampoco lo encontré mirando bash
el código.
No puedo decir que recuerdo exactamente mi tren de pensamientos en ese momento.
Que más o menos vino de alguna reflexión sobre algunos comportamientos de algún software que encuentro peligroso (los comportamientos, no el software). El tipo de comportamiento que te hace pensar: eso no parece una buena idea .
En este caso, estaba reflexionando sobre la configuración común de ssh que permite pasar variables de entorno no saneadas del cliente siempre que su nombre comience con LC_
. La idea es que las personas puedan seguir usando su propio idioma cuando ssh
ingresen a otras máquinas. Una buena idea hasta que empiece a considerar cuán complejo es el manejo de la localización, especialmente cuando UTF-8 se incluye en la ecuación (y ver cuán mal es manejado por muchas aplicaciones).
En julio de 2014, ya había informado de una vulnerabilidad en el manejo de localización de glibc que se combinó con esa sshd
configuración, y otros dos comportamientos peligrosos del bash
shell
permitieron que los atacantes (autenticados) piratearan servidores git siempre que pudieran cargar archivos allí y bash
se usaran como el shell de inicio de sesión del usuario git unix (CVE-2014-0475).
Estaba pensando que probablemente era una mala idea usarlo bash
como el shell de inicio de sesión de los usuarios que ofrecen servicios a través de ssh, dado que es un shell bastante complejo (cuando todo lo que necesita es analizar una línea de comando muy simple) y ha heredado la mayoría de los diseños erróneos de ksh. Como ya había identificado algunos problemas con el bash
uso en ese contexto (para interpretar ssh ForceCommand
s), me preguntaba si había potencialmente más.
AcceptEnv LC_*
permite cualquier variable cuyo nombre comience LC_
y tuve el vago recuerdo de que las bash
funciones exportadas (una característica peligrosa aunque útil en el momento) estaban usando variables de entorno cuyo nombre era algo así
myfunction()
y me preguntaba si no había algo interesante para mirar allí.
Estaba a punto de descartarlo porque lo peor que uno podría hacer sería redefinir un comando llamado LC_something
que realmente no podría ser un problema, ya que esos no son nombres de comandos existentes, pero luego comencé a preguntarme cómo bash
importaron esas variables de entorno.
¿Qué pasa si las variables se llamaron LC_foo;echo test; f()
por ejemplo? Entonces decidí echar un vistazo más de cerca.
UN:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
reveló que mi recuerdo era incorrecto porque las variables no se llamaban myfunction()
pero myfunction
(y es el
valor que comienza con ()
).
Y una prueba rápida:
$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for `true;echo test; f'
confirmó mi sospecha de que el nombre de la variable no fue desinfectado y el código fue evaluado al inicio .
Peor, mucho peor, el valor tampoco fue desinfectado:
$ env 'foo=() { :;}; echo test' bash -c :
test
Eso significaba que cualquier variable de entorno podría ser un vector.
Fue entonces cuando me di cuenta del alcance del problema, confirmó que también era explotable a través de HTTP ( HTTP_xxx
/ QUERYSTRING
... env vars), otros como los servicios de procesamiento de correo, luego DHCP (y probablemente una larga lista) y lo reporté (cuidadosamente) .