Apifox供应链攻击事件(AiPy自查)

admin 2026-03-29 23:43:48 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文围绕Apifox供应链攻击事件展开,攻击者篡改了其公网SaaS版外部JS文件,植入恶意代码实现用户行为追踪、系统信息采集及远程代码执行。作者使用AiPy工具结合不同大模型对被篡改的混淆JS进行逆向分析,揭示了国产模型在无Skill配置下易产生幻觉(将恶意域名误判为apifox.it.co而实际为apifox.it.com),而Gemini模型配合自定义Skill能更准确还原代码逻辑。文章还提供了基于AiPy的自查方法,帮助用户检测浏览器localStorage等是否中招,并分享了完整的混淆JS逆向分析流程与Skill编写规范,强调以原始样本为第一证据链、区分验证事实与推测的重要性。 综合评分: 74 文章分类: 供应链安全,逆向分析,代码审计,AI安全,漏洞分析


cover_image

Apifox 供应链攻击事件(AiPy自查)

heige heige

黑哥虾撩

2026年3月26日 14:29 美国

这次的“Apifox 供应链攻击事件” 可以参考:

官方公告:关于 Apifox 公网 SaaS 版外部 JS 文件受篡改的风险提示与升级公告

另外还有一个最早发布的一个完整分析:

https://rce.moe/2026/03/25/apifox-supply-chain-attack-analysis/

这类的分析其实在 使用Zoomeye 和 AiPy 捕获 Coruna 样本已经有过例子了,秉承AI Agent 下半场 文章中“结果导向”的理念,在这次分析中出现了一个非常典型的 “幻觉”,另外在这几天直播中有人问我:是Skill重要还是模型能力重要,包括这段时间翻炒的 IHarness Engineering 当然这个问题我其实在以往的文章都提到过, 然后这个例子正好用来说明这个问题。

启动AiPy (我用的Cli版本,大家也可以去www.aipyaipy.com 去使用gui版本)

帮我分析下

https://web.archive.org/web/20260305051418if_/https://cdn.apifox.com/www/assets/js/apifox-app-event-tracking.min.js

幻觉(国产模型+没有配置skill)

开始我使用的国内模型(具体就不说了),然后一顿分析后的结果:

解密后发现的域名

https://api.apifox.comhttps://apifox.it.co          ← ⚠️ 恶意域名https://cm.bilibili.comhttps://convert.dop.360.cnhttps://ocpc.p4p.sogou.comhttps://us.i.posthog.comhttps://www.google-analytics.com

关键发现

在 deobfuscated_complete.js 第 22 行:

// 远程服务器 URLconstREMOTE_JS_URL = 'https://apifox.it.co/xxx';constAPIFOX_USER_API = 'https://api.apifox.com/api/v1/user';

确认:版本 1 使用 https://apifox.it.co/xxx 作为远程代码请求地址


随后我还追问了下:

当时我也差点被幻觉误导了,注意看他这里找出来的是 apifox.it.co , 于是我审查了一下整个过程,发现了问题:在编写deobfuscate.js的代码的时候,他直接估计混淆的js脑补了一个地址

原本的混淆的JS源码:

这种幻觉还是非常隐蔽的,不容易被发现,如果不是review下整个过程,很可能就被误导了,这个也对后续的排查也会埋下漏报祸根!

逆向 (AiPy + Gemini31.1 pro)

🚀 Python use – AIPython (0.6.0b17) [https://aipy.app]

[Main] Please enter an instruction or /help for more information

/llm use tt-gemini-3

Success

帮我逆向下

https://web.archive.org/web/20260305051418if_/https://cdn.apifox.com/www/assets/js/apifox-app-event-tracking.min.js

这里分析出来的是 apifox.it.com 生成的md报告:

Apifox App Event Tracking 逆向分析报告

概述

对 apifox-app-event-tracking.min.js 文件进行了深度逆向分析,这是一个高度混淆的JavaScript文件,主要用于收集用户行为数据并与远程服务器通信。

文件基本信息

  • 原始大小

    : 80,255 字节

  • 混淆类型

    : 字符串数组 + RC4加密 + 控制流平坦化

  • 目标环境

    : 浏览器/Electron桌面应用

  • 主要功能

    : 用户行为追踪、远程代码加载、系统信息采集

代码结构分析

1. 混淆机制

  • 字符串数组

    _0x70b33e 包含 400+ 个混淆字符串

  • RC4解密

    _0x3fb9 函数实现RC4流密码解密

  • 字符串洗牌

    : 通过复杂的数学运算重新排列字符串数组

  • 函数重命名

    : 所有函数和变量都使用 _0x[0-9a-f]+ 格式

2. 核心功能模块

2.1 网络通信模块

// 远程JS URL (经过混淆)
REMOTE_JS_URL = "https://apifox.it.com/..."

// API接口
APIFOX_USER_API = "/api/v1/user"

// 代理服务器
PROXY_SERVER = "https://web-proxy.apifox.com/api/v1/request"

2.2 加密模块

  • RSA加密

    rsaEncrypt() / rsaDecrypt()

  • 私钥

    : 硬编码在代码中(PEM格式)

  • 用途

    : 加密敏感数据(用户ID、设备信息等)

2.3 系统信息采集

// 采集的数据包括:
- MAC地址
- CPU型号
- 操作系统版本
- 主机名
- 网络接口信息

2.4 持久化存储

  • localStorage键

    :

  • _rl_mc

    : 机器标识

  • common.headers

    : 请求头信息

  • eventTracking.firstVisit

    : 首次访问标记

  • eventTracking.dailyReportUsers

    : 日报用户记录

3. 主要执行流程

3.1 初始化阶段

  1. 加载字符串数组并解密
  2. 获取或生成设备指纹
  3. 建立网络连接测试

3.2 数据采集阶段

  1. 收集系统信息(CPU、OS、网络)
  2. 生成唯一设备标识符
  3. 加密敏感数据

3.3 远程通信阶段

  1. 向API发送心跳包
  2. 获取远程JS代码 (loadAndExecute())
  3. 执行远程代码 (eval(rsaDecrypt(response)))

3.4 定时任务

  • 随机间隔

    : 4小时 – 24小时

  • 任务类型

    :

  • 数据上报 (scheduleNext)

  • 页面访问统计 (reportPageview)

  • 用户行为追踪 (report)

4. 安全分析

4.1 潜在风险点

  1. 远程代码执行

    : 从 REMOTE_JS_URL 动态加载并执行JS代码

  2. 数据泄露

    : 收集详细的系统信息和用户行为

  3. 持久化跟踪

    : 使用多种存储机制维持长期跟踪

  4. 加密绕过

    : 使用弱加密算法保护传输数据

4.2 反调试措施

  • 复杂的字符串混淆
  • 自修改代码
  • 定时器干扰

5. 关键发现

5.1 远程服务器

  • 主服务器

    https://apifox.it.com

  • API端点

    /api/v1/request/api/v1/user

  • 代理服务

    web-proxy.apifox.com

5.2 跟踪功能

  • Google Analytics集成
  • 百度统计集成
  • PostHog统计集成
  • SLS日志服务

5.3 用户识别

  • 基于硬件信息的设备指纹
  • 用户ID绑定 (common.currentUserId)
  • 会话跟踪 (projectCid)

技术细节

6.1 字符串解密算法

functionrc4_decrypt(key, data) {
// 初始化S盒
// 密钥调度算法
// 伪随机生成算法
// 异或解密
}

6.2 设备指纹生成

functiongenerateDeviceId() {
const components = [
        macAddress,
        cpuModel,
        osVersion,
        hostname,
        networkInterfaces
    ];
returnsha256(components.join('-'));
}

6.3 定时调度算法

functionrandomInterval() {
const min = 4 * 60 * 60 * 1000;  // 4小时
const max = 24 * 60 * 60 * 1000; // 24小时
return min + Math.random() * (max - min);
}

结论

这是一个功能完整的用户行为追踪SDK,具有以下特点:

  1. 高度混淆

    : 使用多层加密和混淆技术保护代码

  2. 全面采集

    : 收集系统和用户行为数据

  3. 远程控制

    : 支持动态更新和执行远程代码

  4. 持久跟踪

    : 使用多种机制维持长期跟踪能力

  5. 多平台支持

    : 同时支持Web和Electron环境

建议

  1. 安全审计

    : 建议对远程服务器进行安全评估

  2. 隐私合规

    : 确保符合GDPR等隐私法规

  3. 代码加固

    : 考虑使用更安全的加密算法

  4. 监控机制

    : 建立异常行为检测机制


分析时间: 2026-03-26 分析工具: 静态分析 + 动态调试 风险等级: 高

自查

有这个分析结果了就非常简单了

帮我查一下是否中招

当然这个前提是你有给他分析那个js,如果不想发时间逆向分析,你也可以随便找一个分析报告让AiPy阅读下也是可以的

看起来还是查得比较仔细的包括浏览器localStorage啥的。

Skill (AiPy+国产模型+Skill)

按AI Agent 下半场 里提到的套路:

Code-use Agent –> 任务 –> 自动总结生成并安装 Skills –> 分发 到 Skills 市场 –> 其他用户下载安装使用

我用国外的模型自动提炼了个Skill:

---name: reverse-obfuscated-jsdescription: Use this skill to reverse engineer obfuscated JavaScript loaders, telemetry scripts, and suspected staged payloads. It focuses on evidence-first analysis, controlled execution, IOC extraction, deobfuscation, and preventing AI hallucinations from entering the evidence chain.---# Reverse Obfuscated JS## When to use this skillUse this skill when the target is a minified or obfuscated JavaScript sample and you need to:- recover important constants, URLs, keys, and storage names- understand loader chains and second-stage payload fetches- inspect telemetry, tracking, or suspicious desktop/Electron behavior- distinguish verified facts from guesses- produce readable deobfuscated output and a defensible reportThis skill is optimized for samples where pure regex extraction is not enough because key strings are restored at runtime.## Core ruleDo not let generated artifacts become evidence.Primary evidence is limited to:- the original sample- controlled runtime interception of the original sample- first-party response bodies returned by the sampleSecondary artifacts are useful for explanation but cannot prove original behavior:- AI-written reports- manually reconstructed code- flowcharts- deobfuscated templates## Output modelEvery conclusion should be labeled as one of:- `Verified`: directly supported by primary evidence- `Inferred`: supported indirectly and should be stated as inference- `Unknown`: not yet establishedNever fill an unknown IOC with a plausible-looking placeholder such as `https://example.com/xxx`.## Workflow### 1. Preserve the original sample- save the raw script exactly as collected- compute and record a hash if practical- avoid editing the original sample### 2. Perform a static sweepUse fast text search first.Recommended commands:```bashrg -n "https?://|localStorage|sessionStorage|fetch|eval|Function\\(|XMLHttpRequest|require\\(|crypto|posthog|gtag|electron|userAgent" sample.jsrg -n "_0x|atob|btoa|fromCharCode|decodeURIComponent|TextDecoder|subtle|createDecipheriv|createHash" sample.js```During the static pass, extract:- obvious URLs- storage keys- crypto API usage- `eval` or code-generation sinks- environment checks such as `Electron`, `window.require`, `process`- identifiers for string-decoder functions and lookup arrays### 3. Build a controlled runtimeIf important values are restored dynamically, execute the original sample in a constrained environment.Prefer Node.js `vm` or an equivalent sandbox with stubbed globals.Intercept at minimum:- `fetch`- `XMLHttpRequest`- `eval`- `Function`- `localStorage.getItem` and `localStorage.setItem`- `sessionStorage`- `window.require`- `setTimeout` and `setInterval`- DOM insertion points such as `document.createElement`, `appendChild`, `insertBefore`For Electron-oriented samples, stub:- `window.require('crypto')`- `window.require('os')`- `window.require('fs')` only if neededThe goal is not full emulation. The goal is to capture:- resolved constants- runtime-decoded strings- fetched URLs- custom request headers- storage keys and values- decryption inputs and outputs- the final code execution sink### 4. Recover dynamic constantsFor values such as `REMOTE_JS_URL`, `LS_HEADERS`, or API paths:- prefer runtime interception over regex guessing- if the script computes headers, log the computed object- if the script writes a storage key, capture the exact key used at runtimeIf a string-decoder function is isolated cleanly, you may evaluate just that decoder and dump its outputs. Still treat the original sample as the source of truth.### 5. Analyze loader and crypto behaviorMap the execution chain in order:- what condition enables the loader- what identifiers or fingerprints are collected- how request headers are built- which endpoint is fetched- whether content is encrypted, compressed, or encoded- which decryptor/decoder is used- where execution finally occurs, such as `eval(decryptedCode)`When describing crypto behavior, be precise:- identify algorithm and mode only if verified- identify hash function only if verified- if key material is partial or hidden, mark it `Unknown`### 6. Reconstruct readable codeAfter evidence is collected, produce a readable reconstruction.Rules for reconstruction:- preserve verified constants exactly- mark approximate logic with comments such as `// inferred`- do not silently replace unknown behavior with plausible logic- keep dangerous calls visible, for example `eval`, network fetches, local fingerprinting### 7. Produce an evidence tableFor each high-value conclusion, include:- claim- status: `Verified`, `Inferred`, or `Unknown`- evidence source- file or runtime referenceExample:```textClaim: REMOTE_JS_URL = https://apifox.it.com/public/apifox-event.jsStatus: VerifiedEvidence: controlled runtime interception of fetch() from original sample```## Hallucination prevention checklistBefore finalizing, verify all of the following:- no IOC came only from an AI-generated report- no generated deobfuscated file is being used as proof of original behavior- all placeholder values are clearly marked- all critical URLs were observed in the sample or during controlled execution- all storage keys were observed exactly, not abbreviated- all API field names were read from real responses or real access paths- every important claim is tagged `Verified`, `Inferred`, or `Unknown`If a guessed value appears in a draft, remove it or relabel it before shipping.## DeliverablesThe default deliverables for this skill are:- a concise finding summary- a readable deobfuscated or reconstructed code file- an evidence-backed notes file- if relevant, a short hallucination-risk section explaining what was verified vs inferred## Practical biasPrefer runtime truth over elegant static theory.If static extraction and runtime behavior disagree, trust the original sample plus controlled interception, then explain the discrepancy.

然后AiPy安装这个skill 使用国产模型跑了下,一次就跑出结果了:

效果还是非常好的。

所以在现在阶段Skills的存在是,其实也就是之前的提示词工程的还是有存在的价值和意义的,这个也让我想起在直播的时候提到的Claud 与 Openai在当时还是提示词工程这个词比较火的时代的PK,这个跟AI Agent 下半场 里提到的MCP/Skills 其实也是一样的:

过度的开发者依赖不符合 AGI 的追求

但是你也不得不承认在先阶段,好的提示词(包括Skill)还是能有效提升模型工作能力的!当然他们两者也不冲突,还有一个就是通用Agent设计也非常重要,在现阶段这三方面都有发挥的空间~

总结:

以“结果为导向”才是AI Agent的下半场的唯一衡量标准!AiPy其实一直都是以“让AI成为您的真正干活牛马”

无耻广告:

我正在体验新一代超级人工智能助手AiPy!现在使用我的专属邀请码:sE5B,立即获得 2,000,000 Tokens额外奖励!

使用方式如下:

① 进入AiPy官网:https://www.aipyaipy.com/,下载最新版AiPy客户端。

② 注册登录时填写上方邀请码即可。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:黑哥虾撩 heige heige《Apifox 供应链攻击事件(AiPy自查)》

评论:0   参与:  0