Ir al contenido

PersistenciaAntiforense

/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

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

ArtefactoRutaEstado normal
Lista de precarga de todo el sistema/etc/ld.so.preloadAusente en las instalaciones habituales de Debian, Ubuntu y la familia RHEL
Precarga por procesoLD_PRELOAD en /proc/<pid>/environNormalmente no definida
Dónde se define/etc/environment, archivos de arranque de la shell, Environment= de systemd, ~/.ssh/environmentRara 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/*.confSolo entradas que pertenecen a paquetes
Caché compilada/etc/ld.so.cacheLa regenera ldconfig
Bibliotecas cargadas (en vivo)/proc/<pid>/mapsSolo 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.preload se 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_PRELOAD en 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

ElementoSignificado
Contenido de /etc/ld.so.preloadLista de rutas de objetos compartidos separadas por espacios en blanco
Orden de cargaPrimero LD_PRELOAD, después la opción --preload de ld.so y por último /etc/ld.so.preload
Modo de ejecución seguraEn 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_AUDITOtras 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/*.confUn 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.preload con debugfs en sistemas de archivos ext o con xfs_db en XFS, y registra sus datos stat incluso 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.preload en 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 con dpkg -S o rpm -qf y consulte la documentación del fabricante.
  • Si ls /etc en el host en vivo no muestra el archivo pero una herramienta estática o debugfs sí, tiene una evidencia sólida de un rootkit activo.
  • La misma ruta de biblioteca apareciendo en /proc/<pid>/maps de 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.
  • ldd sobre un binario no fiable puede ejecutarlo; inspecciónelo con readelf -d u objdump -p.
  • Busque el momento de la implantación: un /etc/ld.so.preload nuevo 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.

Ver también