/etc/ld.so.preload y LD_PRELOAD: secuestro del enlazador
El archivo de precarga del enlazador dinámico, LD_PRELOAD y ld.so.conf: cómo los rootkits de usuario inyectan bibliotecas en cada proceso y cómo detectarlos.
- Ubicación
- /etc/ld.so.preload
- Prueba
- Si se forzó la carga de una biblioteca compartida en los procesos enlazados dinámicamente, cuál y desde cuándo
- Marcas de tiempo
- mtime/ctime/crtime del archivo de precarga y de la biblioteca; sin marcas de tiempo internas
- Acceso
- root para escribir; legible por todos; el propio rootkit puede ocultarlo a las herramientas en vivo
- Retención
- Hasta su borrado; LD_PRELOAD en el entorno de un proceso dura hasta que el proceso termina
- Adquisición
- UAC, debugfs, cp -a, AVML
Herramientas
Comparar todas las herramientas- debugfsCLI · incluido en Linux
- UACCLI · código abierto
- Volatility 3CLI · código abierto
- VelociraptorPlataforma · código abierto
Qué es
Todo programa Linux enlazado dinámicamente empieza ejecutando el enlazador dinámico (ld.so / ld-linux*.so), que carga las bibliotecas compartidas que necesita el programa. Antes que ellas, carga las bibliotecas indicadas en la variable de entorno LD_PRELOAD y después las que figuran en /etc/ld.so.preload. Una biblioteca precargada puede sustituir funciones de libc como readdir, fopen o execve, que es precisamente como los rootkits de espacio de usuario ocultan archivos, procesos y conexiones de red (MITRE ATT&CK T1574.006). MITRE cita a Hildegard y Rocke entre las familias que modificaron /etc/ld.so.preload.
Los archivos relacionados /etc/ld.so.conf, /etc/ld.so.conf.d/*.conf y /etc/ld.so.cache controlan dónde se buscan las bibliotecas. Son menos directos, pero se pueden abusar para que una copia maliciosa de una biblioteca gane la búsqueda.
Dónde se encuentra
| Artefacto | Ruta | Estado normal |
|---|---|---|
| Lista de precarga de todo el sistema | /etc/ld.so.preload | Ausente en las instalaciones habituales de Debian, Ubuntu y la familia RHEL |
| Precarga por proceso | LD_PRELOAD en /proc/<pid>/environ | Normalmente no definida |
| Dónde se define | /etc/environment, archivos de arranque de la shell, Environment= de systemd, ~/.ssh/environment | Rara vez contiene LD_PRELOAD |
| Configuración de búsqueda de bibliotecas | /etc/ld.so.conf (normalmente include /etc/ld.so.conf.d/*.conf), /etc/ld.so.conf.d/*.conf | Solo entradas que pertenecen a paquetes |
| Caché compilada | /etc/ld.so.cache | La regenera ldconfig |
| Bibliotecas cargadas (en vivo) | /proc/<pid>/maps | Solo las bibliotecas esperadas |
Las rutas son las mismas en todas las familias de distribuciones; los directorios de bibliotecas varían (/usr/lib/x86_64-linux-gnu en Debian/Ubuntu, /usr/lib64 en RHEL/Fedora).
Qué prueba
- Una biblioteca que figura en
/etc/ld.so.preloadse cargó en todos los programas enlazados dinámicamente iniciados después de crear el archivo, incluidas las sesiones de sshd y las shells de root. LD_PRELOADen el entorno de un proceso muestra que ese proceso, y normalmente sus hijos, se ejecutaron con la biblioteca inyectada.- Las funciones de la biblioteca definen el alcance del rootkit: los hooks sobre el listado de directorios implican ocultación de archivos, y los hooks sobre funciones de autenticación apuntan a captura de credenciales.
- Lo que no prueba: los binarios enlazados estáticamente no usan el enlazador dinámico y no se ven afectados. La mera presencia del archivo no dice qué hace la biblioteca; para eso hace falta ingeniería inversa.
Campos clave
| Elemento | Significado |
|---|---|
Contenido de /etc/ld.so.preload | Lista de rutas de objetos compartidos separadas por espacios en blanco |
| Orden de carga | Primero LD_PRELOAD, después la opción --preload de ld.so y por último /etc/ld.so.preload |
| Modo de ejecución segura | En binarios setuid/setgid o con capabilities (AT_SECURE), se ignoran las entradas de LD_PRELOAD que contienen una barra, y solo se cargan bibliotecas setuid de los directorios estándar |
LD_LIBRARY_PATH, LD_AUDIT | Otras variables del enlazador que se abusan del mismo modo; restringidas en modo de ejecución segura (LD_LIBRARY_PATH se ignora; LD_AUDIT, como LD_PRELOAD, solo carga bibliotecas set-user-ID de los directorios estándar) |
/etc/ld.so.conf.d/*.conf | Un directorio por línea; un directorio añadido por un atacante y listado al principio puede suplantar bibliotecas reales |
Marcas de tiempo
No hay marcas de tiempo internas. Use el mtime, el ctime y la hora de creación de /etc/ld.so.preload, de la biblioteca que indica y de /etc/ld.so.cache (que se reescribe cada vez que se ejecuta ldconfig). La hora de creación del archivo de precarga suele ser la mejor estimación de cuándo empezó el hooking. Compárela con las horas de inicio de los procesos (ver artefactos en vivo de /proc): los procesos iniciados antes no llevan la biblioteca salvo que se reinicien.
Retención
El archivo persiste hasta que se borra. Eliminarlo no descarga la biblioteca de los procesos que ya están en ejecución. LD_PRELOAD definida en el entorno de un proceso desaparece cuando el proceso termina, así que captúrela en vivo o desde la memoria.
Adquisición
Un rootkit de precarga puede ocultar su propia configuración a las herramientas que usan libc, así que lea el archivo por debajo de la capa de libc:
- Desde una imagen de disco o un montaje de solo lectura en un equipo de análisis limpio (preferible).
- En un host en vivo, con una herramienta enlazada estáticamente o directamente desde el sistema de archivos: UAC incluye un artefacto que vuelca
/etc/ld.so.preloadcondebugfsen sistemas de archivos ext o conxfs_dben XFS, y registra sus datosstatincluso cuando el archivo está oculto. - Capture la memoria (AVML o LiME) para poder extraer las bibliotecas precargadas de cada proceso.
# live, ext4 root on /dev/sda1: read the file through debugfs rather than libc
debugfs -R 'cat /etc/ld.so.preload' /dev/sda1
debugfs -R 'stat /etc/ld.so.preload' /dev/sda1
# live, static busybox from trusted media
/media/ir/busybox cat /etc/ld.so.preload
/media/ir/busybox grep -l LD_PRELOAD /proc/[0-9]*/environ
Análisis
R=/mnt/evidence
ls -la --time-style=full-iso "$R"/etc/ld.so.preload && cat "$R"/etc/ld.so.preload
grep -rn 'LD_PRELOAD\|LD_LIBRARY_PATH\|LD_AUDIT' "$R"/etc "$R"/root "$R"/home/*/.[a-z]* 2>/dev/null
cat "$R"/etc/ld.so.conf "$R"/etc/ld.so.conf.d/*.conf
ldconfig -p -C "$R"/etc/ld.so.cache | less # cache contents from the image
En memoria, linux.envars de Volatility 3 muestra LD_PRELOAD por proceso, linux.proc.Maps enumera las bibliotecas mapeadas y linux.elfs puede volcarlas para su análisis. Linux.Sys.Maps de Velociraptor ofrece la misma visión sobre una flota en vivo.
Consejos para la investigación
- Trate cualquier
/etc/ld.so.preloaden un servidor como un hallazgo prioritario hasta que se explique. Si se alega que un producto lo necesita, confirme a qué paquete pertenece la biblioteca condpkg -Sorpm -qfy consulte la documentación del fabricante. - Si
ls /etcen el host en vivo no muestra el archivo pero una herramienta estática odebugfssí, tiene una evidencia sólida de un rootkit activo. - La misma ruta de biblioteca apareciendo en
/proc/<pid>/mapsde muchos procesos sin relación entre sí es la firma en vivo de una precarga a nivel de todo el sistema. - Las bibliotecas maliciosas suelen llevar nombres que se confunden con bibliotecas del sistema; revise el tipo de archivo, el propietario, el ctime y si algún paquete las incluye.
lddsobre un binario no fiable puede ejecutarlo; inspecciónelo conreadelf -duobjdump -p.- Busque el momento de la implantación: un
/etc/ld.so.preloadnuevo poco antes de un reinicio de sshd u otros demonios es un patrón observado en casos reales. Revise las unidades systemd y el journal en busca de ese reinicio. - Los rootkits de precarga no pueden esconderse del kernel; cuando el análisis del espacio de usuario y el de memoria no coinciden, fíese de la memoria. Si ambos parecen limpios pero el comportamiento es extraño, revise los módulos del kernel.