Llamar a un script desde un programa setuid root C - guión no se ejecuta como root

StackOverflow https://stackoverflow.com/questions/556194

  •  05-09-2019
  •  | 
  •  

Pregunta

necesito para ejecutar un script bash como root (sudo sin contraseña o su no viables) y ya que no puede setuid una secuencia de comandos en Linux, pensé en llamar desde un ejecutable y hacer que 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 en la secuencia de comandos se ejecuta correctamente -. Pero el script se ejecuta como el usuario que ejecuta "./wrapper"

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

Gracias!

¿Fue útil?

Solución

Desde el bit suid en ejecutables sólo cambia el UID efectivo (EUID) el ejecutable se ejecutará como, y no el verdadero UID (RUID) que getuid() devoluciones, y además de la restricción de la suid interpretarse secuencias de comandos (cualquier principio ejecutable con "#!"), algunas conchas como bash como una medida de seguridad adicional establecerá el EUID de nuevo a la RUID en este caso, tendrá que utilizar el setuid(0) llamada en el código C antes de ejecutar la secuencia de comandos.

Ver las man del setuid, seteuid, getuid y geteuid para aprender la semántica exacta de los UID real y efectivo.

( ADVERTENCIA ) Por supuesto, este es un punto apropiado mencionar que la restricción de las secuencias de comandos suid en muchos sistemas UNIX, conchas e intérpretes, están ahí por una razón, y es que si el guión no es muy cuidadoso acerca de higienización su entrada y el estado del ambiente cuando se ejecuta, son peligrosos y pueden ser explotados para la escalada de seguridad. Así que tener mucho cuidado al hacer esto. Establecer el acceso a la secuencia de comandos y la envoltura tan estrictas como sea posible, sólo permiten este script muy específico que tiene la intención de ser ejecutado, y limpiar el medio ambiente dentro de su programa de C antes de comenzar la secuencia de comandos, variables de entorno, como PATH para contener exactamente lo es necesario en el orden correcto y no hay directorios que se puede escribir para los demás.

Otros consejos

Otra cosa a tener en cuenta es que la limitación aquí es de fiesta y no el sistema * nix sí. Bash en realidad hacen verificaciones sobre las secuencias de comandos SUID sólo a ejecutarlos con la raíz EUID. Si se toma proyectiles mayores, a menudo obtendrá lo que quería sacarlo de la caja. Por ejemplo, sh no hace que 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

Sin embargo, la respuesta de Tom es generalmente el camino a seguir para la fabricación de un contenedor para los programas de root

Agregue el setuid (0) en el guión y compilarlo. Se debe trabajar 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 
$ 

Los ejemplos son terriblemente inseguro y permite a cualquier persona con dos bits de conocimiento para ejecutar cualquier programa que quieren que el usuario setuid.

Nunca pasar por una cáscara menos que desinfectar el ambiente en primer lugar, la mayor parte de los ejemplos que se muestran aquí son vulnerables a tener IFS y trayectoria del sistema antes de ejecutarlo.

¿Por qué no es viable sudo? Evita que rabia 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 al ambiente no está adecuadamente desinfectada, por ejemplo, en este caso:

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

sudo desinfecta este caso, y tal vez otros casos extremos y trampas que serían bien en no escribir en una envoltura personalizada SUID.

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