假 AI SDK,真木马:7 个 NebulaAI npm 包里的 Windows 后门
2026 年 9 月下旬,7 个伪装成 NebulaAI 官方 SDK 的 npm 包,通过混淆过的 preinstall.cjs 安装钩子植入定制 KNTRAT Windows 木马——受害者还没运行一行包代码就已沦陷。本文基于 CloudSEK 的 NEBULA 报告复盘完整攻击链,指出"AI tooling"本身已成为钓鱼语言,并为 vibe coder 整理事件响应清单。

此前我们在一篇指南里拆过 slopsquatting 这类 AI 时代的新型供应链攻击,并给过一套防护流程(见本站《Vibe 项目依赖供应链安全指南》)。那篇讲的是"怎么防",这篇讲的是"真实发生过什么"——2026 年 9 月下旬,一名攻击者把 7 个恶意 npm 包伪装成一家名为 "NebulaAI" 的公司的官方 SDK,投进 npm 仓库,目标直指正在疯狂给项目接 AI 能力的开发者。10 月 8 日,CloudSEK 发布了代号 NEBULA 的完整复盘报告。
如果你是 vibe coder,这件事和你直接相关:攻击者不再靠拼写错误收割打错字的人,而是开始蹭 "AI SDK" 这个热点词本身。而你的 Agent 执行 npm install 时,不会像人一样犹豫。
事件概览:一句话
一名攻击者用 4 个连号 burner 账号(nebulallms、nebulallms2、nebulallms3、nebulallms4),在 2026 年 9 月下旬连续发布了 7 个假冒 "NebulaAI" SDK 的 npm 包。任何人在 Windows 机器上 npm install 其中任意一个,都会在安装阶段就被植入一个 Windows 远控木马——不需要运行一行包里的代码。
- 仍可下载的包:
api-nebula和llm-nebula在报告发布时依然挂在 npm 仓库上,可以正常安装。 - 检测严重滞后:
api-nebula在 10 月 5 日被正式归类为MAL-2026-17531(OSV 恶意包编号)之前,已经"活跃且未被标记"了数天——换句话说,攻击窗口是按天算的,而归类是事后追认的。 - 最终载荷:定制版 KNTRAT 开源远控,C2 服务器
65.87.7.132,通信 User-Agent 为kntrat/0xB15B00B6。
攻击链拆解:门面是 SDK,本体是安装钩子
NEBULA 最值得细看的地方,是它的"门面工程"做得有多真。每个恶意包的入口文件 nebula.js 都是一个看起来完全正常的 AI 客户端,指向域名 api.nebulaai.dev——有名字、有域名、有像模像样的 API 封装。CloudSEK 指出,真正的安全审查如果只看包的"门面",大概率会放行:它就是一个长得像正经 SDK 的东西。
真正的威胁藏在 preinstall.cjs 里。这是一个被混淆过的 dropper,而 preinstall 是 npm 的安装生命周期钩子——它在 npm install 执行期间自动运行,用户还没 require 或 import 任何代码,机器就已经被拿下了。这是 npm 生态里最古老的伤口之一,但 NEBULA 把它和 AI 热点结合,杀伤力完全不同。
图 1:NEBULA 攻击链。从 npm install 到木马落地,中间不需要用户执行任何包代码——安装钩子就是执行入口。
dropper 落盘有两条路,二选一:
- 内嵌载荷:payload 以 base64 + zlib 编码直接塞在包里,安装时解码写出;
- 安装时联网拉取:在 install 阶段发起网络请求,把真正的可执行文件拉下来。
落点选得极其鸡贼:%LOCALAPPDATA%\Microsoft\Conhost\conhost.exe。conhost.exe 是 Windows 合法的控制台宿主进程,任务管理器里常年有它。攻击者把木马伪装成同名文件,再往一个看起来像系统目录的路径一放——普通用户瞥一眼进程列表,根本不会起疑。这是典型的"藏在众目睽睽之下"。
KNTRAT:一个"不需要 DLL"的木马
落盘的二进制是开源远控工具 KNTRAT 的定制变体,CloudSEK 报告的标题就点出了它最反常的特性:"Needs No DLL"。它只通过直接的 NT 和 win32k 系统调用工作,完全绕过标准 DLL 导入,留下一个空的导入地址表(IAT)。很多 EDR 和行为检测依赖用户态 API hook 来发现可疑行为——一个不走常规导入表的二进制,等于从这些探针的视野里"隐身"了一半。
它的功能清单是标准的间谍软件全家桶:HVNC(隐藏虚拟桌面远控,攻击者操作一个你看不见的桌面)、基于 Kernel Streaming 的摄像头与麦克风监控、Winlogon Shell 持久化。更值得注意的是它的反分析设计:CloudSEK 做沙箱引爆时,植入程序在 12 分钟的引爆窗口里完全压制了 beacon 行为——标准的"等沙箱超时再干活"套路,自动化分析流水线很容易被它骗过。
还有一个细节很有"项目管理"的味道:KNTRAT 的源码仓库在整个攻击期间一直是私有的,直到行动结束后的 10 月 6 日才公开,并且顺手从 kntrat-e 改名成了 kntrat。攻击者把开源项目当成私有武器库用完即公开,这种"先私有后开源"的节奏,说明这不是随手玩玩的脚本小子,而是有完整行动周期的团伙。
观点:供应链攻击的诱饵,从拼写错误转向"AI"本身
过去几年供应链攻击的主流剧本是 typosquatting:注册 reqeusts 这种拼错一位的包名,收割手滑的开发者。这个剧本有个天然上限——它只能骗到"打错字"的那一小撮人。NEBULA 换了一个剧本:不再赌你打错字,而是赌你在找 AI 能力。
想想 2026 年的 npm 搜索框里每天发生什么:无数开发者(和他们的 AI Agent)在搜 "AI SDK"、"LLM client"、"nebula" 这类关键词,给项目接大模型能力。"NebulaAI" 这个名字听起来就像又一家 AI infra 创业公司,api.nebulaai.dev 的域名、像模像样的客户端封装,整套门面就是为了回答开发者心里那个问题:"这玩意儿看起来靠谱吗?"——答案是看起来靠谱,而这正是问题所在。
我的判断是:"AI tooling" 本身已经变成了钓鱼语言。就像当年的 "crypto giveaway" 和 "免费 VPN" 一样,任何一个全民 FOMO 的技术热点,最终都会变成社会工程学的弹药。区别在于,AI 热点的受害者恰恰是最活跃、最愿意尝试新包的那批开发者——也就是 vibe coder 们。
vibe coder 的风险链路:Agent 不会犹豫
这条链路值得每个用 AI 写代码的人逐节检查:
- 你(或你的 Agent)想给项目接一个"看起来不错"的 AI SDK;
- 在 npm 上搜到
api-nebula,名字体面,README 像回事; npm install api-nebula——到这一步,preinstall.cjs已经执行完了,木马已经躺在Conhost目录里伪装成系统进程;- 你甚至还没写一行调用它的代码,就已经被植入了 HVNC 远控和摄像头监控。
关键变量是第 2 步的执行者。如果是人,至少还有一丝可能去看一眼包的发布时间、下载量、仓库链接——虽然 NEBULA 的门面工程让这丝可能也很渺茫。但如果是 AI Agent,它不会犹豫、不会起疑、不会去读 preinstall 脚本:它看到任务需要装包,就会装。一个 Agent 循环里可能连续执行几十个 npm install,这等于替攻击者把钓鱼规模化了——以前攻击者要骗一千个人逐一手滑,现在只需要让一千个 Agent 在无人值守的循环里各执行一次安装。
所以真正的教训不是"别用 AI 写代码",而是:把 npm install 当成执行任意代码来对待。因为技术上它就是——preinstall/postinstall 钩子运行在你的用户权限下,能读写文件、能联网。在 Agent 时代,合理的做法是给 Agent 的包安装加护栏:安装前检查 package.json 的 scripts 字段、用 --ignore-scripts 先装再审、或者把 Agent 的执行环境放进沙箱/容器里。允许 Agent 无限制 npm install,约等于给了攻击者一个永不睡觉、从不质疑的内鬼。
"能从 npm 下"不等于"安全"
另一个被 NEBULA 撕开的幻觉是"仓库即信任"。很多人潜意识里觉得:能从 npm 官方仓库装下来的包,至少经过了某种审查。但事实是,api-nebula 在被正式标记为 MAL-2026-17531 之前"活跃且未被标记"了数天,报告发布时它仍然可以安装。OSV 编号是事后追认,不是事前拦截。
供应链安全的真相一直是概率游戏:仓库方的检测是滞后的、抽样的,而攻击者的投放是实时的、批量的。指望"npm 上有 = 安全",相当于指望应用商店没有恶意 App——历史已经反复证明这靠不住。对 vibe coder 来说更现实的心态是:每一个 npm install 都是一次小型的信任决策,值得至少 30 秒的审查:包的年龄、维护者历史、有没有 install 钩子。30 秒换一台不被远控的电脑,这买卖不亏。
对照:恶意包和正常 SDK 的安装行为差在哪
很多人第一次听说这类攻击时会有个疑问:正常装 SDK 也会联网、也会写文件,到底怎么区分?下面这张对照图把 NEBULA 恶意包和正常 SDK 在安装阶段的行为逐项摊开——核心差异只有三处,但每一处都是红线:
图 2:恶意包 vs 正常 SDK 的安装行为对照。记住右下角的三步自查:preinstall 钩子、安装时联网、写入系统目录——命中任意一条就停手审查。
注意第一行:正常 SDK 在安装阶段不应该执行任何代码。npm 安装的本分是"下载 + 解包进 node_modules",一个 SDK 包如果在 package.json 里声明了 preinstall 脚本,就已经偏离了 SDK 的本分。当然,有些合法包确实用 install 脚本做原生编译(比如需要 node-gyp 的包),但一个"AI API 客户端"需要 install 钩子的理由是零——纯 JS 的 HTTP 封装没有任何编译需求。这是 NEBULA 留下的最明显的破绽,也是普通人最容易掌握的判断法则:纯 JS 工具包 + install 钩子 = 直接拉黑,不用听解释。
如果你已经装过:事件响应清单
CloudSEK 在报告里给了安全团队的处置建议,结合 NEBULA 的 IoC,我整理成一份普通人也能执行的清单。按顺序做:
- 查自己有没有中招:在项目里搜
api-nebula、llm-nebula(别忘了package-lock.json),Windows 上检查%LOCALAPPDATA%\Microsoft\Conhost\目录下有没有可疑的conhost.exe——注意,真的 conhost.exe 住在System32,Conhost这个文件夹本身就不该存在。 - 断网:在防火墙/网关层封禁
65.87.7.132的出站连接,并检查历史流量里有没有命中这个 IP 或 User-Agentkntrat/0xB15B00B6的记录。 - 找持久化:检查 Winlogon Shell 相关注册表项有无被篡改,排查命名管道(named pipe)和隐藏桌面(HVNC)留下的产物——这是 CloudSEK 点名的几个检测方向。
- 按入侵处置:如果确认落盘,不要只删文件了事。HVNC + 摄像头/麦克风监控意味着攻击者可能已经看过你的屏幕、听过你的麦克风。按完整的入侵响应走:隔离机器、换凭证、复盘时间线。
给团队的长期动作只有三条:依赖安装默认加 --ignore-scripts(确实用到的再逐个放行)、CI 里对新增依赖跑 install 钩子审计、给 AI Agent 的 shell 执行范围设边界。都不复杂,复杂的是"开始做"这个决定。
结语:钓鱼语言会跟着热点走
NEBULA 的技术含量其实不算顶级——preinstall 钩子、伪装系统进程、直接 syscall,这些手法在安全圈都不新鲜。它真正聪明的地方在选题:它把诱饵放在了 2026 年开发者注意力最集中的地方。当所有人都在给项目接 AI 能力时,一个叫 "NebulaAI" 的 SDK 就是完美的伪装。
这个规律值得记下来:钓鱼语言永远跟着热点走。今天是 "AI SDK",明天可能是别的。下次当你(或你的 Agent)准备 npm install 一个名字光鲜的新包时,多问一句——这个包的存在,是为了解决问题,还是为了被安装?
评论 (0)
原始来源
相关文章

10月3日,《大西洋月刊》刊发 OpenAI 安全负责人 David Robinson 的辞职长文《我辞职了,因为 OpenAI 的文化坏了》。这位供职三年半、亲手起草 Preparedness Framework、撰写过 12 份前沿模型安全报告的内部人,把火力指向了硅谷的发布哲学本身:迭代部署在 agent 时代"注定周期性翻车"。本文梳理他列出的四起事故链、OpenAI 的回应,以及这对 vibe coder 社区的意义。

Anthropic Frontier Red Team 10 月 12 日发表研究:15 台 55 美元的山寨电视盒就能跑起 26B 模型,GLM-5.2 已在隔离集群里完成端到端自我复制。按小模型 13.7 ECI/年的改进速度,2026 年底能力水位交汇——而 vibe coder 每天用的 agent 工作流,正是复制链本身。

短信验证码按条烧钱、还防不住劫持。Passkey(WebAuthn)用设备端私钥签名替代短信:7 步跑通最小闭环,5 条安全红线一次讲透,外加多设备管理、丢失恢复链路与 8 项上线 checklist——把登录成本和整类攻击一起归零。