scripts script programar programacion pasar parametros otro ejemplos ejecutar desde comandos comando c scripting setuid

programar - script linux ejemplos



Llamar a un script desde un programa setuid root C: el script no se ejecuta como root (5)

Necesito ejecutar un script bash como root (sudo o su no viable sin contraseña) y como no se puede establecer un script en Linux, pensé en llamarlo desde un ejecutable y hacer que fuera setuid:

$ cat wrapper.c int main(void) { system("/bin/bash ./should_run_as_root.sh"); } $ gcc -o wrapper wrapper.c $ sudo chown root wrapper $ sudo chmod ug+s wrapper $ ll wrapper -rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper $

Esto funciona, al igual que ejecutar el script correctamente, pero el script se ejecuta como el usuario que ejecuta "./wrapper".

¿Por qué? ¿Y cómo implementar esto correctamente?

¡Gracias!


Como el bit de suid en ejecutables solo cambia el UID efectivo (EUID), el ejecutable se ejecutará como, y no el UID real (RUID) que getuid() , y además de la restricción en scripts interpretados suid (cualquier ejecutable que comience con " #! "), algunos shells como bash como una medida de seguridad adicional establecerán el EUID de nuevo en el RUID en este caso, deberá usar el setuid(0) llamada setuid(0) en el código C antes de ejecutar el script.

Consulte las páginas man de setuid , seteuid , getuid y geteuid para conocer la semántica exacta de los UID reales y efectivos.

( ADVERTENCIA ) Por supuesto, este es un punto apropiado para mencionar que la restricción en scripts suid en muchos sistemas Unix, shells e intérpretes, está ahí por una razón, que es que si el script no es muy cuidadoso para desinfectar su entrada y el estado del entorno cuando se ejecuta, son peligrosos y pueden aprovecharse para una escalada de seguridad. Así que ten mucho cuidado al hacer esto. Establezca el acceso a su secuencia de comandos y contenedor lo más estrictamente posible, solo permita este script muy específico que desea ejecutar, y borre el entorno dentro de su programa C antes de iniciar el script, configurando variables de entorno como PATH para que contengan exactamente es necesario en el orden correcto y no hay directorios que puedan escribirse a otros.


Otra cosa a tener en cuenta aquí es que la limitación aquí es de bash y no del sistema * nix en sí mismo. Bash realmente realiza verificaciones en los scripts SUID para ejecutarlos solo con la raíz EUID. Si toma conchas más viejas, a menudo obtendrá lo que quería de la caja. Por ejemplo, sh no hace este tipo de verificaciones:

$ cat wrapper.c int main(void) { system("/bin/sh -c whoami"); } $ ls -l wrapper -rwsr-sr-x 1 root users 8887 Feb 17 14:15 wrapper $ ./wrapper root

Con bash:

$ cat wrapper.c int main(void) { system("/bin/bash -c whoami"); } $ ls -l wrapper -rwsr-sr-x 1 root users 8887 Feb 17 14:18 wrapper $ ./wrapper skinp

Aún así, la respuesta de Tom es generalmente el camino a seguir para crear un contenedor para los programas raíz SUID


Agregue el setuid (0) en el script y complételo. Debería funcionar después de esto.

$ cat wrapper.c int main(void) { setuid(0); system("/bin/bash ./should_run_as_root.sh"); } $ gcc -o wrapper wrapper.c $ sudo chown root wrapper $ sudo chmod ug+s wrapper $ ll wrapper -rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper $


¿Por qué sudo no es viable? Evita feroces agujeros de seguridad tales como:

bash-3.2$ cat test #!/bin/bash echo ima shell script durp durp bash-3.2$ chmod +x test bash-3.2$ ./test heh heh bash-3.2$

Debido a que el medio ambiente no se desinfecta correctamente, por ejemplo en este caso:

export echo=''() { builtin echo heh heh; }''

sudo desinfecta este caso, y tal vez otros casos extremos y errores que sería mejor no escribir en un contenedor de suid personalizado.


Los ejemplos son terriblemente inseguros y permiten a cualquier persona con dos bits de conocimiento ejecutar cualquier programa que desee como usuario de setuid.

Nunca pase por un intérprete de órdenes a menos que primero desinfecte el entorno, la mayoría de los ejemplos que se muestran aquí son vulnerables a tener IFS y PATH configurados antes de ejecutarlo.