README ZIP 恶意软件:审查 AI 工具的实际安装内容

返回
Kevin Riedl

16 分钟 阅读 · 2026年11月5日
最近审核

下一篇
图片在你的设备上生成,不连接 Instagram。文章链接会复制到剪贴板,供链接贴纸使用。

你批准了一个 AI 技能。后来,它的 README 指向了未经你审查的压缩包,SKILL.md 却没有变化。原来的文件检查仍然通过,但这次安装已经依赖那项检查从未覆盖的内容。

README ZIP 恶意软件诱导可以保留原样的技能指令,同时改变安装去向。将仓库身份、准确提交、README 指向的目标、压缩包内容和所需权限一起审查。保存可信的记录;源码、下载字节、复制后的文件或执行权限范围发生变化时,重新作出安装决定。

安装审查针对的是特定软件内容,以及允许它使用的权限。下方的离线实验展示了这项决定的边界,其中也包含一次无害的重新打包:它需要解释,却不足以判定文件恶意。

资料核对日期:2026年11月5日。攻击活动的描述依据研究者公开的证据。我们实际运行的比较使用生成的文本文件、ZIP 和本地 Git 提交,不发送网络请求,也不运行任何待审安装程序。

独立性与商标声明: 本页由 Wavect 发布,Wavect 自身也是服务商,因此我们对本页存在商业利益。我们与本页提及的其他公司没有关联,未获得其背书,也不是其合作伙伴;所有第三方公司名称、品牌与商标均归各自所有者所有。关于其他服务商的陈述来自公开可查的来源,主要是其自己发布的页面,以本页标注的核查日期为准,此后可能已经发生变化。做决定前请自行直接核实。本页依据我们所知的情况撰写,并力求保持客观。如果你认为其中有不准确或不公平之处,请写信告诉我们,我们会更正: [email protected]

73 个假冒 AI 工具仓库的报告说明了什么?

2026年11月4日,SecurityBreak 的 Thomas Roccia 发布了一份涵盖 73 个 GitHub 仓库的 IOC 清单,这些仓库冒充 AI 智能体工具。当天复查时,清单记录了 51 个可访问、22 个返回 404。这些数字描述当时观察到的仓库状态,不代表感染数量,也不说明它们现在是否可访问。

Roccia 描述了仿冒 mcp-superset、hermes-agent 和 ContinuousClaude 等项目的副本。检查过的技能与设置文件看起来正常,但 README 指示读者获取仓库中已提交的 ZIP 文件。

这些指示还要求 Windows 用户绕过安全警告。有一个压缩包位于 .claude/hooks/config/。报告中的 Windows 安装包组合了批处理启动器、LuaJIT 运行时,以及伪装成文本的混淆 Lua 代码。

研究者的公告将其识别为 SmartLoader,这类恶意软件常与 StealC 关联。现有证据并未证明每个仓库都投递了该载荷。IOC 清单区分了样本中已确认的指标,以及尚未在这些版本中确认的其他指标。受害者数量和各账号操作者的身份仍不明确。这些证据也不能证明被仿冒的合法上游项目遭到入侵。

SKILL.md 没有异常,为什么仍可能漏掉 README ZIP 恶意软件?

SKILL.md 检查没有发现异常,只能说明被检查的这个文件。安装还可能依赖其他指令、随附脚本、下载的压缩包和启动配置。如果审查止步于技能文件,就不足以批准运行这些额外组件。必须明确:这次批准究竟覆盖哪些文件和操作?

Agent Skills 规范将技能定义为一个目录,SKILL.md 是必需的入口文件,旁边可以有脚本、参考资料、资源及其他文件。可以据此划定审查范围:列出目录中的内容,并继续追踪它引入的安装依赖,不能用入口文件代替整个软件包。

假设审查者读到的是文档排版指令,没有发现可疑命令,于是批准使用。另一个 README 却要求安装者获取某个运行时。这个新增依赖需要单独说明:为什么需要它,为什么选择这个发布者和版本,又为什么要授予这些访问权限?第一个文件里熟悉的措辞无法回答这些问题。

文件如何被执行同样关键。Netskope 对相关 SmartLoader 样本的分析显示,批处理启动器会把含有 Lua 的文本文件传给解释器。只看扩展名,会漏掉命令如何处理文件内容。文本文件可以提供代码,合法解释器也可以执行这些代码。

审查结论要保留明确的范围。“这些指令已经审查”是有用的证据;将这个结论扩大到之后的所有下载和命令,就留下了缺口。共享技能指令随时间变化时,也要回答同样的范围问题,不过那类工作流还需要自己的评估机制。

AI 工具安装审查应该覆盖哪些内容?

安装审查应把发布者、源码快照与准备启用的文件、启动操作和权限对应起来。我们建议将记录保存在待审工具可写的目录之外。每项记录都要说明检查了什么,以及发生哪种变化时,需要由负责人重新决定。

一次具体安装决定应保留的证据
审查对象应保留的证据回答的问题
发布者与仓库准确的所有者/仓库名称,以及用于确认身份的独立参考来源。审查的是我们原本要使用的项目吗?
源码快照完整提交 ID,以及纳入审查的源码文件。审查者检查的是哪个版本?
README 指向的目标解析后的压缩包路径或最终下载 URL,包括相关重定向。安装指令实际选择了什么?
压缩包压缩包的 SHA-256、成员路径和已审查的内容。这些字节与文件经过审查吗?
安装后的副本预期安装路径与文件哈希的清单。复制或打包是否改变了将被加载的内容?
启动操作准确的命令、参数、工作目录和配置。启用工具时会执行什么?
执行权限所需的文件系统访问、网络目标和凭据。执行过程能够访问什么?
决定负责人审查者、日期、允许的用途及例外理由。谁能批准发生变化的内容?

从实际安装路径开始检查。提交在仓库内的 ZIP 属于该源码快照。README 如果指向别处,就引入了一个需要单独获取的对象。发布标签、下载按钮或压缩包名称,都不足以证明选中的字节已经纳入审查。

预期值要由团队掌控。将待审压缩包与同一个未知发布者随附的校验值比较,可以验证两者内部一致,却不能证明审查者批准过其中任何一项。审查完成后再记录预期摘要,并防止待审工具及其安装程序改写这份记录。

我们的 MCP 安装风险扫描器可以初步检查粘贴的命令或配置模式,但不会获取仓库,也不会检查压缩包字节。按它实际检查的范围使用结果,缺少的证据仍需另行保留。

离线实验中,哪些变化需要重新审查?

在 6 个离线场景中,比较全部已记录的实验输入,只有未变化的场景与基线一致。只检查 SKILL.md,所有场景都会匹配。比较 Git 提交能发现两种已提交的仓库变化,但发现不了快照之外的变化。这些结果衡量的是与先前记录是否一致,不能判定文件是否恶意。

实验使用 Python 3.12.14 和 Git 2.51.1,完成了 24 项已记录检查。脚本创建无害的仓库,每个仓库包含技能文件、README,以及两个相同的仅含文本文件的 ZIP。它还用本地文件模拟外部下载,并将一个已知的文本成员复制到单独的安装目录。

每个场景都从同一基线开始,只改变一种输入。记录包含提交、源码文件哈希、压缩包及其成员哈希,以及安装文件哈希。发布者身份和执行权限不在实验范围内。“一致”表示与基线记录相等;“不同”表示再次沿用原审查结论之前,需要先解释这次变化。

无害离线实验中观察到的比较结果
独立场景SKILL.md 哈希Git 提交全部实验输入发生的变化
基线未变一致一致一致无。
README 改为指向另一个已提交的 ZIP一致不同不同只有 README 内容及其新提交变化;两个 ZIP 原本就包含相同的无害文本。
已提交 ZIP 的内容变化一致不同不同压缩包字节与成员内容变化,并提交为新版本。
外部 URL 标签不变,模拟下载内容变化一致一致不同外部压缩包字节与成员内容。
复制后的安装文件变化一致一致不同已安装的文本文件。
无害地重新打包外部 ZIP一致一致不同只有压缩包注释变化,成员内容完全相同。

README 场景刻意只做一项小改动:修改真实的 Markdown 相对链接,让它在两个已提交的压缩包之间切换。两个压缩包都不含恶意软件。只检查技能文件会漏掉指令变化,而比较提交能够发现它。因此,这项实验并未暗示:正确固定提交后,仍无法绑定仓库中已提交的压缩包。

外部下载和重新打包场景,是对审查问题的假设性延伸,不是关于 Roccia 所列仓库的额外发现。实验没有请求任何 URL,而是用本地文件代替下载字节。

重新打包是一个有用的阴性对照:压缩包摘要变了,内部文本却没有变化。如果流程立即将其标记为“恶意软件”,结论就超出了证据。应重新打开审查,比较打包变化,再决定是否签发新的记录。

每个场景执行 4 项检查:实际变化的字段、比较结果、基线记录保持原样,以及 Git 工作树没有未提交修改。6 个场景乘以 4 项检查,共计 24 项。因此,只比较提交所漏掉的变化,并非通过暗中修改未提交源码制造出来的。

如何复现实验,而不运行未知安装程序?

先阅读独立的实验源码,再用 Python 和 Git 运行其生成数据的比较过程。脚本创建自己的无害待审文件,并在你指定的工作目录中写入 JSON 结果。它不接受目标仓库或下载 URL,也不会启动生成的文件。

下载可阅读的 Python 实验源码和已记录的 JSON 结果。源码需要 Python 3.10 或更高版本及 Git,不依赖第三方 Python 包。检查源码后,在保存脚本的目录执行:

python3 readme-zip-review-lab.py \
  --work-dir .agent-cache/readme-zip-review-lab

python3 -m json.tool \
  .agent-cache/readme-zip-review-lab/results.json

逐个场景对照 observed_controls 与 expected_controls。结果还包含实际变化的字段、文件清单、工具版本及实验源码的 SHA-256。任一检查失败,运行就会停止;下次开始运行前,脚本会删除旧的成功结果文件。

基线记录存放在待审目录和安装副本目录之外。在实际部署中,还需要阻止对该记录的越权写入。本实验只验证运行期间自己的记录保持原样。

文件清单覆盖普通文件的路径与内容,不评估文件权限、符号链接、任意压缩包的解压过程、签名、智能体行为,以及检查到执行之间的变化。安装文件场景先安全地复制已知文本,不能据此先运行未知安装程序,再回头检查损害。

固定提交或校验值一致,究竟能证明什么?

固定提交可确定选中的源码快照;校验值一致可证明字节与可信参考值相符。它们是否有用,取决于审查了什么,以及安装实际使用了什么。准确匹配也可能沿用一项错误决定;无害的打包变化则可能产生需要解释的不匹配。

要区分三个对象:作为仓库文件保存的 ZIP、GitHub 生成的源码压缩包,以及从其他位置获取的下载内容。第一个属于选定提交;第二个是围绕源码内容生成的打包产物;第三个需要单独保留产物证据。

GitHub 关于源码压缩包稳定性的文档说明,只要提交仍可访问且仓库名称不变,基于提交生成的压缩包就能保持文件内容不变。分支和标签则可以移动。文档也区分了解压后内容的稳定性与压缩包字节本身:压缩设置变化时,后者可能改变。

因此,实验同时记录压缩包摘要和成员清单。遇到摘要不匹配,不要悄悄将预期值替换为新下载文件的值。保留旧记录,查明变化,再由负责的审查者接受或拒绝替换。否则,比较过程只是不断记录最后收到的内容。

来源证明回答的是审查中的另一个问题。GitHub 产物证明指南说明,验证过的证明可以将产物关联到源码和构建指令,但文档也明确指出,证明不保证安全。发布者、构建过程和软件行为是否符合你的要求,仍需判断。

还要确保验证对象与实际启动对象相同。如果启动器在审查后重新解析一个可变引用,先前的比较就无法说明这次获取的内容。我们建议由宿主环境保管已审查的产物,并防止启动前被替换。这项离线实验没有测试该限制是否得到执行。

如何在智能体指令之外落实安装审查?

通过待审工具指令之外的控制,约束获取、文件修改和执行。发现工具的过程可以提出建议;是否启用哪些内容和权限,应由受保护的决定控制。待审工具不能写入校验器或预期记录,并且要在实际宿主环境中测试拒绝路径。

在指令文件中写下“只安装已审查的工具”,可以说明政策。要落实政策,则需要客户端或运行环境阻止违规操作。Claude Code 权限文档明确区分了宿主强制执行的权限规则,以及提示词和 CLAUDE.md。后两者影响模型行为,却不改变宿主实际授予的访问能力。

Claude Code 的 allowed-tools 技能设置需要仔细理解:它会在调用该技能的当前轮次中预先批准列出的工具,并不意味着只能调用这些工具。其他工具仍受普通权限规则管理。若把这个字段当成排他的允许列表,审查就会建立在错误的控制假设上。

进程边界也要单独核对。Claude Code Bash 沙箱文档覆盖 shell 命令及其子进程,但也列出了在该边界之外运行的钩子、本地 MCP 服务器和其他辅助程序。是否覆盖整个进程,需要另作部署选择。我们的 Claude mods 与函数钩子评估进一步说明了这些扩展能力。

在 Codex 中,审批策略和沙箱模式是两个独立设置。取消确认提示本身不会移除仍在生效的沙箱;一次批准也不能证明产物安全。应检查真正运行工具的环境中,哪些配置实际生效。

Codex 的 MCP 配置参考同样区分了工具过滤、逐工具审批行为,以及本地服务器的命令、参数、环境和工作目录。限制可调用的 MCP 工具名称,既没有评估服务器的启动过程,也没有为它加上沙箱。先批准这个进程,再决定智能体可以调用哪些方法。

MCP 对一键配置本地服务器的安全指引要求展示准确的命令和参数,并取得明确同意,也建议采用最小权限沙箱。这些是对客户端实现的要求,不能证明每种安装路径已经符合要求。

上述内容是文档说明的控制边界,不是我们的 Python 实验测试过的厂商功能。运行时隔离需要另行审查,可参考智能体沙箱安全检查清单。安装前的文件比较不能代替它。

启用工具前,团队应保存哪些验收证据?

保留一份安装决定,写明审查对象、执行范围、审查者和重新审查的触发条件,并附上比较证据与宿主环境的拒绝测试结果。另一位工程师应能据此判断已安装版本为何在批准范围内,无需依赖智能体对自己批准行为的描述。

起步时可以使用一份简短记录。以下字段描述需要你提供的证据,不是生产配置,也不是实验生成的值:

decision: reviewed-for-local-test
source: <owner/repository and full commit>
artifact: <reviewed relative path or final URL>
archive_sha256: <digest of reviewed archive bytes>
installed_inventory: <protected file-manifest reference>
launch: <exact command, arguments and working directory>
scope: <filesystem, network and credential policy>
reviewer: <responsible person and review date>
recheck_on: [source, artifact, installed-files, launch, scope]

随后,在实际安装环境验证这项决定。我们建议保留下列验收证据;这些属于拟议的部署检查,与上文已经观察到的离线结果分开。

建议在安装宿主环境执行的检查,尚非本实验结果
建议检查项应保留的证据
已审查的基线版本能完成预期任务。仅使用约定访问权限取得的正向结果。
发生变化的内容到达安装检查关口。宿主在启动前拒绝沿用旧决定,并标明发生变化的字段。
待审工具尝试替换预期记录。独立控制拒绝写入,且记录保持原样。
启动器请求新的目标、凭据或文件系统路径。拒绝结果或另行授权的决定,以及实际导致该结果的生效策略。
文件在验证后、执行前发生变化。证明暂存对象无法被替换,或再次比较会阻止启动的证据。

为每项失败指定负责人。字节不匹配可能需要工程师检查重新打包的差异;新增凭据请求可能需要系统负责人判断用途能否接受。两类问题都不能被一个笼统的“继续”操作掩盖。

如果团队需要在开发流程中落实这些控制,我们的 DevSecOps 服务负责仓库、构建和发布控制。验收标准应具体到:在约定范围内启用已审查的安装内容;内容或范围变化时,要求重新作出决定。

README ZIP 安装审查常见问题

克隆这些仓库,就会自动感染电脑吗?
报告中的压缩包攻击链需要执行步骤,仅完成克隆不能证明感染。Apiiro 对更大范围 FakeGit 活动的研究区分了压缩包落盘与启动其中内容。仍应检查周边工具会自动加载或运行什么,并将克隆、启用扩展和执行安装程序作为不同事件调查。
提交到 GitHub 的 ZIP 都是恶意文件吗?
不是。ZIP 是一种打包格式,本实验刻意使用无害压缩包。应调查项目为什么需要压缩包、由谁提供、内部有什么,以及哪条命令会使用它。摘要变化需要解释并重新作出审查决定,不能单凭这一点认定恶意意图。
仓库星标和正常的提交历史,能证明谁在控制它吗?
它们只能作为背景信号,不能代替对预期发布者及当前安装内容的核实。Roccia 的账号观察记录对可能的账号接管仍持暂定判断。不要只凭外观诊断账号状态,应保留独立的发布者参考来源,以及实际审查的准确版本。
扩展名是 .txt,就表示文件无法执行吗?
不是。解释器可以把文本文件作为程序输入读取。相关 Netskope 分析描述了以这种方式提供 Lua 代码的过程。应检查启动器如何使用文件,以及哪个运行时接收它。将所有文本文件视为安全,或把所有解释器视为恶意,都会丢掉判断安装风险所需的上下文。
应该屏蔽 IOC 清单中的所有域名吗?
制定规则前,逐项检查指标的用途、置信度和适用范围。已发布的清单包含合法共享服务,也包含尚未在所分析版本中确认的指标。整域屏蔽可能影响无关业务。应由安全负责人选择范围适当的规则,并结合你自己的遥测数据验证效果。
如果已经运行了陌生安装程序,该怎么办?
停止用该设备处理敏感工作,并联系事件响应负责人。保留安装程序的身份信息、时间戳和现有日志。Island 的响应建议包括隔离疑似受影响的终端,以及撤销相关会话和凭据。按实际情况从确认未受影响的设备协调这些操作;只删除下载文件不能证明已经恢复。
macOS、Linux 或 OpenClaw 扩展也适用这套审查吗?
适用。建议的比较针对安装内容与权限,不依赖特定操作系统。应按扩展实际使用的文件、启动机制和宿主控制调整。报告中的启动器攻击链针对 Windows;我们的无害实验不能证明相同载荷存在于其他平台,也没有验证 OpenClaw 专属的强制控制。

保护从代码到发布的流程

需要团队能够维护的依赖、密钥、构建或发布控制?先选定一个代码仓库和交付路径,再约定控制措施、例外负责人及发布前所需证据。

相关服务:

只收重要内容

关注与你相关的内容

每当我们发布新文章,你会收到一封简短邮件。你可以关注整个博客,也可以只选感兴趣的主题。

你希望接收哪些内容?
选择主题

免费、双重确认、不使用跟踪像素。

返回
Kevin Riedl

16 分钟 阅读 · 2026年11月5日
最近审核

下一篇

获取下一篇关于交付与 QA的一线笔记

有新文章时发送一封简短邮件,不使用跟踪像素,也不发送填充内容。

免费、双重确认、不使用跟踪像素。