Este es un set-root-uid programa

$ls -l
-rwsr-sr-x 1 root root 7406 2011-12-13 22:37 ./x*

El código fuente:

int main(void) {
    printf(
        "         UID           GID  \n"
        "Real      %d  Real      %d  \n"
        "Effective %d  Effective %d  \n",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

seteuid(600);
    printf(
        "         UID           GID  \n"
        "Real      %d  Real      %d  \n"
        "Effective %d  Effective %d  \n",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

setuid(1000);

    printf(
        "         UID           GID  \n"
        "Real      %d  Real      %d  \n"
        "Effective %d  Effective %d  \n",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

setuid(0); //HOW DOES THIS SUCCEED IN SETTING THE EUID BACK TO 0
    printf(
        "         UID           GID  \n"
        "Real      %d  Real      %d  \n"
        "Effective %d  Effective %d  \n",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

    return 0 ;       
}

SALIDA

         UID           GID  
Real      1000  Real      1000  
Effective 0  Effective 0  
         UID           GID  
Real      1000  Real      1000  
Effective 600  Effective 0  
         UID           GID  
Real      1000  Real      1000  
Effective 1000  Effective 1000  
         UID           GID  
Real      1000  Real      1000  
Effective 0  Effective 1000  

Mi pregunta

La página man de los estados que setuid va a cambiar,el real, el salvado y el uid efectivo.
Así que después de la llamada setuid(1000), todos los tres de cambiar a 1000.
Cómo es que setuid(0) me dejo cambiar euid a 0?

4 Comentarios

  1. 30

    Hay dos casos,

    1. Desea quitar temporalmente privilegios de root durante la ejecución del programa setuid
    2. Desea permanentemente gota privilegios de root durante la ejecución del programa setuid…
    • Temporalmente puede hacerlo mediante la configuración de la euid a la real id de usuario y, a continuación, cambiar el uid para cualquier cosa que usted desea.Y más tarde, cuando usted necesita el privilegio de raíz de vuelta, puede setuid root y el buen nombre de usuario se cambie de nuevo a la raíz. Esto es debido a que el guarda el id de usuario no ha cambiado.
    • Puede bajar el privilegio permanentemente por cambiar el uid de inmediato a un menor privilegio de id de usuario. Después de esto, no importa lo que usted no puede recuperar los privilegios de root.

    Caso 1:

    Después de un programa setuid comienza a ejecutar

    1.seteuid(600);
    2.setuid(1000);
    3.setuid(0);
    

    Para este caso los privilegios de root puede ser recuperado de nuevo.

                  +----+------+------------+
                  | uid|euid  |saved-uid   |
                  |---- | ------ | ------------|
                1.|1000| 0    | 0          |
                2.|1000| 600  | 0          |
                3.|1000| 1000 | 0          |
                4.|1000|  0   | 0          |
                  |    |      |            |
                  +------------------------+
    

    Caso 2:

    Después de un programa setuid comienza a ejecutar,

    1.setuid(1000);
    2.setuid(0);
    
    
    
                   +----+------+------------+
                   | uid|euid  |saved-uid   |
                   |---- | ------ | ------------|
                 1.|1000|0     | 0          |
                 2.|1000|1000  | 1000       |
                   |    |      |            |
                   +------------------------+
    

    En este caso, usted no puede recuperar los privilegios de root.
    Esto puede ser verificado mediante el siguiente comando,

    cat /proc/PROCID/tarea/PROCID/estado | menos

    Uid:    1000    0       0       0
    Gid:    1000    0       0       0
    

    Este comando mostrará un Uid y Gid y tendrá 4 campos( los tres primeros campos son los que nos interesa). Algo como lo anterior,

    Los tres campos representan uid,euid y salvos-identificador de usuario. Usted puede introducir una pausa (una entrada de usuario) en su programa setuid y de verificación para cada paso de la cat /proc/PROCID/task/PROCID/status | less comando. Durante cada paso se puede verificar la guarda uid llegar cambiado como se ha mencionado.

    Si usted está euid es root y cambiar el uid, los privilegios se cae permanentemente.Si el id de usuario no es root, a continuación, guarda el id de usuario no se toca y usted puede recuperar los privilegios de root de nuevo en cualquier momento que desee en su programa.

    • ¿Me pueden decir la última columna de Uido: 1000 0 0 0 representa
    • Cuando he intentado probar con un código de ejemplo el cuarto valor que se muestra el mismo identificador de usuario efectivo. Supongo que debe ser el identificador de usuario efectivo, pero aunque no estoy seguro por qué habría de impresión identificador de usuario efectivo dos veces.
    • La última columna es el FSUID
    • para aquellos que están tratando de seguir adelante sin groovy (por ejemplo. en un shell de bash), intente esto: cat /proc/$$/task/$$/status | grep -A2 TracerPid
    • Parece que el escenario es mucho más complicado bajo diferentes sistemas con _POSIX_SAVED_IDS definido o no
  2. 8

    DESCRIPCIÓN
    setuid() establece el ID de usuario efectivo del proceso de llamada. Si el UID efectivo de la persona que llama
    de la raíz, el UID real y guarda set-user-ID también se establecen.

    Bajo Linux, setuid() se implementa como la versión POSIX con el _POSIX_SAVED_IDS característica. Este
    permite un set-user-ID (no root) programa para colocar todos sus privilegios de usuario, hacer un poco de onu-privilegio de trabajo y, a continuación, reanudar el original IDENTIFICADOR de usuario efectivo de una manera segura.

    Si el usuario es root o el programa set-user-ID-de la raíz, se debe tener especial cuidado. El setuid() función comprueba el ID de usuario efectivo de la persona que llama y si es el superusuario, todos los procesos relacionados con el usuario
    ID de set a uid. Después de esto ha ocurrido, es imposible que el programa para recuperar los privilegios de root.

    Por lo tanto, un set-user-ID-raíz de programa que desee quitar temporalmente los privilegios de root, asumir la identidad de un
    usuario sin privilegios, y luego recuperar los privilegios de root después puede utilizar setuid(). Usted puede lograr
    esto con seteuid(2).

    (de Linux) Programadores Manual, 2014-09-21, página setuid.2)

    • De acuerdo a lo que dijo el último segmento de la producción debe mostrar Effective = 1000. Pero es capaz de volver a 0. Ese es precisamente mi pregunta.
    • Creo que es debido a la llamada a la seteuid que estás haciendo; esto hace que el núcleo de «proteger» a su capacidad para recuperar root en el futuro. La eliminación de la llamada que elimina la «puerta trasera» del efecto.
    • Sí, @ajai la respuesta que proporciona la prueba demasiado. Gracias por la respuesta de todos modos
  3. 3

    O! Estas funciones son difíciles de utilizar correctamente.

    La página man de los estados que setuid va a cambiar,el real, el salvado y el uid efectivo. Así que después de la llamada setuid(1000), los tres cambios a 1000.

    Que es el caso si y sólo si son euid 0. En el momento de llamar a setuid(0), sin embargo, se euid 1000 y guardado uid 0 (marque getresuid(2), por ejemplo). Es por eso que usted es capaz de recuperar privilegios.

    • Estás en lo correcto. El getresuid() parece estar funcionando bien. Pero no es POSIX compatible. Pero eso no importa en este caso. Gracias..
  4. 1

    Código:

    #define _GNU_SOURCE
    #include <stdio.h>
    #include <unistd.h>
    
    void print_uid(char *str, int ret)
    {
        uid_t ruid;
        uid_t euid;
        uid_t suid;
        getresuid(&ruid, &euid, &suid);
    
        printf("%s ret:%d\n"
               "Real:%4d  Effective:%4d  Saved:%4d\n",
               str, ret, ruid, euid, suid);
    }
    
    int main(void)
    {
        int ret = 0;
        print_uid("init", ret);            /* Real:1000  Effective:   0  Saved:   0 */
    
        ret = seteuid(600);
        print_uid("seteuid(600)", ret);    /* Real:1000  Effective: 600  Saved:   0 */
    
        ret = setuid(1000);
        print_uid("setuid(1000)", ret);    /* Real:1000  Effective:1000  Saved:   0 */
    
        ret = setuid(0);
        print_uid("setuid(0)", ret);       /* Real:1000  Effective:   0  Saved:   0 */
    
        ret = setuid(1000);
        print_uid("setuid(1000)", ret);    /* Real:1000  Effective:1000  Saved:1000 */
    
        ret = setuid(0);
        print_uid("setuid(0)", ret);       /* Real:1000  Effective:1000  Saved:1000 */
    
        return 0 ;       
    }
    

    sudo chown root setuid_feature

    sudo chmod +s setuid_feature

    Hay tres uid de un proceso en Linux: REAL uid uid EFECTIVO, GUARDA uid.

    Cond 1. Cuando euid es root, setuid o seteuid se puede configurar para cualquier fluido, pero no es un efecto secundario, cuando se utiliza el bit setuid(no seteuid), todos de los tres puede ser la misma uid que no es RAÍZ y, a continuación, el proceso no puede recuperar privilegios de ROOT.

    Cond 2. Cuando euid no es root, setuid o seteuid se puede configurar para ruid o suid, y sólo euid es cambiado.

                           |      seteuid             |          setuid  
    Cond 1. (euid == root) | set euid to any uid      | set all three uids to any uid  
    Cond 2. (euid != root) | set euid to ruid or suid | set euid to ruid or suid  
    

    así, hay 5 setuid o seteuid proceso en el código, me permiten clasificarlos en:

    1. seteuid(600): Cond 1, establece euid a 600

    2. setuid(1000): Cond 2, establece euid a 1000

    3. setuid(0) : Cond 2, establece euid a 0(suid)

    4. setuid(1000): Cond 1, ajuste los tres uid 1000

    5. setuid(0) : Cond 2, todos los tres de uidos no es igual a 0, por lo que no se puede establecer a 0, no pudo con ret = -1

Dejar respuesta

Please enter your comment!
Please enter your name here