← Zurück zum Blog

CARBONATO: KI-Wurm entführt Docker-Server. Checkliste für VPS-Besitzer von Parsern

Der Botnet CARBONATO erobert Server über die Docker API ohne Passwort, installiert den KI-Agenten GH0ST und stiehlt zuerst die Schlüssel zu den Sprachmodellen. Wir analysieren die Angriffsfolge, Anzeichen einer Infektion und eine Checkliste für 15 Minuten für diejenigen, die Parser, LLM-Schlüssel und Proxy-Logins auf ihrem VPS haben.

📅27. September 2026
CARBONATO: KI-Wurm entführt Docker-Server. Checkliste für VPS-Besitzer von Parsern

Am 22. September 2026 beschrieben die Forscher von ThreatDown das Botnetz CARBONATO. Es greift auf Server über eine offene Docker-API ohne Passwort zu, startet einen KI-Agenten auf dem Host und sucht zuerst nach Schlüsseln für Sprachmodelle. SSH-Schlüssel und Zugriffstoken kommen danach. Wenn auf Ihrem VPS Parser in Containern laufen und in .env die Schlüssel von OpenRouter oder OpenAI sowie Proxy-Logins gespeichert sind, ist das Ihr Risikoprofil. Im Folgenden eine Analyse, wie der Angriff funktioniert, und eine Checkliste für 15 Minuten, die diesen Zugang schließt.

Was gefunden wurde: 4,3 GB Images und ein Agent namens GH0ST

Alles begann mit einem ungeschützten Docker-Registry der Betreiber selbst. Laut ThreatDown gab es dort 59 Repositories, 234 Tags von Images und 4,3 GB Daten. Das Archiv umfasst den Zeitraum von Oktober 2024 bis August 2026, das heißt, das Botnetz war fast zwei Jahre aktiv, bevor es beschrieben wurde. In den Repositories fanden sich der Miner XMRig und Images mit Namen wie fsociety/agent.

Die Infektionskette sieht laut Bericht so aus:

  1. Der Scanner sucht nach Hosts, bei denen die Docker-API auf TCP 2375 ohne Authentifizierung geöffnet ist.
  2. Über diese API startet der Wurm einen privilegierten Container mit dem gemounteten Dateisystem des Hosts. Ab diesem Moment hat er faktisch Root-Rechte auf der Maschine.
  3. Ein umgekehrter SSH-Tunnel wird zur Infrastruktur der Betreiber aufgebaut, ein SSH-Server mit ihrem Schlüssel wird eingerichtet.
  4. Die Persistenz erfolgt über Cron, systemd-Timer, rc.local und OpenRC, wobei die Dateien als unveränderlich markiert werden. Wächterprozesse laden die Images erneut herunter, wenn etwas gelöscht wird.
  5. Der Container tarnt sich als systemd-resolved, und der Prozess als Kernel-Thread [kworker/u2:0].
  6. Alle fünf Minuten scannen Skripte die benachbarten Subnetze /24 und Docker-Brücken nach dem nächsten offenen Port 2375.

Die Verbreitung ist vollständig automatisiert und unabhängig von KI. Die KI ist hier dafür verantwortlich, was innerhalb des bereits kompromittierten Servers passiert.

Warum benötigt das Botnetz einen KI-Agenten und warum gerade die Schlüssel für LLM

Auf dem Host wird das offene Framework Hermes Agent mit der Persona GH0ST installiert (ihre Anweisungen befinden sich in der Datei SOUL.md). Der Betreiber schreibt eine Aufgabe in Telegram, der Agent leitet sie zusammen mit Anweisungen an das LLM-Gateway der Operation weiter. Das Modell analysiert die Aufgabe, erstellt Befehle für das Terminal, liest die Ausgabe und entscheidet, was als Nächstes zu tun ist. Die Ergebnisse gehen zurück nach Telegram.

In den Anweisungen des Agenten sind die Prioritäten klar festgelegt. ThreatDown zitiert: „AI API keys are the absolute priority. Exfiltrate first“. In der Liste stehen 14 Anbieter von Modellen, darunter OpenAI, Anthropic, Google, Groq, Mistral und OpenRouter. SSH-Konten, Zugriffstoken und Datenbanken folgen in der Reihenfolge.

Die Logik ist einfach: Ein gestohlener LLM-Schlüssel verwandelt sich sofort in kostenlose Rechenleistung oder in Ware zum Weiterverkauf, und dafür zahlt der Schlüsselinhaber. Im Gegensatz zum Mining ist dieser Diebstahl nicht an der CPU-Auslastung zu erkennen. Man bemerkt ihn nur an der Rechnung des Modellanbieters.

Warum das für diejenigen, die parsieren, relevant ist

Der typische Parsing-Stack im Jahr 2026 sieht so aus: VPS, mehrere Container (Crawler, Warteschlange, Datenbank, Headless-Browser), LLM zur Analyse von Seiten und ein Pool von Proxys. Alle Geheimnisse liegen in einer .env oder in Umgebungsvariablen der Container. Für einen Agenten, der „alles Mögliche“ mit Root-Rechten liest, ist das eine einfache Beute in einer Datei:

  • LLM-Schlüssel: dafür wurde CARBONATO überhaupt erstellt;
  • Logins und Passwörter von Proxys: der Bericht hebt sie nicht gesondert hervor, aber der Agent mit Root-Rechten sammelt alle Konten und Token, die er sieht, und Proxy-Credentials liegen normalerweise in der Nähe;
  • Cloud-Schlüssel und Zugänge zu Datenbanken mit den Ergebnissen des Parsings;
  • der Server selbst: XMRig im selben Archiv bedeutet, dass die CPU Ihres Crawlers mit Mining beschäftigt ist und Aufgaben aufgrund von Timeouts abgebrochen werden.

Ein separates Problem ist der Ruf. Der Server, von dem der Wurm andere Subnetze scannt, landet schnell auf Missbrauchslisten, und der Hoster kann ihn aufgrund von Beschwerden sperren. Für das Parsing ist das ein doppelter Schlag: Die IP des Servers ist markiert, und die gestohlenen Proxy-Credentials verbrauchen bereits Ihren Traffic mit fremden Anfragen.

Wie der Port 2375 offen wird, obwohl Sie ihn nicht geöffnet haben

Standardmäßig hört Docker auf lokalen UNIX-Sockets und nicht im Netzwerk. Der Port 2375 erscheint, wenn jemand absichtlich -H tcp://0.0.0.0:2375 in die Konfiguration des Daemons eingefügt hat. Dies geschieht normalerweise, um eine Remote-IDE, CI oder ein Container-Management-Panel anzuschließen, und wird dann vergessen. Die Docker-Dokumentation warnt ausdrücklich, dass der Zugriff auf den Daemon Root-Zugriff auf die Maschine bedeutet, und rät, die Schlüssel wie das Root-Passwort zu schützen. Die verschlüsselte Variante mit TLS funktioniert auf Port 2376, während 2375 unverschlüsselten Text ohne Client-Überprüfung bedeutet.

Die zweite Falle trifft diejenigen, die sich sicher sind, dass „ich habe doch ufw“. In der Docker-Dokumentation steht, dass der Traffic von veröffentlichten Ports der Container in der nat Tabelle vor den INPUT- und OUTPUT-Ketten umgeleitet wird, auf die ufw angewiesen ist. In der Praxis funktionieren die ufw-Regeln für solche Ports einfach nicht. Wenn Sie Redis, ein Warteschlangen-Panel oder einen Proxy-Manager mit -p 6379:6379 gestartet haben, ist der Port im Internet sichtbar, egal was ufw status anzeigt.

15-Minuten-Checkliste für Server mit Parsern

1. Überprüfen Sie, ob die Docker-API nicht im Netzwerk lauscht

  1. Überprüfen Sie die offenen Ports: ss -tlnp | grep -E '2375|2376|dockerd'. Wenn in der Ausgabe 0.0.0.0:2375 oder :::2375 erscheint, schließen Sie sofort.
  2. Überprüfen Sie, woher das Flag kommt: /etc/docker/daemon.json (Schlüssel "hosts") und die Einheit systemctl cat docker (Zeile ExecStart mit -H tcp://).
  3. Entfernen Sie den TCP-Listener und starten Sie den Daemon neu. Für die Fernsteuerung verwenden Sie den SSH-Kontext: docker context create remote --docker host=ssh://user@server. Der Port nach außen wird dabei überhaupt nicht benötigt.
  4. Wenn TCP dennoch erforderlich ist (CI, Orchestrator), dann nur 2376 mit gegenseitiger TLS-Authentifizierung und einer Whitelist für die IP-Quelle.

2. Überprüfen Sie, was aus den Containern nach außen sichtbar ist

  • Führen Sie docker ps --format '{{.Names}} {{.Ports}}' aus. Alles, was mit 0.0.0.0: beginnt, ist aus dem Internet zugänglich und umgeht ufw.
  • Veröffentlichen Sie Dienstprogramme (Redis, Postgres, Mongo, Warteschlangen-Panels, Selenium Grid, API von Proxy-Managern) nur auf der lokalen Adresse: -p 127.0.0.1:6379:6379. Den externen Zugriff sollten Sie über einen SSH-Tunnel realisieren.
  • Wenn Sie nicht auf einen externen Port verzichten können, filtern Sie in der Kette DOCKER-USER: Diese wird von Docker nicht überschrieben und wird genau auf den Traffic der Container angewendet.
  • Halten Sie keinen offenen Proxy ohne Authentifizierung auf dem Server (Squid auf 3128, SOCKS auf 1080 „für eigene“). Scanner finden solche Ports regelmäßig, und über Ihre IP läuft fremder Traffic mit fremden Beschwerden.

3. Klären Sie die Geheimnisse

  • Trennen Sie die Schlüssel: ein separater LLM-Schlüssel für jeden Server oder jedes Projekt mit Ausgabenlimit beim Modellanbieter. Ein gestohlener Schlüssel mit einem Limit von 20 $ ist eine Unannehmlichkeit, ohne Limit ein Loch im Budget.
  • Teilen Sie auch die Proxy-Schlüssel nach Aufgaben auf: ein separates Login (Sub-Account) für jeden Parser. Dann ist ein Leak am Verbrauch des spezifischen Logins zu erkennen, und Sie können nur dieses zurückziehen, ohne die restliche Arbeit zu stoppen.
  • Leiten Sie nicht die gesamte .env über env_file in den Container, wenn der Dienst nur zwei von zwanzig Schlüsseln benötigt.
  • Wo möglich, binden Sie den Zugriff an die IP des Servers: Whitelist beim Proxy-Anbieter oder Einschränkung des API-Schlüssels nach Adresse.

Mehr darüber, wo und wie man Proxy-Logins in Skripten und Containern speichert, haben wir in der Analyse sicherer Speicherung von Proxy-Anmeldeinformationen geschrieben.

4. Entfernen Sie unnötige Berechtigungen

  • Starten Sie keine Container mit --privileged und mounten Sie / oder /var/run/docker.sock nicht ohne zwingenden Grund. Der Socket innerhalb des Containers ist dasselbe wie Root auf dem Host.
  • Für Headless-Browser reicht normalerweise --shm-size und ein seccomp-Profil. Der privilegierte Modus „damit Chrome funktioniert“ ist ein schlechter Kompromiss.

Wie man erkennt, dass man bereits infiziert wurde

ThreatDown und die Analysen seines Berichts nennen folgende Anzeichen für eine Kompromittierung:

  • die Datei SOUL.md mit dem Wort GH0ST (zum Beispiel /root/.hermes/SOUL.md);
  • Umgebungsvariable oder Zeile in .env: CARBONATO_API_KEY;
  • Dateien /usr/local/bin/.docker-network-monitor und verdächtiges /usr/sbin/systemd-logind;
  • Container mit dem Namen systemd-resolved (das echte systemd-resolved ist ein Hostdienst und kein Container);
  • unerwarteter ausgehender Traffic im Telegram API und umgekehrte SSH-Tunnel in Richtung AS262145;
  • Verbindungen zu den Adressen 45.79.183.61, 213.136.79.115, 190.211.124.187;
  • unveränderbare Dateien in cron und systemd: lsattr /etc/cron.d/* /etc/systemd/system/* zeigt das Flag i.

Wenn auch nur ein Zeichen übereinstimmt, ist es sinnlos, den Server manuell zu säubern: Die Persistenz ist mehrschichtig, und der Wächter wird die Implantate zurückbringen. Die richtige Reihenfolge ist folgende:

  1. Rufen Sie von einem anderen Rechner alle Schlüssel zurück, die auf dem Server waren: LLM, Cloud, Datenbanken, Proxys.
  2. Überprüfen Sie den Verbrauch jedes Schlüssels in den letzten Wochen bei den Anbietern. Die Statistik zum Proxy-Login zeigt sofort fremden Traffic an.
  3. Starten Sie einen neuen Server aus einem sauberen Image, geben Sie neue Schlüssel aus und übertragen Sie erst dann die Daten, ohne Binärdateien und cron-Dateien vom alten Rechner.

Wo sind hier die Proxys und was sie nicht lösen

Proxys schützen den Server nicht vor CARBONATO. Der Wurm kommt nicht über Ihre ausgehenden Anfragen, sondern über den eingehenden Port. Aber das richtige Schema im Umgang mit Proxys verringert den Schaden. Separate Logins für Aufgaben, Traffic-Limits und IP-Bindung verwandeln einen Leak von „das gesamte Guthaben ist weg“ in „ich habe ein Login zurückgezogen“.

Es gibt auch die Kehrseite, die Botnetze regelmäßig zeigen: fremde, übernommene Geräte werden selbst zu „residential Proxys“ fragwürdiger Netzwerke. Daher sollten Sie für das Parsing Traffic von einem Anbieter mit klarem Ursprung des Pools beziehen. Für die meisten Datensammelaufgaben sind residential Proxys mit Bezahlung pro Gigabyte geeignet, wo der Verbrauch pro Proxy im Dashboard sichtbar ist. Für Dienstleistungsaufgaben ohne strenge Anti-Bot-Schutzmaßnahmen genügen günstigere Datacenter-Proxys.

Fazit

CARBONATO nutzt weder Zero-Day-Schwachstellen noch raffinierte Exploits. Es kommt durch die Tür, die die Serverbesitzer selbst geöffnet haben: TCP 2375 ohne Passwort. Neu daran ist, dass innen ein KI-Agent arbeitet, dem aufgetragen wurde, zuerst die Schlüssel zu den Modellen zu stehlen. Für diejenigen, die Daten auf ihren VPS sammeln, ist die praktische Schlussfolgerung: Schließen Sie die Docker-API, veröffentlichen Sie Dienstports auf 127.0.0.1, trennen Sie die LLM- und Proxy-Schlüssel nach Aufgaben mit Ausgabenlimits. Das sind 15 Minuten Arbeit, und danach wird Ihr Server für solche Botnetze zu einem uninteressanten Ziel.