Aller au contenu

PersistanceAnti-forensique

/etc/ld.so.preload et LD_PRELOAD : détournement du linker

Fichier de préchargement de l'éditeur de liens, LD_PRELOAD et ld.so.conf : comment les rootkits userland injectent des bibliothèques et comment les repérer.

Emplacement
/etc/ld.so.preload
Prouve
Qu'une bibliothèque partagée a été imposée aux processus liés dynamiquement, laquelle, et depuis quand
Horodatages
mtime/ctime/crtime du fichier de préchargement et de la bibliothèque ; aucun horodatage interne
Accès
root pour écrire ; lisible par tous ; peut être masqué aux outils live par le rootkit lui-même
Rétention
Jusqu'à suppression ; LD_PRELOAD dans l'environnement d'un processus disparaît à la fin du processus
Collecte
UAC, debugfs, cp -a, AVML

Ce que c'est

Tout programme Linux lié dynamiquement commence par exécuter l'éditeur de liens dynamique (ld.so / ld-linux*.so), qui charge les bibliothèques partagées nécessaires. Avant celles-ci, il charge les bibliothèques indiquées dans la variable d'environnement LD_PRELOAD, puis celles listées dans /etc/ld.so.preload. Une bibliothèque préchargée peut remplacer des fonctions de la libc comme readdir, fopen ou execve : c'est précisément ainsi que les rootkits userland masquent fichiers, processus et connexions réseau (MITRE ATT&CK T1574.006). MITRE cite notamment Hildegard et Rocke parmi les familles ayant modifié /etc/ld.so.preload.

Les fichiers associés /etc/ld.so.conf, /etc/ld.so.conf.d/*.conf et /etc/ld.so.cache déterminent où les bibliothèques sont recherchées. Leur abus est moins direct, mais ils peuvent faire gagner la recherche à une copie malveillante d'une bibliothèque.

Où il se trouve

ArtefactCheminÉtat normal
Liste de préchargement globale/etc/ld.so.preloadAbsent sur les installations Debian, Ubuntu et famille RHEL courantes
Préchargement par processusLD_PRELOAD dans /proc/<pid>/environNormalement non défini
Où il est défini/etc/environment, fichiers de démarrage du shell, Environment= systemd, ~/.ssh/environmentContient rarement LD_PRELOAD
Configuration de recherche/etc/ld.so.conf (en général include /etc/ld.so.conf.d/*.conf), /etc/ld.so.conf.d/*.confUniquement des entrées fournies par des paquets
Cache compilé/etc/ld.so.cacheReconstruit par ldconfig
Bibliothèques chargées (live)/proc/<pid>/mapsUniquement les bibliothèques attendues

Les chemins sont identiques d'une famille de distributions à l'autre ; seuls les répertoires de bibliothèques diffèrent (/usr/lib/x86_64-linux-gnu sur Debian/Ubuntu, /usr/lib64 sur RHEL/Fedora).

Ce qu'il prouve

  • Une bibliothèque listée dans /etc/ld.so.preload a été chargée dans chaque programme lié dynamiquement démarré après la création du fichier, y compris les sessions sshd et les shells root.
  • LD_PRELOAD dans l'environnement d'un processus montre que ce processus, et en général ses enfants, s'est exécuté avec la bibliothèque injectée.
  • Les fonctions de la bibliothèque définissent la portée du rootkit : des hooks sur le listage de répertoires signifient du masquage de fichiers, des hooks sur les fonctions d'authentification évoquent une capture d'identifiants.
  • Non prouvé : les binaires liés statiquement n'utilisent pas l'éditeur de liens dynamique et ne sont pas affectés. La présence du fichier ne dit pas ce que fait la bibliothèque ; il faut pour cela de la rétro-ingénierie.

Champs clés

ÉlémentSignification
Contenu de /etc/ld.so.preloadListe de chemins d'objets partagés séparés par des espaces
Ordre de chargementLD_PRELOAD d'abord, puis l'option --preload de ld.so, puis /etc/ld.so.preload
Mode d'exécution sécuriséPour les binaires setuid/setgid ou dotés de capacités (AT_SECURE), les entrées de LD_PRELOAD contenant une barre oblique sont ignorées et seules les bibliothèques setuid des répertoires standard sont chargées
LD_LIBRARY_PATH, LD_AUDITAutres variables de l'éditeur de liens abusées de la même manière ; restreintes en mode d'exécution sécurisée (LD_LIBRARY_PATH est ignorée ; LD_AUDIT, comme LD_PRELOAD, ne charge que des bibliothèques set-user-ID des répertoires standard)
/etc/ld.so.conf.d/*.confUn répertoire par ligne ; un répertoire ajouté en tête par un attaquant peut masquer les vraies bibliothèques

Horodatages

Aucun horodatage interne. Utilisez mtime, ctime et date de naissance de /etc/ld.so.preload, de la bibliothèque qu'il désigne et de /etc/ld.so.cache (réécrit à chaque exécution de ldconfig). La date de création du fichier de préchargement est en général la meilleure estimation du début du détournement. Comparez avec les heures de démarrage des processus (voir artefacts live de /proc) : les processus démarrés avant ne portent pas la bibliothèque, sauf s'ils ont été redémarrés.

Rétention

Le fichier persiste jusqu'à sa suppression. Le supprimer ne décharge pas la bibliothèque des processus déjà en cours. LD_PRELOAD défini dans l'environnement d'un processus disparaît à la fin de celui-ci : capturez-le en live ou depuis la mémoire.

Collecte

Un rootkit de préchargement peut masquer sa propre configuration aux outils qui passent par la libc : lisez le fichier sous la couche libc.

  • Depuis une image disque ou un montage en lecture seule sur une machine d'analyse saine (à privilégier).
  • Sur un hôte live, avec un outil lié statiquement ou directement depuis le système de fichiers : UAC inclut un artefact qui extrait /etc/ld.so.preload avec debugfs sur les systèmes ext ou xfs_db sur XFS, et enregistre ses données stat même si le fichier est masqué.
  • Capturez la mémoire (AVML ou LiME) pour pouvoir extraire les bibliothèques préchargées de chaque processus.
# 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

Analyse

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 mémoire, le plugin Volatility 3 linux.envars affiche LD_PRELOAD par processus, linux.proc.Maps liste les bibliothèques mappées et linux.elfs permet de les extraire pour analyse. L'artefact Velociraptor Linux.Sys.Maps donne la même vue sur un parc live.

Conseils d'investigation

  • Traitez tout /etc/ld.so.preload sur un serveur comme une découverte prioritaire tant qu'il n'est pas expliqué. Si un produit est censé en avoir besoin, vérifiez le paquet propriétaire de la bibliothèque avec dpkg -S ou rpm -qf et la documentation de l'éditeur.
  • Si ls /etc sur l'hôte live ne montre pas le fichier alors qu'un outil statique ou debugfs le voit, vous tenez une preuve solide d'un rootkit actif.
  • Le même chemin de bibliothèque présent dans /proc/<pid>/maps de nombreux processus sans rapport est la signature live d'un préchargement global.
  • Les bibliothèques malveillantes portent souvent des noms imitant des bibliothèques système : vérifiez le type de fichier, le propriétaire, le ctime et si un paquet les fournit.
  • ldd sur un binaire non fiable peut l'exécuter ; inspectez-le plutôt avec readelf -d ou objdump -p.
  • Cherchez l'événement d'implantation : un nouveau /etc/ld.so.preload peu avant le redémarrage de sshd ou d'autres démons est un schéma observé dans des cas réels. Vérifiez les unités systemd et le journal pour ce redémarrage.
  • Les rootkits de préchargement ne peuvent pas se cacher du noyau ; quand l'analyse userland et l'analyse mémoire divergent, faites confiance à la mémoire. Si les deux semblent propres mais que le comportement reste anormal, examinez les modules noyau.

Voir aussi