<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>SSH后门 on AI博士 万戈</title>
        <link>https://www.yesmiracle.net/tags/ssh%E5%90%8E%E9%97%A8/</link>
        <description>AI博士万戈的技术博客，聚焦 Agentic AI、AI Infra 与 Agent Security，分享 AI 基础设施与工程落地实践。</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <managingEditor>admin@yesmiracle.net (万戈)</managingEditor>
        <webMaster>admin@yesmiracle.net (万戈)</webMaster>
        <lastBuildDate>Sat, 31 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.yesmiracle.net/tags/ssh%E5%90%8E%E9%97%A8/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Claude Code 官方扩展被投毒：IDE 插件市场正成为 Agent 供应链的新前线</title>
        <link>https://www.yesmiracle.net/post/20261031-claude-code-extension-marketplace-supply-chain/</link>
        <pubDate>Sat, 31 Oct 2026 00:00:00 +0000</pubDate>
        <author>admin@yesmiracle.net (万戈)</author>
        <guid>https://www.yesmiracle.net/post/20261031-claude-code-extension-marketplace-supply-chain/</guid>
        <description>&lt;img src="https://www.yesmiracle.net/post/20261031-claude-code-extension-marketplace-supply-chain/cover.svg" alt="Featured image of post Claude Code 官方扩展被投毒：IDE 插件市场正成为 Agent 供应链的新前线" /&gt;&lt;p&gt;先说这次跟今年前几起 AI 供应链事件最不一样的一点：&lt;strong&gt;没有冒充可识别&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;以往这类攻击你还能靠三个动作发现：看包名像不像正品、对一下源码或 Git tag、确认发布者是不是官方。这次三个动作全部失效。攻击者用的是 Anthropic 的官方扩展、官方发布者身份 &lt;code&gt;anthropic.claude-code&lt;/code&gt;、正常的版本号递增，被替换的是真东西。&lt;/p&gt;
&lt;p&gt;Manifold Security 的研究负责人 Ax Sharma 那句话把这个性质说得比谁都清楚：这次没有冒充可以识别，那就是 Cursor 自己市场里的官方 Claude Code 扩展，一个被污染的上架条目把 SSH 后门推给了最多 5,000 名用户。他还补了一句我认为是全文最关键的趋势判断，查发布者名字在发布者本身就是真的时帮不上忙，能帮上忙的是盯行为。&lt;/p&gt;
&lt;h2 id=&#34;先把事实摆清&#34;&gt;先把事实摆清&lt;/h2&gt;
&lt;p&gt;10 月 29 日，Cursor 的 VS Code 扩展市场里出现了一个被篡改的 Claude Code 扩展。窗口期是太平洋时间凌晨 2:27 到下午 1:35，大约 11 小时。受影响的版本号是 2.1.312 和 2.1.313，Cursor 的公告最初只提了 313，后来把 312 一并纳入。装机量上限是 5,000 名用户，Cursor 说会逐个联系他们。&lt;/p&gt;
&lt;p&gt;载荷是在扩展的 &lt;code&gt;extension.js&lt;/code&gt; 里前置的一段立即执行函数（IIFE），被塞在压缩后的扩展包最前面。它就做一件事：Node 一加载这个文件就执行，早于扩展自己的 activate 回调跑起来，用户完全不需要跟 Claude Code 交互。&lt;/p&gt;
&lt;p&gt;macOS 安全公司 Phorion 发现并披露了这个包，OpenSourceMalware 同步跟进。Cursor 的处置是下架、关停整个市场做审计、确认没有别的扩展被同样手法改过、轮换自己的密钥、重建市场再上线，并联合托管商把攻击者的服务器下线。Anthropic 随后发布了干净版本 2.1.314。&lt;/p&gt;
&lt;h2 id=&#34;哪些是事实哪些还不清楚&#34;&gt;哪些是事实，哪些还不清楚&lt;/h2&gt;
&lt;p&gt;这篇稿子有一节必须单独写，因为这个事件里被引用最广的几个说法，可靠程度并不一样。同时这也是标题需要打折的地方。&lt;/p&gt;
&lt;p&gt;属于事实的部分：恶意版本由 Cursor 的市场分发，后来确认这是唯一的分发源；Cursor 在公告里明确写了这些恶意版本不是 Anthropic 开发的；Anthropic 的两名员工（Felix Rieseberg 与负责安全的 David Dworken）公开否认自家系统或员工电脑被攻破，Rieseberg 的说法是有人拿到了 Cursor 市场的访问权限，发布了一个被篡改的副本，而那个副本不是他们构建或发布的；攻击者的服务器已经停止工作。&lt;/p&gt;
&lt;p&gt;还不清楚的部分更重要：恶意版本究竟是怎么进到市场的。Cursor 到现在没有解释这一步。BleepingComputer 把这个未解问题写得很直白，攻击者如何以 Anthropic 的名义在 Cursor 市场发布扩展，以及 Cursor 或 Anthropic 的系统是否在这个过程中被攻破，都还没有答案。&lt;/p&gt;
&lt;p&gt;另外还有一处报道打架，值得读者知道。Phorion 说的是他们在 Open VSX 上发现了这个恶意包，但后来的报道确认 Cursor 是唯一分发源，而 Sharma 公开反驳了「Open VSX 版本也被污染」的说法。初始发现位置与实际分发位置，在报道里没有完全对齐。&lt;/p&gt;
&lt;p&gt;最后是标题那一句。「官方扩展被投毒」在窄义上成立，因为被篡改的确实是官方扩展的构建；但如果读成「Anthropic 的官方发布被投毒」，那就错了。被污染的是第三方市场的上架条目，Anthropic 的官方分发链路没有受影响，他们也已经把干净版本发出来了。这个区别决定了读者该找谁负责，所以我在正文里保留这个限定。&lt;/p&gt;
&lt;h2 id=&#34;前置一段-iife意味着它不需要理解扩展&#34;&gt;前置一段 IIFE，意味着它不需要理解扩展&lt;/h2&gt;
&lt;p&gt;载荷的结构比内容更值得注意。它没有改扩展的逻辑，只是在压缩包最前面插了一段代码，导入 &lt;code&gt;child_process&lt;/code&gt;、&lt;code&gt;fs&lt;/code&gt;、&lt;code&gt;os&lt;/code&gt;、&lt;code&gt;path&lt;/code&gt;、&lt;code&gt;http&lt;/code&gt;、&lt;code&gt;crypto&lt;/code&gt; 这些标准模块，然后就跑了。&lt;/p&gt;
&lt;p&gt;这个做法说明攻击者不需要读懂 Claude Code 是怎么实现的。任何插件，只要发布位被拿下，都可以被这样在前面加一段。插件本身写得安不安全，跟它会不会被这样改写是两件事。这也解释了 Cursor 的反应为什么是关掉整个市场而不是下架一个包：出问题的地方在上架这个动作本身可不可靠，跟单个包写得安不安全无关。&lt;/p&gt;
&lt;p&gt;顺带一个架构层面的细节，它让这件事更值得担心。微软的官方市场条款限制它只能服务微软自己的产品，所以基于 VS Code 开源代码做的编辑器（Cursor、Windsurf 这类）得靠别的市场，Open VSX 或者自建市场。分发路径比大多数人以为的要分散，而每一个都是独立的信任点。&lt;/p&gt;
&lt;h2 id=&#34;名单本身就是情报&#34;&gt;名单本身就是情报&lt;/h2&gt;
&lt;p&gt;载荷偷的东西里，有一项值得单独说：它上报了最多 40 个「看起来像密钥、token、密码、AWS 或 GCP 凭据」的环境变量&lt;strong&gt;名字&lt;/strong&gt;。值留在本机。&lt;/p&gt;
&lt;p&gt;Phorion 的 CEO Calum Hall 对这个设计的解读是，这份名单给了操作者一份清单，告诉他哪些主机握着什么凭据、该先打哪一台。这句话要点出来，因为它意味着这次外泄的资产是「目标排序」，而不是凭据本身。对攻击者来说，知道哪台机器值钱，比一次性捞走一堆可能过期的字符串更有用。&lt;/p&gt;
&lt;p&gt;载荷还上报主机名、用户名、操作系统、架构、家目录、工作目录、Git 邮箱和公网 IP，并且是明文 HTTP 发到 134.209.82.225 的 8099 端口。&lt;/p&gt;
&lt;p&gt;明文 HTTP 是个低级错误，我不打算把它说成高明行动。但它反过来提示了这类攻击的真实门槛：不需要高明也能成。真正致命的部分只有一个筹码，就是拿到上架权限。&lt;/p&gt;
&lt;p&gt;还有一个信号说明这不是快进快出的活儿。它装的是 SSH 公钥，上线方式是反向隧道，大约每 60 秒重试一次，编辑器关掉之后仍然在跑，并且三平台都做了持久化，macOS 是启动项，Linux 写 cron，Windows 建一个名叫 SysMon 的计划任务、失败则退回启动目录。这套设计的意图是长期可交互的立足点，而不是装完就偷。而且脚本没有直接去读凭据的值，BleepingComputer 的判断是攻击者打算拿到访问权之后手动去取。&lt;/p&gt;
&lt;h2 id=&#34;那个-bug-不能当防御&#34;&gt;那个 bug 不能当防御&lt;/h2&gt;
&lt;p&gt;有一件事让很多人松了一口气：载荷在启用 SSH 服务这一步写错了，所以在大多数机器上隧道连不进来。&lt;/p&gt;
&lt;p&gt;macOS 上的错误在 Phorion 的披露里写得很具体。脚本想用 &lt;code&gt;systemsetup -getremotelogin&lt;/code&gt; 检查远程登录是否开着，但它是以普通用户身份跑的，这条命令返回的是管理员权限错误、退出码却是 0，输出里没有 &lt;code&gt;Off&lt;/code&gt;。而脚本只在输出包含 &lt;code&gt;Off&lt;/code&gt; 时才去启用 SSH，于是它跳过了启用这一步。Windows 上的错误更直接，它试图通过 &lt;code&gt;/bin/sh&lt;/code&gt; 调 PowerShell 去装并启动 OpenSSH，而标准 Windows 上没有这个 shell，所以失败。&lt;/p&gt;
&lt;p&gt;要注意的是这个 bug 不是防护。Hall 明确说了，在本来就开着远程登录的 Mac 上，或者用户事后自己打开的情况下，后门就是现成可用的。Cursor 也提醒，这个 bug 只在大多数 macOS 和 Windows 主机上成立，前提是没有用管理员权限启动 Cursor 这类相当罕见的情形。它装了 key、装了持久化、把主机详情发出去了，处置步骤一个都不能略。&lt;/p&gt;
&lt;p&gt;还有一条最容易漏：卸载扩展不够。载荷会落下独立脚本继续跑，所以处置要按主机侧来做，而不是按插件侧来做。&lt;/p&gt;
&lt;h2 id=&#34;为什么说这是新前线&#34;&gt;为什么说这是新前线&lt;/h2&gt;
&lt;p&gt;把两件事叠在一起看，就明白这个判断不是在造词。&lt;/p&gt;
&lt;p&gt;插件在 agent 时代的权限和周边资产都变了。扩展是拿 IDE 和当前用户的权限跑的，模块一加载就能碰本地文件、源码和开发工具链。而 agent 时代这些东西旁边躺着什么？BYOK 的模型 key、云凭据、各类 token，也就是载荷真正想要的那 40 个变量名的来源。市场侧的信任模型没有变，被保护资产的价值变了。&lt;/p&gt;
&lt;p&gt;分发侧也一样。Sharma 说的那句「越来越多是 agent 和自动更新在装这些东西，而不是人在装」值得抄下来。自动更新把「人做一次判断」这一步整个删掉了，11 小时窗口、5,000 台机器，这个比例就是这么来的。&lt;/p&gt;
&lt;p&gt;行业侧的量级也有人在做统计。据 Phoenix Security 的 campaign 追踪，VS Code 市场从接近零起步，在 18 个月里攒到 7 起已记录的 campaign；ReversingLabs 的检测数从 2024 年 27 起涨到 2025 年前十个月的 105 起；它追踪的 59 起 campaign 里，至少 14 起把 AI agent 工具当投递载体，手法包括 &lt;code&gt;.cursorrules&lt;/code&gt; 与 &lt;code&gt;CLAUDE.md&lt;/code&gt; 里的零宽字符隐藏指令、MCP server 注入、SessionStart 钩子。这些数字要打个折，Phoenix 是做供应链安全的厂商，这类统计本身就是它的市场材料，方向可信、绝对值存疑。但方向跟这次的形态是一致的。&lt;/p&gt;
&lt;h2 id=&#34;三起对照落点在上移&#34;&gt;三起对照：落点在上移&lt;/h2&gt;
&lt;p&gt;把今年的三起放在一张表里，能看出一个不太舒服的走势。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;事件&lt;/th&gt;
          &lt;th&gt;被替换的位置&lt;/th&gt;
          &lt;th&gt;存活/影响&lt;/th&gt;
          &lt;th&gt;传统自查动作是否有效&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;LiteLLM 2026-03&lt;/td&gt;
          &lt;td&gt;CI 里未固定版本的 Trivy 被投毒，泄漏了发布凭据&lt;/td&gt;
          &lt;td&gt;PyPI 上约 40 分钟&lt;/td&gt;
          &lt;td&gt;部分有效&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;LiteLLM 2026-10&lt;/td&gt;
          &lt;td&gt;三名工程师的 GitHub CLI OAuth token 被盗，触发并批准了发布流程&lt;/td&gt;
          &lt;td&gt;PyPI 上约 2 小时&lt;/td&gt;
          &lt;td&gt;查源码、对 tag、审 sdist 全部给出「干净」&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;本次&lt;/td&gt;
          &lt;td&gt;第三方市场里的官方扩展上架条目&lt;/td&gt;
          &lt;td&gt;11 小时，最多 5,000 台&lt;/td&gt;
          &lt;td&gt;看发布者、看包名、看版本号全部失效&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这条线的走向是在往上游挪：从依赖包，到构建产物，再到分发市场的上架位。每往上一格，就有一部分「自己事后能验证」的能力被拿掉。对依赖，你还能看源码；对 wheel，你还能对 Git tag；到了上架位，你没有可对照的东西，因为那本来就是官方的那一份。&lt;/p&gt;
&lt;p&gt;关于前两起，站内写过更细的拆解，见&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261021-litellm-supply-chain-attack-1070/&#34; &gt;《LiteLLM 又被投毒了》&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;插件市场缺的是包管理器十年前就有的东西&#34;&gt;插件市场缺的，是包管理器十年前就有的东西&lt;/h2&gt;
&lt;p&gt;把两个生态的防线并排放，差距就出来了。&lt;/p&gt;
&lt;p&gt;包管理器这十年攒下的东西大致是五样：lockfile 锁住确切版本、用 digest 而不是 tag、发布产物的签名与 attestation、企业私有源做路径隔离、以及 SBOM 这类可审计清单。这五样不是理论，站内拆过的另一起事件刚给出实证。LiteLLM 十月那次，浮动的标签体系（latest、main-latest、main-stable）全线中招，而走隔离私有发布路径的企业私有 registry 没有受影响。同一批攻击、同一批包，有没有可验证性和隔离路径，结果就是不一样。&lt;/p&gt;
&lt;p&gt;插件市场这边，这几样基本都缺或者很弱。扩展通常没有 lockfile 级别的版本固定，宿主默认开着自动更新，发布产物一般没有可验证的 attestation，权限却按 IDE 加当前用户来给。反过来看，Docker 那边的 MCP catalog 倒是把构建 attestation 和签名 SBOM 做成了默认，还可以在运行时验签。也就是说同类问题在别的生态里已经有解，只是插件市场还没补上。&lt;/p&gt;
&lt;p&gt;我想给的判断很直白：&lt;strong&gt;插件市场的安全水位比包管理器落后大约十年，而它承载的资产比包管理器更值钱。&lt;/strong&gt; 这个落差就是这次事件能发生 11 小时的结构原因，不是某个工程师的疏忽。&lt;/p&gt;
&lt;p&gt;能立刻做的是把插件当依赖来管：固定版本、关掉自动更新、把「谁装了哪些扩展、从哪个市场来的」变成一份清单。这三件事今天下午就能做完，而且不依赖任何厂商改产品。&lt;/p&gt;
&lt;h2 id=&#34;这次处置里最关键的一步不是下架&#34;&gt;这次处置里，最关键的一步不是下架&lt;/h2&gt;
&lt;p&gt;Cursor 的动作有三个：下架恶意版本并关停整个市场做审计、轮换自己的密钥、联合托管商把攻击者的服务器打掉。&lt;/p&gt;
&lt;p&gt;我认为最有效的一步是轮换密钥，而不是下架。理由跟根因未明有关：下架只处理了已经知道的那一个包，而密钥轮换处理的是「同一条路径还能不能再用」这个你还没弄清的未知。在不知道对方怎么拿到上架权限的情况下，轮换是唯一能同时覆盖已知和未知的动作。&lt;/p&gt;
&lt;p&gt;关停整个市场的代价很大，所有人的插件更新都得停，但它是唯一能证明「只有这一个包被改」的办法。这个取舍值得记下来：当发布位的完整性本身被质疑时，你能给出的最强证据是把发布路径重新走一遍，并把结果公开说出来。&lt;/p&gt;
&lt;p&gt;打掉攻击者服务器这个动作的效果是双份的，既断了回传也断了隧道。但它同时销毁了取证现场。这里有个真实的两难，我给不出更好的答案，只能指出来：响应速度和取证完整性在这一步是冲突的，这次他们选了速度。&lt;/p&gt;
&lt;h2 id=&#34;三个判断&#34;&gt;三个判断&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;发布者身份不再是信任锚。&lt;/strong&gt; 这一条对个人开发者的含义是具体的：市场页面上你能看到的那些信号，名称、图标、下载量、发布者认证，这次的攻击一个都没碰坏，全是真的。可用的替代是盯行为而不是盯身份，一个补全代码的插件为什么要往 &lt;code&gt;authorized_keys&lt;/code&gt; 里写东西、为什么要起一条 SSH 连接、为什么要在重启后还跑着。Sharma 给的判断标准很干脆，一个编码扩展在装 SSH 密钥，这件事本该在几秒内被抓住。这句话在技术上成立，在工程上代价很高，因为「几秒内」意味着你得有主机行为的连续观测，而绝大多数开发者机器上没有。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;责任会在厂商之间流转，处置成本落在用户这边。&lt;/strong&gt; 这次两家的声明都很克制，一家说不是我们造的，一家说不是我们的系统被攻破，而「怎么进的市场」没有解释。我不觉得这是谁在藏，我更倾向于它是这类事件的结构：只要分发市场是第三方，每一次都会以各方都能自证清白、用户去轮换凭据结账。能做的是把自己这侧的处置提前写进流程，比如哪几台机器开着 SSH、哪些环境变量里躺着生产凭据、出了事用哪台可信机器去轮换，而不是等公告出来再想。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;agent 时代把这一层的杠杆放大了，而这跟站内写过的那条线是同一个结构。&lt;/strong&gt; 插件就是 agent 的能力来源，所以「装一个插件」的语义已经变了，它从给自己加个功能，变成了给一个会自动执行东西的程序加权限。今年早些时候写 MCP 供应链那条线（&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261001-agent-mcp-supply-chain-security/&#34; &gt;《MCP 供应链安全》&lt;/a&gt;）时的结论是 npm 的教训在 agent 生态重演，这次的差别在载体换成了 IDE 市场，而被替换的是真品。载体还会换，结构不会。&lt;/p&gt;
&lt;h2 id=&#34;如果你在那-11-小时里更新过&#34;&gt;如果你在那 11 小时里更新过&lt;/h2&gt;
&lt;p&gt;版本号先对一下：2.1.312 和 2.1.313，Windows 与 macOS。Phorion 建议组织层面直接排查环境里有没有用过这两个版本，发现用了就启动应急响应。&lt;/p&gt;
&lt;p&gt;检查顺序按主机侧来。先看 &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; 里有没有一条标记为 &lt;code&gt;svc-telemetry&lt;/code&gt; 的条目。别只卸载扩展，载荷落了独立脚本，所以还要看 macOS 的启动项、Linux 的 crontab、Windows 里名为 SysMon 的计划任务和启动目录。然后轮换这台机器能碰到的所有凭据和会话，并且要在一台可信的机器上做这件事，因为被污染的机器上任何操作都可能被看着。想确认有没有人真的登进来过，可以按 Phorion 的建议查 SSH 日志里来自 localhost、用的正是 &lt;code&gt;svc-telemetry&lt;/code&gt; 这个 key 的登录。&lt;/p&gt;
&lt;p&gt;Cursor 已经发过检查命令和 macOS/Windows 的清理脚本，两家也都给了失陷指标。&lt;/p&gt;
&lt;p&gt;一句话收在这里：这次事件里值得反复看的是「没有冒充可识别」这七个字。它把供应链防御里最便宜的那一层，也就是看名字认人，整层拿掉了。剩下的那层要花钱，要建观测，而且得由每个用 agent 的团队自己出。&lt;/p&gt;
&lt;p&gt;相关阅读：&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261021-litellm-supply-chain-attack-1070/&#34; &gt;《LiteLLM 又被投毒了》&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261001-agent-mcp-supply-chain-security/&#34; &gt;《MCP 供应链安全：npm 的惨痛教训正在 Agent 生态重演》&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261019-opencode-byok-console-credential-breach/&#34; &gt;《OpenCode 被「蒸馏攻击」打穿》&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
