Cuando se invoca bash
en el contexto de setuid (o setgid), es decir, cuando el uid efectivo es diferente del uid real, entonces bash
elimina los privilegios (establece el uid efectivo de nuevo al uid real).
La excepción es cuando se usa -p
o -o privileged
(la variable SHELLOPTS
se ignora, por lo que privileged
allí también) o cuando se invoca como sh
.
Sin embargo, en ese caso, las funciones no se importan del entorno (ni tampoco son cosas como BASH_ENV
, BASH_OPTS
, SHELLOPTS
por las mismas razones obvias).
Si lo fueran, no necesitarías la vulnerabilidad de shellshock para explotarla. Solo con exportar una función echo
(o cualquier cosa llamada por el script, incluidas las rutas como /bin/mount
), sería suficiente.
Algunos comandos setuid pueden optar por establecer el ruid en el euid. Si lo hacen y no sanean el entorno y llaman a bash (o cualquier otro shell), entonces el juego ha terminado, la vulnerabilidad de Shellshock o no.
El vinculador dinámico de libc se encarga de eliminar algunas variables que afectan a libc o vinculador (LD_PRELOAD, LOCPATH, LD_LIBRARY_PATH ...), pero depende de la aplicación setuid borrar el resto si invocan otros comandos como un shell ( o Python, o cualquier otro comando cuyo comportamiento se pueda controlar con variables de entorno), el enfoque típico y sensato es eliminar todo excepto una lista blanca desinfectada.
Un ejemplo típico de dicha aplicación es sudo
.
De forma predeterminada (con la opción env_reset
activada), sudo
borra el entorno, establece algunos (como PATH
, HOME
, SUDO_USER
...) y coloca algunas listas blancas después de verificar su contenido como TERM
o DISPLAY
. Parte de esa comprobación se ocupa especialmente de las variables cuyo contenido comienza con ()
.
Si env_reset
está desactivado (deshabilitado por el usuario / administrador), entonces sudo
aún enlista algunas variables que afectan a varios shells u otras herramientas comunes (como PS4
, BASH_ENV
...) y esas cuyo contenido comienza con ()
.
Así que shellshock no puede ser explotado haciendo:
DISPLAY='() {(:);}; ouch;}' sudo trusted-bash-script
Ahora, es posible que existan comandos setuid que configuren ruid y no verifiquen las variables que comienzan con ()
e invocan bash
(posiblemente de manera indirecta), pero nuevamente no es necesario que el bug de shellshock se aproveche esos.
Una posible excepción a eso es suexec
de apache. Por lo que sé, suexec
desinfecta el entorno, pero solo enumera en la lista blanca algunas variables basadas en su nombre, no en su contenido. Sin CVE-2014-6271, eso no sería preocupante, ya que los nombres de variables como QUERYSTRING
, HTTP_USER_AGENT
probablemente no coincidirán con el nombre de un comando, por lo que no se consideró necesario bloquear las variables cuyo contenido comienza con "() {"
, pero en la práctica eso significa que está expuesto a CVE-2014-6271.