← Zurück zu allen Beiträgen
Veröffentlicht am · von Renaud Deraison

Die Befehle kamen über die API

Am 12. November zeigte Darktrace, wie ein gestohlener Claude-Console-Schlüssel das eigene Claude Code eines Entwicklers in ein Command-and-Control-Implantat verwandelt: Aufträge kommen über einen Claude Memory Store, der Agent scannt das Netz, versucht ein Passwort an allen Konten und lädt 1 GB in die Files API, und jedes Paket geht an api.anthropic.com. In Bromure Agentic Coding ist der Schlüssel, den der Angreifer stiehlt, ein Platzhalter, der die VM beim Hinausgehen anhält, ein mitgebrachter Schlüssel wird abgewiesen, der Netzwerkscan wird auf dem Mac abgewiesen, und jeder Auftrag steht im Trace.

Der Operator tippte jeden Befehl in eine Textdatei in einem Claude Memory Store. Das eigene Claude Code des Entwicklers las sie, startete nmap und smbclient und lud die Beute zu Anthropic hoch.

Am 12. November veröffentlichten Moishe Tajtelbaum und Sam Lister, Forscher bei Darktrace Signal Labs, Living off the AI: Shared Memories as a Covert C2 Channel. Es ist eine Labordemonstration, und Darktrace sagt, die Technik sei in freier Wildbahn noch nicht aufgetaucht. Sie „beruht nicht auf einer Schwachstelle der Claude-Plattform“, heißt es außerdem. Es wird nichts gepatcht. Alles besteht aus Claude-Funktionen, die so arbeiten wie vorgesehen.

Ausgangspunkt ist ein Linux-Rechner, auf dem ein Entwickler Claude Code nutzt. Eine kleine Payload, mit curl geholt und von dash ausgeführt, sucht die Claude-Code-Installation, sammelt die API- und OAuth-Zugangsdaten für das Claude-Console-Konto des Entwicklers und schickt sie mit einem weiteren curl an den Staging-Server des Angreifers.

Mit diesen Zugangsdaten legt der Angreifer einen Memory Store an, eine Sammlung von Textdateien, die an einen Claude-Console-Workspace gebunden ist, und zwar in einem Workspace, dem der Entwickler angehört. Er enthält drei Dateien: einen Heartbeat, eine Eingabedatei für Aufträge und eine Ausgabedatei für Ergebnisse.

Zurück auf dem Rechner des Entwicklers erzeugt die Payload mit systemd-run einen transienten Dienst, der Claude Code immer wieder startet. Jeder Lauf meldet sich über einen Hook in der Heartbeat-Datei, bittet Claude Sonnet 4.5 im nicht interaktiven Modus, den nächsten Auftrag aus der Eingabedatei zu lesen, führt ihn mit Bash-Toolaufrufen aus und schreibt das Ergebnis in die Ausgabedatei. Dann löscht sich die Payload selbst. Ab diesem Punkt schickt der Operator jeden Befehl in normalem Englisch in eine Datei auf den Servern von Anthropic.

Neun Aufträge, ein Ziel

Darktrace ließ neun Aufträge gegen ein simuliertes Active-Directory-Netz laufen:

  1. Im lokalen Netz nach SSH, SMB und FTP suchen. Der Agent nutzte ip, ss und nc und fand einen Server unter 192.168.1.2.
  2. Einen vorgegebenen nmap-Befehl gegen diesen Server ausführen.
  3. Herunterladen, was die anonyme FTP-Freigabe anbietet. Sie enthielt Mitarbeiterdaten und ein Passwort ohne zugehörigen Namen.
  4. Aus den Mitarbeiternamen eine Liste von Benutzernamen bauen: 190 Einträge in /tmp/usernames.txt.
  5. Das Passwort per SMB am Domänencontroller gegen alle Namen probieren. Bei einem Konto klappte es.
  6. Mit smbclient die SMB-Freigaben auflisten, die dieses Konto sieht.
  7. Den Inhalt einer Freigabe auflisten, darunter eine 1-GB-Datei.
  8. Diese Datei in einen temporären Ordner laden.
  9. Sie in drei Teile zerlegen und in die Claude Files API hochladen.

Jeder dieser Befehle, jedes Ergebnis und der 1-GB-Upload gingen an api.anthropic.com, denselben Host, mit dem der Agent des Entwicklers den ganzen Tag spricht. Die meisten Unternehmen, die Coding-Agenten einsetzen, haben diesen Host auf ihre Allowlist gesetzt. Darktraces Punkt: Die Allowlist ist jetzt der C2-Kanal, und der Angreifer musste nach dem ersten curl nie einen eigenen Server betreiben.

Living off the AI (Darktrace-Labor, 12. November)1. Schlüssel stehlencurl … | dashfindet Claude Code,nimmt API- und OAuth-Zugangsdatencurl → Staging-Server2. Memory Storeim Console-Workspacedes Entwicklersheartbeatinput (Aufträge)output (Ergebnisse)3. Agent als Implantatsystemd-runstartet Claude Codeimmer neu: Auftrag lesen,mit bash ausführen, meldenPayload löscht sich4. Die Aufträgenc, nmap 192.168.1.2anonymes FTPSMB-Passwortspraysmbclient-Freigaben1 GB → Files APIJedes Paket ab Schritt 2api.anthropic.com /v1/filesDer Host, den Ihre Firewall für Agenten freigibt. Kein Angreiferserver zu sperren.
Die Laborkette von Darktrace. Sobald die gestohlenen Zugangsdaten den Rechner verlassen haben, geht jeder Befehl, jedes Ergebnis und jeder Upload an api.anthropic.com, einen Host, den die meisten Netze für Coding-Agenten freigeben.

Darktraces Ratschläge folgen daraus. Entwickler von langlebigen API-Schlüsseln auf OAuth oder föderierte Identität umstellen. Wo das nicht geht, Schlüssel kurzlebig halten, auf einen Workspace beschränken und aus Dotfiles und Shell-Historie heraushalten. Sicherstellen, dass die Endpoint-Telemetrie die Befehlszeilen und Kindprozesse eines Agentenprozesses mit der Datenmenge verbinden kann, die er sendet. Auf Upload-Volumen weit über normalem Inferenz-Traffic achten, und auf Agentenprozesse, die nc, nmap oder smbclient starten.

Bromure Agentic Coding wurde um genau diese Ratschläge herum gebaut, nur angewendet auf dem Mac statt auf dem Laptop des Entwicklers.

Derselbe Rechner in Bromure Agentic Coding

Bromure Agentic Coding betreibt Claude Code, Codex, Grok, Kimi und omp in Ubuntu-VMs auf Ihrem Mac, eine VM pro Maschine. Der Agent, seine Shell und jedes Programm, das er startet, bleiben in dieser VM. Die Zugangsdaten in der VM sind Platzhalter. Jede ausgehende Verbindung läuft über einen virtuellen Switch und einen Proxy auf dem Mac, außer Reichweite des Agenten.

Geben wir dem Angreifer denselben Brückenkopf: Seine Payload läuft in einer Bromure-Maschine, als Benutzer des Agenten, und sucht nach den Zugangsdaten von Claude Code.

Der gestohlene Schlüssel hält die VM an

Ist ein Anthropic-API-Schlüssel eingerichtet, enthält ANTHROPIC_API_KEY in der VM sk-ant-api03-brm- gefolgt von Zufallszeichen. Er hat die richtige Form, also akzeptiert Claude Code ihn, aber Anthropic hat ihn nie ausgestellt. Der echte Schlüssel liegt verschlüsselt auf dem Mac, und der Proxy setzt ihn nur in Anfragen an Anthropics Hosts ein.

Mit einem Claude-Abonnement findet die Anmeldung auf dem Mac statt. Der Proxy beantwortet den Token-Austausch selbst und bewahrt die OAuth-Tokens im Speicher des Hosts auf, und Claude Code wird mitgeteilt, dass die Zugangsdaten auf dem Mac bleiben. In der VM gibt es keine OAuth-Tokens, die die Payload einsammeln könnte.

Dann schickt die Payload ihren Fund an den Staging-Server, und jede ausgehende Anfrage aus der VM durchläuft die Prüfung des Proxys. Ein Bromure-Platzhalter hat genau eine legitime Zielfamilie, und der Staging-Server gehört nicht dazu. Der Proxy blockiert die Anfrage mit HTTP 451, leitet nichts davon weiter und hält die VM an. Eine Warnung mit dem Titel This environment may have been compromised nennt die Zugangsdaten, den Host, zu dem sie gehören, und den Host, an den sie gingen. Shut down, die Voreinstellung, stoppt die Maschine und markiert sie als kompromittiert. Der Angriff endet bei Schritt eins, bevor überhaupt ein Memory Store existiert.

Kein echter Schlüssel, kein Kanal

Angenommen, die Payload versteckt den Schlüssel gut genug, um ihn hinauszubringen. Der Operator besitzt jetzt sk-ant-api03-brm-…. Anthropics API lehnt ihn ab. Er kann in Ihrem Workspace keinen Memory Store anlegen, keinen Auftrag hineinschreiben und kein Ergebnis herauslesen. Der Kanal setzt voraus, dass der Operator den Store von seiner Seite aus erreicht, und von seiner Seite aus funktioniert der Schlüssel nicht.

Der Angreifer könnte stattdessen einen eigenen Schlüssel mitbringen: einen Anthropic-Schlüssel für ein Konto unter seiner Kontrolle, in der VM abgelegt, sodass das Implantat Aufträge aus dem Workspace des Angreifers liest. Schalten Sie in den Guardrails der Maschine Only allow credentials Bromure injects ein. In diesem strikten Modus wird jede Anfrage, die Zugangsdaten trägt, die Bromure nicht eingesetzt hat, blockiert und löst dieselbe Kompromittierungswarnung aus. Ihr Anthropic-Traffic funktioniert weiter. Ein zweites Anthropic-Konto in derselben VM kommt nicht durch.

Der Scan endet am Mac

Die Aufträge selbst brauchen das Netz. Bromure-Maschinen sitzen in einem eigenen privaten Subnetz, und jedes ausgehende Paket läuft über den Mac. Stellen Sie die Maschine auf OpenShell + Sentry, und alles ist verboten, was keine Regel erlaubt. Private Bereiche wie 192.168/16 sind nur über einen exakten Hostnamen oder einen allowed_ips-Eintrag erreichbar. Darktraces erster Auftrag findet unter 192.168.1.2 nichts, nmap bekommt keine Antwort, und es gibt weder eine FTP-Freigabe noch einen Domänencontroller für das Passwortprobieren. Jede abgewiesene Verbindung ist eine Firewall-Zeile in der Security Timeline.

Mit Enforce binaries verknüpft ein root-eigener Attestor in der VM jede Verbindung mit dem Programm, das sie geöffnet hat, und jede Regel nennt die Programme, die sie nutzen dürfen. nc, nmap und smbclient stehen nirgends. Derselbe Modus nimmt jeden Weg zu root, also kann die Payload ihn nicht mit sudo umgehen.

Auch die Agenten in der Maschine erfahren davon. Mit Tell the agent when policy blocks it, auf OpenShell-Maschinen voreingestellt, nutzt Bromure die Prozessketten des Kernel-Sentry, um den Agenten hinter einer blockierten Verbindung zu finden, und schreibt eine Notiz in seine Unterhaltung: was blockiert wurde, dass das Absicht ist, und dass er es weder wiederholen noch auf anderem Weg dasselbe erreichen soll. Eine Claude-Code-Sitzung, die man zum Netzwerkscan überredet hat, bekommt diese Notiz direkt nach dem blockierten Befehl.

Maschinen-VMWas die Payload findetsk-ant-api03-brm-…Abonnement: keine Tokens in der VMDie Aufträgenc, nmap, smbclient→ 192.168.1.2Enforce binariesVerbindung an Programm gebunden;kein sudo, kein DockerIhr MacStolperdrähtePlatzhalter an Staging-Server:HTTP 451, VM angehalteneigener Schlüssel: strikter ModusDefault-Deny192.168.1.2 abgewiesenAgent: nicht wiederholenAgent watchdogBlockaden-Häufung, Riesen-Upload:Netz gekappt, VM angehaltenSehen, rückgängig machenTrace InspectorMethode, Pfad, Bytes pro AnfrageAnthropic-Bodies ausgewertet:jeder Auftrag, jeder ToolaufrufNetwork lineageclaude → bash → nmap→ 192.168.1.2 abgewiesenWipe and Launchoder Rewind home / Reset disk;Tokens, Einstellungen bleiben
Dieselbe Kette in einer Bromure-Maschine. Der gestohlene Schlüssel ist ein Platzhalter und hält die VM auf dem Weg zum Staging-Server an. Ein mitgebrachter Schlüssel scheitert am strikten Modus. Die Scans laufen auf dem Mac ins Default-Deny, der Watchdog kappt das Netz bei einer Häufung von Blockaden oder einem übergroßen Upload, und der Trace enthält jeden Auftrag im Klartext.

Der Upload löst den Watchdog aus

Darktraces letzter Auftrag schickt 1 GB in drei Teilen an die Files API. Der normale Traffic eines Agenten besteht aus Prompts, Antworten und kleinen Tool-Ergebnissen. Der agent watchdog beobachtet jede Sitzung von außerhalb der VM. Er zählt das ausgehende Volumen am Netzwerk-Switch, unabhängig vom Proxy, und vergleicht es mit der eigenen Baseline der Sitzung. Er zählt auch Häufungen blockierter Anfragen, etwa einen Scan oder ein Passwortprobieren, das ins Default-Deny läuft. Auf Quarantine gestellt, kappt er innerhalb von Millisekunden das Netz der VM und hält sie an, listet dann auf, was er gesehen hat, und fragt Sie, was zu tun ist.

Der Trace zeigt jeden Auftrag

Darktraces Erkennungsratschläge laufen auf Korrelation hinaus: den Agentenprozess mit seinen Befehlszeilen, seinen Kindprozessen und den gesendeten Bytes verknüpfen. In einer Bromure-Maschine liegen diese Daten schon auf Ihrem Mac, und der Agent kann sie nicht ändern.

Der Proxy schreibt pro Anfrage einen Trace-Eintrag: Host, Methode, Pfad, Status sowie Bytes von Anfrage und Antwort. Ein Heartbeat alle paar Sekunden, Lese- und Schreibzugriffe auf einen Memory Store und drei große POSTs an /v1/files bekommen jeweils eine eigene Zeile, mit ihrer Größe.

Neue Maschinen tracen auf der Stufe AI request details, die die vollständigen Anfrage- und Antwortkörper für Anthropic und die anderen Modellanbieter aufbewahrt und auswertet. In der Conversation-Ansicht des Trace Inspector erscheinen die Aufträge des Operators, die Claude aus dem Memory Store gelesen und in seinen Kontext übernommen hat, im Klartext. Daneben stehen die Bash-Toolaufrufe des Modells mit ihren genauen Befehlen: die nmap-Zeile, der smbclient-Aufruf, das split. Darktrace musste die Kette aus Netzwerk- und Endpoint-Telemetrie rekonstruieren. Hier liegt sie der Reihe nach vor.

Auf einer Maschine mit dem Kernel-Sentry wird jeder Programmstart und jede Verbindung aus dem Kernel der VM gemeldet, über einen Kanal, den der Agent nicht durch das Beenden eines Prozesses zum Schweigen bringen kann. Eine abgewiesene Verbindung zu 192.168.1.2 öffnet sich zu ihrer network lineage: der Prompt, die Überlegung des Agenten vor dem Aufruf, der Toolaufruf und die Prozesskette von claude über bash bis nmap. Die Prompt-Karte enthält einen Auftrag, den Sie nie geschrieben haben.

Aufräumen

Hat die Kompromittierungswarnung ausgelöst, ist die Maschine als kompromittiert markiert und startet erst wieder, wenn Sie Wipe and Launch wählen. Das löscht ihr Disk-Image und ihren Home-Ordner und behält Ihre Tokens, SSH-Schlüssel und Einstellungen. Ohne Warnung klont Reset disk die Systemplatte neu aus dem Basis-Image. Rewind home… setzt den Home-Ordner auf den Beginn eines früheren Tages zurück, bevor die Payload ankam. Und weil die Maschine Ihren echten Anthropic-Schlüssel nie hatte, bleibt der Schlüssel, den Sie sonst rotieren müssten, wo er war: auf Ihrem Mac.

Der Schlüssel ist eine Falle

Die Payload findet einen sk-ant-api03-brm-Platzhalter, mit Abonnement gar keine Tokens. Geht er an den Staging-Server, gibt es HTTP 451, und die VM hält an.

Kein Kanal zu öffnen

Ein Platzhalter kann keinen Memory Store anlegen oder lesen. Einen mitgebrachten Schlüssel weist der strikte Zugangsdatenmodus ab.

Die Aufträge laufen gegen die Wand

Default-Deny weist 192.168.1.2 ab, Enforce binaries nennt nmap und smbclient nirgends, und Claude Code wird gesagt, es nicht erneut zu versuchen.

Jeder Befehl protokolliert

Der Trace hält Pfad und Größe jeder Anfrage fest und wertet die Aufträge und Toolaufrufe aus. Der Watchdog stellt eine Sitzung bei einem übergroßen Upload unter Quarantäne.

Was Sie diese Woche tun sollten

  • Finden Sie heraus, wo die API-Schlüssel Ihrer Entwickler für Claude, OpenAI und andere Modelle liegen: Shell-Profile, .env-Dateien, Konfigurationsordner der Agenten. Stellen Sie um, was geht, auf OAuth oder föderierte Anmeldung, und machen Sie den Rest kurzlebig und auf einen Workspace beschränkt.
  • Prüfen Sie in der Claude Console, welche Workspaces jeder Schlüssel erreicht, und suchen Sie dort nach Memory Stores und Files-API-Uploads, die Sie nicht kennen.
  • Alarmieren Sie bei Agentenprozessen, die nc, nmap, smbclient oder ähnliche Werkzeuge starten, bei systemd-run-Units, die einen Agenten starten, und bei Uploads zu Modellanbietern weit über normalem Inferenz-Traffic.
  • Behandeln Sie einen Allowlist-Eintrag für api.anthropic.com nicht als Vertrauensentscheidung über das, was darüber läuft.

Geben Sie Ihren Agenten dann eine Maschine, in der der Schlüssel, den sie halten, nur auf dem Weg zu Anthropic funktioniert, das erreichbare Netz das ist, das Sie aufgelistet haben, und jede ihrer Anfragen dort aufgezeichnet wird, wo sie sie nicht ändern können. Platzhalter und der strikte Modus sind im Kapitel Credentials & the Wire Boundary des Handbuchs beschrieben, Default-Deny und der Kernel-Sentry in Sandbox Policy, und der Trace in Tracing & Audit.