sistema() vs execve()

Tanto system() y execve() se puede utilizar para ejecutar otro comando dentro de un programa. ¿Por qué en el set-UID programas, system() es peligroso, mientras que execve() es seguro ?

InformationsquelleAutor Jake | 2014-12-12

3 Kommentare

  1. 16

    sistema de va a llamar a la shell (sh) para ejecutar el comando enviado como argumento. El problema con system debido a que la cáscara comportamiento depende del usuario que ejecuta el comando. Un pequeño ejemplo:

    La creación de un archivo de test.c:

    #include <stdio.h>
    
    int main(void) {
        if (system ("ls") != 0)
            printf("Error!");
        return 0;
    }
    

    A continuación:

    $ gcc test.c -o test
    
    $ sudo chown root:root test
    
    $ sudo chmod +s test
    
    $ ls -l test
    -rwsr-sr-x 1 root root 6900 Dec 12 17:53 test
    

    La creación de un script llamado ls en el directorio actual:

    $ cat > ls
    #!/bin/sh
    
    /bin/sh
    
    $ chmod +x ls
    

    Ahora:

    $ PATH=. ./test
    # /usr/bin/id
    uid=1000(cuonglm) gid=1000(cuonglm) euid=0(root) egid=0(root) groups=0(root),
    24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),105(scanner),
    110(bluetooth),111(netdev),999(docker),1000(cuonglm)
    # /usr/bin/whoami
    root
    

    Uy, tengo un shell con privilegios de root.

    execve no llamar a una shell. Se ejecuta el programa que se le pasa como primer argumento. El programa debe ser un archivo binario ejecutable o una secuencia de comandos de inicio con shebang línea.

    • No digo system() es sin problemas, pero no el de arriba se resuelve mediante el uso de rutas de acceso absolutas en el binario ejecutable?
    • no, necesitarías al menos para despejar el ambiente, dar cuerda valores predeterminados para un par de envvars (RUTA de acceso, CASA…), si es necesario preservar algunos env variables después de la esterilización (PLAZO, PANTALLA, LANG…) asegúrese de que el fds 0, 1, 2 están abiertos… Básicamente hacer lo que sudo no. Incluso entonces, yo no iría allí. No se debe invocar una shell en la escalada de privilegios en contexto si que se puede evitar. Tenga en cuenta que ls puede hacer cosas de lujo con su entorno, por lo que incluso sin system(), probablemente, usted debe higienizar el medio ambiente. Cuando se utiliza setuids desea minimizar lo que se hace como root (normalmente no ejecutar comandos).
    • No, usted todavía tiene un problema, incluso si utiliza la ruta de acceso completa. Si utiliza /bin/ls, el usuario puede agregar / a $IFS, causando la concha dividida /bin/ls a bin y ls. Ahora, un ejecutable llamado bin en el directorio actual puede hacer la misma cosa como ls en mi respuesta.
    • Gracias a ambos. De hecho, esta fue una bastante interesante respuesta.
  2. 11

    system() y execve() trabajo de diferentes maneras. system() siempre invocar la shell y esta concha se va a ejecutar el comando como un proceso independiente (esta es la razón por la que usted puede utilizar caracteres comodín y otras instalaciones de shell en la línea de comandos cuando se utiliza system()).

    execve() (y las otras funciones de la exec() familia) reemplaza el actual proceso con el que está siendo generado directamente (el execve() función de no devolución, excepto en caso de fallo). De hecho system() aplicación se supone que el uso de una secuencia de fork(), execve() y wait() llamadas para realizar su función.

    Por supuesto, ambas son peligrosas dependiendo de lo que se ejecuta cuando el proceso tiene privilegios de root. system(), sin embargo, trae algunos extras peligros debido a la shell «capa» se utiliza la que se abre la sala de brechas de seguridad como se llama a una shell de root como en el caso de tu pregunta (es decir, el proceso tiene el bit suid).

    • Así que cuando se utiliza execve() .. que mencionar que reemplaza el actual proceso .. sería el proceso sigue siendo el bit setuid ?
    • Sí. El «nuevo» proceso iniciado por execve hereda un número de propiedades de un ser reemplazado, como filedescriptors, sockets, etc. y el uid efectivo es uno de ellos, pero hay situaciones en las que el uid cambios durante la ejecución de execve, como si el ejecutable señalado por el execve parámetro se ha activado el bit suid. En este caso, el líquido se cambia el propietario del archivo y como se define en el sistema de ficheros.
  3. 1

    Aparte de la metioned problemas de seguridad con system(), el proceso generado hereda el principal programa del medio ambiente. Esto puede ser muy problemático cuando se utiliza suid, por ejemplo, cuando el proceso de llamada conjuntos de LD_LIBRARY_PATH-variable de entorno.

    Con el exec()-familia el programa de llamada puede configurar el entorno para exactamente lo que se necesita (y seguro) para el llamado programa antes de llamar a exec().

    Y, por supuesto, la concha se llama por system() puede tener problemas de seguridad en sí mismo.

    • La variable de entorno LD_LIBRARY_PATH será ignorada cuando setuid programa es ejecutado por el usuario no-root, excepto cuando el uid real también es 0.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea