一、概述
近日,工作中监测到 Apifox 文件存在被投毒情况。
Apifox 是一款 API 一体化协作平台,其桌面端应用基于 Electron 框架开发,提供 Windows、macOS、Linux 三平台客户端。因未严格启用 sandbox 参数,并暴露了 Node.js 的 API 接口,导致攻击者可通过 JS 控制 Apifox 的终端——三个平台均受影响。
Apifox 在启动过程中会加载:
|
该文件正常大小为 34KB,但在 3 月 4 日之后可能会请求到被投毒的版本(77KB)。被投毒的 JS 文件会动态加载 hxxps://apifox[.]it[.]com/public/apifox-event.js(该域名非官方域名),在满足特定条件下加载攻击载荷,采集主机系统环境和敏感信息(SSH 密钥、Git 凭证、命令行历史、进程列表),上报到 hxxps://apifox[.]it[.]com/event/0/log。后续攻击者会控制主机拉取执行后门程序,并尝试发起横向攻击,控制更多有价值目标。
目前入口文件已被还原,仅在 Wayback Machine 存档中可见投毒版本。
关于 apifox.it.com 域名
攻击者使用的 C2 域名 apifox.it.com 极具迷惑性,值得单独说明。
.it.com 并非意大利国别域名 .it 的子域,而是一个商业性质的二级域名服务,由 it.com 域名持有者提供类似”子域名注册”的商业服务。它不属于 ICANN 标准注册局体系,不受标准 gTLD/ccTLD 监管约束,无公开 WHOIS 信息可查,注册门槛极低,非常适合被攻击者滥用。
从受害者视角来看,apifox.it.com 在第一眼很容易被误认为:
- Apifox 的内部测试/研发域名(类似
apifox.internal.com) - Apifox 意大利区域的服务域名
- Apifox 官方的某个子产品域名
这种域名选择体现了攻击者在社会工程学层面的精心设计——利用域名的视觉相似性和 .it.com 的模糊属性来降低被怀疑的概率。
被动 DNS 时间线
通过被动 DNS 查询,apifox[.]it[.]com 的历史 A 记录如下:
| IP 地址 | 所属组织 | 首次发现 | 最后发现 | 持续时间 |
|---|---|---|---|---|
104.21.2.104 |
Cloudflare, Inc. | 2026-03-04 | 2026-03-22 | 18 天 |
172.67.129.21 |
Cloudflare, Inc. | 2026-03-04 | 2026-03-22 | 18 天 |
无 AAAA(IPv6)记录,攻击者未配置 IPv6 解析。
关键时间节点:
|
攻击者利用 Cloudflare 作为前置 CDN 代理,既隐藏了真实源站 IP,又获得了合法的 HTTPS 证书和全球加速能力,使恶意流量在网络层面更难以与正常 CDN 流量区分。DNS 记录在活跃 18 天后被移除,可能是攻击者主动撤收、也可能是被 Cloudflare 或域名服务商处置。
二、被投毒文件结构
投毒后的 apifox-app-event-tracking.min.js(77KB)由两部分组成:
| 区域 | 大小 | 内容 |
|---|---|---|
| 第一部分 | ~34KB | 合法 Apifox 事件追踪 SDK(Webpack 打包) |
| 第二部分 | ~42KB | ⚠️ 恶意后门代码(严重混淆) |
合法 SDK 包含 GA4、百度统计、阿里云 SLS、PostHog 等多平台事件追踪模块,本身不存在恶意行为。攻击者在该文件末尾追加了约 42KB 的严重混淆 JavaScript 代码。
注:通过 Wayback Machine 存档获取的版本头部包含约 1KB 的 wombat 代理包装器代码,这是 Wayback Machine 自动注入的回放层,并非投毒文件本身的内容。
三、混淆技术分析
恶意代码采用了 7 层混淆,逆向难度极高:
| 技术 | 说明 |
|---|---|
| 字符串数组旋转 | _0x10e4() 函数返回 300+ 条编码字符串,通过 IIFE 暴力旋转数组到目标偏移 |
| Base64 + RC4 双层解密 | _0x3fb9() 解码器对字符串先 Base64 解码,再 RC4 解密还原明文 |
| 代理函数 | _0x2c838a、_0x15440c 等函数包装解码器,增加间接调用层次 |
| 十六进制算术混淆 | 所有数值常量使用复杂十六进制算术表达式(如 0x2425+-0x1*-0x415+0x80b*-0x5 表示简单数字) |
| 控制流扁平化 | 通过对象属性间接调用函数,打乱执行逻辑顺序 |
| 死代码注入 | 大量永远不会执行的代码分支,增加分析干扰 |
| 反调试陷阱 | toString 正则检测 + 条件无限递归,检测到调试器则触发死循环 |
反混淆过程
通过精确复现 Base64 解码和 RC4 解密逻辑,暴力枚举字符串数组的旋转偏移量(最终确定为偏移 275),成功解密全部 300+ 条编码字符串,还原出完整的恶意代码逻辑。
四、反混淆后的恶意代码分析
完整还原后的恶意代码为纯 Node.js 脚本,核心功能如下:
4.1 嵌入 RSA-2048 私钥
恶意代码中硬编码了一个 RSA-2048 私钥(PKCS#8 格式,1703 字符),用于:
- 加密上报的敏感信息:从私钥中提取公钥,使用
publicEncrypt(OAEP 填充)加密后附加到 HTTP 请求头 - 解密 C2 服务器下发的指令:使用
privateDecrypt(OAEP + SHA-256)解密 Stage-1 payload
|
注:攻击者将私钥嵌入客户端代码,这使得任何获取该代码的人都能解密 C2 通信——这是攻击者的设计失误,也是本次分析能够完整还原攻击链的关键。
4.2 机器指纹采集
恶意代码通过以下字段构造机器唯一标识:
|
将拼接的字符串进行 SHA-256 哈希,得到 64 字符的十六进制指纹(af_uuid),存储在 localStorage 的 _rl_mc 键中。
4.3 Apifox 用户凭证窃取
恶意代码从 localStorage 读取 common.accessToken(Apifox 登录令牌),利用该令牌调用官方 API 获取用户信息:
|
从响应中提取用户 邮箱 和 姓名,经 RSA 加密后附加到后续请求头中。
4.4 C2 通信协议
恶意代码向 C2 服务器发送带有以下自定义 HTTP 头的请求:
| Header 字段 | 内容 | 加密方式 |
|---|---|---|
af_uuid |
机器指纹 SHA-256 | 明文 |
af_os |
操作系统类型 + 版本号 | 明文 |
af_user |
用户主目录路径 | RSA-2048 OAEP |
af_name |
主机名 | RSA-2048 OAEP |
af_apifox_user |
Apifox 账户邮箱 | RSA-2048 OAEP |
af_apifox_name |
Apifox 账户姓名 | RSA-2048 OAEP |
4.5 远程代码执行
|
从 C2 获取 RSA 加密的 payload → 私钥解密 → eval() 直接执行,实现完全的远程代码执行能力。
4.6 持久化机制
执行完毕后,通过 setTimeout 在 30 分钟 ~ 3 小时的随机间隔后重新执行整个流程,只要 Apifox 应用保持运行,恶意代码就会持续活跃。
五、攻击载荷深度分析
通过提取的 RSA 私钥解密 C2 返回的数据,我们获得了攻击者实际下发的完整攻击载荷。攻击分为两个阶段:
5.1 Stage-1:加载器(Loader)
C2 服务器(hxxps://apifox[.]it[.]com/public/apifox-event.js)返回 344 字节的 Base64 编码 RSA 加密数据,解密后为:
|
关键特点:
- 路径随机化:每次请求生成不同的 Stage-2 文件名(如
b8ee3b68.js、f51782ec.js、c74fe621.js),阻碍基于 URL 的检测 - 用完即焚:历史路径访问返回 404,只有最新生成的路径有效
- 反取证:脚本加载完毕后自动从 DOM 中移除
<script>标签 - 服务端绑定:C2 服务器读取 Stage-1 请求中的
af_uuidheader,将其硬编码到 Stage-2 代码中,实现客户端追踪
5.2 Stage-2 v1:信息窃取(collectPreInformations)
Stage-2 为明文 Node.js 脚本(约 3,400 字节),代码中保留了完整的中文开发注释(详见 5.4 节)。
窃取目标
全平台通用:
~/.ssh/— 递归读取整个目录(私钥、公钥、config、known_hosts、authorized_keys)
macOS / Linux 额外窃取:
~/.zsh_history— Zsh 命令行历史(含密码、Token、内部 URL)~/.bash_history— Bash 命令行历史~/.git-credentials— Git 明文凭证(GitHub PAT、GitLab Token)ps aux— 完整进程列表
Windows 额外窃取:
tasklist— 进程列表
数据外泄协议
|
AES 加密参数:
- 密码:
apifox - 盐值:
foxapi - 密钥派生:
scryptSync(password, salt, 32) - IV:12 字节随机值
- 格式:
Base64(IV[12] + AuthTag[16] + CipherText)
上传端点:
|
5.3 Stage-2 v2:纵深窃取(collectAddInformations)
在持续监控中发现 C2 服务器已升级攻击载荷(约 4,400 字节),新增了第二轮窃取,上报到不同端点 /event/2/log:
| 新增窃取目标 | 说明 |
|---|---|
~/.zshrc |
Shell 环境变量(可能含 API Key、Vault 地址、数据库连接串) |
~/.npmrc |
npm registry 认证 token |
~/.kube/* |
Kubernetes 集群配置(含 OIDC refresh token、集群 API 地址) |
~/.subversion/* |
SVN 凭证 |
| 目录树遍历 | 主目录、桌面、文档目录结构(深度 1-2 层),Windows 额外扫描 D:\、E:\、F:\ |
这表明攻击者在首轮窃取完成后,根据受害者环境定制后续攻击策略,逐步扩大窃取范围。
5.4 关于 Stage-2 代码中的中文注释
值得注意的是,C2 下发的 Stage-2 攻击载荷——这些由服务端动态生成、RSA 加密传输的”机密”脚本——在解密后竟然保留了完整的中文开发注释,例如:
|
攻击者在入口文件中精心部署了 7 层混淆、反调试陷阱和 RSA 加密通信,却在服务端下发的实际攻击载荷中留下了如此详尽的中文注释,甚至包括对加密参数的”教学式”说明(如”盐值也必须提供””scryptSync 会根据密码和盐值,计算出一个确定的 32 字节密钥”)。这种前后矛盾的 OPSEC 水平差异耐人寻味——可能暗示入口混淆层和后端载荷并非同一人编写,或者攻击者认为 RSA 加密传输已经足够安全,不必再对载荷本身做处理。
5.5 未捕获的后续阶段:完整的灵活 C2 平台
必须强调:目前我们捕获到的 Stage-2 v1 和 v2 仅为前期侦察和凭据采集阶段,并非攻击的终点。
从架构设计来看,这套恶意软件本质上是一个完整且高度灵活的远程代码执行(RCE)平台:
|
每一次 Apifox 启动后的定时轮询(30 分钟 ~ 3 小时),C2 服务器都可以返回完全不同的攻击载荷。我们观测到的 v1(凭据采集)和 v2(纵深窃取)只是攻击者选择在侦察阶段下发的脚本,但该架构完全支持:
| 潜在后续阶段 | 说明 |
|---|---|
| 高价值目标筛选 | 根据已回传的 SSH 密钥(目标服务器)、K8s 配置(集群规模)、Git 仓库(代码价值)、Apifox 邮箱(所属公司)等信息,识别金融、加密货币交易所、云服务商等高价值目标 |
| 定制化攻击载荷 | 针对筛选出的高价值目标,下发量身定制的脚本——例如针对特定银行内网环境的横向移动工具、针对特定 K8s 集群的持久化后门 |
| 后门植入 | 下发独立的持久化后门程序,脱离 Apifox 进程独立运行(概述中已提及”后续攻击者会控制主机拉取执行后门程序”) |
| 横向移动 | 利用窃取的 SSH 密钥直接登录内网服务器,利用 K8s OIDC Token 接管集群 |
| 数据窃取 | 针对性地下载源代码、数据库备份、密钥管理系统中的证书 |
| 供应链二次投毒 | 利用窃取的 npm Token 或 Git 凭证,向受害者的开源项目注入恶意代码,扩大攻击面 |
攻击者的完整作战流程可以理解为:
|
由于 eval() 可以执行任意代码,且每次轮询返回的载荷可以完全不同,攻击者在凭据采集阶段之后对特定目标执行了哪些操作,目前无法确知。 受影响用户不能仅因为我们公开的 IoC 中只包含侦察类行为就假定攻击仅止于此——对于被攻击者标记为高价值的目标,后续可能已经遭受了远超凭据窃取的深度入侵。
六、完整攻击链
|
七、C2 服务器行为特征
通过实际交互分析 C2 服务器,发现以下行为特征:
| 特征 | 说明 |
|---|---|
| 服务器技术栈 | nginx/1.28.2 + Express (Node.js) |
| Stage-2 路径动态生成 | 每次 Stage-1 请求返回不同的随机 8 位 hex 路径 |
| 一次性 URL | 历史 Stage-2 路径全部返回 404,无法复用 |
| 客户端绑定 | af_uuid 从 header 读取后硬编码到 Stage-2 代码中 |
| CORS 全开 | Access-Control-Allow-Origin: * |
| 无缓存 | Cache-Control: no-store |
| 攻击载荷迭代 | 持续更新 Stage-2 代码(v1 → v2,窃取范围扩大) |
观测到的 Stage-2 URL 样本
| 时间 | Stage-2 路径 |
|---|---|
| 2026-03-12 10:53 | /49b5e0ba.js |
| 2026-03-14 16:19 | /69bd75f5.js |
| 2026-03-15 16:33 | /bf0475de.js |
| 2026-03-16 04:47 | /ad0ff2db.js |
| 2026-03-17 05:35 | /185f3323.js |
| 2026-03-18 06:45 | /2a44e5af.js |
| 2026-03-18 19:59 | /46066214.js |
| 2026-03-19 09:06 | /4a8b213c.js |
| 2026-03-19 21:57 | /5dc09173.js |
| 2026-03-20 10:44 | /8e349a9b.js |
以上路径在 2026-03-25 验证时已全部返回 404。
八、IoCs(攻陷指标)
网络指标
| 类型 | 指标 |
|---|---|
| C2 域名 | apifox[.]it[.]com(非标准 ICANN 域名,无 WHOIS) |
| 域名性质 | .it.com 商业二级域名服务,非意大利 ccTLD |
| DNS 活跃期 | 2026-03-04 至 2026-03-22(18 天) |
| 投毒入口 | hxxps://cdn[.]apifox[.]com/www/assets/js/apifox-app-event-tracking.min.js (77KB 版本) |
| Stage-1 URL | hxxps://apifox[.]it[.]com/public/apifox-event.js |
| Stage-2 URL | hxxps://apifox[.]it[.]com/<随机8位hex>.js |
| 数据外泄端点 | hxxps://apifox[.]it[.]com/event/0/log(v1 窃取数据) |
| 数据外泄端点 | hxxps://apifox[.]it[.]com/event/2/log(v2 窃取数据) |
| 凭证窃取 API | hxxps://api[.]apifox[.]com/api/v1/user(被滥用的合法 API) |
| 部分反混淆后js/功能js | https://gist.github.com/phith0n/7020c55bf241b2f3ccf5254192bd48a5 |
部分
主机指标
| 类型 | 指标 |
|---|---|
| localStorage 键 | _rl_headers、_rl_mc |
| 被读取的凭证 | common.accessToken |
| 异常 HTTP 头 | af_uuid、af_os、af_user、af_name、af_apifox_user、af_apifox_name |
| 被访问的文件 | ~/.ssh/*、~/.git-credentials、~/.zsh_history、~/.bash_history、~/.kube/*、~/.npmrc、~/.zshrc、~/.subversion/* |
| 被执行的命令 | ps aux (Linux/macOS)、tasklist (Windows) |
加密指标
| 类型 | 指标 |
|---|---|
| RSA 私钥指纹 | PKCS#8 格式,1703 字符,模数起始 MIIEvQIBADANBgkqh... |
| AES 密码 | apifox |
| AES 盐值 | foxapi |
| AES 算法 | AES-256-GCM,scryptSync 密钥派生,12 字节 IV |
九、Wayback Machine 存档
投毒版本的完整代码可在以下 Wayback Machine 存档中获取:
|
存档时间为 2026 年 3 月 5 日,文件大小 77KB,末尾包含完整的混淆恶意代码。
十、受影响范围与风险评估
受影响人群
- 所有在 2026 年 3 月 4 日之后启动过 Apifox 桌面端的用户
- 全平台受影响:Windows、macOS、Linux 三个操作系统的用户均在攻击范围内,恶意代码针对不同平台实现了差异化的窃取逻辑(macOS/Linux 读取
.zsh_history、.bash_history、执行ps aux;Windows 执行tasklist、额外扫描 D:\E:\F:\ 盘符),不存在”只影响某个平台”的情况 - 特别是拥有 SSH 密钥、Git 凭证、K8s 集群权限的高权限用户
风险等级:🔴 严重(Critical)
已确认的风险(基于已捕获的侦察阶段载荷):
| 风险 | 影响 |
|---|---|
| SSH 私钥泄露 | 攻击者可直接登录服务器、跳板机,实施横向移动 |
| Git 凭证泄露 | 源代码仓库被未授权访问,可能引发更大范围的供应链攻击 |
| Shell 历史泄露 | 暴露内部 URL、数据库连接串、API Key、Vault Token 等硬编码敏感信息 |
| K8s 配置泄露 | 集群 OIDC Token / kubeconfig 泄露,可能直接获得生产环境集群管理权限 |
| npm Token 泄露 | 攻击者可向 registry 发布恶意包,扩大供应链攻击面 |
| Apifox 账户泄露 | 攻击者获取用户邮箱和姓名,可用于定向钓鱼或内部社工 |
潜在的风险(基于 C2 平台的 RCE 能力,无法排除):
| 风险 | 影响 |
|---|---|
| 任意远程代码执行 | eval() 可执行 C2 下发的任意脚本,完全控制主机 |
| 定制化深度入侵 | 攻击者可根据已回传的凭据,对高价值目标下发量身定制的后续载荷 |
| 独立后门驻留 | 可能已植入脱离 Apifox 进程的独立持久化后门 |
| 横向移动 | 利用窃取的 SSH 密钥、K8s Token 渗透内网,扩大失陷范围 |
| 二次供应链投毒 | 利用窃取的 Git/npm Token 向受害者的开源项目注入恶意代码 |
十一、攻击时间线总览
| 日期 | 事件 |
|---|---|
| 2026-03-04 | apifox[.]it[.]com DNS 解析上线(Cloudflare 托管),CDN 上的 JS 文件开始被投毒 |
| 2026-03-05 | Wayback Machine 抓取并存档了投毒版本(77KB) |
| 2026-03-12 ~ 03-20 | 观测到至少 10 次不同的 Stage-2 载荷下发(见第七节 URL 样本) |
| 2026-03-22 | apifox[.]it[.]com DNS 记录下线,域名不再解析 |
| 2026-03-25 | CDN 入口文件已被还原为正常版本(34KB),DNS 失效但源站 IP 仍在响应 |
攻击活跃窗口:2026-03-04 至 2026-03-22,共计 18 天。
十二、处置建议
紧急措施
- 立即停用 Apifox 桌面端应用
- 轮换所有 SSH 密钥(
~/.ssh/下的全部密钥对) - 吊销所有 Git Personal Access Token(GitHub、GitLab 等)
- 轮换 K8s 集群 OIDC Token 和 kubeconfig
- 轮换 npm registry Token
- 修改命令行历史中暴露的所有密码、Token 和 API Key
- 审查服务器登录日志,检查是否有异常 SSH 登录
检测方法
- 检查 Electron
localStorage中是否存在_rl_headers、_rl_mc键 - 监控网络流量中是否有到
apifox[.]it[.]com的历史请求流量 - 检查历史 HTTP 请求头中是否包含
af_uuid、af_os等异常字段
长期建议
- Apifox 应启用 Electron
sandbox模式,限制渲染进程的 Node.js API 访问 - 对加载的远程 JS 文件实施 Subresource Integrity (SRI) 校验
- 建立 CDN 资源的文件完整性监控机制
- 企业用户应对开发工具类软件的网络通信进行审计
十三、总结
这是一起典型的供应链攻击,攻击者通过篡改 Apifox CDN 上的合法 JavaScript 文件,在数万开发者的工作电脑上植入后门。攻击设计精巧:
- 7 层代码混淆使静态分析极其困难
- RSA-2048 加密通信保护 C2 指令不被中间人截获
- 一次性 URL 和 DOM 自清理增加取证难度
- AES-256-GCM 加密外泄数据规避 DLP 检测
- 随机间隔持久化避免产生规律性网络流量
.it.com非标准域名规避 WHOIS 追踪,利用视觉欺骗降低怀疑
然而攻击者也暴露了明显的矛盾——入口文件精心部署了 7 层混淆和反调试陷阱,服务端下发的实际攻击载荷中却留下了详尽的中文开发注释,甚至包含”盐值也必须提供””scryptSync 会根据密码和盐值,计算出一个确定的 32 字节密钥”等教学式说明。同时,将 RSA 私钥嵌入客户端代码更是关键失误,使得安全研究人员能够解密全部 C2 通信,完整还原攻击链条并获取实际下发的攻击载荷。
但必须清醒认识到:本次分析捕获到的 Stage-2 v1/v2 仅为前期侦察和凭据采集阶段。 该恶意软件的核心本质是一个基于 eval() 的完整灵活 C2 平台——C2 服务器在每一次轮询中都可以下发完全不同的任意 JavaScript 代码。攻击者完全有能力根据已回传的机器指纹、Apifox 邮箱(判断所属公司)、SSH 密钥(判断可达服务器)、K8s 配置(判断集群规模和权限)等信息,筛选出金融机构、加密货币交易所等高价值目标,为其量身定制后续攻击载荷。
对于这些被标记为高价值的目标,攻击者在侦察阶段之后可能已经执行了远超凭据窃取的深度入侵——包括但不限于后门植入、横向移动、源代码窃取、生产环境接管。受影响用户切不可因为当前公开的 IoC 仅涵盖侦察行为就低估威胁等级,应当按照”已失陷”的最高级别进行应急响应。