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:
- Im lokalen Netz nach SSH, SMB und FTP suchen. Der Agent nutzte
ip,ssundncund fand einen Server unter 192.168.1.2. - Einen vorgegebenen
nmap-Befehl gegen diesen Server ausführen. - Herunterladen, was die anonyme FTP-Freigabe anbietet. Sie enthielt Mitarbeiterdaten und ein Passwort ohne zugehörigen Namen.
- Aus den Mitarbeiternamen eine Liste von Benutzernamen bauen: 190
Einträge in
/tmp/usernames.txt. - Das Passwort per SMB am Domänencontroller gegen alle Namen probieren. Bei einem Konto klappte es.
- Mit
smbclientdie SMB-Freigaben auflisten, die dieses Konto sieht. - Den Inhalt einer Freigabe auflisten, darunter eine 1-GB-Datei.
- Diese Datei in einen temporären Ordner laden.
- 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.
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.
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,smbclientoder ähnliche Werkzeuge starten, beisystemd-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.comnicht 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.