InfraFenceInfraFence

Live Security Operations

Loslegen

So erkennst und entfernst du ein Rootkit in /etc/ld.so.preload

Zuletzt aktualisiert:

/etc/ld.so.preload listet Bibliotheken, die der dynamische Linker vor allem anderen in jedes Programm lädt. Auf einem normalen Server gibt es diese Datei nicht. Angreifer mit Root-Rechten tragen dort eine Bibliothek ein, die Funktionen der C-Bibliothek ersetzt, etwa die zum Auflisten von Verzeichnissen oder zum Öffnen von Dateien, sodass ps, top, ls, netstat und ss die Prozesse, Dateien und Verbindungen des Angreifers nicht mehr zeigen. Open-Source-Kits wie libprocesshider, Azazel und Jynx arbeiten so, ebenso mehrere Familien von Krypto-Minern und Hintertüren.

Die Schwäche des Tricks: Er wirkt nur auf Programme, die die C-Bibliothek laden. Statisch gelinkte Tools, das direkte Lesen von /proc und ein Blick von außerhalb des laufenden Systems umgehen ihn. Hier erfährst du, wie du prüfst, wie du aufräumst und wann du den Server besser neu aufsetzt. Die Befehle gelten für Debian und Ubuntu sowie für die RHEL-Familie; /usr/lib/libhide.so steht für die Bibliothek, die du findest.

Verstehen, wie sich ein Preload-Rootkit versteckt

  • Prozesse: ps und top lesen das Verzeichnis /proc; ein manipuliertes readdir() überspringt die Prozess-IDs des Angreifers.
  • Dateien: Derselbe Hook versteckt Dateien nach Namen, oft auch /etc/ld.so.preload selbst und die Bibliothek, sodass ls und cat behaupten, sie gäbe es nicht.
  • Verbindungen: netstat und ss verlieren die Zeilen der Sockets des Angreifers.
  • Alles andere funktioniert normal, und genau darum geht es: Der Server wirkt in jedem Tool sauber, dem du sonst vertrauen würdest.

Wovor es sich nicht verstecken kann: vor Programmen, die die C-Bibliothek des Systems nicht nutzen (statisch gelinkte Binärdateien wie busybox-static), vor dem Kernel und vor einem System, das von einem anderen Medium gebootet wurde. Ein Rootkit, das als Kernelmodul geladen wird, ist ein anderer, schwierigerer Fall: Es versteckt sich vor /proc selbst, und die Prüfungen unten können es übersehen.

Mit Tools prüfen, die das Rootkit nicht täuschen kann

Ein statisch gelinktes busybox besorgen

busybox-static ist eine einzige Binärdatei mit ls, cat, grep, sh und mehr, gelinkt ohne die C-Bibliothek, sodass eine vorgeladene Bibliothek nie in sie geladen wird. ldd muss not a dynamic executable antworten.

Debian / Ubuntu
sudo apt install busybox-static
ldd /bin/busybox

Die RHEL-Familie hat in ihren Basis-Repositories kein statisches busybox. Kopier eines von einem sauberen Debian- oder Ubuntu-Rechner (nachdem du dort busybox-static installiert hast) und ruf es in den Befehlen unten als /root/busybox statt busybox auf:

Auf deinem sauberen Rechner
scp /bin/busybox root@SERVER_IP:/root/busybox
ssh root@SERVER_IP 'chmod 700 /root/busybox && ldd /root/busybox'

Hinweis: Ein Paket auf einem kompromittierten Server zu installieren läuft über dessen eigenen, dynamisch gelinkten Paketmanager. Eine Kopie von einem sauberen Rechner ist auf jeder Distribution die vertrauenswürdigere Wahl.

Die Datei direkt lesen

Vergleiche, was busybox sieht, mit dem, was die systemeigenen Tools sehen. Zeigt busybox die Datei und behaupten das normale ls und cat, sie existiere nicht, dann ist gerade ein Rootkit aktiv.

Jede Distribution
sudo busybox ls -la /etc/ld.so.preload
sudo busybox cat /etc/ld.so.preload
ls -la /etc/ld.so.preload
cat /etc/ld.so.preload

Prüf für jede Bibliothek, die die Datei nennt, ob sie zu einem Paket gehört. Es gibt seltene legitime Nutzer, etwa den Befehls-Logger Snoopy und manche Monitoring-Agenten, und sie stammen aus einem Paket, das du installiert hast:

Debian / Ubuntu
dpkg -S /usr/lib/libhide.so
RHEL, Rocky Linux, AlmaLinux, Oracle Linux, Fedora
rpm -qf /usr/lib/libhide.so

Eine Bibliothek, die zu keinem Paket gehört, ist verdächtig. Notier dir Größe und Hash, sieh dir die enthaltenen Namen an (manipulierte Funktionen wie readdir, das Wort /proc) und prüf, welche Prozesse sie geladen haben:

Jede Distribution
sudo busybox ls -la /usr/lib/libhide.so
sudo busybox sha256sum /usr/lib/libhide.so
sudo busybox strings /usr/lib/libhide.so | busybox grep -iE 'readdir|/proc|preload|hide' | busybox head
Jede Distribution
sudo busybox sh -c "busybox grep -l '/usr/lib/libhide.so' /proc/[0-9]*/maps"

/proc mit ps vergleichen

busybox liest /proc ohne den Hook; ps nutzt ihn. Jede Prozess-ID, die busybox findet und ps nicht, ist versteckt, und die Zeile zeigt ihre Binärdatei. Prozesse, die während der Schleife enden, können einmal auftauchen: Lass sie zweimal laufen und sieh dir die IDs an, die beide Male erscheinen.

Jede Distribution
sudo busybox sh -c 'for d in /proc/[0-9]*; do p=${d#/proc/}; /bin/ps -p "$p" > /dev/null 2>&1 || echo "$p $(busybox readlink "$d/exe")"; done'

Dasselbe für Netzwerkverbindungen: busybox netstat liest /proc/net direkt. Eine Verbindung, die in der ersten Liste steht und in der zweiten fehlt, ist versteckt.

Jede Distribution
sudo busybox netstat -tan
sudo ss -tanp

LD_PRELOAD in Umgebungen und Diensten

Derselbe Trick funktioniert pro Prozess, über die Variable LD_PRELOAD in einer Unit-Datei, einem Shell-Profil oder /etc/environment. Such danach in den laufenden Prozessen und in den üblichen Dateien:

Jede Distribution
sudo busybox sh -c "busybox grep -l LD_PRELOAD /proc/[0-9]*/environ"
sudo busybox grep -rs LD_PRELOAD /etc/environment /etc/profile /etc/profile.d /etc/bash.bashrc /etc/bashrc \
  /etc/systemd /lib/systemd/system /usr/lib/systemd/system /root/.bashrc /root/.profile

Veränderte Systembinärdateien

Manche Kits ersetzen zusätzlich ps, ls oder sshd. Die Paketdatenbank listet paketierte Dateien, deren Inhalt sich geändert hat (Konfigurationsdateien ausgenommen):

Debian / Ubuntu
sudo dpkg --verify | grep -v ' c /'
RHEL, Rocky Linux, AlmaLinux, Oracle Linux, Fedora
sudo rpm -Va 2>/dev/null | grep -E '^..5' | grep -v ' c /'

Der sichere Weg: aus einem Rettungssystem

Auch dpkg und rpm sind dynamisch gelinkt. Für ein Ergebnis, auf das du dich verlassen kannst, bootest du das Rettungssystem des Providers, hängst die Festplatte des Servers ein und liest die Datei dort, wo nichts vom Server läuft. Finde die Root-Partition zuerst mit lsblk: /dev/sda1 ist ein Beispiel.

Rettungssystem
lsblk -f
mount /dev/sda1 /mnt
ls -la /mnt/etc/ld.so.preload && cat /mnt/etc/ld.so.preload

Das Preload-Rootkit entfernen

Wenn der Provider einen Snapshot der Festplatte anlegen kann, tu das zuerst. Behalte dann eine Kopie der Datei und der Bibliothek als Beweis:

Jede Distribution
sudo busybox mkdir -p /root/evidence
sudo busybox cp -a /etc/ld.so.preload /usr/lib/libhide.so /root/evidence/
sudo busybox sha256sum /root/evidence/*

Rootkits machen ihre Dateien oft unveränderlich, sodass selbst root Operation not permitted bekommt. busybox-static unter Debian hat kein chattr; die systemeigenen lsattr und chattr funktionieren hier, weil Preload-Kits Dateien nach Namen verstecken und Attribute meist nicht anfassen:

Jede Distribution
sudo lsattr /etc/ld.so.preload /usr/lib/libhide.so
sudo chattr -i -a /etc/ld.so.preload /usr/lib/libhide.so

Entferne die Preload-Datei mit busybox. Ab dem nächsten gestarteten Programm wird nichts mehr vorgeladen, und auch das normale ls bestätigt, dass die Datei weg ist:

Jede Distribution
sudo busybox rm /etc/ld.so.preload
ls -la /etc/ld.so.preload

Die bereits laufenden Prozesse haben die Bibliothek noch geladen, die neuen ps und ss, die du startest, aber nicht mehr, was versteckt war, ist jetzt also sichtbar. Such danach und friere ein, was nicht dorthin gehört, bevor du es beendest:

Jede Distribution
ps -ef --forest | less
sudo ss -tanp
sudo kill -STOP PID

Entferne, was es zurückbringt: Cronjobs, systemd-Units, SSH-Schlüssel und Konten, wie in Krypto-Miner auf dem Server finden und entfernen, wo jede Stelle durchgegangen wird. Lösch dann die Bibliothek und starte neu, damit kein laufender Prozess sie behält:

Jede Distribution
sudo busybox rm /usr/lib/libhide.so
sudo ldconfig
sudo reboot

Achtung: Geh davon aus, dass jedes Geheimnis auf dem Server bekannt ist: SSH-Schlüssel, Passwörter, Datenbank-Passwörter und API-Schlüssel in Konfigurationsdateien. Der Angreifer hatte root. Ändere sie von einem sauberen Rechner aus.

Entscheiden, wann du den Server neu aufsetzt

Um /etc/ld.so.preload zu schreiben, braucht man root. Hatte ein Angreifer einmal root, entfernt das Aufräumen, was du gefunden hast, nicht unbedingt alles, was da war. Setz den Server aus einem frischen Image neu auf, wenn einer dieser Punkte zutrifft:

  • Systembinärdateien wurden verändert (die Paketprüfung oben).
  • Der Kernel ist durch ein unbekanntes Modul tainted, oder lsmod listet ein Modul, das du nicht erklären kannst.
  • Du hast nicht herausgefunden, wie der Angreifer hereingekommen ist.
  • Der Server enthält Kundendaten, Zahlungsdaten oder Zugangsdaten zu anderen Systemen.
Jede Distribution
cat /proc/sys/kernel/tainted
lsmod | sort | head -50
sudo dmesg | grep -iE 'taint|module verification|unsigned'

0 in tainted ist ein sauberer Kernel; andere Werte haben Gründe, etwa proprietäre Treiber, also schlag sie nach, bevor du Schlüsse ziehst. Zum Neuaufsetzen: Richte einen neuen Server aus dem Image des Providers ein, aktualisiere ihn, stell die Daten (keine Programme oder Konfigurationen, die du nicht prüfen kannst) aus einem Backup von vor der Infektion wieder her, ändere jedes Geheimnis und zieh dann den Verkehr um. Die Checkliste für einen neuen VPS deckt die erste Stunde ab.

Wie InfraFence ld.so.preload-Rootkits erkennt

Der InfraFence-Agent ist ein statisch gelinktes Programm: Er lädt die C-Bibliothek des Systems nicht, eine vorgeladene Bibliothek läuft also nicht in ihm und kann Dateien oder Prozesse nicht vor dem verstecken, was der Agent selbst liest.

  • Dateiintegrität: /etc/ld.so.preload gehört zu den überwachten Dateien, mit einem SHA-256-Fingerabdruck, der alle 30 Minuten verglichen wird. Eine Änderung wird als kritisches Ereignis integrity_change mit altem und neuem Hash gemeldet. Siehe Dateiintegrität und Persistenz.
  • Malware-Scan, Systemintegrität: Eine /etc/ld.so.preload mit Einträgen ist ein kritischer Fund, der ihren Inhalt zeigt; Prozesse, die in /proc stehen, aber in ps fehlen, werden als versteckt gemeldet; ausführbare Dateien in /tmp und /dev/shm und Systembinärdateien, die sich seit der Installation ihres Pakets geändert haben (dpkg -V, rpm -Va), werden ebenfalls gemeldet. Siehe Malware-Scan.
  • Dieselbe Überwachung deckt die Persistenz ab, die meist dazugehört: Crontabs, systemd-Units, authorized_keys und sudoers.

Grenzen: Die Fingerabdrücke werden beim Start des Agenten erstellt, die Integritätsüberwachung meldet also Änderungen an einer Datei, die damals existierte; eine /etc/ld.so.preload, die später auf einem Server ohne diese Datei auftaucht, findet der Malware-Scan. Scans laufen nach dem Zeitplan, den du festlegst (**Automatische Scans aktiv** ist standardmäßig aus), oder wenn du **Jetzt scannen** drückst. Ein Rootkit, das als Kernelmodul geladen wird, kann sich auch vor /proc verstecken, und InfraFence hat dafür keine eigene Erkennung. InfraFence löscht weder /etc/ld.so.preload noch die Bibliothek: Das Aufräumen und die Entscheidung zum Neuaufsetzen bleiben bei dir.

Fragen

Ist /etc/ld.so.preload immer bösartig?
Nein, aber selten. Ein normaler Server hat keine. Einige legitime Tools nutzen sie, etwa der Befehls-Logger Snoopy, und sie stammen aus einem Paket, das du installiert hast: dpkg -S oder rpm -qf auf die Bibliothek sagt es dir.
Reicht es, die Datei zu löschen?
Es beendet das Verstecken für jedes neue Programm, deshalb ist es der erste Schritt. Es entfernt nicht, was der Angreifer mit root getan hat: Persistenz, weitere Hintertüren, gestohlene Geheimnisse. Dafür ist der Rest des Aufräumens da, oder ein Neuaufsetzen.
Finden rkhunter und chkrootkit das?
Sie suchen nach vorgeladenen Bibliotheken und bekannten Kits und sind einen Lauf wert. Es sind Skripte, die die systemeigenen Tools aufrufen, auf einem infizierten System kann man ihnen also dieselbe versteckte Sicht zeigen. Lass sie aus einem Rettungssystem laufen, wenn du dich auf das Ergebnis verlassen willst.

Kostenlos auf 1 Server testen

Starter ist für einen Server kostenlos, mit vollem Schutz und automatischen Sperren. Ohne Kreditkarte.

Installiere den Agenten als root, mit deinem Token anstelle von <TOKEN>:

curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>

Das Token erstellst du im Dashboard unter Server › Server hinzufügen.