Pregunta

¿Alguien puede señalar algún código que se ocupe de la seguridad del acceso a los archivos a través de una ruta especificada (en parte) por una variable de entorno, específicamente para Unix y sus variantes, pero las soluciones de Windows también son interesantes?

Esta es una gran pregunta larga: no estoy seguro de qué tan bien se ajusta al paradigma SO.

Considere este escenario:

Antecedentes :

  • El paquete de software PQR se puede instalar en una ubicación elegida por los usuarios.
  • La variable de entorno $ PQRHOME se usa para identificar el directorio de instalación.
  • Por defecto, todos los programas y archivos bajo $ PQRHOME pertenecen a un grupo especial, pqrgrp.
  • Del mismo modo, todos los programas y archivos bajo $ PQRHOME pertenecen a un usuario especial, pqrusr, o al usuario root (y esos son programas raíz SUID).
  • Algunos programas son SUID pqrusr; algunos programas más son SGID pqrgrp.
  • La mayoría de los directorios son propiedad de pqrusr y pertenecen a pqrgrp; algunos pueden pertenecer a otros grupos, y los miembros de esos grupos adquieren privilegios adicionales con el software.
  • Muchos de los ejecutables privilegiados deben ser ejecutados por personas que no son miembros de pqrgrp; los programas tienen que validar que el usuario puede ejecutarlo mediante reglas arcanas que no conciernen directamente a esta pregunta.
  • Después del inicio, algunos de los programas privilegiados tienen que conservar sus privilegios elevados porque son demonios de larga duración que pueden actuar en nombre de muchos usuarios a lo largo de su vida útil.
  • Los programas no están autorizados para cambiar el directorio a $ PQRHOME por una variedad de razones arcanas.

Comprobación actual:

  • Los programas actualmente verifican que $ PQRHOME y los directorios clave debajo de él son 'seguros' (propiedad de pqrusr, pertenecen a pqrgrp, no tienen acceso de escritura pública).
  • Posteriormente, los programas acceden a los archivos bajo $ PQRHOME a través del valor total de la variable de entorno.
  • En particular, G11N y L10N se logran accediendo a archivos en directorios 'seguros' y leyendo cadenas de formato para printf (), etc. de los archivos en esos directorios, utilizando el nombre de ruta completo derivado de $ PQRHOME más un sub conocido -estructura (por ejemplo, $ PQRHOME / g11n / en_us / messages.l10n).

Suponga que el valor 'como instalado' de $ PQRHOME es / opt / pqr.

Ataque conocido:

  • El atacante establece PQRHOME = / home / attacker / pqr.
  • Esto es en realidad un enlace simbólico a / opt / pqr, por lo que cuando uno de los programas PQR, lo llama pqr-victim, comprueba el directorio, tiene los permisos correctos.
  • Inmediatamente después de que la comprobación de seguridad se complete con éxito, el atacante cambia el enlace simbólico para que apunte a / home / attacker / bogus-pqr, que está claramente bajo el control del atacante.
  • Suceden cosas terribles cuando pqr-victim ahora accede a un archivo en el directorio supuestamente seguro.

Dado que PQR actualmente se comporta como se describe, y es un paquete grande (múltiples millones de líneas de código, desarrollado durante más de una década para una variedad de estándares de codificación, que con frecuencia se ignoraron, de todos modos), qué técnicas utilizarías para remediar el problema?

Las opciones conocidas incluyen:

  1. Cambie todas las llamadas de formato para usar la función que verifica los argumentos reales contra las cadenas de formato, con un argumento adicional que indica los tipos reales pasados ??a la función. (Esto es complicado y potencialmente propenso a errores debido a la gran cantidad de operaciones de formato que se deben cambiar, pero si la función de verificación es sólida, funciona bien).
  2. Establezca la ruta directa a PQRHOME y valídelo por seguridad (detalles a continuación), negándose a comenzar si no es seguro, y luego usando la ruta directa y no el valor de $ PQRHOME (cuando difieren). (Esto requiere todas las operaciones de archivo que usan $ PQRHOME para usar no el valor de getenv () sino la ruta asignada. Por ejemplo, esto requeriría
¿Fue útil?

Solución

La opción 2 funciona, si escribe un nuevo valor para $ PQRHOME después de resolver su ruta real y verificar su seguridad. De esa manera, muy poco de su código debe cambiarse posteriormente.

En cuanto a mantener los privilegios de setuid, sería útil si puede hacer algún tipo de separación de privilegios, de modo que cualquier operación que involucre la entrada del usuario real se ejecute bajo el uid real. El proceso privilegiado y el proceso de uid real luego hablan usando un socketpair o algo similar.

Otros consejos

Bueno, suena paranoico, pero si es o no depende de qué sistema (s) está ejecutando su aplicación y qué daño puede hacer un atacante.

Por lo tanto, si su base de usuarios es posiblemente hostil y si el daño es posiblemente muy alto, elegiría la opción 4, pero se modificaría de la siguiente manera para eliminar sus inconvenientes.

Permítanme citar dos cosas relevantes:

1)

  

Los programas actualmente verifican que $ PQRHOME y los directorios clave   debajo de él son 'seguros' (propiedad de pqrusr,   pertenecer a pqrgrp, no tener público   acceso de escritura).

2)

  

Posteriormente, los programas acceden a los archivos bajo $ PQRHOME a través de la cuenta completa   valor de la variable de entorno.

No necesita codificar realmente la ruta completa, puede codificar solo la ruta relativa desde el " programa " usted mencionó en 1) a la ruta mencionada en 2) donde están los archivos.

Problema a controlar:

a) debe estar seguro de que no hay nada "atacante accesible" (por ejemplo, en términos de enlaces simbólicos) entre la ruta del ejecutable y la ruta de los archivos

b) debe asegurarse de que el ejecutable verifique su propia ruta de manera confiable, pero esto no debería ser un problema en todos los Unix que conozco (pero no los conozco a todos y no los conozco) t saber windows en absoluto).


EDITADO después del 3er comentario:

Si su sistema operativo admite / proc, el syslink / proc / $ {pid} / exe es la mejor manera de resolver b)


EDITADO después de dormir en él:

¿La instalación es segura? ¿proceso? Si es así, puede crear (en el momento de la instalación) un script de contenedor. Este script debe ser ejecutable pero no escribible (y posiblemente ni legible). Establecería la variable $ PQRHOME env en la opción "seguro". valor y luego llame a su programa real (podría eventualmente hacer otras cosas útiles también). Dado que en UNIX los elementos de un proceso en ejecución no se pueden cambiar por otra cosa que no sea el proceso en ejecución, usted está a salvo (por supuesto, los elementos de entorno pueden ser modificados por el padre antes comienza el proceso). Sin embargo, no sé si este enfoque funciona en Windows.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top