凭证植入型供应链投毒成为攻击AI开发者的典型范式

—Cursor恶意Claude Code扩展事件的关联研判

版本:1.0   编制日期:2026年11月1日(北京时间)

摘要


2026年10月29日,Cursor 扩展市场分发的 Anthropic.claude-code 2.1.312 与 2.1.313 中出现恶意篡改版本,官方确认的目标平台为 Windows 与 macOS。攻击代码随扩展进入开发终端,在模块加载时执行,尝试写入攻击者 SSH 公钥、启用系统 SSH 服务、建立反向 SSH 转发,并在扩展目录之外留下脚本、密钥文件与启动项。下线恶意软件包、卸载扩展或者关闭当时的攻击服务器,都不能代替对这些目标端遗留状态的清理。安天第一时间获取到对应样本展开分析,并快速在垂直响应平台上发布了风险提示和分析报告,并验证安天智甲可有效防护、查杀此事件样本。[1-3]

安天认为该事件体现的关键范式是:供应链恶意代码在目标环境中植入攻击者凭证,再利用合法远程服务形成可独立保留的访问入口。更精确地说,目标保存的是允许某把密钥登录的授权记录;攻击者保有与之对应的私钥。初始执行代码负责制造这种授权状态,系统 SSH 服务负责后续认证和会话执行。入口可独立于原扩展保留,但其可用性仍取决于服务、权限、网络通路和认证策略。

本事件存在实质性的恶意功能代码,安天认为不能归类为“只投放配置、不投放代码”,也不是严格意义上的无文件攻击。其特殊性在于访问能力被分散到授权文件、合法服务、反向转发和启动脚本之中,不需要由一个专用远控服务端持续承载全部能力。投放载荷没有另行下载恶意可执行文件,并不意味着没有释放脚本、没有落盘凭证,或没有后续交互风险。[3]

通过梳理公开历史案例材料发现,账户或密钥植入早于大模型时代。1998年已有诱饵程序写入系统账户的记录;2013年的篡改版 WordPress 插件、最迟2020年有公告记录的 leetlog,以及2024—2025年的恶意 npm 包均展示了相关链条。2026年的 sidecar-mcp 与本事件,则把这一组合直接带入 MCP 配置工具与 AI 编程扩展场景。公开证据支持将其列为 AI 软件工具链中值得重点防御的一类攻击范式,但尚不足以量化其普及速度,或证明早期真实发生率较低。[13-20]

安天工程师提示,本事件核心处置原则是:同时恢复软件来源可信、身份授权可信、远程通路可信与启动状态可信。调查应区分恶意版本安装、代码执行、授权落地、转发建立和攻击者实际登录,不能仅凭版本号、公钥注释、进程存在或脚本退出码作出最终判断。

1.事件边界与证据口径


1.1事件时间和受影响范围

Cursor 公告给出的分发窗口为2026年10月29日约02:27—13:35太平洋夏令时,换算为09:27—20:35 UTC,以及北京时间10月29日17:27至10月30日04:35,约11小时8分钟。该窗口是已知恶意包可被分发的时间,不是每台主机实际执行恶意代码的时间。缓存包、离线安装和延后启动可能使执行发生在窗口之后。[1]

表 1-1受影响对象确认范围与研判边界说明

对象 已确认范围 判定边界
分发渠道 Cursor 扩展市场中的被篡改包 不能扩大为所有 VS Code 扩展市场同时被攻陷
扩展标识 Anthropic.claude-code manifest 中的发布者字符串不等于发布者授权证明
版本 2.1.312 和 2.1.313 版本号是筛查条件,来源、内容和哈希更能区分恶意副本
官方公布的包平台 darwin-arm64 和 win32-x64 macOS 与 Windows 的其他架构是否存在受影响包,不能仅凭代码跨平台推断
Linux 载荷包含 Linux 分支和对应 IoC 属于代码能力,不等于已确认 Linux 分发或受害数量
其他官方渠道 微软市场、官方 npm 包与 Open VSX 未被证实受此次事件影响 保留事件和时间范围,不能写成这些渠道永久安全

1.2已知事实与尚未确定的问题

安天工程师分析认为,当前公开信息能够支撑恶意包分发、载荷行为和部分残留物的判断,但不能独立确定攻击者进入 Cursor 分发系统的具体方式、归属组织、每台终端上每一步是否成功,以及最终成功登录的受害数量。市场重建和密钥轮换是必须落实的处置动作,不是“其他扩展必然被污染”或“某个发布密钥必然泄露”的证明。

部分初期报道引用了最多约5000名安装用户的估算。安装用户数、下载次数、代码执行主机数与成功远程访问主机数是不同指标。本报告不将该数字作为已入侵主机数量;本事件的风险评估应依据技术能力与本组织遥测,而不是未经统一口径核验的规模数字。[4]

2.从扩展分发到目标端执行


2.1信任边界如何被跨越

开发者信任的对象通常是发布者、扩展名称和正常更新流程。本事件中,恶意内容借用了合法扩展身份和分发入口,使用户在安装或自动更新时获得攻击者修改的包。即使上游项目本身未被攻陷,下游镜像、聚合市场或重新分发服务发生失陷,也足以破坏从发布者到终端的内容完整性。[1,4]

因此,供应链审计不能只检查“是否安装了官方名称的扩展”。应同时记录实际下载源、包内容摘要、平台构建、版本、下载时间、发布者验证信息与执行位置。存在多个分发渠道时,同名同版本也不能被自动视为字节一致。

2.2恶意代码的触发时机

安天工程师分析发现,攻击者在 extension.js 的正常扩展代码之前新增了一个函数。其长度约66行,使用 Node.js 的进程、文件系统、系统信息、HTTP 与密码学接口。它在扩展模块被加载时运行,无须等待用户开始一次 Claude 对话。该样本未依靠 npm 的 preinstall 或 postinstall 等生命周期钩子触发。[3]

部分文章的“安装后运行恶意代码”容易让读者理解为安装动作本身必然触发。更准确的描述是:安装或更新使恶意扩展进入环境,随后的扩展模块加载触发代码。启动编辑器、恢复工作区或扩展激活都应纳入时间线;具体宿主版本的激活过程应以日志为准。

这也解释了为什么模型侧的提示词过滤、对话审查或工具调用确认并非本事件的直接阻断点。恶意代码在扩展宿主中执行,处于模型交互流程之外。没有证据表明本事件依靠提示注入、模型权重篡改或大模型自主决策完成入侵。

2.3投放物和目标端产物的组成

表 2-1恶意载荷各层级组件及功能说明

层次 本事件内容 性质与作用
扩展内执行代码 前置 JavaScript 逻辑 采集、写文件、调用系统工具、配置持久化与回传
扩展内数据 登录授权公钥、另一套隧道身份材料、地址与路径字符串 驱动认证、连接与落地位置选择
目标端授权状态 authorized_keys 中新增公钥 为持有对应私钥的一方增加登录资格
目标端功能脚本 .smt、smt.cmd 与回退启动脚本 重建或使用隧道身份文件,循环发起 SSH 连接
目标端启动配置 LaunchAgent、计划任务、Startup 文件、Linux cron 分支 在登录、启动或进程退出后继续运行相关脚本
合法系统组件 ssh、可用时的 autossh、sshd、shell、PowerShell 提供连接、认证、转发和命令执行能力

这里的“合法”描述组件本身的来源与功能,不代表其当前调用获得了用户授权。恶意性主要体现在谁发起了授权变更、谁持有密钥、访问去向和是否违背用户意图。

3.攻击链的技术拆解


3.1环境采集与主机登记

安天分析发现,载荷采集主机名、用户名、操作系统、架构、主目录、工作目录、Git 配置邮箱,并筛选最多40个名称包含 KEY、TOKEN、SECRET、PASS、AWS 或 GCP 的环境变量。回传内容是变量名称,不是这些变量的值;不能据此认为已窃取对应 API 密钥。[2]

变量名称仍具有侦察价值。例如,它们可能暴露终端使用何种云平台、部署系统或凭证类型。用户名和主目录有助于把授权文件与目标账户对应起来;主机名和 Git 邮箱有助于区分多台开发终端。工作目录只是一个路径值,不能单凭这一字段认定载荷已遍历源码、读取所有项目或窃取文件。

公网 IP 通过 ifconfig.me 或 api.ipify.org 获取。这两个站点是合法的地址查询服务,仅有访问记录不足以构成入侵证据。HTTP 外部回传目标是攻击者地址的8099端口 /beacon;对127.0.0.1同路径的请求只是环回尝试,不能当作已经向互联网外传。[1]

3.2写入授权公钥

载荷把注释为 svc-telemetry 的 Ed25519 公钥追加到当前用户的 SSH 授权文件。Unix 类系统分支还设置 .ssh 目录和授权文件的权限。其改变的是目标服务接受哪些公钥进行登录认证,而非替换 SSH 的认证算法。[3]

严格说,公钥不是攻击者需要保密的登录秘密;真正保密的是对应私钥。把该行为简称为“植入凭证”可以用于攻击链概括,但技术表述宜写为“植入攻击者控制身份的公钥授权记录”。svc-telemetry 是公钥注释,不是因此创建了名为 svc-telemetry 的本地账户。本事件也没有证据显示初始载荷必然创建了新系统账户。

通常,进程能够修改其所属用户的授权文件,并不需要管理员权限。它能否进一步允许 SSH 登录,则由服务配置、文件格式、权限、账户限制和附加认证要求共同决定。公开修复脚本还提示,恶意公钥追加时没有先保证文件以换行结束,可能与已有内容连在同一行。因此,“看到字符串”“存在格式正确的授权记录”和“SSH 实际接受该密钥”必须分别确认。[6,9]

3.3两套密钥承担的角色

安天分析确认,载荷解码内嵌的隧道身份材料,临时文件后缀由主机名和主目录派生。该私钥文件的 SHA-256 摘要与 SSH 公钥指纹是两类不同对象,不能互相替换匹配。附录甲3分别列出文件摘要和指纹。[2,5]

表 3-1事件中SSH 身份材料分布与用途说明

身份材料 放置位置或持有方 实际用途
登录目标的攻击者公钥 目标 authorized_keys 告诉目标 SSH 服务允许哪一把私钥对应的身份登录
与上项对应的私钥 攻击者一侧 用于对目标账户进行认证;不能认为它已被载荷写入目标
隧道连接私钥 载荷内嵌并解码至 .stk_ 文件,以及 .smtk 或 smtk 让受害机以 tunnel 账户连接攻击者服务器
目标 SSH 主机密钥 系统 SSH 服务自身维护 证明服务端身份,和上述两套用途不同

3.4启用合法 SSH 服务及权限限制

Cursor 将多数 macOS、Windows 主机上的接入失败归因于权限要求及恶意代码错误。但这不构成“只有管理员模式启动的 Cursor 才可能有风险”的通用规则:如果目标原本已经运行 SSH,且新增公钥位于实际生效的授权文件中,攻击链就不一定需要成功启用服务。[1,9]

Windows 还需区分普通用户授权文件与管理员账户常用的 C:\ProgramData\ssh\administrators_authorized_keys。写入用户目录中的文件,不保证管理员账户的 sshd 配置会读取它;文件 ACL、账户类型及实际 sshd_config 都应核验。不能用 Unix chmod 成功与否替代 Windows ACL 判断。[10]具体不同平台代码行为与判定对比见下表:

表 3-2多平台 SSH 服务部署行为与判定限制

平台 代码试图执行的动作 主要成功条件 不应推导出的结论
macOS 检查 Remote Login,必要时调用 systemsetup 打开 管理权限、系统设置与账户允许登录 失败不等于用户公钥或 LaunchAgent 未写入
Windows PowerShell 安装 OpenSSH Server 能力,配置启动并启动 sshd 功能安装可用、提升权限、服务与认证配置允许 请求 SYSTEM 运行不等于已经获得 SYSTEM
Linux 分支 检查 sshd 或 ssh 并尝试启动服务 对应服务存在且调用者具备所需权限 存在该分支不代表 Linux 版本实际被投放

3.5反向 SSH 转发如何解决可达性

安天分析发现,载荷的关键命令行片段为 ssh -N -R '*:0:localhost:22',可用于关联进程遥测中的反向转发请求。

其中,-N 表示不在隧道服务器上执行远程命令;-R 请求远端端口转发;0 请求由远端分配监听端口;localhost:22 指向发起连接的受害主机一侧的本地22端口。星号表达对远端绑定地址的请求,是否真正对其他主机开放仍受服务器配置约束。[8,9]

受害机先主动连接攻击者的 SSH 服务器,随后远端到达该转发端口的连接,可沿已有通道抵达受害机的 SSH 服务。该设计可减少直接入站连接受 NAT 或边界策略阻碍的影响,但不能绕过所有网络控制:出站 SSH 必须被允许,隧道服务器必须接受身份和转发请求,本地服务也必须存在并可被连接。

因此,攻击者不必预先知道受害机的可直接入站地址。主机回传提供定位信息,反向转发提供实际接入路径,两者解决的是不同问题。公网 IP 不等于可直接登录地址;同一公网出口后也可能存在多台终端。把此行为笼统称为“反向 shell”容易混淆两层能力。初始建立的是 SSH 反向端口转发;交互式 shell 需要随后通过目标 SSH 服务的认证。外层隧道进程成功存在,不等于内层登录已成功,更不等于取得管理员权限。

图3-1 恶意 Claude Code 扩展 SSH 后门攻击链路示意图

3.6独立脚本与启动持久化

macOS 使用用户 LaunchAgent,Windows 尝试创建以 SYSTEM 运行的 SysMon 计划任务并提供 Startup 脚本后备;Linux 代码分支使用用户 crontab 的 @reboot。脚本和隧道密钥位于扩展目录之外,因此卸载该恶意扩展时,不会自动清除后门相关配置,访问权限仍可保留。

Unix 分支的 .smt 能够在运行时重建持久使用的 .smtk 身份文件,然后执行连接循环。只删除某一个密钥文件、但保留其生成脚本和启动项,可能使该文件再次出现。Windows 分支将身份文件和批处理脚本分别写入磁盘。[2]

“约每60秒重试”应理解为连接退出或失败后的重连等待,而不是每隔60秒必定新建一条并行隧道,也不是已证明每60秒上报一次主机详情。持续运行的启动机制、隧道循环和初始延时信标属于不同生命周期。[2]

3.7网络回传与后续载荷边界

安天分析发现一次延时回调尝试向环回和外部地址发送 JSON。初始阶段没有把 HTTP 响应解释为代码或配置,也没有通过这些请求下载新的恶意脚本;curl 的已知用途是取得公网 IP 文本。独立脚本和密钥来自扩展内已有内容的生成或解码。[3]

这一结论只限定被分析的初始载荷。若后续 SSH 登录成立,操作员可以执行命令或传输文件,相关动作未必体现在原始 extension.js 中。反过来,不能因为该能力存在就把源码窃取、令牌盗取、横向移动或进一步供应链污染认为是已发生事实。

4.凭证植入形成独立入口的关键范式


4.1一次代码执行如何转化为持续授权

本事件的实质是让一次来自供应链的代码执行,改变目标环境长期保存的身份授权状态。开发工具承担进入与执行,授权文件保存攻击者身份,合法服务负责认证,脚本与启动项维持网络路径。各部分可以分开存在,删除其中一个不必然消除其余部分。

这里的“预设后门不在投放物中”需要限定解释。若其含义是“最终提供远程登录能力的 SSH 服务原本属于目标系统或系统可安装组件”,这一概括成立;若其含义是“投放物没有恶意代码、没有密钥、没有后门准备逻辑”,则与证据不符。更合适的说法是:远程会话能力由合法服务提供,恶意投放物负责植入授权并使通路持久化。

4.2授权残留三类独立属性辨析

该事件的凭证型持久化后门,攻击服务器下线会中断指向该服务器的回传和转发,但不会从受害主机撤销公钥。若系统 SSH 通过其他网络路径可达,残留授权仍可能被利用;若本地服务未启用且没有可达路径,该授权暂时不构成可用入口,但仍应撤销。不能把“留有授权”写成“无条件可远程登录”,也不能把“当前不可达”写成“没有残留风险”。

表 4-1本次事件中三类独立属性的含义与依赖条件

独立性 本事件能够成立的含义 仍然依赖的条件
对原扩展的独立性 授权条目和扩展外脚本可在卸载后保留 文件未删除、启动配置仍有效
对专用远控程序的独立性 认证和会话可由系统 SSH 承载 合法服务可用,账户策略允许
对攻击基础设施的独立性 授权记录可独立于当时服务器继续存在 原反向隧道仍依赖对应服务器;其他接入需另有可达路径

4.3条件模型与风险分层

基于本事件的特点,我们对其进行凭证型持久化入口的访问成立条件拆解,可用的凭证型入口至少需要:攻击者控制认证材料,目标接受相应授权,合法服务可用,并存在可达通路。跨重启持续访问还需要相关授权、服务与必要网络机制在重启后仍有效。任意一项缺失都可能阻断当前访问,但不等于其他植入物不存在。

表 4-2事件调查状态、研判结论与处置重点

调查状态 可得结论 处置重点
仅发现相关版本或缓存 存在暴露线索 核验来源、哈希、模块加载与安装日志
确认载荷执行但服务或转发失败 已发生本地恶意执行 仍清理授权、脚本、启动项并评估信息暴露
发现格式有效的恶意授权且 SSH 可达 具备潜在访问条件 立即隔离并核查认证记录,不能等待发现进一步恶意文件
确认转发成功 形成了连接路径 继续核验目标密钥认证与会话执行
确认攻击者登录或后续命令 已发生交互式入侵 扩大凭证、源码、构建环境和关联资产调查

4.4对恶意代码检测的含义

对于此类事件威胁,安天认为静态扫描适合识别已知扩展文件和脚本,但还需要监测“谁改变了可登录身份”。授权文件的内容差异、密钥指纹、服务配置变化、任务动作和网络转发参数,可能比某一恶意二进制文件是否仍在磁盘上更能说明风险。合法 ssh、PowerShell 或 launchctl 被调用不应单独作为恶意判据。更高价值的组合是:编辑器扩展宿主派生系统命令,紧接着出现未经批准的授权公钥、陌生外部 SSH 连接,以及指向用户可写脚本的启动项。每一条信号单独都可能正常,关联后的身份和控制关系才构成完整证据。

5.历史前例与 AI 工具链中的组合演变


5.1历史案例应按共性强弱归类

本事件与安天此前分析的传统 npm 生态凭证植入投毒事件与中国开源AI模型代码仓库的潜伏式污染攻击事件不同的是:以往恶意包大多局限包管理器生命周期,而本次依托 AI 编程扩展市场分发,载荷完成植入之后,整套访问入口完全脱离扩展本体实现持久留存,同时面向高价值开发工作环境,威胁影响面进一步放大。安天还梳理了历史上类似投毒植入身份配置的案例如下表:

表 5-1同类供应链投毒历史案例对比

时间与案例 投放和授权行为 与本事件的共性 不能忽略的差异
1998 sshdwarez 或 sshdexp 诱饵安全程序以 root 执行后向 /etc/passwd 加账户并回邮 代码执行转化为账户状态改变 没有证明合法官方供应链失陷,公告也未还原完整接入链 [13]
2013分发 2014披露的篡改版 WordPress 插件 第三方插件下载渠道;回传站点 URL,触发后创建管理员 借软件投放植入身份,再使用正常登录 是第三方再分发污染;服务为 WordPress,不是 SSH [14]
2016 CCTM 恶意更新 官方插件目录更新;后续脚本建立 support 管理员 官方分发链与账户植入同时出现 同时有下载后门、Web shell 和盗密,是混合型事件 [15]
leetlog 最迟2020年有公告 npm 0.1.2和0.1.3写入硬编码 SSH 公钥 公钥授权植入机制直接相同 2020年是公告日期,首次投放日、服务状态和受害规模未明 [16]
2024 ethers-mew 仿冒 ethers 分支,写入 root 授权公钥 开发包执行与 SSH 身份植入 同时窃取以太坊私钥;需要写入 root 文件的权限 [17]
2024 streamserch 等包 npm 拼写仿冒,植入授权公钥并回传身份和公网 IP 包投放、主机定位和合法 SSH 入口组合 没有证明 AI 参与攻击;不等于合法依赖维护者被攻陷 [18]
2025 node-telegram-utils 等包 仿冒 Telegram 库,写入两把公钥并回传地址 卸包后公钥保留,后续依赖系统 SSH 属开发者包生态;与 AI 没有直接关联证据 [19]
2026 sidecar-mcp 公告 MCP 设置 CLI 写入授权公钥,尝试开启 macOS Remote Login AI 工具链入口,授权独立于包保留 需运行 CLI;不能误写为安装即触发或官方 MCP 项目失陷 [20]
2026 Cursor 本事件 市场中篡改扩展,写授权、启动脚本和反向转发 将供应链投放与凭证型持续入口直接组合 本地 SSH、权限和通路均有成功条件 [1-3]

上表梳理了多起依托软件供应链实施身份植入的历史案例,按照时间顺序对比其投放方式、授权机制,提炼与本次 Cursor 恶意扩展事件的共性,同时标注关键差异点,避免简单类比。案例覆盖传统 SSH 账户投毒、npm 生态拼写仿冒、AI 工具链 MCP 场景投毒等不同阶段,重点区分:分发渠道、持久化逻辑、是否复用系统 SSH、是否关联 AI 生态等要素。其中两处案例补充说明:2013 年 WordPress 篡改插件案例素材来自 Sucuri 2014 年调查报告。报告记录 Restrict Content Pro、Flat Skin Pack 等篡改插件最早于 2013 年 6 月流入第三方下载站点;SEOPressor 恶意载荷会回传站点地址、新建预设密码管理员账号,并复用网站后台正常登录通道。该时间仅为首批样本流入时间,不可统一认定为全部样本的分发时间。[14]sidecar-mcp 事件由 Amazon Inspector 上报,收录于 OpenSSF 与 OSV,公告日期 2026 年 7 月 10 日。该载荷借 MCP 配置流程写入 SSH 公钥、尝试开启 macOS 远程登录,授权配置在卸载包后仍可保留;该案例仅证明 AI 工具生态成为供应链投毒新场景,不存在模型自主生成、执行攻击策略的证据。[20]

5.2凭证后门植入的典型范式的风险

如上文所述,植入账户、公钥或其他授权材料,是长期存在的持久化方法;将其与软件供应链组合,也不是 AI 时代才出现。相对于普通漏洞利用后加账户的案例,“供应链投放—植入新授权—借合法服务形成独立入口”这一完整链条,在本次检索到的早期材料中表现为跨年份的零散个案。这个观察描述的是公开证据的可见度,不能直接等同于历史真实发生率。

2024—2026年的材料显示,该组合在开发者软件包中被反复采用,并已出现在 MCP 配置工具和 AI 编程扩展中。这足以支持将它提升为 AI 软件工具链的一种典型威胁模型,纳入检测、应急和供应链审核设计;不宜将其写成已经统计证实的“快速普及”或“主要由 AI 导致”。

早期已存在这一组合,但公开记录较为零散;随着开发工具、包管理器与 AI 插件生态连接到更多高价值工作环境,这种利用一次投放改变长期授权状态的链条获得了更广的适用场景,并可能开始成为需要按典型范式防范的风险。

5.3AI 工具链为什么提高这种组合的防御优先级

安天认为,首先,AI 编程工具通常与源码工作区、终端、包安装器及远程开发环境相邻。被污染的扩展或配置工具更容易处于能够写入用户目录、接触 SSH 材料并调用系统命令的进程上下文。这里讨论的是部署结构带来的机会,不是宣称所有 AI 工具都有相同权限。其次,插件、MCP 服务器和依赖包可通过更新、推荐或一条设置命令进入开发环境。新接入点增多,使身份授权变更更容易被埋在“配置开发工具”的正常任务中。sidecar-mcp 是这种任务伪装的直接前例;本事件则体现市场分发内容失真后的风险。[1,20]再次,开发终端同时连接个人工作区、组织仓库、构建平台和云资源。攻击者即便只获得普通用户权限,也可能接触该用户有权读取的数据。此类风险来自身份权限的实际覆盖范围,不需要先证明管理员提权,也不应把可访问范围自动写成已经窃取的范围。最后,单纯针对恶意扩展的处置常围绕版本回退和卸载展开,而凭证型入口的生命周期跟随系统授权。两种生命周期不一致,会使“软件已更新”与“终端授权已恢复可信”出现差距。AI 时代的新意主要在工具链组合和资产聚合,并不在 SSH 密钥认证机制本身。

5.4关注此类攻击范式的演化趋势

安天认为后续观测应按独立攻击活动而不是包数计数,并同时记录官方发布链失陷、第三方篡改分发、拼写仿冒和纯诱饵工具四类入口。每例还需标注是否新植入身份、是否依靠合法服务、是否在卸包后保留、是否存在其他远控载荷,以及 AI 是目标场景、品牌诱饵、开发工具还是攻击执行主体。

在相同监测覆盖下,以年度供应链事件数或暴露资产数为分母,可以比较这一战术组合的占比变化。把六个同源恶意包当作六次独立活动,或把带有 AI 检测产品名称的报告当作 AI 攻击,都会放大趋势。

6.排查处置与恢复验证


6.1先保全证据再清理

安天建议对已发现执行或植入迹象的终端进行网络隔离,同时保留必要的受控取证能力。记录终端、用户、安装来源、扩展路径、版本、包摘要、相关时间戳和时区,保存恶意文件副本、授权文件副本、启动配置与进程网络信息。原始授权文件和隧道身份文件应按敏感证据管理,不把私钥内容复制进工单或公开报告。

清理会改变时间线、文件内容和进程状态,因此应先完成必要取证。若业务风险要求立即阻断连接,可以先隔离,再采集本地证据;不必为了等待完整取证而保持攻击通道在线。

6.2把单点检查改为多证据判断

Cursor官方建议使用 grep 或 Select-String 搜索 svc-telemetry,并在未命中时输出 machine not impacted。安天认为该结论偏于绝对。未命中只表示在本次成功读取的范围内未发现该字符串;还可能存在文件不存在、权限不足、不同用户、条目被删除、恶意代码仅部分执行等情况。检查程序应分别输出“命中”“未命中”“未能检查”,而不是把后两者合并为安全结论。建议先按公钥主体或指纹确认,再结合注释。注释可以被更改或仿造;授权文件也可能包含行首限制选项,直接按整行文字匹配并不总是可靠。搜索范围包括所有实际受影响的用户、Windows 管理员授权文件,以及 sshd 实际配置的其他 AuthorizedKeysFile 路径。初始快查命令见附录丙。

6.3排查顺序与应收集的证据

攻击者的远程连接经反向隧道进入本地 sshd 的连接,在目标侧可能呈现为来自环回地址。因此,不能仅搜索认证日志中的攻击者公网 IP;还应关联密钥指纹、会话时间、用户名、隧道进程与后续命令。该提示来自转发机制推论,不代表公开资料已提供了本事件的具体登录日志。建议参考下表和附录甲进行排查。

表 6-2排查对象、核验内容与能回答的问题列表

排查对象 核验内容 能够回答的问题
分发和扩展记录 实际来源、哈希、版本、加载时间、更新缓存 是否获得并加载恶意副本
授权文件 新增密钥、指纹、格式、权限、实际读取路径 是否形成有效的攻击者授权
SSH 服务 安装时间、启动方式、监听、登录范围和认证策略 原先是否开启,是否被更改,是否接受植入身份
进程和网络 父子进程、身份文件路径、转发参数、目的地址 是否启动隧道,是否持续连接
启动项 名称、动作、运行身份、文件内容 是否能跨启动或登录继续运行
认证和会话 密钥接受记录、用户名、会话、后续命令 是否存在实际登录和交互
项目和远端系统 源码读取、令牌使用、仓库或构建变更 是否向其他资产扩展影响

6.4清理对象和官方脚本使用边界

安天建议,清理应覆盖恶意扩展副本和缓存、未经授权的公钥、运行中的隧道与重试进程、独立脚本、隧道身份文件和启动项。必须核对启动动作,避免仅凭 SysMon 等名称误删合法软件。授权文件只删除确认属于攻击者的材料,保留合法公钥和必要的文件权限。

Cursor 提供 macOS 和 Windows 修复脚本。macOS 脚本要求以受影响用户运行而不是 root;多用户环境需覆盖各相关用户。Windows 脚本要求提升权限,注释要求先关闭编辑器,并遍历用户配置目录。脚本应从公告所链接的官方地址取得、审阅后在受控变更流程中执行,记录所用版本和输出。[6,7]

本次对公开脚本文本的复核还发现两个边界。其一,Windows脚本主要处理各用户目录的授权文件,不能据此假定 C:\ProgramData\ssh\administrators_authorized_keys 或自定义授权路径也已清理。其二,脚本没有完整恢复 SSH 服务安装、启动方式与远程登录设置。因此,运行成功后仍需与原有配置基线比对。[6,7]

脚本的非零退出码可提示其检查到的问题;零退出码只能说明该版本脚本的检查未报告残留,不能证明没有遗漏路径、其他载荷或已经发生的后续入侵。原文“若仍有残留,脚本会以非零状态退出”应注意为“若脚本覆盖的检查发现未清理项或相应错误,可返回非零状态”。

6.5凭证轮换与系统重建

同时,安天建议对确认执行载荷的终端,应评估该用户可访问的会话、仓库令牌、云密钥、签名材料和其他秘密。初始信标只包含环境变量名称,不构成“不需要轮换”的依据;如果实际访问无法排除,应依据资产敏感度与调查完整性采取保守轮换和会话撤销。轮换操作应在可信终端进行,避免新凭证再次落入失信主机。

若发现攻击者登录、额外持久化、无法解释的系统修改,或证据缺口使主机可信状态无法恢复,应从可信镜像重建。重建和恢复前要核验备份、扩展缓存及开发配置,防止把恶意授权或启动脚本一并恢复。

6.6系统恢复验证

安天提示,恢复被攻击系统至少验证这些内容:已不再加载恶意扩展内容;所有相关授权位置没有攻击者密钥;启动项和运行进程不再指向恶意脚本;SSH 服务与网络策略符合原有基线;注销或重启后相关产物不再生成;关联仓库、云服务与会话已按风险完成处置。重启只能验证部分持久化是否恢复,不能证明过去没有入侵。

7.面向软件工具链的防御建设


该事件再次警示,分发侧应验证内容与发布者授权之间的对应关系,保留可追溯的版本、平台、哈希和来源记录。针对镜像或聚合市场,要检测其与权威上游之间的异常差异;对未在上游出现的版本、同版本内容改变和签名关系变化分别报警。更新缓冲期与小范围验证可降低快速扩散风险,但不能保证迟滞后所有恶意包都会被发现。

安天工程师建议,端点侧应把授权文件、远程服务和启动状态纳入联合监控。检测规则需要记录变更发起进程、目标用户、密钥指纹、服务状态前后差异和启动动作。开发工具宿主写入 authorized_keys,并外连新的 SSH 目的地址,是比“使用了 ssh”更具体的调查线索。网络侧应限制开发终端到未经批准目的地的远程管理连接,关联长期出站 SSH、异常转发参数与终端授权变化。只封禁本次 IP 可切断已知通路,但不能代替撤销授权,也不能覆盖换址后的相同手法。合法公网 IP 查询服务应作为上下文信号,不宜直接列为全局恶意域名。

同时,当前传统凭证安全工作视角存在明显局限性,部分机构的身份治理意识仍然停留在特权账户管理的传统思路;安全产品的设计视角,也大多聚焦凭证失窃、凭证外泄场景,尚未围绕 “恶意植入新增授权凭证” 构建完整检测、监控、处置防御闭环。攻击者不再以窃取已有凭证为唯一目标,转而通过供应链直接在终端植入攻击者可控凭证,这对现有凭证安全体系提出新挑战。在人工智能开发工具链时代,凭证的范畴已经远远不局限于传统系统账户、账号密码;SSH 公钥授权、MCP 配置授权、扩展落地的身份材料、开发工具内置访问凭据都已经成为攻击者重点争夺的凭证对象。针对 AI 工具生态,安天认为,扩展、MCP 程序、技能执行脚本和包依赖都应按可执行软件管理。模型工具调用审批可以约束模型主动发起的动作,却未必约束扩展初始化代码,防御设计应明确各执行层的实际权限、可写目录、网络出口与身份材料访问范围。

总体而言,本事件所呈现的攻击范式可归纳为:供应链恶意代码在目标环境植入攻击者凭证,依托系统合法远程服务构建可独立留存的持久访问入口。植入凭证本身是攻击活动中由来已久的基础手段,但这套完整战术组合在早期历史案例中并不多见;在 AI 生态叠加开发工具链的场景下,该攻击链路可能逐步演变为一类快速增多的典型范式。

附录甲 本次事件入侵指标


甲1 使用规则

以下指标仅用于本次 Cursor 事件。历史案例的地址、密钥和文件名不混入当前事件指标集。精确哈希和公钥主体的关联性高;路径、任务名和命令片段需结合上下文。网络地址按历史披露记录使用,不代表报告编制时仍由攻击者控制。没有对相关地址进行主动连接验证。[1]

甲2 扩展包名与载荷摘要

对象 摘要
2.1.312 darwin-arm64 VSIX SHA-256: fcbb327e38e61c4fec795e0d0591f52cd1014b813d20a5912104953c3a17c364MD5: e0d64d53e802a0217ba6f0e656ed2f20
2.1.312 win32-x64 VSIX SHA-256: 3de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081MD5: bd3b71ddf3d0cc3af76249afd2c0eda1
2.1.313 darwin-arm64 VSIX SHA-256: 80402fdcad8799285fd93044976973ca000da7995fb93363f819bb8e4f84ee6cMD5: 34e491161e056c9b899a79b602ac73b9
2.1.313 win32-x64 VSIX SHA-256: 6786ec90cbd45949695bd7805c9fbb26cfc91bc5fc897de0183d9bcb9cb21731MD5: 7838a3be2ca0ff08c1bdb160ef516d39
extension.js SHA-256: ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15MD5: f49bcd657ef1e626e85ce858958c1769
解码后的隧道私钥文件 SHA-256: 7e0a52885fadee05544a9e99eb18c792bec05900a5e1a66d68f8383decb0e278

单个样本的摘要不能保证覆盖所有改名、重新打包或字节不同的变体。MD5仅作历史兼容检索,优先使用 SHA-256。

甲3 网络与 SSH 身份数据

类型 值 解释
历史攻击地址 134[.]209[.]82[.]225 公告称已协调下线;保留历史检索
外层 SSH tunnel@134[.]209[.]82[.]225 TCP 22 受害机连接远端服务器的账户与地址
外部回传 hxxp://134[.]209[.]82[.]225:8099/beacon HTTP POST
环回请求 http://127.0.0.1:8099/beacon 本机请求,不能单独视为对外回传
授权公钥注释 svc-telemetry 关联字符串,优先核对公钥主体和指纹
隧道密钥注释 svc-telemetry-tun 公开研究补充的关联字符串 [5]
合法地址查询服务 ifconfig.me 和 api.ipify.org 不是独立恶意 IoC,不能据此一律封禁

攻击者登录授权公钥

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P svc-telemetry

授权公钥指纹

SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk

反向隧道身份指纹

SHA256:KOAU57+ZG6u3MG4WwzPzPX2O5YEe9qdOC1Bl+6MVyDQ

甲4 文件和启动项

平台 文件或位置 检索说明
macOS ~/.ssh/authorized_keys 检查恶意公钥,不把整个授权文件视为恶意
macOS ~/.config/.smt 和 ~/.config/.smtk 脚本与隧道身份文件
macOS $TMPDIR/.stk_<10hex> 临时身份文件模式
macOS ~/Library/LaunchAgents/com.apple.sysmond.plist 标签 com.apple.sysmond;检查实际动作
Windows %USERPROFILE%\.ssh\authorized_keys 用户授权路径
Windows C:\ProgramData\ssh\administrators_authorized_keys 管理员账户补充排查路径,不等于已证实载荷总会写入
Windows %USERPROFILE%\.config\smt.cmd 和 smtk 脚本与隧道身份文件
Windows %TEMP%\.stk_<10hex> 临时身份文件模式,兼顾多用户与会话临时目录
Windows 计划任务 SysMon 结合动作是否指向 .config\smt.cmd 判断
Windows %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\sysmon.cmd 用户启动后备脚本
Linux 代码分支 ~/.ssh/authorized_keys 和 ~/.config/.smt 及 .smtk 行为能力指标,非确认受影响平台
Linux 代码分支 /tmp/.stk_<10hex> 临时身份文件模式
Linux 代码分支 cron @reboot /bin/sh "<HOME>/.config/.smt" 用户 crontab 条目,保留无关任务

临时文件名可使用正则 \.stk_[0-9a-f]{10} 进行初筛;模式命中不等于完成恶意判定。Windows 的 smtk 完整路径为 %USERPROFILE%\.config\smtk。

甲5 进程和命令行片段

片段 对应行为
ssh -N -R '*:0:localhost:22' 反向端口转发请求
autossh -M 0 Unix 分支使用的连接维持工具片段
schtasks /create /tn SysMon 计划任务创建尝试
systemsetup -setremotelogin on macOS 远程登录启用尝试
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 Windows SSH Server 能力安装尝试
StrictHostKeyChecking=no 放宽主机密钥信任检查,自动接受新密钥;已知密钥变更仍有部分限制
UserKnownHostsFile=/dev/null 不使用通常的 known_hosts 文件
ServerAliveInterval=30 和 ServerAliveCountMax=3 连接保活参数
ExitOnForwardFailure=yes 无法建立所请求的转发时退出;后续连接最终目标失败不必然使隧道退出
IdentitiesOnly=yes 限定所使用的认证身份材料

以上是关联检索片段,不应单独认定进程恶意;尤其要核对身份文件路径、父进程、目的地址和启动来源。连接参数的精确含义参见 OpenSSH 客户端配置手册。[1,22]

附录乙 本事件ATT&CK 战术枚举与技术映射


乙1 全部战术的本事件覆盖状态

战术 本事件状态 判断依据
TA0043 Reconnaissance 侦察 未确认入侵前侦察 载荷运行后的主机信息获取归入 Discovery
TA0042 Resource Development 资源开发 基础设施存在,取得方式未明 有服务器和密钥,不足以认定其购买、租赁或劫持方法
TA0001 Initial Access 初始访问 已确认分发事件 被篡改的软件供应链内容进入终端
TA0002 Execution 执行 代码能力明确,逐机执行需验证 JavaScript 及系统解释器调用
TA0003 Persistence 持久化 代码和残留机制明确 授权公钥、启动项及扩展外脚本
TA0004 Privilege Escalation 权限提升 存在高权限运行请求,未证实成功 SYSTEM 计划任务及需管理权限的服务配置
TA0005 Stealth 隐蔽 存在对应代码行为 任务名称伪装、Unix 点文件、隐藏窗口等
TA0112 Defense Impairment 防御削弱 未见充分证据 静默捕获错误不等于禁用防护或清除日志
TA0006 Credential Access 凭证访问 初始载荷未证实窃取秘密值 植入攻击者身份不是窃取受害者凭证
TA0007 Discovery 发现 代码能力明确 系统、用户、网络地址及配置线索
TA0008 Lateral Movement 横向移动 未确认 构建反向隧道不等于已登录组织内其他主机
TA0009 Collection 收集 未确认额外业务数据采集 未见初始载荷批量读取源码、文档等证据
TA0011 Command and Control 命令与控制 转发能力明确,实际接入有条件 SSH 隧道提供潜在操作通路
TA0010 Exfiltration 外传 主机元信息回传尝试明确 外部 HTTP POST;秘密和业务数据窃取未确认
TA0040 Impact 影响 未确认破坏活动 没有据此确认加密、擦除或业务破坏

乙2 主要技术映射表

技术 本事件战术 对应行为及证据状态
T1195.002 Compromise Software Supply Chain 初始访问 Cursor 市场分发被篡改包;事件事实
T1059.007 JavaScript 执行 扩展模块前置 JavaScript;公开样本分析
T1059.001 PowerShell 执行 Windows 服务配置及连接循环;代码与尝试
T1059.003 Windows Command Shell 执行 smt.cmd 等批处理;文件存在不证明已执行
T1059.004 Unix Shell 执行 shell 调用及 .smt 脚本;Linux 限代码分支
T1082 System Information Discovery 发现 主机名、操作系统、架构
T1033 System Owner/User Discovery 发现 当前用户名和身份上下文
T1016 System Network Configuration Discovery 发现 获取公网 IP;不自动认定网络扫描
T1098.004 SSH Authorized Keys 持久化 添加攻击者公钥;不自动代表认证成功或提权
T1572 Protocol Tunneling 命令与控制 请求 SSH 反向转发;成功状态待遥测确认
T1543.001 Launch Agent 持久化 用户 LaunchAgent;不是系统级 LaunchDaemon
T1053.003 Cron 持久化和执行 Linux 用户 @reboot 分支;不扩大实际影响范围
T1053.005 Scheduled Task 持久化和执行 SysMon 任务尝试请求 SYSTEM;高权限成功未证实
T1547.001 Registry Run Keys / Startup Folder 持久化 使用 Startup Folder 部分;没有证据表明修改 Run 键
T1140 Deobfuscate/Decode Files or Information 隐蔽 解码内嵌隧道身份材料;不是解密受害者密钥
T1036.004 Masquerade Task or Service 隐蔽 SysMon、com.apple.sysmond 等名称伪装
T1564.001 Hidden Files and Directories 隐蔽 Unix 点文件;Windows 点前缀不等同隐藏属性
T1564.003 Hidden Window 隐蔽 Windows 隐藏 PowerShell 窗口的代码行为

附录丙 初筛命令的安全结论表达


以下命令仅作当前账户的只读初筛,不修改授权文件,不建立远程连接。它们搜索公钥主体,并明确区分未发现与无法检查。文件存在但未命中,不代表载荷没有运行;当前用户检查也不能代替多用户调查。需将命令输出与版本、哈希、进程、启动项和网络证据结合。

macOS 或 Linux 当前用户初筛

                          key='AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P'
                          file="$HOME/.ssh/authorized_keys"
                          if [ ! -e "$file" ]; then
                            echo '文件不存在;不能据此排除其他恶意动作'
                          elif [ ! -r "$file" ]; then
                            echo '无法读取;本项检查未完成'
                          else
                            grep -qF -- "$key" "$file"
                            rc=$?
                            if [ "$rc" -eq 0 ]; then
                              echo '发现关联公钥主体;需保存证据并核验指纹与授权格式'
                            elif [ "$rc" -eq 1 ]; then
                              echo '本文件未命中;不能据此判定主机未受影响'
                            else
                              echo '读取或检索失败;本项检查未完成'
                            fi
                          fi

                        

Windows 当前用户和管理员授权路径初筛

                          $key = 'AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P'
                          $paths = @(
                            "$env:USERPROFILE\.ssh\authorized_keys",
                            "$env:ProgramData\ssh\administrators_authorized_keys"
                          )
                          foreach ($path in $paths) {
                            try {
                              $item = Get-Item -LiteralPath $path -ErrorAction Stop
                              $hit = Select-String -LiteralPath $item.FullName `
                                -Pattern $key -SimpleMatch -Quiet -ErrorAction Stop
                              if ($hit) { "命中关联公钥主体:$path;需核验指纹和格式" }
                              else { "本文件未命中:$path;不能排除受影响" }
                            } catch [System.Management.Automation.ItemNotFoundException] {
                              "文件不存在:$path;不能排除其他恶意动作"
                            } catch {
                              "检查未完成:$path;请核验权限和读取错误"
                            }
                          }

                        

如果使用 ssh-keygen 对保存的公钥文件计算指纹,应对照附录甲的授权公钥指纹;不能把隧道身份指纹误作目标授权指纹。上述命令为报告提供的初筛示例,未在受影响的 macOS 或 Windows 终端进行执行验证。

5. 参考资料


[1] Cursor。Security notice — malicious version of Anthropic.claude-code 2.1.312 and 2.1.313 identified in the Cursor VS Code Extension Marketplace。2026-10-29发布,页面注明2026-10-30 11:30 PT更新 IoC。https://cursor.com/blog/claude-code-extension-security-notice

[2] Microsoft Security Research。Inside a malicious Claude Code-branded extension and its persistent SSH backdoor。2026-10-30。https://www.microsoft.com/en-us/security/blog/2026/10/30/inside-malicious-claude-code-branded-cursor-extension-persistent-ssh-backdoor/

[3] OpenSourceMalware。Trojanized Claude Code Extension Plants an SSH Backdoor。采用其修订后的渠道归属及公开样本分析。https://opensourcemalware.com/blog/trojanized-claude-code-extension-plants-persistent-ssh-backdoor

[4] Socket Research Team。Cursor Removes Malicious Claude Code 2.1.313 Extension From Its Marketplace。2026-10-30。https://socket.dev/blog/claude-code-extension-compromise

[5] Netskope Threat Labs。Trojanized Claude Code Extension on the Cursor Marketplace。2026-10-30。仅引用其载荷和隧道身份指标;渠道和版本以更新后公告为准。https://threatlabs.netskope.com/blog/2026/10/trojanized-claude-code-extension/

[6] Cursor 官方 macOS 修复脚本文本。检索副本 SHA-256 为 c15900de25dd12d92adca3fa75b40253ae11edc96e70fbef0fd44252b292443a。https://cursor.com/static/security/claude-code-extension/remediate-macos.sh

[7] Cursor 官方 Windows 修复脚本文本。检索副本 SHA-256 为 4189b85194cadee9f3624493ec126b76a69f64b15c515bec7d2dd3d30bca4e7b。脚本可能继续更新,摘要用于区分本次审阅版本,不是恶意指标。https://cursor.com/static/security/claude-code-extension/remediate-windows.ps1

[8] OpenBSD OpenSSH 手册 ssh。端口转发和参数语义。https://man.openbsd.org/ssh

[9] OpenBSD OpenSSH 手册 sshd_config。AuthorizedKeysFile、AuthenticationMethods、GatewayPorts 等配置语义。https://man.openbsd.org/sshd_config

[10] Microsoft Learn。Key-based authentication in OpenSSH for Windows。https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement

[11] MITRE ATT&CK Enterprise tactics。当前战术列表。https://attack.mitre.org/tactics/enterprise/

[12] MITRE ATT&CK Version History 与2026年4月更新。https://attack.mitre.org/resources/versions/ ;https://attack.mitre.org/resources/updates/updates-april-2026/

[13] Tatu Ylönen。Comments on the sshdwarez exloit。1998-11-17公开邮件,LWN存档。https://lwn.net/1998/1119/sshdwarez.html

[14] Denis Sinegubko,Sucuri。Unmasking Free Premium WordPress Plugins。2014-03-26。https://blog.sucuri.net/2014/03/unmasking-free-premium-wordpress-plugins.html

[15] Denis Sinegubko,Sucuri。When a WordPress Plugin Goes Bad。2016-03-04。https://blog.sucuri.net/2016/03/when-wordpress-plugin-goes-bad.html

[16] OSV 与 GitHub Advisory Database。GHSA-gfm8-g3vm-53jh,Malicious Package in leetlog。2020-09-03公告。https://osv.dev/vulnerability/GHSA-gfm8-g3vm-53jh

[17] Phylum,现由 Veracode 托管。Trojanized Ethers Forks on npm Attempting to Steal Ethereum Private Keys。2024-10-18。https://www.veracode.com/blog/trojanized-ethers-forks-on-npm-attempting-to-steal-ethereum-private-keys/

[18] Socket。Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries。2024-11-22。https://socket.dev/blog/malicious-npm-packages-inject-ssh-backdoors-via-typosquatted-libraries

[19] Socket。npm Malware Targets Telegram Bot Developers。2025-04-18。https://socket.dev/blog/npm-malware-targets-telegram-bot-developers

[20] OSV 与 OpenSSF Malicious Packages。MAL-2026-10161,sidecar-mcp;原始发现者 Amazon Inspector。2026-07-10公告。https://osv.dev/vulnerability/MAL-2026-10161

[21] MITRE ATT&CK 官方技术页。正文所列每项技术均可按其编号查阅;子技术采用 /techniques/父编号/子编号/ 路径。完整链接清单见配套 ATTACK_mapping.csv。

[22] OpenBSD OpenSSH 手册 ssh_config。StrictHostKeyChecking、ExitOnForwardFailure 和 IdentitiesOnly 参数。https://man.openbsd.org/ssh_config