euid, ruid, suid
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Variables de Identificación de Usuario
ruid: El ID de usuario real denota al usuario que inició el proceso.euid: Conocido como el ID de usuario efectivo, representa la identidad del usuario utilizada por el sistema para determinar los privilegios del proceso. Generalmente,euidreflejaruid, salvo en instancias como la ejecución de un binario SetUID, dondeeuidasume la identidad del propietario del archivo, otorgando así permisos operativos específicos.suid: Este ID de usuario guardado es fundamental cuando un proceso de alto privilegio (normalmente ejecutándose como root) necesita renunciar temporalmente a sus privilegios para realizar ciertas tareas, solo para luego recuperar su estado elevado inicial.
Nota Importante
Un proceso que no opera bajo root solo puede modificar su euid para que coincida con el ruid, euid o suid actuales.
Entendiendo las Funciones set*uid
setuid: Contrario a las suposiciones iniciales,setuidmodifica principalmenteeuiden lugar deruid. Específicamente, para procesos privilegiados, alinearuid,euidysuidcon el usuario especificado, a menudo root, solidificando efectivamente estos IDs debido alsuidque prevalece. Se pueden encontrar detalles en la página del manual de setuid.setreuidysetresuid: Estas funciones permiten el ajuste matizado deruid,euidysuid. Sin embargo, sus capacidades dependen del nivel de privilegio del proceso. Para procesos que no son root, las modificaciones están restringidas a los valores actuales deruid,euidysuid. En contraste, los procesos root o aquellos con la capacidadCAP_SETUIDpueden asignar valores arbitrarios a estos IDs. Se puede obtener más información de la página del manual de setresuid y de la página del manual de setreuid.
Estas funcionalidades no están diseñadas como un mecanismo de seguridad, sino para facilitar el flujo operativo previsto, como cuando un programa adopta la identidad de otro usuario al alterar su ID de usuario efectivo.
Notablemente, aunque setuid puede ser un recurso común para la elevación de privilegios a root (ya que alinea todos los IDs a root), diferenciar entre estas funciones es crucial para entender y manipular los comportamientos del ID de usuario en diferentes escenarios.
Mecanismos de Ejecución de Programas en Linux
Llamada al Sistema execve
- Funcionalidad:
execveinicia un programa, determinado por el primer argumento. Toma dos argumentos de matriz,argvpara argumentos yenvppara el entorno. - Comportamiento: Retiene el espacio de memoria del llamador pero actualiza la pila, el montón y los segmentos de datos. El código del programa es reemplazado por el nuevo programa.
- Preservación del ID de Usuario:
ruid,euidy los IDs de grupo suplementarios permanecen inalterados.euidpuede tener cambios matizados si el nuevo programa tiene el bit SetUID establecido.suidse actualiza desdeeuiddespués de la ejecución.- Documentación: Se puede encontrar información detallada en la página del manual de
execve.
Función system
- Funcionalidad: A diferencia de
execve,systemcrea un proceso hijo utilizandoforky ejecuta un comando dentro de ese proceso hijo utilizandoexecl. - Ejecución de Comandos: Ejecuta el comando a través de
shconexecl("/bin/sh", "sh", "-c", command, (char *) NULL);. - Comportamiento: Como
execles una forma deexecve, opera de manera similar pero en el contexto de un nuevo proceso hijo. - Documentación: Se pueden obtener más detalles de la página del manual de
system.
Comportamiento de bash y sh con SUID
bash:- Tiene una opción
-pque influye en cómo se trataneuidyruid. - Sin
-p,bashestableceeuidaruidsi inicialmente difieren. - Con
-p, se preserva eleuidinicial. - Se pueden encontrar más detalles en la página del manual de
bash. sh:- No posee un mecanismo similar a
-penbash. - El comportamiento respecto a los IDs de usuario no se menciona explícitamente, excepto bajo la opción
-i, enfatizando la preservación de la igualdad entreeuidyruid. - Información adicional está disponible en la página del manual de
sh.
Estos mecanismos, distintos en su operación, ofrecen una gama versátil de opciones para ejecutar y transitar entre programas, con matices específicos en cómo se gestionan y preservan los IDs de usuario.
Pruebas de Comportamientos de ID de Usuario en Ejecuciones
Ejemplos tomados de https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail, consúltalo para más información
Caso 1: Usando setuid con system
Objetivo: Entender el efecto de setuid en combinación con system y bash como sh.
Código C:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
system("id");
return 0;
}
Compilación y Permisos:
oxdf@hacky$ gcc a.c -o /mnt/nfsshare/a;
oxdf@hacky$ chmod 4755 /mnt/nfsshare/a
bash-4.2$ $ ./a
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Análisis:
ruidyeuidcomienzan como 99 (nadie) y 1000 (frank) respectivamente.setuidalinea ambos a 1000.systemejecuta/bin/bash -c iddebido al symlink de sh a bash.bash, sin-p, ajustaeuidpara que coincida conruid, resultando en que ambos sean 99 (nadie).
Caso 2: Usando setreuid con system
Código C:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setreuid(1000, 1000);
system("id");
return 0;
}
Compilación y Permisos:
oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b
Ejecución y Resultado:
bash-4.2$ $ ./b
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Análisis:
setreuidestablece tanto ruid como euid a 1000.systeminvoca bash, que mantiene los IDs de usuario debido a su igualdad, operando efectivamente como frank.
Caso 3: Usando setuid con execve
Objetivo: Explorar la interacción entre setuid y execve.
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/usr/bin/id", NULL, NULL);
return 0;
}
Ejecución y Resultado:
bash-4.2$ $ ./c
uid=99(nobody) gid=99(nobody) euid=1000(frank) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Análisis:
ruidpermanece en 99, pero euid se establece en 1000, en línea con el efecto de setuid.
Ejemplo de Código C 2 (Llamando a Bash):
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setuid(1000);
execve("/bin/bash", NULL, NULL);
return 0;
}
Ejecución y Resultado:
bash-4.2$ $ ./d
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
Análisis:
- Aunque
euidse establece en 1000 porsetuid,bashrestableceeuidaruid(99) debido a la ausencia de-p.
Ejemplo de código C 3 (Usando bash -p):
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
char *const paramList[10] = {"/bin/bash", "-p", NULL};
setuid(1000);
execve(paramList[0], paramList, NULL);
return 0;
}
Ejecución y Resultado:
bash-4.2$ $ ./e
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) euid=100
Referencias
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


