TL; DR
La vulnerabilidad de shellshock está completamente corregida en
- En la rama bash-2.05b: 2.05b.10 y superior (parche 10 incluido)
- En la rama bash-3.0: 3.0.19 y superior (parche 19 incluido)
- En la rama bash-3.1: 3.1.20 y superior (parche 20 incluido)
- En la rama bash-3.2: 3.2.54 y superior (parche 54 incluido)
- En la rama bash-4.0: 4.0.41 y superior (parche 41 incluido)
- En la rama bash-4.1: 4.1.14 y superior (parche 14 incluido)
- En la rama bash-4.2: 4.2.50 y superior (parche 50 incluido)
- En la rama bash-4.3: 4.3.27 y superior (parche 27 incluido)
Si su bash muestra una versión anterior, es posible que su proveedor de sistema operativo todavía la haya parcheado, así que lo mejor es verificar.
Si:
env xx='() { echo vulnerable; }' bash -c xx
muestra "vulnerable", todavía eres vulnerable. Esa es la única prueba que es relevante (si el analizador de bash todavía está expuesto al código en cualquier variable de entorno).
Detalles
El error estaba en la implementación inicial de la función de exportación / importación introducido en el 5 ° de agosto de 1989, Brian Fox, y por primera vez en bash-1.03 aproximadamente un mes más tarde, en un momento en el golpe no era de uso tan generalizado, antes de la seguridad era una gran preocupación y HTTP y la web o Linux incluso existían.
Desde ChangeLog en 1.05 :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Algunas discusiones en gnu.bash.bug y comp.unix.questions en ese momento también mencionan la característica.
Es fácil entender cómo llegó allí.
bash exporta las funciones en env vars como
foo=() {
code
}
Y en la importación, todo lo que tiene que hacer es interpretar eso =
con un espacio reemplazado ... excepto que no debe interpretarlo ciegamente.
También se divide en eso bash
(al contrario que el shell Bourne), las variables y funciones escalares tienen un espacio de nombre diferente. En realidad si tienes
foo() { echo bar; }; export -f foo
export foo=bar
bash
felizmente pondrá ambos en el entorno (sí, entradas con el mismo nombre de variable) pero muchas herramientas (incluidas muchas shells) no los propagarán.
También se podría argumentar que bash debería usar un BASH_
prefijo de espacio de nombres para eso, ya que eso es solo relevante de bash a bash. rc
usa un fn_
prefijo para una característica similar.
Una mejor manera de implementarlo habría sido poner la definición de todas las variables exportadas en una variable como:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Eso todavía necesitaría ser desinfectado, pero al menos eso no podría ser más explotable que $BASH_ENV
o $SHELLOPTS
...
Hay un parche que impide bash
interpretar algo más que la definición de la función allí ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), y esa es la que tiene aplicado en todas las actualizaciones de seguridad de las diversas distribuciones de Linux.
Sin embargo, bash todavía interpreta el código allí y cualquier error en el intérprete podría ser explotado. Ya se ha encontrado uno de estos errores (CVE-2014-7169) aunque su impacto es mucho menor. Entonces habrá otro parche próximamente.
Hasta que se solucione el problema y evite que bash interprete el código en cualquier variable (como usar el BASH_FUNCDEFS
enfoque anterior), no sabremos con certeza si no somos vulnerables a un error en el analizador de bash. Y creo que habrá una solución tan duradera lanzada tarde o temprano.
Editar 2014-09-28
Se han encontrado dos errores adicionales en el analizador (CVE-2014-718 {6,7}) (tenga en cuenta que la mayoría de los depósitos tienen errores en su analizador para casos de esquina, eso no habría sido una preocupación si ese analizador no hubiera ha sido expuesto a datos no confiables).
Si bien los 3 errores 7169, 7186 y 7187 se han corregido en los siguientes parches, Red Hat presionó para que se solucionara el problema. En su parche, cambiaron el comportamiento para que las funciones se exportaran en variables llamadas BASH_FUNC_myfunc()
más o menos preventivas de la decisión de diseño de Chet.
Más tarde, Chet publicó esa corrección como un parche de bash oficial de upstreams .
Ese parche de refuerzo, o sus variantes, ahora están disponibles para la mayoría de las principales distribuciones de Linux y finalmente llegaron a Apple OS / X.
Eso ahora llena la preocupación por cualquier env arbitrario que explote el analizador a través de ese vector, incluidas otras dos vulnerabilidades en el analizador (CVE-2014-627 {7,8}) que luego fueron reveladas por Michał Zalewski (CVE-2014-6278 siendo casi tan malo como CVE-2014-6271) afortunadamente después de que la mayoría de la gente haya tenido tiempo de instalar el parche de endurecimiento
Los errores en el analizador también se corregirán, pero ya no son tan problemáticos ahora que el analizador ya no se expone tan fácilmente a entradas no confiables.
Tenga en cuenta que si bien la vulnerabilidad de seguridad se ha solucionado, es probable que veamos algunos cambios en esa área. La solución inicial para CVE-2014-6271 ha roto la compatibilidad hacia atrás en que deje de funciones de importación con .
o :
o /
en su nombre. Sin embargo, esos pueden ser declarados por bash, lo que genera un comportamiento inconsistente. Debido a que las funciones con .
y :
en su nombre se usan comúnmente, es probable que se restablezca un parche aceptando al menos las del entorno.
¿Por qué no se encontró antes?
Eso también es algo de lo que me preguntaba. Puedo ofrecer algunas explicaciones.
Primero, creo que si un investigador de seguridad (y yo no soy un investigador de seguridad profesional) hubiera estado buscando vulnerabilidades específicamente en bash, probablemente lo habrían encontrado.
Por ejemplo, si fuera un investigador de seguridad, mis enfoques podrían ser:
- Mire de dónde
bash
obtiene información y qué hace con ella. Y el medio ambiente es obvio.
- Mire en qué lugares
bash
se invoca al intérprete y en qué datos. De nuevo, se destacaría.
- La importación de funciones exportadas es una de las características que se deshabilita cuando
bash
se configura / establece, lo que lo hace un lugar aún más obvio para buscar.
Ahora, sospecho que nadie pensó en considerar bash
(al intérprete) como una amenaza, o que la amenaza podría haber venido de esa manera.
El bash
intérprete no está destinado a procesar entradas no confiables.
Los scripts de shell (no el intérprete) a menudo se miran de cerca desde un punto de vista de seguridad. La sintaxis de shell es tan incómoda y hay muchas advertencias al escribir scripts confiables (¿alguna vez me has visto a mí u otros mencionando el operador split + glob o por qué deberías citar variables, por ejemplo?) Que es bastante común encontrar vulnerabilidades de seguridad en los scripts que procesan datos no confiables
Es por eso que a menudo escuchas que no debes escribir scripts de shell CGI, o los scripts setuid están deshabilitados en la mayoría de los Unices. O que debe tener mucho cuidado al procesar archivos en directorios de escritura mundial (consulte CVE-2011-0441, por ejemplo).
El foco está en eso, los guiones de shell, no el intérprete.
Puede exponer un intérprete de shell para datos no confiables (alimentación de datos extranjeras como código de cáscara de interpretar) a través de eval
o .
o llamando en los archivos de usuario proporcionada, pero entonces no se necesita una vulnerabilidad en bash
explotarlo. Es bastante obvio que si está pasando datos no higienizados para que un shell los interprete, lo interpretará.
Entonces el shell se llama en contextos confiables. Se le dan guiones fijos para interpretar y la mayoría de las veces (porque es tan difícil escribir guiones confiables) datos fijos para procesar.
Por ejemplo, en un contexto web, se puede invocar un shell en algo como:
popen("sendmail -oi -t", "w");
¿Qué puede salir mal con eso? Si se prevé algo incorrecto, se trata de los datos que se envían a ese correo de envío, no de cómo se analiza esa línea de comando de shell o qué datos adicionales se envían a ese shell. No hay ninguna razón por la que desee considerar las variables de entorno que se pasan a ese shell. Y si lo hace, se da cuenta de que es todo env VARs cuyo nombre empieza con "HTTP_" o son bien conocidos CGI env vars como SERVER_PROTOCOL
o QUERYSTRING
ninguno de los cuales la cáscara o Sendmail tienen cualquier negocio que ver con.
En contextos de elevación de privilegios como cuando se ejecuta setuid / setgid o vía sudo, generalmente se considera el entorno y ha habido muchas vulnerabilidades en el pasado, nuevamente no contra el shell en sí sino contra las cosas que elevan los privilegios como sudo
(ver por ejemplo CVE -2011-3628 ).
Por ejemplo, bash
no confía en el entorno cuando setuid o es llamado por un comando setuid (piense, mount
por ejemplo, que invoca ayudantes). En particular, ignora las funciones exportadas.
sudo
hace limpiar el medio ambiente: todo por defecto a excepción de una lista blanca, y si no se configura, al menos listas negras unos pocos que se sabe que afectan una concha u otro (como PS4
, BASH_ENV
, SHELLOPTS
...). También incluye en la lista negra las variables de entorno cuyo contenido comienza ()
(razón por la cual CVE-2014-6271 no permite la escalada de privilegios a través de sudo
).
Pero, de nuevo, eso es para contextos en los que no se puede confiar en el entorno: un usuario malintencionado puede establecer cualquier variable con cualquier nombre y valor en ese contexto. Eso no se aplica a los servidores web / ssh o todos los vectores que explotan CVE-2014-6271 donde se controla el entorno (al menos se controla el nombre de las variables de entorno ...)
Es importante bloquear una variable como echo="() { evil; }"
, pero no HTTP_FOO="() { evil; }"
, porque HTTP_FOO
ningún script de shell o línea de comando lo llamará como un comando. Y apache2 nunca establecerá una echo
o BASH_ENV
variable.
Es bastante obvio que algunas variables de entorno deben incluirse en una lista negra en algunos contextos según su nombre , pero nadie pensó que deberían incluirse en una lista negra según su contenido (excepto sudo
). O, en otras palabras, nadie pensó que los entornos arbitrarios podrían ser un vector para la inyección de código.
En cuanto a si las pruebas exhaustivas cuando se agregó la característica podrían haberlo atrapado, diría que es poco probable.
Cuando prueba la característica , prueba la funcionalidad. La funcionalidad funciona bien. Si exporta la función en una bash
invocación, se importa bien en otra. Una prueba muy exhaustiva podría haber detectado problemas cuando se exportan tanto una variable como una función con el mismo nombre o cuando la función se importa en una ubicación diferente de la que se exportó.
Pero para poder detectar la vulnerabilidad, no es una prueba de funcionalidad que habría tenido que hacer. El aspecto de seguridad debería haber sido el foco principal, y no estaría probando la funcionalidad, sino el mecanismo y cómo podría abusarse de él.
No es algo que los desarrolladores (especialmente en 1989) a menudo tengan en mente, y un desarrollador de shell podría ser excusado para pensar que es poco probable que su software sea explotable en la red.