¿Cuál es la forma segura de cambiar los permisos de UNIX en un archivo codificado a menudo?

2

Estoy escribiendo un demonio que supervisa algo en el sistema operativo y cambia los permisos de ejecución en un archivo en / run / back and forward. El archivo tiene contenido estático y el nombre del archivo está codificado en el demonio. Hice que el demonio se ejecute como root para que pueda escribir en / run /.

Se supone que el demonio se utiliza en una gran cantidad de máquinas Linux de escritorio, por lo que quiero asegurarme de que no sea explotable. Sin embargo, no estoy particularmente preocupado por los ataques DDoS porque el demonio no es de misión crítica. Sin embargo, todas las formas de hacer un archivo ejecutable o no ejecutable parecen tener una falla de seguridad.

Forma # 1: chmod () de ida y vuelta

Crea el archivo y chmod() de un lado a otro. No estoy de acuerdo con la idea porque si un atacante logra reemplazar el archivo con un enlace simbólico a otra cosa, un archivo o carpeta arbitrario se convertirá en legibilidad y posiblemente en ejecutabilidad. Sin embargo, el atacante necesitaría permisos de root para eso.

Forma # 2: elimine el archivo y vuelva a crearlo de forma atómica con open ()

Primero elimine el archivo y luego cree de forma atómica uno nuevo con los permisos correctos usando open(path, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, permissions) , luego escriba el contenido en la secuencia y ciérrelo. Me gusta este uno más porque lo único que se puede explotar es eliminar un archivo con un nombre codificado sustituyendo el directorio de destino con un enlace simbólico a algún otro directorio, y si puede sobrescribir los directorios raíz no debería necesitar engañar a los demonios para eliminar un archivo con un nombre de archivo codificado de todos modos.
¿Qué sucede si el archivo se elimina mientras el demonio está escribiendo para transmitir en este caso?
Está utilizando g_remove () bien o debo usar unlink () solamente y abortar si falla?

¿Me estoy perdiendo algo o simplemente estoy siendo paranoico y la forma # 2 es lo suficientemente segura?

    
pregunta Shnatsel 21.11.2012 - 00:47
fuente

2 respuestas

6

Su método # 1 puede adaptarse para protegerse contra los ataques de enlaces simbólicos:

  1. lstat() la ruta del archivo que desea modificar. Guarde los valores de st_dev y st_ino en el struct stat que se devuelve. Estos dos números identifican de manera única el archivo en su sistema.
  2. open() el archivo con O_RDONLY .
  3. fstat() el descriptor de archivo abierto. Asegúrese de que st_dev y st_ino sean iguales a los que guardó anteriormente. Si son diferentes, solo has seguido un enlace simbólico y deberías irte.
  4. fchmod() el descriptor de archivo para establecer el bit de ejecución. fchmod() es como chmod() , excepto que opera en un descriptor de archivo abierto.

Si el atacante no puede modificar ningún directorio ancestral del directorio que contiene este archivo, esto es todo lo que necesita hacer. Si el atacante puede modificar directorios de antepasados, entonces es posible que haya seguido un enlace simbólico en un componente anterior de la ruta cuando llamó a lstat . Por lo tanto, se vuelve un poco más complicado:

  1. lstat() el primer componente de la ruta que podría ser un enlace simbólico. Ahorre st_dev y st_ino .
  2. chdir() en el siguiente componente de la ruta usando una ruta relativa .
  3. stat() el directorio actual ( . ) y asegúrese de que st_dev y st_ino sean iguales.
  4. Repita hasta que llegue al directorio que contiene el archivo.

Cuando finalmente haya llegado al directorio que contiene el archivo, realice los pasos originales anteriores, pero asegúrese de llamar a lstat() y open() en una ruta relativa.

    
respondido por el AGWA 21.11.2012 - 05:14
fuente
1

Tenga en cuenta: configurar un ejecutable como no ejecutable no impide que se ejecute si es legible (sin mencionar el concepto de copiar el archivo).

$ cp /bin/ls ~/bin/ls
$ chmod a-x ~/bin/ls
$ /lib/x86_64-linux-gnu/ld-2.15.so ~/bin/ls
#Yup, that worked.

... aunque puedes evitarlo si el archivo no se puede leer, lo que no detiene la ejecución.

$ chmod a+x ~/bin/ls 
$ chmod a-r ~/bin/ls
$ ~/bin/ls
#Worked
$ /lib/x86_64-linux-gnu/ld-2.15.so ~/bin/ls 
/home/me/bin/ls: error while loading shared libraries: /home/me/bin/ls: cannot open shared object file: Permission denied

Podría evitar que un programa se ejecute como suid, pero la respuesta a eso probablemente no implique establecer el bit de ejecución.

    
respondido por el Jeff Ferland 21.11.2012 - 02:35
fuente

Lea otras preguntas en las etiquetas