摘要
三个版本的 node-ipc(9.1.6、9.2.3、12.0.1)于 2026 年 5 月 14 日被一个遭到入侵的维护者账户(atiertant)发布到 npm。每个版本都包含相同的 80KB 混淆有效载荷,附加到 node-ipc.cjs,窃取超过 100 类敏感文件(SSH 密钥、云服务提供商凭据、.env 文件、Kubernetes 配置、AI 工具配置),并通过 DNS 隧道以 gzip 压缩的 tar 归档形式外传数据。该包的周均下载量为 822,000 次。
影响范围:
- 窃取 SSH 密钥、AWS/Azure/GCP 凭据、
.npmrc、.env文件、Kubernetes 配置等(Linux 系统上 113 个目标路径,macOS 系统上 127 个) - 通过 DNS TXT 记录查询以外传收集到的数据,使用 HMAC 签名和 gzip 压缩的 tar 归档
- 创建一个分离的子进程用于后台执行,即使父进程退出也能继续运行
- 专门针对 AI 编程工具配置(
.claude.json、.kiro/settings/mcp.json)
失陷指标(IoC):
- 软件包:
[email protected](SHA-256:449e4265979b5fdb2d3446c021af437e815debd66de7da2fe54f1ad93cbcc75e)、[email protected](SHA-256:c2f4dc64aec4631540a568e88932b61daebbfb7e8281b812fa01b7215f9be9ea)、[email protected](SHA-256:78a82d93b4f580835f5823b85a3d9ee1f03a15ee6f0e01b4eac86252a7002981) - 注入的有效载荷 SHA-256:
3427a90c8cb9af764445448648176e120ebc6af0a538158340cf6220de4d01b7 - C2 端点:
sh[.]azurestaticprovider[.]net:443 - HMAC 签名密钥:
qZ8pL3vNxR9wKmTyHbVcFgDsJaEoUi - 防重复执行环境变量:
__ntw=1 - 临时目录模式:
~/nt-{PID}/ - 归档文件名模式:
{hmac}.tar.gz - 发布账户:
atiertant([email protected])
分析
软件包概述
node-ipc 是一个广泛使用的 Node.js 进程间通信库,支持 Unix/Windows 套接字、TCP 和 UDP。npm 注册表显示其过去一周的下载量为 822,257 次。该软件包有一个值得关注的历史记录:2022 年 3 月,原始维护者(riaevangelist)故意引入了抗议软件有效载荷,针对来自俄罗斯和白俄罗斯 IP 地址的用户(CVE-2022-23812)。
这次的入侵事件有所不同。2026 年 5 月 14 日,三个版本在几分钟内相继发布,全部由 atiertant 发布,这位合作维护者的账户可能已被攻陷:
$ curl -s "https://registry.npmjs.org/node-ipc" | jq '.time | {"9.1.6", "9.2.3", "12.0.1"}'{
"9.1.6": "2026-05-14T14:26:25.106Z",
"9.2.3": "2026-05-14T14:26:01.584Z",
"12.0.1": "2026-05-14T14:25:30.311Z"
}干净版本(9.1.5、12.0.0)由原始维护者 riaevangelist 发布。三个恶意版本均由 atiertant 发布,该维护者大约在 npm 上维护着 20 个其他软件包。12.0.1 版本被标记为 latest,这意味着任何 npm install node-ipc(未指定固定版本)的用户都会获取到被植入恶意代码的版本。
入口点和有效载荷注入
攻击者的策略在不同的版本线上有所不同。对于 12.0.1,与 12.0.0 的差异显示 package.json 有两处变更:
// package.json diff: 12.0.0 → 12.0.1
"version": "12.0.0",
"version": "12.0.1",
"prepare": "esbuild node-ipc.js --bundle --format=cjs --target=es2018 --platform=node --outfile=node-ipc.cjs",prepare 脚本被移除,node-ipc.cjs 被替换为包含有效载荷的预编译捆绑包。没有安装钩子。当 node-ipc.cjs 被 require() 时,恶意代码作为副作用运行。
注入点在 node-ipc.cjs 的第 1271 行,紧接在合法模块的 module.exports 赋值之后:
// node-ipc.cjs — line 1269 (legitimate)
module.exports = singleton;
// line 1271 — injected payload begins
(function(_0xaed59b,_0x282d65){var _0x4524e4=_0x1a49,_0x41d0c3=...附加的有效载荷是 80,079 字节的混淆 JavaScript 代码。三个被入侵的版本包含字节完全相同的有效载荷(SHA-256:3427a90c8cb9af764445448648176e120ebc6af0a538158340cf6220de4d01b7)。
对于 9.1.6,攻击者更进一步。版本 9.1.5 原本没有 node-ipc.cjs 文件。攻击者添加了它,将 package.json 改为设置 "main": "node-ipc.cjs"(同时支持 ESM 和 CJS 导出),并将整个包结构升级以匹配 12.x 版本线。这个重新构建的捆绑包携带了相同的有效载荷。
混淆与反混淆
该有效载荷使用了标准 JavaScript 混淆器,带有轮换字符串查找数组。一个 443 元素的字符串数组(_0x3afe)在加载时被乱序,直到校验和匹配 0xb5c88。所有字符串字面量都通过 _0x1a49(index) 进行索引查找访问,控制流使用带有间接函数调用的辅助对象。
敏感字符串(C2 地址、HMAC 密钥和文件路径列表)使用了一层额外的保护:一种自定义的十六进制编码,其中十六进制数字 a 到 f 被替换为 G、H、J、K、M、P(跳过了容易与数字混淆的字母)。最后一个字符用作校验和。解码时半字节顺序是反转的(低位半字节优先)。
将这应用于三个编码的常量:
| 编码后 | 解码后 |
|---|---|
3786M216G757275637471...34343339 | sh.azurestaticprovider.net:443 |
17G58307J43367M487259...54P655966 | qZ8pL3vNxR9wKmTyHbVcFgDsJaEoUi |
2647M2M6P64656M2G637H | bt.node.js |
还有两个额外的编码字符串(分别为 5,141 和 5,601 个字符),解码为平台特定的的文件路径列表。
目标凭据
该有效载荷根据 os.platform() 选择目标列表。Linux 列表包含 113 个 glob 模式;macOS(darwin)列表包含 127 个。以下是部分目标路径的示例:
云服务提供商凭据:
~/.aws/credentials
~/.aws/sso/cache/*
~/.azure/accessTokens.json
~/.azure/msal_token_cache.*
~/.config/gcloud/application_default_credentials.json
~/.config/gcloud/credentials.db
~/.oci/config
~/.config/doctl/config.yaml
~/.aliyun/config.json
~/.bluemix/config.jsonSSH 和 Git 凭据:
~/.ssh/id_rsa
~/.ssh/id_ed25519
~/.ssh/id_ecdsa
~/.ssh/authorized_keys
~/.ssh/config
~/.git-credentials
~/.gitconfig开发环境密钥:
**/.env
**/.env.local
**/.env.production
~/.npmrc
~/.pypirc
~/.netrc
~/.docker/config.jsonKubernetes 和基础设施:
~/.kube/config
/etc/rancher/k3s/k3s.yaml
~/.terraform.d/credentials.tfrc.json
**/terraform.tfvars
/var/run/secrets/kubernetes.io/serviceaccount/tokenAI 编程工具配置:
~/.claude.json
~/.claude/mcp.json
.kiro/settings/mcp.jsonCI/CD 和 DevOps:
**/.github/workflows/ci.yml
**/.github/workflows/deploy.yml
**/.github/workflows/release.yml
**/.gitlab-ci.yml
/etc/gitlab-runner/config.toml值得注意的是 .claude.json、.claude/mcp.json 和 .kiro/settings/mcp.json 的包含。这些是 AI 编程助手的配置文件,可能包含 MCP 服务器凭据和 API 密钥。这表明攻击者正在跟踪 AI 开发工具的采用情况,并专门针对其凭据存储。
数据收集与归档创建
恶意软件的执行流程,从 _0x541368 中的混淆 switch-case 结构重构而来:
- 在
~/nt-{PID}/创建临时目录 - 生成随机字节,使用硬编码密钥派生 HMAC 签名
- 解析系统主机名
- 遍历文件路径列表,展开 glob 并读取匹配的文件
- 将收集的文件打包成 tar 归档(使用
ustar格式头手动实现 tar) - 使用
zlib.gzipSync()压缩 - 将归档写入
~/nt-{PID}/{hmac}.tar.gz
然后归档被外传,临时文件被删除。
DNS 外传
该有效载荷通过 DNS TXT 记录查询外传数据。这种技术绕过了大多数出口防火墙和网络监控,因为 DNS 流量很少在应用层被检查。
外传函数(_0x39bb3b)的工作原理如下:
- 将 gzip 压缩的归档分割成适合 DNS 标签大小的块
- 将每个块编码为 base64
- 构建包含
machineHex、cloud、archivePath、gzipBytes、块计数和hostLabel的 JSON 元数据头 - 使用硬编码密钥以及
|p和|t后缀对头和数据块进行 HMAC 签名 - 构建 DNS 查询域:
{chunk}.{sig}.{metadata}.{c2_domain} - 通过
dns.Resolver发送查询,使用自定义 DNS 服务器(1.1.1.1、8.8.8.8) - 发送包含总块计数的最终“完成”消息
C2 域 sh[.]azurestaticprovider[.]net 旨在乍看之下与合法的 Azure 静态 Web 应用基础设施相融合。
持久化机制
该有效载荷使用 child_process.fork() 生成一个分离的后台进程:
// Reconstructed from obfuscated code
child_process.fork(modulePath, [], {
cwd: process.cwd(),
detached: true,
stdio: 'ignore', // String.fromCharCode(0x69,0x67,0x6e,0x6f,0x72,0x65)
env: { ...process.env, __ntw: '1' }, // anti-re-execution flag
});__ntw 环境变量防止分叉的子进程再次分叉。分离的进程在父 Node.js 进程退出后继续运行,使恶意软件有足够时间完成文件收集和 DNS 外传,即使导入它的应用程序快速关闭也是如此。
SHA-256 哈希比较(fdba4191831a13debf9d8c0c940b0301c7b7f01d27f1b1c73ed3ceaa2db4103b)在分叉前验证模块的文件路径,这可能是作为一种反分析措施,避免在意外环境中执行。
根本原因:维护者账户被接管
atiertant 账户一直是 npm 上 node-ipc 的合作维护者,与原始作者并列。该账户还维护着约 20 个其他软件包(node-turn、asynk、offshore 等)。三个恶意版本在 56 秒内发布,跨越三个不同的主要版本线,并被标记为最大化安装覆盖范围(latest、unpublished、legacy-9.1)。
这一模式指向凭据泄露而非恶意维护者:同时发布多个版本且有效载荷完全相同表明使用了自动化工具,而且该有效载荷本身与 atiertant 维护者的正常发布活动毫无相似之处。
结论
这次入侵事件针对的是 npm 上下载量最高的 IPC 库之一,使用了复杂的凭据窃取器。攻击者选择 DNS 隧道而不是更简单的 HTTP 外传,使用 HMAC 签名有效载荷,实现自定义十六进制编码来隐藏失陷指标,并针对异常广泛的凭据集,包括 AI 工具配置。C2 域名模仿 Azure 基础设施命名。
如果您安装了 node-ipc 版本 9.1.6、9.2.3 或 12.0.1,请轮换受感染机器上的所有凭据。检查 ~/nt-*/ 临时目录和正在运行的分离 Node.js 进程。将版本固定到已知干净的版本(9.1.5、12.0.0),或使用 vet 进行审计,以在恶意版本到达 CI 之前标记它们。
- npm
- oss
- malware
- supply-chain
- node-ipc
- credential-theft
- dns-exfiltration
- account-takeover
来自 SafeDep 博客的最新内容
关注我们,获取开源安全与工程的最新更新和见解