¿Por qué la capacidad de definir funciones en una variable ambiental no es un riesgo de seguridad en sí mismo?

9

Según tengo entendido, generalmente se considera seguro permitir que cualquiera proporcione información que se almacenará en una variable ambiental. La vulnerabilidad de shellshock es un problema aquí porque significa que el código al final de una definición de función dentro de una variable ambiental se ejecutará cuando se inicie una nueva instancia de bash y obviamente no desea que nadie ejecute ningún código que desee en su servidor . Sin embargo, las definiciones de funciones en sí mismas aparentemente no son un riesgo de seguridad y están permitidas porque deben llamarse explícitamente para que se ejecute su código.

Mi pregunta es ¿por qué un usuario malintencionado no puede simplemente definir una función, que contiene su código malicioso como un comando común como lsy luego esperar que el script (o lo que se esté ejecutando) use este comando en algún momento?

Un ejemplo de lo que tengo en mente:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
Reed Espinosa
fuente

Respuestas:

10

Es un riesgo de seguridad. En general, es por eso que no puede hacerlo al cambiar a otro contexto (control remoto de un sistema, cambio de usuarios, etc.).

Si tiene la capacidad de crear cualquier variable de entorno que desee, existen varias formas posibles de ejecutar código arbitrario.
Toma $LD_PRELOADcomo ejemplo. Si tiene la capacidad de establecer esa variable, puede reemplazar las funciones de la biblioteca y pegar su código allí. Puede configurar la $DISPLAYvariable y redirigir la pantalla X a la que se conecta el programa para que pueda controlar la aplicación.

Es por eso que cosas como sudoquitar el entorno de todas las variables. sudosolo permite algunas variables de selección a través. Y de esas variables, las desinfecta (pasa a través de la $TERMvariable, pero no lo hará si contiene caracteres inusuales).

Patricio
fuente
Wow, siempre me pregunté por qué algunos scripts enormes que hago en BASH tendrían fallas arcanas extrañas cuando comencé con sudo, particularmente alrededor de los caminos, lo que me llevó a verificar los inicios de sudo y bloquearlos, pero nunca supe por qué sucedió eso y fue un problema, gracias por la buena explicación re sudo eliminando variables ambientales.
Lizardx
3

Yo diría que sí, cuando bash es tu / bin / sh. No es una característica de bourne shell, y apuesto a que tampoco es una característica de posix shell, de hecho, es posible que quieran prohibirlo expresamente.

Bash es realmente más una cáscara derivada de korn, que una cáscara de bourne, a pesar de su nombre, y es la única cáscara similar a Korn que tiene la característica, y en mi opinión es la característica del fregadero de cocina que no tiene virtudes prácticas. Los desarrolladores que evitan las funciones bash para los estándares, como el shell bourne, el shell posix o el subconjunto ksh88 que los shells modernos tienen en común, o en otras palabras, se comprometieron con las buenas prácticas y las expresiones idiomáticas estándar, se sorprenden cuando su software está encendido Linux y Mac y ahora potencialmente vulnerables, ya que los autores de exploits son libres de usar los 'bashismos', a pesar de sus intenciones. En cuanto a la compatibilidad mejorada, cuando se invoca como / bin / sh, sobre otros derivados de shell korn, solo si / bin / sh es su shell de inicio de sesión, o shell interactivo, cuando bash se comporta más como un shell bourne que un shell korn,

Trataré de persuadirlo de que es la función de fregadero de cocina, con 2 casos: usted es un desarrollador integrado, que hace que dispositivos como enrutadores, almacenamiento conectado a la red 1er env más grande, significa más, memoria, por lo tanto, más costo, así que menos ganancias, entonces, si esta fuera una razón para considerar el uso de esta función de bash, ¿no deberías usar FPATH y carga automática, funciones ksh88 en su lugar? en lugar de pasar toda la función byte por byte en el entorno? Incluso podría considerar analizar y podar el entorno al por mayor, antes de que llegue a un shellscript que pueda confundir una variable, como simplemente filtrar ^ $ (. *) $, Y similares ...

Eso subraya lo que es único acerca de esto, no importa cuál sea la variable, y el script no tiene que hacer referencia o usar la variable, aún podría ser vulnerable.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Para todo lo demás bajo el sol, lo anterior debería ser tan seguro como el script perl, no estás usando ninguna variable, ¿cómo podrías confundir alguna? Cambiando a

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

Tampoco ayuda, esto no tenía nada que ver con ENV ni nada por el estilo: todos se queman porque bash debe ser único. El hecho de que fiesta de la versión 2 tiene el problema, me demuestra que nadie utiliza esta característica para sus aplicaciones, porque de lo contrario debería no haber acechado alrededor de este tiempo. Y lo que es peor, básicamente no se puede evitar esta característica . Aquí hay un ejemplo con: con 'su -', que si le pregunta a alguien, la explicación sería que descarta el medio ambiente, consulte la página de manual y encontrará solo el 99.9%. Probé de la manera correcta, ya que en este sistema / bin / sh es el shell de inicio de sesión de root y / bin / sh es bash PERO , en este ejemplo intentopara endurecer mi .bash_profile. Cambié el nombre de mi raíz existente (que está habilitada), pero mi pensamiento era si su, entonces posiblemente sudo, de todos modos, cambié a esto:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Entonces, en realidad estoy lanzando el entorno por completo, y uso un entorno mínimo, y luego ejecuto un shell que no debería tener el problema, en lugar del proceso actual. Luego, en lugar del ejemplo estándar, intente:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

Esto ilustra cómo no tiene nada que ver con el análisis de una función en particular, y un exploit puede referirse y usar la función. Puedes imaginar que la función tiene lógica para probar si es root, etc. En este caso, es solo una forma modificada de una función para iconizar o acoplar una ventana de terminal, usando una secuencia de escape, eso es bastante estándar, así que después de hacer clic para desiconificar, yo ver muelle de aterrizaje, pero ¿y qué? Ahora intenta esto:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

¿Y adivina qué? La ventana queda atrapada en el muelle. Así es como se ve después ...

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

¡Entonces, mucho por eso! Las funciones exportadas en realidad tienen prioridad sobre los scripts rc. No puedes esquivarlo.

Dan LaBell
fuente
1
POSIX permitió funciones exportables en el borrador 2, y luego las rechazó. La característica es una locura.
mikeserv