命令是从 API 送进来的
11 月 12 日,Darktrace 展示了一把被盗的 Claude Console 密钥如何把开发者自己的 Claude Code 变成命令与控制植入程序:任务通过 Claude 的 memory store 送达,代理扫描网络、拿一个密码逐一试遍所有账号,再把 1 GB 上传到 Files API,而每个数据包都发往 api.anthropic.com。在 Bromure Agentic Coding 中,攻击者偷到的密钥是替身,一离开就让 VM 暂停;攻击者自带的密钥会被拒绝;网络扫描在 Mac 上就被拦下;每一项任务都留在追踪记录里。
操作者把每一条命令写进 Claude memory store 里的一个文本文件。开发者自己的 Claude Code 读了它,运行 nmap 和 smbclient,再把战利品上传到 Anthropic。
11 月 12 日,Darktrace Signal Labs 的研究人员 Moishe Tajtelbaum 和 Sam Lister 发布了 Living off the AI: Shared Memories as a Covert C2 Channel。这是一个实验室演示,Darktrace 表示尚未在真实攻击中见到这种手法。他们还说,这种手法不依赖 Claude 平台的任何漏洞。没有什么会被修补。它完全由按设计运行的 Claude 功能拼成。
起点是一台开发者在上面使用 Claude Code 的 Linux 机器。一个用 curl 下载、交给 dash 执行的小型载荷,会找到 Claude Code 的安装位置,收集开发者 Claude Console 账号的 API 和 OAuth 凭据,再用另一个 curl 发回攻击者的中转服务器。
拿到这些凭据后,攻击者在开发者所属的一个工作区里创建 memory store,也就是挂在 Claude Console 工作区下的一组文本文件。里面有三个文件:一个心跳文件、一个存放任务的输入文件,以及一个存放结果的输出文件。
回到开发者的机器上,载荷用 systemd-run 创建一个临时服务,不断重新启动 Claude Code。每次运行都通过一个钩子在心跳文件里报到,请以非交互模式运行的 Claude Sonnet 4.5 从输入文件读取下一项任务,用 bash 工具调用完成它,再把结果写进输出文件。随后载荷自行删除。从那一刻起,操作者用普通英语下达每一条命令,写进 Anthropic 服务器上的一个文件。
九项任务,同一个目的地
Darktrace 针对一个模拟的 Active Directory 网络执行了九项任务:
- 在本地网络中寻找 SSH、SMB 和 FTP。代理用了
ip、ss和nc,在 192.168.1.2 找到一台服务器。 - 对那台服务器运行一条指定的
nmap命令。 - 下载匿名 FTP 共享提供的内容。里面有员工资料,以及一个没有对应名字的密码。
- 用员工姓名生成一份用户名列表:
/tmp/usernames.txt里有 190 条。 - 通过 SMB 对域控制器,拿这个密码逐一试遍所有账号。有一个账号成功了。
- 用
smbclient列出这个账号能看到的 SMB 共享。 - 列出其中一个共享的内容,里面有一个 1 GB 的文件。
- 把那个文件下载到临时文件夹。
- 切成三份,上传到 Claude 的 Files API。
这些命令、每一个结果,以及那 1 GB 的上传,全都发往 api.anthropic.com,也就是开发者的代理整天都在连接的同一台主机。大多数使用编码代理的公司都已把这台主机加入允许列表。Darktrace 的要点是:允许列表现在就是 C2 通道,而攻击者在第一个 curl 之后,根本不必搭建自己的服务器。
Darktrace 的建议由此而来。让开发者从长期有效的 API 密钥改用 OAuth 或联合身份。做不到的地方,就让密钥短期有效、只限一个工作区,并且不要留在 dotfiles 和 shell 历史记录里。确保终端遥测能把代理进程的命令行和子进程,与它发出的数据量关联起来。留意远高于正常推理流量的上传量,以及运行 nc、nmap 或 smbclient 的代理进程。
Bromure Agentic Coding 正是围绕同样的建议打造的,只是应用在 Mac 上,而不是开发者的笔记本上。
在 Bromure Agentic Coding 中的同一台机器
Bromure Agentic Coding 在你 Mac 上的 Ubuntu VM 中运行 Claude Code、Codex、Grok、Kimi 和 omp,每台机器一个 VM。代理、它的 shell 以及它启动的每个程序都留在那个 VM 里。VM 里的凭据都是替身。每一条出站连接都经过 Mac 上的虚拟交换机和代理服务器,代理够不着它们。
给攻击者同样的立足点:他们的载荷在一台 Bromure 机器里、以代理的用户身份运行,并开始寻找 Claude Code 的凭据。
偷到的密钥让 VM 暂停
如果配置的是 Anthropic API 密钥,VM 里的 ANTHROPIC_API_KEY 存的是 sk-ant-api03-brm- 加上一串随机字符。它的格式正确,所以 Claude Code 会接受,但 Anthropic 从未签发过它。真正的密钥加密存放在 Mac 上,代理服务器只会在发往 Anthropic 主机的请求里换上它。
如果用的是 Claude 订阅,登录在 Mac 上完成。代理服务器自己响应令牌交换,并把 OAuth 令牌保存在主机的存储里,Claude Code 也会被告知凭据留在 Mac 上。VM 里没有任何 OAuth 令牌可供载荷收集。
接着载荷把找到的东西发往中转服务器,而 VM 发出的每个请求都要经过代理服务器的扫描。Bromure 替身只有一组合法的目的地,中转服务器不在其中。代理服务器以 HTTP 451 拦下请求,一个字节都不转发,并暂停 VM。一条标题为 This environment may have been compromised 的警报会列出该凭据、它所属的主机,以及它被发往的主机。默认的 Shut down 会关闭机器,并将其标记为已被入侵。攻击停在第一步,连一个 memory store 都还不存在。
没有真密钥,就没有通道
假设载荷把密钥藏得足够好,成功发了出去。操作者现在手里是 sk-ant-api03-brm-…。Anthropic 的 API 会拒绝它。他们无法在你的工作区创建 memory store,无法写入任务,也无法读出结果。这个通道需要操作者从自己那一端访问 store,而在他们那一端,这把密钥根本无效。
攻击者也可以改带自己的密钥:一把属于他们所控制账号的 Anthropic 密钥,放进 VM 里,让植入程序从攻击者自己的工作区读取任务。请在机器的 Guardrails 中打开 Only allow credentials Bromure injects。开启这个严格模式后,任何带着并非 Bromure 放入的凭据的请求都会被拦下,并触发同一条入侵警报。你的 Anthropic 流量照常工作。同一个 VM 里的第二个 Anthropic 账号则过不去。
扫描在 Mac 上止步
这些任务本身需要网络。Bromure 机器位于自己的私有子网,每个出站数据包都经过 Mac。把机器切换到 OpenShell + Sentry,除非有规则允许,否则一律拒绝。像 192.168/16 这样的私有网段,只能通过精确的主机名或 allowed_ips 条目才能访问。Darktrace 的第一项任务在 192.168.1.2 什么也找不到,nmap 收不到任何响应,也没有 FTP 共享或域控制器可供试密码。每一条被拒绝的连接,都是 Security Timeline 里的一行 Firewall。
开启 Enforce binaries 后,VM 里一个属于 root 的证明程序会把每条连接对应到打开它的程序,每条规则也会列出可以使用它的程序。nc、nmap 和 smbclient 哪里都没有被列出。同一个模式还拿走了所有通往 root 的途径,所以载荷无法用 sudo 绕过。
机器里的代理也会收到通知。开启 Tell the agent when policy blocks it 时(OpenShell 机器的默认值),Bromure 会利用内核哨兵的进程链,找出被拦连接背后的代理,并在它的对话中写入一条说明:什么被拦了、这是有意为之,以及不要重试,也不要换个办法去做同一件事。被说服去扫描网络的 Claude Code 会话,会在被拦的命令之后立刻收到这条说明。
上传触发 watchdog
Darktrace 的最后一项任务把 1 GB 分三份发到 Files API。代理的正常流量是提示、响应和小型工具结果。agent watchdog 从 VM 外部监视每个会话。它在网络交换机上统计出站流量,独立于代理服务器,并与该会话自己的基线比较。它也会统计一连串被拦截的请求,例如撞上默认拒绝的扫描或密码喷洒。设为 Quarantine 时,它会在几毫秒内切断 VM 的网络并将其暂停,然后列出它看到的内容,询问你如何处理。
追踪记录显示每一项任务
Darktrace 的检测建议归结起来就是关联:把代理进程与它的命令行、子进程以及发出的字节数关联起来。在 Bromure 机器里,这些记录早已在你的 Mac 上,而且代理无法修改。
代理服务器为每个请求写下一条追踪记录:主机、方法、路径、状态,以及请求和响应的字节数。每隔几秒一次的心跳、对 memory store 的读写,以及发往 /v1/files 的三个大型 POST,各自都有独立的一行,并附上大小。
新机器以 AI request details 级别追踪,会保留 Anthropic 及其他模型提供商完整的请求和响应内容,并加以解析。在 Trace Inspector 的 Conversation 视图中,操作者的任务(Claude 从 memory store 读出并带入上下文的内容)以明文呈现。旁边是模型的 Bash 工具调用和确切的命令:nmap 那一行、smbclient 的调用、split。Darktrace 不得不从网络和终端遥测中重建这条攻击链。在这里,它按顺序排好了。
在装有内核哨兵的机器上,每一次程序启动和每一条连接,都从 VM 的内核内部上报,经由一条代理无法靠终止进程让它沉默的通道。点开一条被拒绝、连往 192.168.1.2 的连接,就会看到它的 network lineage:提示、代理在调用前的推理、工具调用,以及从 claude 经 bash 到 nmap 的进程链。Prompt 卡片里是一项你从未写过的任务。
善后
如果入侵警报已经触发,机器会被标记为已被入侵,在你选择 Wipe and Launch 之前都不会启动。这会清除它的磁盘镜像和主目录,并保留你的令牌、SSH 密钥和设置。没有警报时,Reset disk 会从基础镜像重新克隆系统盘。Rewind home… 会把主目录回退到载荷到达之前某一天的开头。而且因为这台机器从未持有你真正的 Anthropic 密钥,原本必须轮换的那把密钥仍在原处:你的 Mac 上。
密钥是绊线
载荷找到的是 sk-ant-api03-brm- 替身,若是订阅则根本没有令牌。把它发往中转服务器会得到 HTTP 451,VM 随即暂停。
没有通道可开
替身无法创建或读取 memory store。攻击者自带的密钥会被严格凭据模式拒绝。
任务撞墙
默认拒绝拦下 192.168.1.2,Enforce binaries 从未列出 nmap 或 smbclient,Claude Code 也会被告知不要重试。
每条命令都有记录
追踪记录保留每个请求的路径和大小,并解析任务和工具调用。遇到异常庞大的上传,watchdog 会隔离该会话。
本周该做的事
- 找出开发者的 Claude、OpenAI 及其他模型 API 密钥放在哪里:shell 配置文件、
.env文件、代理的配置文件夹。能改的就改用 OAuth 或联合登录,其余则改为短期有效、只限一个工作区。 - 在 Claude Console 中检查每把密钥能访问哪些工作区,并查看其中是否有你不认识的 memory store 或 Files API 上传。
- 针对启动
nc、nmap、smbclient或类似工具的代理进程、启动代理的systemd-run单元,以及远高于正常推理流量、发往模型提供商的上传设置告警。 - 不要把允许列表里的
api.anthropic.com条目,当成对经过它的一切所做的信任决定。
接着,给你的代理一台这样的机器:它们持有的密钥只在通往 Anthropic 的路上有效,它们能访问的网络就是你列出的那些,而它们发出的每个请求都记录在它们改不了的地方。替身和严格模式请见手册的 Credentials & the Wire Boundary 一章,默认拒绝和内核哨兵请见 Sandbox Policy,追踪记录请见 Tracing & Audit。