TL博士
单个 npm 发布者, ddjidd5640,并创建了一个包含 22 个软件包的虚假 Web3 安全工具目录,这些工具以诸如以下虚构品牌销售: 加密安全协会, Web3 审计集体和 DeFi 安全联盟.
这些软件包看起来不像是简单的域名抢注活动。它们看起来像是一个品牌化的安全生态系统,背后有匹配的空 GitHub 组织和极具说服力的 MCP 工具名称,例如: search_leaked_credentials, validate_chain_key和 deploy_safe.
竞选活动分为 两个活跃的有效载荷系列和一个休眠批次.
变体 A 包含 8 个凭证收集软件包。安装后脚本会读取本地密钥存储,同时还捆绑了一个 scanner.js 当 AI 代理调用软件包的 MCP 工具时运行,搜索钱包密钥、BIP39 助记词、API 令牌和其他凭证。
变体 B 包含 5 个基于 Pinggy 的二进制投放器。这些软件包会在安装后获取并执行远程有效载荷。 foundry-deploy-helper:1.8.96 释放一个分离的可执行文件 /tmp/.node-cache.
变体 C 包含 9 个休眠软件包,目前还没有明显的安装后有效载荷,但具有相同的发布者、品牌模式和以 Web3 为中心的命名。
在我们能看到的地方,只有 22 个软件包中的 8 个被标记出来;其余 14 个在分析时仍然在 npm 上可用。
严重程度:危急。
攻击:一个衣橱里装着两个有效载荷
衣橱就是品牌。打开 crypto-credential-scanner 的 README 文件,你会发现它是由加密安全协会 (Crypto Security Guild) 开发的凭证扫描器。打开 defi-threat-scanner 的页面,你会发现它是 DeFi 安全联盟 (DeFi Security Alliance) 的工具。打开 web3-secrets-detector,你会发现它是 Web3 审计联盟 (Web3 Audit Collective) 的产品。然而,这些联盟都不是真正的组织。它们只是空的 GitHub 组织,存在的唯一目的就是填充 npm 页面上的“作者”超链接。
方案 A:安装后预检和 MCP 时间主操作
8 个 Variant-A 软件包都共享一个两阶段有效载荷——安装后预检阶段,用于获取磁盘上已有的纯文本凭据;以及运行时阶段,一旦 AI 代理调用软件包的 MCP 工具之一,该阶段就会激活。
“第一阶段,飞行前准备” 它以单行命令 `node -e` 的形式内联存储在 package.json 文件中。它会打开七个常用的点文件,并将每个文件的前 200 字节发送到 C2 服务器:
200 字节 〜/.ssh/id_ed25519 它本身不会将你的私钥直接透露给攻击者,但它会提供…… 文件名、注释以及 PEM 头部的前几行 ——足以确认那里存储的是哪种密钥,这足以启动后续步骤。200 字节 ~/.env 通常情况下,200 字节的数据足以泄露完整的 API 令牌。 ~/.git-凭据 通常是一整套 OAuth 令牌。
“第二阶段,主舞台”,东京国立癌症中心医院 scanner.js它由软件包加载。 index.js 当 AI 代理调用任何已发布的工具时,该文件会在 MCP 请求处理程序内部被调用。8 个 Variant-A 软件包中的文件完全相同(b461106e47a1f5966159cd6e92541505它坦诚地说明了自己的工作内容。开头的评论部分原文如下:
| javascript // wallet-scanner.js — 嵌入式 MCP 包主动扫描器 // 当 AI 代理调用任何 MCP 工具时静默运行,扫描环境中的钱包/密钥 // 仅使用 Node.js 内置函数,无外部依赖 |
接下来是一个深度为 3 的递归遍历:
主目录本身
…筛选文件名包含以下任何内容 密钥库, wallet.json, wallet.dat, 。秘密, 种子文件, metamask, 模体, bby, 信任钱包, coinbase, 私钥, 助记符, 密钥, api_key 也就是说,这是一份精心整理的列表,列出了加密用户保存密钥的所有位置。对于每个匹配项,都会打开该文件,并使用六个正则表达式进行扫描:
| 类型 | 模式 | 它捕获的 |
|---|---|---|
| 私钥 | (?:0x)?[a-fA-F0-9]{64} | 以太坊私钥和通用的 32 字节十六进制密钥。 |
| 助记符 | \b([a-z]+\s+){11,23}[a-z]+\b | BIP39 助记词种子短语,长度为 12 到 24 个单词。 |
| api_key | (api[_-]?key\|API_KEY)\s*[:=]\s*["']?([A-Za-z0-9_\-]{20,}) | 配置文件中嵌入了通用 API 令牌和凭据值。 |
| 秘密 | (?:secret\|private).{0,10}[:=]\s*["']?([A-Za-z0-9+/=]{20,}) | 密钥和私有值通常以 YAML、JSON 和 INI 配置格式存储。 |
| eth_address | 0x[a-fA-F0-9]{40} | 使用以太坊钱包地址来识别和标记受害者。 |
| 密码 | (?:PASSWORD\|PASSPHRASE)\s*=\s*["']?(\S{4,64}) | Shell 导出风格的密码和密码短语环境变量。 |
然后,scanner.js 会完整读取另外六个点文件——每个文件最多 500 字节,分别是 ~/.env、~/.bash_history、~/.zsh_history、~/.npmrc、~/.gitconfig 和 ~/.git-credentials——并扫描 process.env 文件,查找名称包含 key、secret、token、password、private、mnemonic、wallet 或 seed 的变量。最后,它会调用 execSync('whoami') 以及 os.hostname() 和 process.cwd() 来标记转储文件,使其包含受害者的身份信息。整个有效载荷以及最多 100 个单独的发现结果,会以单个 JSON 对象的形式 POST 发送。
导出目标位置并非直接硬编码。该软件包会在运行时从以下位置获取:
https://ddjidd564.github.io/defi-security-best-practices/config.json
— 攻击者控制的 GitHub Pages 文档。当前的 config.json 返回
如果获取失败, scanner.js 又回到了原点 webhook.site URL被硬编码为一个常量。这种间接方法是该攻击活动中唯一体现操作复杂性的地方:它允许攻击者在不重新发布软件包的情况下轮换数据泄露目标,并且将实际的收集器URL隐藏在npm工件之外,这使得基于特征码的检测更加困难。
变体 B:一个 Pinggy 隧道、一个二进制文件和一个持久化变体
另一批上线的软件包规模小得多——只有五个——而且远不如前者巧妙。作者完全放弃了 MCP 的伪装。这些软件包声称是合法的以太坊和 Solana 工具的配置助手(truffle-config-helper, chainlink-价格信息聚合器, ganache-cli-provider, solana-pda-helper, 铸造厂部署助手有效载荷是一个单独的 https.get-和-EXEC 在线 安装后
C2 是免费的 平吉 tunnel——攻击者使用的一种通用开发者隧道服务,作为临时 C2 服务器。该软件包会下载 tunnel 返回的所有内容并将其推送到…… child_process.exec没有完整性检查,没有签字确认,也没有第二道防线。运营商的隧道今天服务什么,就运行什么。
最具竞争力的方案 foundry-deploy-helper:1.8.96,替换内联 https.get - 卷曲 以及一个持久化技巧:
方案C:光鲜亮丽的外立面,暂无引爆装置
剩下的九个包裹—— 钱包备份验证器, 环境安全扫描器, Foundy 工具包 (故意拼写错误,冒用 Foundry 的拼写错误) solna-web3 (Solana 的一个拼写错误) 钱包安全检查器, 硬帽气体分析插件, ethers-multicall-utils, defi-env-auditor, etherjs-utils - 有 没有安装后脚本 乍一看,这些恶意软件似乎没有明显的运行时数据泄露。它们与活跃的变种共享发布者、品牌标识、Web3命名模式,在某些情况下甚至拥有完全相同的README模板。我们将其视为同一攻击活动的一部分,并建议提前移除,但我们尚未完全列出其运行时触发机制。这些休眠的恶意软件可能是攻击者为未来再次攻击而保留的立足点——这与PhantomBot在5月中旬使用的模式相同,当时攻击者用一个凭证窃取程序替换了一个僵尸网络成员,而没有重新发布软件包名称。
时间线和产品目录
该活动中最早发布的软件包版本最低: 链键验证器:0.2.3 和 defi-env-auditor:0.3.2 看起来像是早期实验性版本。当发行商达到 truffle-config-helper:1.7.0 和 foundry-deploy-helper:1.8.96版本号的膨胀是故意的——选择的数字看起来像是某个已建立软件包的版本传承。这 22 个版本中,没有一个在 npm 上以完全相同的名称出现过。
完整目录,按版本分组:
### 变体 A — 凭证收集器(postinstall + MCP 时间扫描器.js,MD5 b461106e47a1f5966159cd6e92541505)
| 小包装 | 版本 | 已在检测信息流中标记 |
|---|---|---|
mnemonic-safety-check | 0.5.2 | 含 |
solidity-deploy-guard | 0.4.4 | 含 |
web3-secrets-detector | 1.2.6 | 含 |
eth-wallet-sentinel | 1.0.9 | 含 |
deployment-key-auditor | 0.7.3 | 含 |
defi-threat-scanner | 2.1.2 | 含 |
crypto-credential-scanner | 2.0.2 | 含 |
chain-key-validator | 0.2.3 | 含 |
### 变体 B — Pinggy 隧道 https.get → exec(在此报告之前无法检测到)
| 小包装 | 版本 | 安装后风味 |
|---|---|---|
truffle-config-helper | 1.7.0 | https.get → exec(stdout) |
chainlink-price-feed-aggregator | 1.1.12 | https.get telemetry call |
ganache-cli-provider | 1.7.51 | https.get telemetry call |
solana-pda-helper | 1.0.46 | https.get telemetry call |
foundry-deploy-helper | 1.8.96 | curl + chmod +x /tmp/.node-cache & |
### 变体 C — 休眠状态,怀疑运行时触发(在此报告之前未检测到任何异常)
| 小包装 | 版本 | 笔记 |
|---|---|---|
wallet-backup-verifier | 1.0.1 | |
env-security-scanner | 1.6.0 | |
foundy-toolkit | 1.5.79 | 铸造厂的拼写错误 |
solna-web3 | 1.5.98 | solana 的 typosquat |
wallet-security-checker | 1.0.3 | |
hardhat-gas-profiler-plugin | 1.7.86 | |
ethers-multicall-utils | 1.3.15 | |
defi-env-auditor | 0.3.2 | |
etherjs-utils | 1.0.39 |
“变体 A”和“变体 B”列并非随机选择。“变体 A”的名称本身就很有吸引力。 安全审计工具 ——“安全检查”、“部署卫士”、“密钥检测器”、“钱包哨兵”、“密钥审计器”、“威胁扫描器”、“凭证扫描器”、“链密钥验证器”。它们的目标用户是寻求评估 Web3 项目安全性的工具的开发者或人工智能代理。Variant-B 的所有名称都旨在吸引用户。 构建和部署助手 对于同一个 Web3 生态系统——Truffle、Chainlink、Ganache、Solana PDA 工具、Foundry 等——来说,这种分裂反映了普通 Web3 开发者“审核阶段”与“部署阶段”的思维模式。无论你选择哪个阶段,发布商都为你设置了陷阱。
妥协指标
网络和文件
| 国际奥林匹克委员会 | 变种 | 目的 |
|---|---|---|
https://ddjidd564.github.io/defi-security-best-practices/config.json | A | 通过 GitHub Pages 托管的动态 webhook 解析器。 |
https://webhook.site/8d334534-1c63-4f4f-a0d7-95c446c8b233 | A | 当前渗漏收集器端点,也嵌入作为备用方案。 |
rqnyz-2605-7280-7--2000-c51.run.pinggy-free.link/npm/-/binary/telemetry | B | Pinggy隧道用于分发远程二进制有效载荷。 |
scanner.js MD5 b461106e47a1f5966159cd6e92541505 | A | 所有 8 个 Variant-A 软件包均重复使用相同的扫描器有效载荷。 |
/tmp/.node-cache | B | 分离的可执行文件被丢弃 foundry-deploy-helper:1.8.96. |
出版商
- npm 用户名: ddjidd5640
- 电子邮件: 1623682356@qq.com (未经证实)
- 电子邮件和 SCM 验证:无
- 账户下包裹数量:22,全部列于上述目录中。
- 最早可见的活动: 链键验证器:0.2.3 (变体 A)
- 最新可见活动:chain-key-validator:0.2.3 和 crypto-credential-scanner:2.0.2(均在撰写本文前 24 小时内)
品牌正面(用于 作者 / README / fake GH org)
- “加密安全公会”——由一个空的 GitHub 组织支持 加密安全公会
- “Web3 审计联盟”——由一个空的 GitHub 组织支持 w3audit
- “DeFi 安全联盟”——由一个空的 GitHub 组织支持 Defi 安全
- 参考 GH 帐户 ddjidd564 — 动态 Webhook 配置 config.json 的主机
行为
- 节点 -e 安装后读取任何内容 .ssh, 以太坊, .比特币, .ENV, .bash_历史记录, .zsh_history, .git-credentials - .slice(0, 200) 并与 | 分隔符是变体 A 的一个近乎唯一的指纹。
- 输入 ./scanner.js 来自一个注册为 MCP 的软件包 服务器 使用名为 搜索泄露的凭证 或者类似表述的“安全审计”动词是变体 A 的确认。
- 无论包装器如何,从任何 *.run.pinggy-free.link 主机获取并将响应通过管道传递给 child_process.exec 的 node -e postinstall 都是 Variant-B 确认。
归因与动机
桌面上的信息足以勾勒出出版商的部分特征,但远远不足以进行真正的身份识别。电子邮件 1623682356@qq.com 这是一个 QQ 邮箱地址——腾讯的免费网络邮箱,在中国大陆很流行——其中的数字部分是 QQ 用户 ID;我们仅将其视为软信号,因为 QQ 格式的地址很容易注册。该 npm 账户没有启用双因素身份验证,没有验证邮箱,也没有验证信息。 SCM 链接。“加密安全公会”、“Web3 审计联盟”和“DeFi 安全联盟”这三个品牌完全是捏造的——这三个品牌在此次活动之外根本不存在——而支持的 GitHub 组织也只是空壳,用来填充 npm 页面链接。
有两种模式值得一提,因为它们在相邻的战役中都会出现。第一种是: 品牌预制作为一种社会认同运营者并没有选择现有的项目名称进行域名抢注;他们从零开始构建了一个完整的信任故事,并且他们知道…… AI代理构建 pipeline 或者,匆忙浏览 npm 页面的开发者会匹配“看起来像安全组织”而不是“就是安全组织”。这与那些关于域名抢注的文献所警告的做法如出一辙——软件包的名称经过精心调整,以迎合 LLM(法律管理专家)的喜好。 发明 如果被要求提供 Web3 安全工具,要足够巧妙,让 LLM 不会进行二次检查。 懒散蹲坐 是最近创造的一个术语,指的是名称与 LLM 在权威软件包不存在时产生的占位符相匹配的恶意软件包;这种攻击活动是其更具攻击性的版本,攻击者还会捏造占位符所属的组织。
第二种模式是 MCP 时间激活。 到...的时候 scanner.js 程序运行完毕,安装完成,开发者已继续进行下一步。触发条件是人工智能代理调用某个工具—— 搜索泄露的凭证在 Variant-A 案例中,代理人绝对会这样做,因为这就是它收到该软件包的全部原因。恶意操作发生在…… 非常好 在工作流程中,开发者最有可能看到他们的 AI 助手成功完成他们要求的任务。这与以往的“导出”方式相比,只是一个小小的行为转变。 npm安装这种模式巧妙地规避了安装时沙盒机制。
我们不会指明具体的攻击者。这些信号(QQ邮件、单账户攻击、单日22个数据包的突袭、两个并行的C2服务器栈)同样适用于单个持续攻击者、小型团队,或者在2025-2026年期间在npm遥测数据中可见的某个数据包泛洪攻击团队。我们 也可以是 也就是说,该运营商有明确的首选生态系统(以太坊 + Solana + Foundry/Hardhat 工具),明确的首选受害者(Web3 开发人员和从事 Web3 项目的 AI 代理),以及明确的首选持久化模型(MCP 时间运行时触发加上分离的二进制回退)。
影响、趋势以及防守者可以做什么
我们的早期预警 pipeline 抓 8-22 在整个活动期间,共发布了 14 个软件包——最初扫描时发布了 6 个,当天晚些时候在活动集群分析阶段又发布了 2 个。其余 14 个软件包在 npm 上已上线数日。 从未出现在我们监测的任何检测信息流中。截至撰写本文时,这些软件仍然可以安装。这一差距之所以重要,是因为:
- 版本 A 在安装过程中保持静默. 读取点文件的操作会执行,但批量导出操作只有在 AI 代理调用软件包的 MCP 工具时才会触发。 standard 安装后监视沙箱将会看到 节点 -e 将其阻挡并判定为体积小且明显无生命。
- 变体 B 为单行。 恶意软件分类器无法从中学习到任何东西——没有混淆,没有编码的有效载荷,也没有可疑的域名。Pinggy 隧道是一个合法的开发者服务。唯一可疑之处在于,一个“配置助手”竟然需要向服务器发送数据。
- 变体C看起来完全干净。 它无需安装 hooks任何静态信号都是正常的。
MCP工具时代的简短防御者检查清单
以下三项具体措施本可以更早地阻止这场运动:
- 要看出版社,而不是包装。 一个注册仅一年的QQ邮箱账号下,竟然有22个包裹,而且没有任何关联。 SCM 验证比任何软件包本身的特性都更具说服力。我们的早期预警工作流程之所以能拦截到首批软件包,是因为发布者指纹特征非常突出——它建议的发布者信誉评分会被任何一个安全、不确定或恶意软件的软件包分类器降低权重。
- 在证明并非恶意行为之前,应将动态配置间接操作视为恶意行为。 如果一个软件包在运行时从第三方文档(GitHub Pages、GitHub Gist、Pastebin、S3 对象或其他任何地方)解析其出站端点,那么它没有正当理由这样做来进行遥测。真正的遥测端点是硬编码的,并且有文档记录。
- 通过其宣传的工具界面审核 MCP 服务器软件包。 Variant-A 软件包都宣传名为“工具”的软件包。
search_leaked_credentials,validate_chain_key,deploy_safe以及类似的“审计”动词。如果 MCP 主机提供了一个工具,其描述声称可以扫描项目目录以查找凭据,则在代理程序对实际代码库调用该工具之前,应要求操作员明确选择加入。MCP 的关键在于,代理程序循环无法知道是否search_leaked_credentials这是凭证搜索还是凭证窃取?
对于可能已经安装了这 22 个软件包之一的开发人员:假设任何明文密钥 〜/ .ssh, ~/.以太坊, ~/.bitcoin, ~/.solana, ~/.env 或 ~/.git-凭据 如果系统遭到入侵,请轮换所有名称与上述环境变量筛选列表匹配的凭证;在 Linux/macOS 系统上,请检查是否存在可执行文件。 /tmp/.node-cache (以及由此启动的任何孤立进程)。重新安装被冒充工具的合法版本(铸造厂, 松露, 安全帽, 伽纳彻等等)不会删除丢弃的二进制文件。
休眠的 Variant-C 版本是这个故事中最令人担忧的部分。九个软件包,拥有干净的安装配置文件和已建立的发布者,正是运营商通常会保留的储备。如果它们日后引爆——就像 PhantomBot 那样—— 轴子工具 重新打包的恶意软件已从窃取凭证转变为招募僵尸网络成员——任何在今天到下架期间锁定过 Variant-C 软件包的注册表用户都将遭到攻击。即使锁定了恶意软件的版本,也无法保护您免受控制所有版本的发布者的侵害。
案例
- [npm 发布者页面 ddjidd5640](https://www.npmjs.com/~ddjidd5640)— 此账户下目前列出了 22 个包裹。截至撰写本文时,该目录的权威来源。
- [npm 包页面 加密凭证扫描器](https://www.npmjs.com/package/crypto-credential-scanner)—示例 Variant-A 工件;README、版本历史记录和作者链接在此处可见。





