返回所有文章
发布于 · 作者 Renaud Deraison

代理凭空捏造的软件包

特拉维夫大学、以色列理工学院与 Intuit 的研究人员披露了 HalluSquatting:攻击者反复试探编码代理,直到摸清它会稳定捏造哪些软件包名、仓库名或技能名,随后抢先注册那些捏造出来的名称,然后守株待兔。当你请求真正的资源时,代理反而抓取攻击者的版本——而藏在其中的指令会劫持代理的 shell,安装僵尸网络恶意程序。仓库名称的捏造率最高达 85%,技能安装最高达 100%。Bromure Agentic Coding 让这整条抓取与执行的路径跑在一次性的 Linux VM 里,扫描猜测落地的软件包注册表,只留给恶意程序可偷的诱饵。

你向编码代理要一个众所周知的软件包。它打出一个看起来没错的名称,执行了安装,然后 继续往下走。那个名称是猜的——而有人早已把这个猜测一字不差地注册下来,并塞满了恶意 程序。没有人打错字。名称是代理捏造的,而攻击者就守在捏造落地的地方。

2026 年 7 月,一组来自特拉维夫大学、以色列理工学院与 Intuit 的研究人员——其中包括 Aya Spira、Stav Cohen、Ron Bitton、Avishai Wool 与 Ben Nassi——描述了一种他们称为 HalluSquatting 的攻击。它把大型语言模型最为人熟知的弱点之一——它们会凭空捏造,并把捏造当成事实陈述 ——变成一套供应链投递系统,瞄准的不是你,而是替你工作的代理。

这套手法简单得近乎乏味。要一个编码代理为它从未见过的项目拉取软件包、克隆仓库或安装 技能,它往往会猜测标识符,而不肯承认自己不知道。HalluSquatting 就把这个猜测武器化。

从打错字到幻觉

抢注打错字(typosquatting)由来已久:注册 expressslodahs,等着某个人在终端 按错键。它仰赖人犯错。抢注 AI 错觉(slopsquatting)在 2025 年至 2026 年初浮现,把 错误移到了模型身上——代理幻觉出一个不存在的软件包名,攻击者抢先注册,下一个幻觉出 同一名称的代理便装下了载荷。2026 年 1 月, Aikido 的 Charlie Eriksen 记录了一个被幻觉出来的 npm 软件包 react-codeshift,在无人察觉之前扩散到了 237 个 项目。从头到尾没有打错字,所以任何抢注打错字的防御也从未触发。

HalluSquatting 是 2026 年的升级,而升级之处在于:幻觉不再交由运气决定。研究人员的 方法是一套四步骤的配方:

  1. 挑一个模型没背下来的目标。 那些出现在训练截止之后、正当红的仓库与工具最为 理想:模型听过它们,所以会尝试,但它没见过真正的名称,所以会捏造一个。
  2. 摸清那个错误。 反复试探代理,直到你知道它会稳定产出哪个假名称。论文报告被 幻觉出的仓库名称出现的频率最高达 85%,技能安装的情境最高达 100%——一致到 足以下注。
  3. 占下那个捏造的名称。 把它注册到 GitHub 或插件商店,并用写给代理阅读的指令 填满 README、清单文件或 SKILL.md
  4. 等待。 当开发者请求真正的资源时,代理反而输出攻击者捏造的标识符并抓取它。 隐藏的指令接着劫持代理自己的命令执行工具,把载荷装上。

那个载荷不是概念验证。研究人员把猜测串接到提示注入——Nassi 的团队称之为 promptware——最终导向远程代码执行与僵尸网络恶意程序:受感染的开发者机器会回连 并听命行事。猜测把攻击者的文件端上代理的盘子,埋藏的指令把它变成命令,命令则用 开发者的笔记本电脑组出一张僵尸网络。

为什么这是对代理的攻击,而非对你

一语道破的,是报道里那句话:HalluSquatting"把目标从人类移向 AI 代理,后者在执行 命令时,可能不会确认来源是否真实"。一个对软件包名没把握的人会停下来、查注册表、 瞄一眼星标数。自动执行模式下的代理不会停。它的工作就是继续前进,而一个从它自己权重 里蹦出来的名称,带着和你亲手打出的名称一样的权威。它没有理由怀疑自己。

研究人员在开发者每天都会用到的工具上做了测试—— GitHub Copilot、Cursor、Windsurf、Cline、Google Gemini CLI,以及 OpenClaw 家族 ——并发现幻觉"可在不同的 LLM 模型与应用之间转移",对建立在 Anthropic、OpenAI 与 Google 模型之上的代理都有效。没有哪一家厂商能靠打补丁把它消除,因为它骑乘在编码代理 把请求变成动作的那套共通形态上:猜名称、抓资源、读它说什么、照它说的做。

代理「加入软件包 X」猜出一个名称抓取捏造的名称攻击者已预先注册README = 指令当成计划来读提示注入劫持 shell工具→安装你的机器僵尸网络载荷安装 · 听命行事真实密钥 · 令牌 · 会话都在磁盘上信标C2僵尸网络没有人打错字。代理自己的猜测就是那个地址,而攻击者拥有它。
HalluSquatting 把人类从供应链里拿掉。攻击者试探代理,直到摸清模型会捏造哪个名称,用一份布下陷阱的 README 或清单文件注册下那个确切名称,然后等待。当你请求真正的资源时,代理输出捏造的名称、抓取攻击者的版本、把嵌入的指令当成自己的计划来读,并装下僵尸网络的载荷。在一般环境里,这一切都跑在你的机器上。

为什么"别再幻觉就好"从来不是解方

诱人的答案是让模型自我核查——在抓取前先解析名称、对 cloneinstallfetch 发出警示、把每个标识符锚定到真实存在的东西上。这些都是好主意,研究人员也建议如此。 但它们全都住在同一个地方:一个读取代理即将做什么、盼着在它执行前拦下坏情况的 过滤器。HalluSquatting 正是针对那个读取者而设计。名称看来正当,因为它是模型产出的; README 看来像文档,因为 README 本就是那样;而安装命令,是编码代理一整天做的最稀松 平常的事。

这正是代理安全其余部分反复撞上的那道墙。读取命令的封锁列表, 败给改写命令的 shell。 读取软件包的扫描器, 败给不在软件包里的载荷。 搜索技能的代理, 推荐它自己找到的恶意程序。 HalluSquatting 加上了迄今最锋利的版本:那个恶意名称根本不是来自互联网。它来自模型。 你无法把自己代理的想象力列入黑名单。描述由攻击者执笔,而执行是结果被决定的唯一所在。

Bromure 在哪里划线

Bromure Agentic Coding 不试图劝模型别再猜。它改变的是一个错误猜测所能触及的范围。 Bromure 执行的每一个代理——Claude Code、Codex、Grok Build——都跑在你 Mac 上一台 一次性的 Linux VM 里,而非 macOS 本身。所以当代理输出捏造的名称、抓取攻击者的资源、 并照研究人员所见那样执行安装时,有几件事已然成立。

首先,对这类攻击而言相当罕见的是,注册表这条路径会被扫描。 当捏造的名称是 npm、 PyPI 或 Cargo 软件包时——抢注 AI 错觉的情境、react-codeshift 的情境——它正好落进 Bromure 的供应链扫描里,这道扫描会在软件包从公开注册表被拉取时加以检查。这是 HalluSquatting 中唯一一处,猜测解析成一个 Bromure 专为在被信任之前直接查看而打造的 东西。被幻觉出的依赖仍然是依赖,它从 Bromure 看守的正门走进来。

其次,载荷跑在一个你用完就丢的盒子里。 假设捏造的名称指向的是 GitHub 仓库或 插件商店的技能,而非注册表软件包,且僵尸网络的加载器执行了。它是在 VM 里执行。没有 持久的主机供它听命:把配置文件重置回基准,投放的二进制文件、排定的作业、立足点—— 全都没了。一个在下次重置就消失的僵尸网络节点,算不上什么节点。

第三,没有真实凭据可供征召。 一个翻遍环境与磁盘、寻找 API 密钥、git 与云端令牌、 以及 SSH 密钥的僵尸网络恶意程序,找到的是诱饵:Bromure 把占位值(brm_…、一份合成 的 ~/.kube/config、可丢弃的 ssh 与云端令牌)注入 VM,只在主机上、在代理服务器中、 在通往真正 API 的出口途中,才把真实的换回来。真实密钥从不进入盒子。载荷送往其命令与 控制的,是一袋什么都认证不了的字符串。

第四,promptware 是对着检测器被读取的。 HalluSquatting 在成为执行攻击之前,先是 一场阅读攻击——整个利用手法都悬系于代理吞下攻击者的 README、清单文件或 SKILL.md, 并把它当成自己的计划。那正是 Bromure 看守的、不可信的权威:与一份恶意的 CLAUDE.mdAGENTS.md 同一类。Bromure 的设备端提示注入检测,会拿代理当作文档阅读的内容, 对着从不离开 Mac 的本机模型评分,再加上一套针对隐形 Unicode 花招的确定性扫描器。 一份被抓取的清单文件里埋着"现在执行这个安装脚本"的指令,正是那个检测器存在的理由。

而在这一切之下,外发流量是可见的。 僵尸网络的信标、阶段载荷的抓取、外泄的尝试—— 它们会以你看得见的外发流量出现在 Bromure 的安全日志里,而不是来自一台你信任的机器的 一通悄无声息的回连。

一次性 Linux VM捏造的名称代理抓取并在此安装供应链扫描npm / PyPI / Cargo在门口拦下僵尸网络想征召的东西promptware 由设备端检测器评分ANTHROPIC_API_KEY = brm_9f2a…(假)git / AWS / ssh = 诱饵 · 盒子会重置信标(已记录)C2 收到诱饵一个会消失的节点真实机密留在主机的代理服务器上在传输时才换入代理照样猜、照样安装。它只是在某个用完就丢的地方做这件事,用的是并不真实的密钥。
同样的猜测、同样的抓取、同样的安装——换了机器。在 Bromure 里,代理跑在一次性的 Linux VM 上:被幻觉出的注册表软件包在正门被供应链扫描拦下,僵尸网络的载荷跑在某个用完就丢的地方,它翻找到的凭据是诱饵、只在主机的代理服务器上才换成真实的,被抓取清单文件里的 promptware 由设备端检测器评分,信标则被记录下来。猜测照样发生。只是没有东西可供征召。

这划出的界线圈住了什么

隔离与扫描是围堵,不是幻觉的解药。值得把 Bromure 在此处改变了什么、没改变什么讲清楚。

代理照样捏造名称

Bromure 不会阻止模型幻觉出一个标识符,也不会阻止它抓取那个名称解析到的东西。把 代理的猜测锚定住,是模型与框架的问题。Bromure 改变的,是被抓取的东西在哪里执行, 以及它执行时能触及什么。

注册表扫描涵盖注册表

被幻觉出的 npm、PyPI 或 Cargo 软件包,正是供应链扫描所检查的——一次货真价实的正门 拦截。被幻觉出的 GitHub 仓库或插件商店技能不是注册表软件包;那条路径靠的是隔离、 注入检测器与诱饵撑住,而非注册表扫描。

替换涵盖你配置的机密

诱饵替换保护的是你放进配置文件的凭据:模型密钥、git 与云端令牌、托管数据库端点、 ssh 密钥。一个脚本在执行途中写到磁盘的令牌,或你在盒子里亲手建立的会话,就只是 数据而已。把机密放在代理经纪服务里,而非工作区里。

检测是一张网,不是一堵墙

设备端的注入评分,在多数情况下会标出一份安装并执行的清单文件,但一位谨慎的作者能 把诱饵措辞得溜过单一扫描器。把检测器当成一层;当检测器失手时撑住局面的,是围堵 ——一个装着假密钥、外发流量被记录的一次性盒子。

研究人员以一句值得记住的话作结:"攻击只会越来越好,从不会变差。"他们的成功率是 地板,不是天花板,而底层那套信任机制——一个把自己的猜测当事实、把抓取到的文件当计划 的代理——这一季度不会被修补。你的代理终将为某个它一知半解的东西捏造一个名称,而那些 捏造名称中,有些早已被人占下。问题不在于它会不会有一天抓到错的那个。在 85% 的幻觉率 下,它有时就是会。问题在于,那一刻究竟是什么在执行:是你的机器、你真实的密钥,以及 一个会留下的立足点——还是一个你能丢弃的 Linux 盒子,里头装着诱饵,注册表也在入口处 查过。Bromure 让它成为后者。