So findest und entfernst du einen Krypto-Miner auf deinem Server
Zuletzt aktualisiert:
Ein Krypto-Miner ist das, was man auf einem kompromittierten Linux-Server am häufigsten findet. Er nimmt sich so viel CPU, wie er bekommt, und schürft damit Monero oder eine andere Kryptowährung für jemand anderen. Das erste Anzeichen ist oft eine langsame Website, ein Lüfter auf Volllast, eine Rechnung für CPU-Credits oder eine Abuse-Mail vom Provider.
Der Miner selbst ist der einfache Teil. Entscheidend ist, was ihn hereingelassen hat und was ihn zurückbringt: ein Cronjob, eine systemd-Unit, ein SSH-Schlüssel, eine Bibliothek, die in jeden Prozess vorgeladen wird. Geh in dieser Reihenfolge vor: finden, eindämmen, entfernen, den Einstiegspunkt finden, härten. Die Befehle gelten für Debian und Ubuntu sowie für die RHEL-Familie; PID steht für die Prozess-ID, die du in Schritt 1 findest.
Den Miner erkennen
Fang damit an, was die CPU belastet. Ein Miner belegt meist einen Prozess mit 100 % pro Kern, und das seit Tagen.
ps -eo pid,user,%cpu,etime,args --sort=-%cpu | head -n 15- Namen:
xmrigund seine Varianten, oder Namen, die harmlos wirken sollen:kdevtmpfsi,kinsing,kworkerds, ein von Hand geschriebenes[kthreadd], eine zufällige Zeichenfolge. - Ein Kernel-Thread erscheint in eckigen Klammern und hat keine Binärdatei: Ein Name in Klammern, hinter dem ein Pfad steht, ist eine Fälschung.
- Der Benutzer: Ein Miner, der als
www-data,apache,nginx,redisoderpostgresläuft, ist über diesen Dienst hereingekommen.
Bei einer verdächtigen PID siehst du dir die Binärdatei an, das Arbeitsverzeichnis, die vollständige Befehlszeile und welche systemd-Unit den Prozess gestartet hat:
sudo ls -l /proc/PID/exe /proc/PID/cwd
sudo tr '\0' ' ' < /proc/PID/cmdline; echo
systemctl status PIDEine Binärdatei mit dem Vermerk (deleted) oder eine, die aus /tmp, /var/tmp oder /dev/shm läuft, ist ein starkes Indiz. Dieser Befehl listet alle solchen Prozesse auf einmal auf:
sudo ls -l /proc/[0-9]*/exe 2>/dev/null | grep -E '\(deleted\)|/tmp/|/var/tmp/|/dev/shm/'Wenn top nichts zeigt: ld.so.preload
Ist die Last hoch, aber kein Prozess erklärt sie, versteckt sich der Miner womöglich hinter einer Bibliothek, die über /etc/ld.so.preload in jedes Programm geladen wird. Diese Datei gibt es normalerweise nicht. Existiert sie und nennt eine Bibliothek, die du nicht kennst, dann lügen dich ps und top an.
ls -l /etc/ld.so.preload 2>/dev/null && cat /etc/ld.so.preload
sudo grep -l LD_PRELOAD /proc/[0-9]*/environ 2>/dev/nullVerbindungen zu einem Mining-Pool
Miner sprechen mit ihrem Pool über das Stratum-Protokoll. Ports wie 3333, 4444, 5555, 7777 und 14444 sind typisch, Pools lauschen aber auch auf 443 und 80. Sieh dir deshalb auch die Verbindungen des Prozesses selbst an:
sudo ss -tnp state established '( dport = :3333 or dport = :4444 or dport = :5555 or dport = :7777 or dport = :14444 )'
sudo ss -tnp state established | grep PIDDie Konfigurationsdateien von Minern enthalten meist eine Pool-URL. Dieser Befehl sucht an den üblichen Stellen danach:
sudo grep -rIl -E 'stratum\+(tcp|ssl)://|"pools"|donate-level' /tmp /var/tmp /dev/shm /root /home /var/www /etc 2>/dev/nullWas ihn zurückbringt
Such nach Persistenz, bevor du irgendetwas beendest, damit du weißt, was du entfernen musst. Zuerst Cron: Zeilen, die mit curl oder wget herunterladen, base64 dekodieren oder aus /tmp starten.
sudo cat /etc/crontab
sudo ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily /var/spool/cron 2>/dev/null
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -l -u "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo grep -rE 'curl|wget|base64|/tmp/|/dev/shm' /etc/crontab /etc/cron.* /var/spool/cron 2>/dev/nullDann die systemd-Timer und die Unit-Dateien, die in den letzten 30 Tagen geändert wurden:
systemctl list-timers --all
sudo sh -c "find /etc/systemd/system /usr/lib/systemd/system /lib/systemd/system /root/.config/systemd /home/*/.config/systemd \
-type f \( -name '*.service' -o -name '*.timer' \) -mtime -30 2>/dev/null"Dann SSH-Schlüssel, die du nicht hinzugefügt hast, rc.local, Shell-Startdateien und Konten, die du nicht angelegt hast:
sudo sh -c 'cat /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys 2>/dev/null'
ls -l /etc/rc.local 2>/dev/null
sudo sh -c "grep -lE 'curl|wget|/tmp/|/dev/shm' /etc/profile.d/* /etc/bash.bashrc /etc/bashrc /root/.bashrc /root/.profile /home/*/.bashrc 2>/dev/null"
awk -F: '$3 == 0 || $3 >= 1000 {print $1, $3, $7}' /etc/passwdPrüfe zum Schluss, ob die Binärdateien des Systems selbst ersetzt wurden. Die Ausgabe listet Dateien aus Paketen, deren Inhalt sich geändert hat; Konfigurationsdateien sind ausgenommen.
sudo dpkg --verify | grep -v ' c /'sudo rpm -Va 2>/dev/null | grep -E '^..5' | grep -v ' c /'Den Miner eindämmen
Wenn dein Provider einen Snapshot der Festplatte anlegen kann, mach das jetzt: Er sichert die Beweise und einen Weg zurück. Dann schneidest du den Miner von seinem Pool ab. Ersetze 198.51.100.23 durch die Pool-Adresse aus Schritt 1. Diese nftables-Tabelle funktioniert unter Debian, Ubuntu und der RHEL-Familie neben ufw oder firewalld und ist nach einem Neustart wieder weg.
sudo nft add table inet quarantine
sudo nft 'add chain inet quarantine out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet quarantine out ip daddr 198.51.100.23 dropSichere eine Kopie der Binärdatei und ihrer Befehlszeile, bevor sie gelöscht wird. /proc/PID/exe funktioniert auch dann noch, wenn die Datei auf der Festplatte schon entfernt wurde. Den SHA-256 kannst du in öffentlichen Malware-Datenbanken nachschlagen.
sudo mkdir -p /root/evidence
sudo cp /proc/PID/exe /root/evidence/miner.bin
sudo tr '\0' ' ' < /proc/PID/cmdline | sudo tee /root/evidence/cmdline.txt
sudo sha256sum /root/evidence/miner.binFriere den Prozess zuerst ein, damit ein Watchdog nicht bemerkt, dass er stirbt, und ihn sofort neu startet. Sieh dir seinen Elternprozess an und beende ihn dann. Ist der Elternprozess ein Skript oder ein zweiter Miner-Prozess, kümmere dich auch um diesen.
sudo kill -STOP PID
ps -o pid,ppid,user,args -p PID
sudo kill -9 PIDAchtung: Geh davon aus, dass jedes Geheimnis auf dem Server bekannt ist: SSH-Schlüssel, Passwörter, die Datenbankpasswörter und API-Schlüssel in .env und in Konfigurationsdateien. Ändere sie von einem sauberen Rechner aus, beginnend mit den Konten, die Zugriff auf andere Server haben.
Den Miner entfernen und alles, was ihn zurückbringt
Entferne jedes Stück Persistenz, das du in Schritt 1 gefunden hast, und danach die Binärdateien. Für eine systemd-Unit (ersetze NAME):
sudo systemctl disable --now NAME.service
sudo rm /etc/systemd/system/NAME.service
sudo systemctl daemon-reload- Cron: Lösche die Zeilen mit
sudo crontab -e -u USERund die Dateien in/etc/cron.d, die du nicht angelegt hast. - SSH: Lösche die Schlüssel, die du nicht kennst, aus jeder
authorized_keys. - Konten: Sperre oder lösche Benutzer, die du nicht angelegt hast (
sudo usermod -L NAME), und prüfe/etc/sudoersund/etc/sudoers.d/. - Binär- und Konfigurationsdateien des Miners, wo auch immer Schritt 1 sie gefunden hat.
Miner machen ihre Dateien oft unveränderlich, sodass rm selbst als root mit Operation not permitted scheitert. Prüfe die Attribute zuerst und entferne sie:
sudo lsattr /path/to/file
sudo chattr -i -a /path/to/file
sudo rm /path/to/fileNennt /etc/ld.so.preload eine Bibliothek, die du nicht kennst, verschiebe die Datei (legitime Software nutzt sie nur selten) und lösche die Bibliothek, die darin stand:
sudo mv /etc/ld.so.preload /root/evidence/ld.so.preload
sudo ldconfigStarte neu und prüfe die CPU nach einer Stunde erneut, und noch einmal am nächsten Tag: Kommt der Miner zurück, ist noch ein Stück Persistenz oder der Einstiegspunkt vorhanden.
Achtung: Lief der Miner als root, wurden System-Binärdateien geändert oder wurde ld.so.preload verwendet, kannst du nicht sicher sein, dass der Server sauber ist. Setz ihn aus einem frischen Image neu auf und spiel die Daten aus einem Backup von vor der Infektion zurück, nachdem du es geprüft hast. Eine Bereinigung im laufenden System ist nur vertretbar, wenn der Miner als unprivilegierter Benutzer lief und sich außerhalb der Dateien dieses Benutzers nichts geändert hat.
Herausfinden, wie er hereingekommen ist
Wenn du den Weg hinein nicht schließt, ist der Miner in wenigen Tagen wieder da. Der Benutzer, als der der Miner lief, und der Zeitpunkt, zu dem seine Dateien angelegt wurden, weisen darauf hin:
ps -o user,pid,lstart,args -p PID
sudo stat /path/to/miner- Läuft als Benutzer des Webservers: ein verwundbares Plugin, Theme oder eine verwundbare Anwendung, oder ein Upload-Formular. Sieh dir die Web-Logs rund um den Zeitpunkt an, zu dem die Datei aufgetaucht ist.
- Läuft als
redis, oder die Dateien wurden von diesem Benutzer angelegt: Redis ohne Passwort aus dem Internet erreichbar. - Von einem Container oder von
dockerdgestartet: die Docker-API offen auf 2375 oder 2376. - Läuft als root oder als normaler Benutzer mit einer Anmeldung kurz davor: ein schwaches Passwort oder ein gestohlener SSH-Schlüssel.
last -i -n 50
sudo journalctl --since "14 days ago" | grep -E "Accepted (password|publickey)"sudo grep -hE 'wget|curl|base64|%2Fbin%2Fsh|/bin/sh' \
/var/log/nginx/access.log* /var/log/apache2/access.log* /var/log/httpd/access_log* 2>/dev/null | tail -n 50Und die Dienste, die häufig als Einstieg dienen, wenn sie auf allen Schnittstellen lauschen: die Docker-API, Redis, Webkonsolen auf 8080, Elasticsearch, MongoDB, Memcached.
sudo ss -tlnp | grep -E ':(2375|2376|6379|8080|9200|27017|11211)\b'Den Server danach härten
- Schließ den Einstiegspunkt, den du gefunden hast: Aktualisiere oder entferne die Anwendung, binde Redis und die Datenbanken mit Passwort an localhost, stell die Docker-API nie offen ins Netz.
- SSH nur mit Schlüsseln und ohne root-Login: siehe So stoppst du SSH-Brute-Force-Angriffe.
- Installiere Updates, schalte automatische Sicherheitsupdates und die Firewall ein: siehe Einen neuen VPS absichern: die Checkliste.
- Begrenze ausgehenden Verkehr, wo es geht: Ein Webserver muss nur selten Verbindungen zu beliebigen Ports aufbauen.
- Überwache ab jetzt CPU-Last, ausgehende Verbindungen und Änderungen an Cron, systemd und SSH-Schlüsseln, damit der nächste Miner in Minuten auffällt und nicht erst nach Wochen.
Wie InfraFence einen Krypto-Miner erkennt
Mehrere Detektoren von InfraFence decken die Schritte oben ab, jeder von einer anderen Seite:
- Prozesserkennung: Ein laufender Prozess, dessen Name oder Befehlszeile zu einem bekannten Miner (xmrig, minerd, cpuminer und andere), einer Stratum-URL oder einem bekannten Pool passt, wird als kritisch gemeldet, mit PID und Befehlszeile. Auch Reverse Shells und Skripte, die aus
/tmplaufen, werden gemeldet. - Malware-Scan: Signaturen für Krypto-Miner, Web-Shells und Backdoors in deinen Websites, täglich aktualisierte YARA-Regeln und ein Abgleich der System-Binärdateien mit der Paketdatenbank (
dpkg -V/rpm -Va). - Ausgehender Verkehr und DNS: Verbindungen zu Adressen auf öffentlichen Bedrohungslisten und jede DNS-Anfrage, dem Programm zugeordnet, das sie gestellt hat.
- Dateiintegrität: Von
/etc/ld.so.preload, den Crontabs, den systemd-Units und jederauthorized_keyswerden Hashes gebildet und überwacht, und jede Änderung löst sofort einen Alarm aus. - Härtungsprüfungen, die die üblichen Einfallstore melden: aus dem Internet erreichbare Datenbanken, veraltete Software, SSH mit Passwörtern.
Die Prozessprüfung vergleicht Namen und Befehlszeilen: Ein umbenannter Miner, der seinen Pool aus einer Konfigurationsdatei liest, fällt dabei nicht auf und bleibt den anderen Detektoren überlassen. Die Bereinigung aus dieser Anleitung musst du weiterhin selbst erledigen.
Fragen
- Kann ich den Prozess nicht einfach beenden?
- Er kommt wieder. Miner richten einen Cronjob, eine systemd-Unit oder einen SSH-Schlüssel ein, um neu zu starten, und die Lücke, durch die sie hereingekommen sind, ist weiterhin offen. Entferne die Persistenz und schließ den Einstiegspunkt.
- Muss ich den Server neu installieren?
- Wenn der Miner als root lief, System-Binärdateien geändert wurden oder
/etc/ld.so.preloadverwendet wurde: ja, denn du kannst nicht nachweisen, dass der Server sauber ist. Lief er als unprivilegierter Benutzer und hat sich sonst nichts geändert, kann eine sorgfältige Bereinigung genügen. - Mein Provider sagt, der Server schürft Kryptowährung, aber ich sehe nichts. Warum?
- Der Miner kann über
/etc/ld.so.preloadversteckt sein, in einem Container laufen oder per Cron nur zu bestimmten Uhrzeiten starten. Prüfe die Preload-Datei,docker psund die Verbindungen, die der Server über die Zeit aufbaut.
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.
