Cursor 扩展后门自查:清 Claude Code 残留五步

10 月 29 日(美国太平洋时间),Cursor 扩展市场上的 Anthropic.claude-code 2.1.312 / 2.1.313 被植入 SSH 后门,窗口大约 11 小时,官方估计最多约 5000 人装到或自动更新到了它们。只升级到 2.1.314 或卸载扩展清不掉残留。下面按 Cursor 通告和 Phorion 分析,按「先查、清理、换凭证、以后少踩坑」做成可复制步骤;本机在 Linux 运维环境跑过通告里的公钥与持久化路径检查。
这件事和「普通扩展更新」差在哪
Cursor 写明:这两个版本不是 Anthropic 开发的;Ars Technica 援引 Phorion 的说法,恶意包是从 Anthropic 在 Cursor 上的官方账号发出的。账号怎么被拿到,两家截至发稿都还没公开完整说明。Cursor 的处置是下架恶意版本、短暂关停扩展市场、审计其他扩展、轮换密钥后重建上线,并和云厂商一起把攻击者服务器弄下线。
载荷干了四件事:收集主机名、用户名、Git 邮箱、公网 IP 和环境变量名;往 authorized_keys 塞一把 svc-telemetry 公钥;尝试开反向 SSH 隧道;用 LaunchAgent / cron / 计划任务做持久化。隧道对端是 134.209.82.225,HTTP beacon 打在 :8099/beacon。多数 macOS / Windows 没有管理员权限时,开启本机 SSH 服务这一步会失败,但公钥和持久化脚本照样留下——这就是「升级扩展 ≠ 清理完毕」的原因。
前置条件
- 在 Cursor(或同族 VS Code 编辑器)里,从 Cursor 扩展市场装过或更新过
Anthropic.claude-code的 2.1.312 / 2.1.313(macOS / Windows;Linux 主机也建议查一遍残留)。 - 窗口:太平洋时间 10 月 29 日约 2:27–13:35(北京时间 29 日 17:27 至 30 日 4:35)。
- 先关掉 Cursor / VS Code,再动手删扩展目录;有命中再隔离机器。
- 官方修复脚本:macOS remediate-macos.sh;Windows remediate-windows.ps1。事件背景见快讯;同日发布的Claude Code 2.1.314 是市场上的替换版本之一。
第 1 步:30 秒判断有没有中招
恶意包会往 ~/.ssh/authorized_keys 追加一把注释为 svc-telemetry 的 Ed25519 公钥。Cursor 通告给的检查命令:
# macOS / Linux
grep -qs svc-telemetry ~/.ssh/authorized_keys \
&& echo "svc-telemetry key found" \
|| echo "No key found; machine not impacted"
# Windows PowerShell
$files = "$HOME\.ssh\authorized_keys", "C:\ProgramData\ssh\administrators_authorized_keys" |
Where-Object { Test-Path $_ }
if ($files -and (Select-String svc-telemetry $files)) {
"svc-telemetry key found"
} else {
"No key found; machine not impacted"
}
本机运维环境没有 ~/.ssh/authorized_keys,上述 grep 路径检查结果为未命中。Phorion 提醒:脚本是按注释字符串判断「已写入」,狩猎时最好再对指纹 SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk 做一次核对,别只信注释。通告公布的完整公钥以官方页面为准,复制时注意行首不要多空格。
grep 没命中不能当干净:扩展目录、LaunchAgent / 计划任务和隧道进程还要看。
第 2 步:扫扩展目录和持久化落点
后门写在 extension.js 最前面的一段 IIFE,Node 一加载就跑,不必等你点 Claude。扩展目录仍叫 2.1.312 / 2.1.313,所以要按内容搜 svc-telemetry,不能只看版本号。官方 remediation 脚本也是这个策略:grep -qF 命中才 rm -rf 整个扩展文件夹。
# 在用户主目录下找被篡改的 extension.js(路径因编辑器而异)
find ~ -path '*/extensions/anthropic.claude-code-*/extension.js' 2>/dev/null |
while read -r f; do
grep -qF svc-telemetry "$f" && echo "HIT $f"
done
# 常见持久化与临时密钥(按平台取用)
ls -la ~/.config/.smt ~/.config/.smtk 2>/dev/null
ls -la ~/Library/LaunchAgents/com.apple.sysmond.plist 2>/dev/null # macOS
crontab -l 2>/dev/null | grep -E '\.smt|sysmond' || true # Linux
ls /tmp/.stk_* "${TMPDIR:-/tmp}"/.stk_* 2>/dev/null || true
# Windows:计划任务 SysMon、%USERPROFILE%\.config\smt.cmd、Startup\sysmon.cmd
本机同样扫了这些路径:无 .smt / .smtk、无 com.apple.sysmond.plist、无匹配 cron、无 /tmp/.stk_*。临时隧道私钥文件名是 .stk_ 加「主机名+HOME」MD5 的前 10 位十六进制,所以通配符比写死文件名更稳。
| 平台 | 持久化 | 通告里的清理要点 |
|---|---|---|
| macOS | ~/Library/LaunchAgents/com.apple.sysmond.plist(标签伪装成系统组件)+ ~/.config/.smt | launchctl bootout 后删 plist 与脚本,杀隧道进程 |
| Linux | 用户 crontab @reboot 跑 ~/.config/.smt | 删 cron 条目与脚本;Phorion 提到重复跑可能搞乱原有 crontab,改前先备份 |
| Windows | 计划任务 SysMon(试图以 SYSTEM 跑),失败则写 Startup sysmon.cmd | 管理员 PowerShell 跑官方 ps1;先关编辑器,否则扩展目录删不掉 |
第 3 步:优先跑官方 remediation,再人工复核
Cursor 脚本会卸 LaunchAgent / 计划任务、按内容删带标记的扩展目录、清 .smt 与 .stk_*、从 authorized_keys 抠掉那把公钥(macOS 脚本用 perl 处理「公钥被拼在同一行」的情况)。有残留时退出码非 0。
# macOS:以受影响用户身份运行,不要 sudo
curl -fsSL -o remediate-macos.sh \
https://cursor.com/static/security/claude-code-extension/remediate-macos.sh
# 建议先打开文件看一眼,再执行
bash remediate-macos.sh
# Windows:管理员 PowerShell,先关掉所有编辑器
# 下载 remediate-windows.ps1 后:
powershell -ExecutionPolicy Bypass -File .\remediate-windows.ps1
脚本跑完后,再手动确认三件事:
grep/Select-String对svc-telemetry应无命中;必要时用指纹再扫一遍。- 扩展市场装回官方 Claude Code,版本 ≥ 2.1.314(本稿核对 npm 上
@anthropic-ai/claude-code最新为 2.1.316;CLI 与扩展是不同分发渠道,版本号不必强行对齐)。 - 本机若还装了 CLI:我们这台运维机当时
claude --version是 2.1.309,按你平时的升级方式更新即可。
通告还列了被篡改 VSIX 的 SHA-256(按 darwin-arm64 / win32-x64 与 2.1.312 / 2.1.313 分列)。如果你从别处留过安装包,可以对一下哈希,避免把黑包又装回去。
第 4 步:在干净机器上轮换凭证
通告写明:卸载扩展不够,持久化脚本会自己接着跑;环境变量采集本身只上报名字,但不代表后门存活期间没有别的访问。命中后请:
- 从另一台确认干净的电脑轮换:GitHub / GitLab PAT、云厂商密钥、npm / PyPI token、SSH 私钥、CI secret。
- 吊销旧会话,检查审计日志里有无异常登录或异常 git push。
- 若本机本来就开着 SSH,重点看是否出现过从 localhost 用
svc-telemetry指纹登录的记录——反向隧道把流量转到本机 22 时,日志里来源常是 127.0.0.1。
第 5 步:以后少踩坑的日常规矩
- 关键扩展关掉自动更新,或钉到已核对哈希的版本;把通告里的恶意 SHA-256 留进内部黑名单。
- 企业环境用私有扩展源或允许名单,限制「谁能往市场发包」;市场账号的 2FA / 硬件密钥按最高级别保护。
- 监控 IDE 扩展宿主进程写
~/.ssh/authorized_keys、新建伪装成com.apple.*的 LaunchAgent——正常扩展不该干这些。 - 这和 Python 依赖投毒是一类问题:供应链入口不止 pip。可对照站内Python 依赖防投毒自查做分层防护;Agent 从 Downloads 拉指令文件的风险见AGENTS.md 劫持自查。
常见坑
- 只升级版本就收工。 2.1.314 是干净替换包,但 312/313 留下的公钥、LaunchAgent、计划任务不会跟着消失。
- 以为「SSH 没开起来就安全」。 Phorion 指出 macOS 上
systemsetup -getremotelogin无管理员权限时输出不含Off,恶意逻辑会跳过开启步骤;多数非管理员场景开不了 sshd,但公钥和持久化仍会落下,以后你自己开了 SSH 就暴露。 - Linux 用户照搬 macOS 脚本完事。 Cursor 通告的修复脚本目前是 macOS / Windows;Linux 要按 IOC 手工清 cron 与
~/.config/.smt*,并确认没有残留的ssh -R/autossh进程连向通告 IP。 - 只在一台电脑查。 自动更新窗口内登录过的每台装 Cursor 的机器都要扫;共享账号的构建机、跳板机一并列入。
- 根用户跑 macOS 脚本。 官方脚本检测到 root 会直接退出并提示「run as the affected user」——持久化是装在用户目录下的。
完成标准
authorized_keys无svc-telemetry/ 对应指纹;无.smt、com.apple.sysmond、SysMon、.stk_*残留。- 扩展目录里不再有带该标记的
extension.js;已装回 ≥ 2.1.314 的官方包。 - 敏感凭证已在干净环境轮换;团队有一份「扩展自动更新 / 私有源」约定。
最后
先跑第 1 步 grep。命中就隔离机器、跑官方脚本、换凭证;没命中也把第 2 步路径扫完。需要对照事件时间线与 IOC 全文,打开文末 Cursor 通告和 Phorion 分析。