GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuándo se introdujo el error Shellshock (cve-2014-6271/7169) y cuál es el parche que lo soluciona por completo?

Algo de contexto sobre el error:CVE-2014-6271

Bash admite la exportación no solo de variables de shell, sino también de funciones de shell
a otras instancias de bash, a través del entorno de proceso a
procesos secundarios (indirectos). Las versiones actuales de bash utilizan una variable de entorno
nombrada por el nombre de la función y una definición de función
que comienza con "() {" en el valor de la variable para propagar las definiciones de función
a través del entorno. La vulnerabilidad ocurre porque
bash no se detiene después de procesar la definición de la función;
continúa analizando y ejecutando comandos de shell siguiendo la definición de función
. Por ejemplo, una configuración de variable de entorno de

  VAR=() { ignored; }; /bin/id

ejecutará /bin/id cuando el entorno se importe al proceso bash
.

Fuente:http://seclists.org/oss-sec/2014/q3/650

¿Cuándo se introdujo el error y cuál es el parche que lo soluciona por completo? (Ver CVE-2014-7169)

¿Cuáles son las versiones vulnerables más allá de las indicadas en el CVE (inicialmente) (3.{0..2} y 4.{0..3})?

¿Se ha reutilizado el código fuente con errores en otros proyectos?

Es deseable obtener información adicional.

Relacionado:¿Qué significa env x='() {:;}; command' bash do y por qué es inseguro?

Respuesta aceptada:

TL;DR

La vulnerabilidad shellshock está completamente solucionada 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 el proveedor de su sistema operativo aún lo haya parcheado por sí mismo, por lo que es mejor verificarlo.

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 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 introducida el 5 de agosto de 1989 por Brian Fox, y lanzada por primera vez en bash-1.03 aproximadamente un mes después, en un momento en el que bash no estaba en un uso tan generalizado, antes de que la seguridad fuera esa 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 función.

Es fácil entender cómo llegó allí.

bash exporta las funciones en env vars como

foo=() {
  code
}

Y al importar, todo lo que tiene que hacer es interpretarlo con = reemplazado con un espacio... excepto que no debe interpretarlo a ciegas.

También está roto en eso en bash (al contrario del shell de Bourne), las variables y funciones escalares tienen un espacio de nombres diferente. En realidad si tienes

foo() { echo bar; }; export -f foo
export foo=bar

bash felizmente colocará ambos en el entorno (sí, entradas con el mismo nombre de variable), pero muchas herramientas (incluidos muchos 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 es env vars solo relevante de bash a bash. rc usa un fn_ prefijo para una función similar.

Una mejor manera de implementarlo hubiera sido poner la definición de todas las variables exportadas en una variable como:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

Eso aún 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 de interpretar cualquier otra cosa que no sea 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 se ha aplicado en toda la seguridad actualizaciones de las distintas distribuciones de Linux.

Sin embargo, bash aún 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. Así que pronto habrá otro parche.

Hasta una solución de endurecimiento que evita 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 bash. Y creo que tarde o temprano se lanzará una corrección de endurecimiento.

Relacionado:¿Cómo encontrar archivos con una ruta secundaria determinada?

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 shells tienen errores en su analizador para casos de esquina, eso no habría sido una preocupación si ese analizador no lo hubiera hecho). no ha estado expuesto a datos que no son de confianza).

Si bien los 3 errores 7169, 7186 y 7187 se corrigieron en los siguientes parches, Red Hat presionó para que se corrigiera el endurecimiento. En su parche, cambiaron el comportamiento para que las funciones se exportaran en variables llamadas BASH_FUNC_myfunc() adelantándose más o menos a la decisión de diseño de Chet.

Chet publicó más tarde esa solución como un parche bash upstream oficial.

Ese parche de refuerzo, o variantes del mismo, ahora están disponibles para la mayoría de las principales distribuciones de Linux y eventualmente llegaron a Apple OS/X.

Eso ahora soluciona la preocupación por cualquier env var arbitrario que explote el analizador a través de ese vector, incluidas otras dos vulnerabilidades en el analizador (CVE-2014-627{7,8}) que fueron reveladas más tarde por Michał Zalewski (CVE-2014-6278 siendo casi tan malo como CVE-2014-6271) afortunadamente después de que la mayoría de las personas tuvieron tiempo de instalar el parche de refuerzo

Los errores en el analizador también se corregirán, pero ya no son un gran problema ahora que el analizador ya no está expuesto tan fácilmente a entradas que no son de confianza.

Tenga en cuenta que, si bien se solucionó la vulnerabilidad de seguridad, es probable que veamos algunos cambios en esa área. La solución inicial para CVE-2014-6271 ha roto la compatibilidad con versiones anteriores, ya que deja de importar funciones con . o : o / en su nombre Esos todavía pueden ser declarados por bash, lo que hace que el comportamiento sea inconsistente. Porque funciona con . y : en su nombre se usan comúnmente, es probable que un parche se restaure aceptando al menos los del entorno.

¿Por qué no se encontró antes?

Eso también es algo que me preguntaba. Puedo ofrecer algunas explicaciones.

Primero, creo que si un investigador de seguridad (y no soy un investigador de seguridad profesional) hubiera estado buscando específicamente vulnerabilidades en bash, probablemente las habría encontrado.

Por ejemplo, si fuera un investigador de seguridad, mis enfoques podrían ser:

  1. Mira donde bash obtiene entrada y lo que hace con ella. Y el entorno es obvio.
  2. Mira en qué lugar se encuentra el bash se invoca el intérprete y sobre qué datos. Una vez más, se destacaría.
  3. La importación de funciones exportadas es una de las funciones que se deshabilita cuando bash es setuid/setgid, lo que lo convierte en un lugar aún más obvio para buscar.

Ahora, sospecho que nadie pensó en considerar bash (el intérprete) como una amenaza, o que la amenaza pudo haber llegado de esa manera.

El bash El intérprete no está diseñado para procesar entradas que no sean de confianza.

Shell guiones (no el intérprete) a menudo se examinan de cerca desde el punto de vista de la seguridad. La sintaxis de shell es tan incómoda y hay tantas advertencias al escribir scripts confiables (¿alguna vez me ha visto a mí o a otros mencionar el operador split+glob o por qué debería citar variables, por ejemplo?) que es bastante común encontrar vulnerabilidades de seguridad en scripts que procesan datos no confiables.

Es por eso que a menudo escucha que no debe escribir scripts de shell CGI, o que 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 scripts de shell, no en el intérprete.

Puede exponer un intérprete de shell a datos que no son de confianza (alimentando datos externos como código de shell para interpretar) a través de eval o . o llamarlo en los archivos proporcionados por el usuario, pero entonces no necesita una vulnerabilidad en bash para explotarlo. Es bastante obvio que si está pasando datos no desinfectados para que los interprete un shell, los interpretará.

Entonces, el shell se llama en contextos confiables. Tiene scripts fijos para interpretar y la mayoría de las veces (porque es muy difícil escribir scripts confiables) datos fijos para procesar.

Por ejemplo, en un contexto web, se podría 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 sendmail, no de cómo se analiza la línea de comando del shell en sí o qué datos adicionales se envían a ese shell. No hay ninguna razón por la que quiera considerar las variables de entorno que se pasan a ese shell. Y si lo hace, se dará cuenta de que todos son variables de entorno cuyo nombre comienza con "HTTP_" o son variables de entorno CGI conocidas como SERVER_PROTOCOL o QUERYSTRING ninguno de los cuales shell o sendmail tienen nada que ver.

Relacionado:¿Usar un transistor para iluminar "completamente" una lámpara?

En contextos de elevación de privilegios, como cuando se ejecuta setuid/setgid o a través de sudo, el entorno generalmente se considera 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 se llama mediante un comando setuid (piense en mount por ejemplo, que invoca ayudantes). En particular, ignora las funciones exportadas.

sudo limpia el entorno:todo de forma predeterminada, excepto una lista blanca, y si está configurado para no hacerlo, al menos incluye una lista negra de algunos que se sabe que afectan a un shell u otro (como PS4 , BASH_ENV , SHELLOPTS …). También incluye en la lista negra las variables de entorno cuyo contenido comienza con () (razón por la cual CVE-2014-6271 no permite la escalada de privilegios a través de sudo ).

Pero nuevamente, eso es para contextos en los que no se puede confiar en el entorno:cualquier variable con cualquier nombre y valor puede ser configurada por un usuario malintencionado 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 no será llamado como un comando por ningún script de shell o línea de comando. Y apache2 nunca establecerá un echo o BASH_ENV variables.

Es bastante obvio algunos las variables de entorno deben estar en la lista negra en algunos contextos en función de su nombre , pero nadie pensó que deberían estar en la lista negra en función de su contenido (excepto sudo ). O, en otras palabras, nadie pensó que las variables de entorno arbitrarias podrían ser un vector para la inyección de código.

En cuanto a si las pruebas exhaustivas cuando se agregó la función podrían haberlo detectado, diría que es poco probable.

Cuando prueba la función , prueba la funcionalidad. La funcionalidad funciona bien. Si exporta la función en un 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 configuración regional diferente a la que se exportó.

Pero para poder detectar la vulnerabilidad, no es necesario realizar una prueba de funcionalidad. El aspecto de seguridad tendría que haber sido el foco principal, y no estarías probando la funcionalidad, sino el mecanismo y cómo se podría abusar de él.

No es algo que los desarrolladores (especialmente en 1989) tengan a menudo en mente, y un desarrollador shell podría tener excusas para pensar que es poco probable que su software sea explotable en la red.


Linux
  1. En Bash, ¿cuándo alias, cuándo escribir y cuándo escribir una función?

  2. Seguimiento y corrección de un error del instalador

  3. ¿Cuál es la diferencia entre #!/usr/bin/env bash y #!/usr/bin/bash?

  4. ¿Cuál es el uso de $# en Bash?

  5. ¿Cuál es la diferencia entre procfs y sysfs?

¿Cuál es la diferencia entre Linux y Unix?

¿Cuál es el significado de caddr_t y cuándo se usa?

¿Qué tiene de malo mi secuencia de comandos bash para mantener los últimos archivos x y eliminar el resto?

¿Cuál es la diferencia entre &> y >&en bash?

¿Cuál fue el método de compresión SquashFS?

¿Cuál es la diferencia entre unlink y rm?