10 月 29 日,安全公司 Phorion 披露:Anthropic 官方 Claude Code 的 VS Code 扩展在 Cursor 扩展市场被植入后门。恶意版本 2.1.312 与 2.1.313 面向 Windows 和 macOS,在市场里存活约 11 小时(当地时间凌晨 2:27 到下午 1:35,即 UTC 09:27 到 20:35),Cursor 估计至多 5000 名用户装到了它。本文基于 Phorion 的样本逆向、Cursor 官方安全公告和 Sophos X-Ops 的跟进报告,把这条植入链逐环节拆开:它如何启动、如何植入钥匙、如何穿过防火墙、如何在重启后存活,以及它在 macOS 上因为一处实现错误没能走完最后一步的过程。
11 小时窗口内发生了什么
Cursor 在 10 月 29 日的安全公告里给出的事件轮廓:恶意版本只出现在 Cursor 自己的 VS Code 扩展市场(Windows 与 macOS 包),这两个版本并非由 Anthropic 开发;检测到之后 Cursor 下架了恶意版本、短暂关停整个市场,审计访问记录确认没有其他扩展被篡改,轮换密钥并重建市场后重新上线;同时与托管攻击服务器的云厂商合作把它下线,公告注明攻击者服务器已失效。
几个可以立即用来判断影响范围的事实:
| 渠道 | 状态 |
|---|---|
| Cursor 市场(10-29 09:27–20:35 UTC) | 恶意 2.1.312 / 2.1.313,至多 5000 用户 |
| 微软官方 VS Code 市场 | 无恶意版本 |
| Open VSX | 无恶意版本 |
| npm(@anthropic-ai/claude-code) | 无恶意版本 |
Anthropic 工程师 Dworken 在 Hacker News 讨论中说明:只有 Cursor 市场托管的这份扩展受影响,官方 VS Code 市场、OpenVSX 都干净,直接在 VS Code 里用 Claude Code 的用户不受波及。第三方在 10 月 30 日核验了公开注册表:三处官方渠道的版本列表从 2.1.312 直接跳到 2.1.314,2.1.313 从未在官方渠道存在过;干净版的官方 2.1.312(npm,10-27 18:36 UTC 发布)与 Cursor 市场里的恶意 2.1.312 同号不同物。判断是否中招要看安装来源加时间窗口,单看版本号不够。
66 行代码接管了扩展的启动
Phorion 逆向发现,被篡改的 extension.js 在压缩后的正常扩展代码前面多了一段立即执行函数表达式(IIFE),OpenSourceMalware 统计约 66 行。它引入 Node.js 标准库(child_process、fs、os、path、http、crypto),在 Node 加载文件的瞬间执行,早于扩展自身的 activate 回调。用户不需要点任何按钮,打开编辑器就触发。
这决定了威胁模型的量级:VS Code 系扩展以 IDE 和当前用户的全部权限运行,能读本地文件、源码、SSH 私钥、云凭据。微软官方市场页面显示该扩展独立安装数 29,151,062。攻击者选中的是开发者机器上权限最高的入口之一。
两把钥匙,方向相反
第一阶段的动作看起来很朴素:确认 ~/.ssh 存在,向 authorized_keys 追加一把攻击者控制的 Ed25519 公钥(注释 svc-telemetry),目录权限 0700、文件权限 0600。
理解整条链的关键在分清两把钥匙的用途:
| 钥匙 | 存放位置 | 作用方向 |
|---|---|---|
| svc-telemetry 公钥 | 追加进受害者的 authorized_keys | 攻击者用它登录受害机器 |
| svc-telemetry-tun 私钥 | 内嵌在脚本里,运行时写入临时目录 | 受害机器用它连出攻击者服务器 |
私钥落盘的文件名是 .stk_ 加上 MD5(hostname + HOME) 的前 10 位十六进制,每台机器文件名不同,按固定文件名做检测会漏。Phorion 提醒取证时查公钥指纹,注释字符串随时可以换。
反向隧道穿得透防火墙

第二阶段建立出站 SSH 连接:以 tunnel 用户连 134.209.82[.]225:22,带远端转发参数 -R *:0:localhost:22。端口号写 0 是让攻击者的服务器动态分配一个监听端口,打到那个端口的流量沿隧道回到受害机器的 localhost:22。-N 让连接只保持转发不执行远端命令。操作者要登录时,从自己服务器上的分配端口发起第二条 SSH 会话,用第一阶段植入的公钥对应的私钥认证,拿到完整的交互 shell 和文件传输能力。恶意 JavaScript 里因此不需要任何自定义 C2 协议,全部复用 SSH 自身。
对家庭路由器和办公防火墙来说,这条连接是受害者机器自己发起的出站流量,NAT 和入站封堵对它不起作用。
连接参数把隐蔽性做满:装了 autossh 就优先用(自动重连),否则裸 ssh;重试循环每 60 秒一次、detached 运行,用户关掉 IDE 也不中断;StrictHostChecking=no、UserKnownHostsFile=/dev/null、ServerAliveInterval=30、ServerAliveCountMax=3、ExitOnForwardFailure=yes、BatchMode、IdentitiesOnly。
重启之后还在
第三阶段按平台部署持久化:
| 平台 | 落地文件 | 机制 |
|---|---|---|
| macOS | ~/.config/.smt、.smtk | 用户级 LaunchAgent(~/Library/LaunchAgents/com.apple.sysmond.plist),RunAtLoad + KeepAlive,launchctl 加载 |
| Linux | ~/.config/.smt、.smtk | 写入 @reboot crontab 条目 |
| Windows | %USERPROFILE%.config\smt.cmd、smtk | SysMon 计划任务(请求 SYSTEM 权限);失败则回退到启动文件夹的 sysmon.cmd |
macOS 的 plist 故意命名为 com.apple.sysmond,混进 Apple 自家进程的命名空间,且以用户上下文运行(root 的 LaunchDaemon 反而会更显眼)。.smt 脚本内嵌隧道私钥,每次启动先写出 .smtk 再进入重连循环。Linux 侧有个副作用型缺陷:crontab 检查逻辑在重复运行时可能清掉用户已有的 cron 任务。
macOS 上最后一步没能走通

第一阶段之后,脚本会尝试确保本地 SSH 服务在监听。macOS 路径的写法:无提权运行 systemsetup -getremotelogin,输出匹配 /Off/i 才执行 sudo -n systemsetup -setremotelogin on。
实际行为是:标准用户运行 systemsetup -getremotelogin,macOS 返回 "You need administrator access to run this tool... exiting!",退出码 0。取回 stdout 的辅助函数拿到的是这句报错,/Off/i 匹配失败,脚本直接跳过开启 Remote Login 的分支。「无权查询」被当成了「已经开着」。
后果:SSH 原本关闭的 Mac 上,出站隧道照常建立,但经隧道转回的流量撞在本机关闭的 22 端口上,操作者进不来。钥匙和持久化都在,门没开。Cursor 公告确认了这个判断:除 Cursor 以管理员权限启动等罕见情形,开启本地 SSH 所需的管理员权限是恶意扩展拿不到的,这一步在多数 macOS 和 Windows 主机上失败。Windows 路径另有缺陷:安装 OpenSSH Server 的 PowerShell 命令经由硬编码 /bin/sh 的辅助函数执行,在标准 Windows 上走不通。
这属于运气成分:用户本来开着 Remote Login,或者之后某天打开,植入的钥匙立刻可用。
上报只发变量名
第四阶段收集主机信息,以明文 HTTP POST 发往 /beacon 端点(134.209.82[.]225:8099 与 127.0.0.1:8099 各一份):主机名、用户名、操作系统、架构、home 目录、工作目录、git config --global user.email、公网 IP(查 ifconfig.me,失败转 api.ipify.org)、各阶段状态标志,以及最多 40 个匹配 /KEY|TOKEN|SECRET|PASS|AWS|GCP/i 的环境变量名。
只报名字,不报值。这份清单给操作者的信息是每台机器上有哪些云凭据和 token 可挖,用来排优先级。上报是一次性的(1.5 秒延时触发,丢弃响应),之后的实际访问全走 SSH 隧道。发往 127.0.0.1:8099 的那份副本用途不明,样本中没有对应的本地监听。
四个检测盲点
Phorion 的检测视角给出四个具体位置:
- 写 authorized_keys 用的是 Node 的 fs.appendFileSync,不经过 shell。盯着 echo/tee 类进程命令行的规则抓不到,需要文件修改遥测:IDE 扩展宿主进程(Code Helper、Cursor Helper)在后台改 SSH 认证文件本身就是异常。
- 非 Apple 进程写入 com.apple.* 标签的 LaunchAgent 是强信号;LaunchAgent 执行 /bin/sh 跑用户主目录下的隐藏脚本同理。
- 初始隧道 detached 启动,后续 ssh/autossh 进程的父进程不是 IDE,进程树关联会断;要靠命令行特征(-R :0:localhost:22,identity 文件在 /tmp/.stk_ 或 ~/.config/.smtk)和网络特征(连 134.209.82[.]225 的 22 与 8099 端口)。
- 经隧道成功登录的会话,在受害者 SSH 日志里来源显示为 localhost(127.0.0.1 或 ::1),认证钥匙是 svc-telemetry。这台机器上日志里的「本机登录」就是远控会话的痕迹。
排查感染机器要区分两种状态:隧道建立了但无人进入,和操作者实际登录过。后者按 Cursor 的建议考虑整机重建。
自查与清除

macOS 和 Linux 上一行命令自查:
grep -qs svc-telemetry ~/.ssh/authorized_keys && echo "svc-telemetry key found" || echo "not found"Windows 在 PowerShell 里检查两个路径($HOME.ssh\authorized_keys 与 C:\ProgramData\ssh\administrators_authorized_keys),命令在 Cursor 公告里。
命中之后的处理顺序:先杀隧道进程(连着 134.209.82[.]225 的 ssh/autossh 和对应 /bin/sh 重试循环),再清持久化(macOS 卸载并删除 com.apple.sysmond.plist;Linux 清 @reboot cron 条目;Windows 删 SysMon 计划任务与启动文件夹脚本,以及各平台的 .smt/.smtk),然后删 authorized_keys 里的 svc-telemetry 公钥和 $TMPDIR/.stk_* 文件,最后轮换该用户可触及的凭据与会话,优先处理名字匹配 KEY|TOKEN|SECRET|PASS|AWS|GCP 的环境变量。Cursor 提供 remediate-macos.sh(以受影响用户身份运行,不要用 root)和 remediate-windows.ps1(管理员 PowerShell 运行),脚本检测到残留会以非零状态退出;Linux 没有官方脚本,按上面的清单手工清。
自动更新把投放自动化了
扩展自动更新默认开启,用户没有做任何安装动作也可能拿到坏版本。HN 讨论中有用户指出 VS Code 系编辑器的扩展自动更新通常有约 12 小时延迟、且需要重载编辑器才生效,这与 11 小时的存活窗口擦肩;新加入的 extensions.autoUpdateDelay 设置可以把延迟进一步拉长。存量管理上,code --list-extensions --show-versions 输出装机清单,复盘时可以一条命令核对全部开发机。
来源
- Phorion:Official Claude Code Extension Compromise: Security Advisory(2026-10-30)
- Cursor:Security notice,malicious version of Anthropic.claude-code (2.1.312 and 2.1.313)(2026-10-29,10-30 更新 IOC)
- Sophos X-Ops 跟进分析(2026-10-30)
- Hacker News 讨论(约 700 分,74 条顶层评论,含 Anthropic 工程师说明)
- 微软官方市场 anthropic.claude-code 页面安装量数据(2026-10-31 查询)