sanitize: replace all site/vendor names with abbreviations (RS/JY/TK)

This commit is contained in:
白夜
2026-04-18 09:34:42 +08:00
parent 2ae0c35a6e
commit 94f71bfcdb
11 changed files with 92 additions and 92 deletions
+1 -1
View File
@@ -396,7 +396,7 @@ Hook 是 JS 逆向中最核心的技术之一。通过劫持/拦截 JS 原生函
5. **使用 `console.trace`**:在关键点输出调用栈
6. **Camoufox 优势**:Juggler 协议沙箱隔离,Hook 不会被页面 JS 检测到
7. **使用 Proxy 代替直接覆写**:更隐蔽,不改变 `typeof` 结果
8. **首屏挑战页用 `navigate(pre_inject_hooks=[...])`** [v2.5.0]:瑞数/Akamai 首包挑战在 hook 装好前就跑完了,用这个参数让 hook 先装再 goto
8. **首屏挑战页用 `navigate(pre_inject_hooks=[...])`** [v2.5.0]:RS/Akamai 首包挑战在 hook 装好前就跑完了,用这个参数让 hook 先装再 goto
9. **装完 hook 想让它先于页面 JS 跑**:用 `reload_with_hooks()` [v2.5.0] 替代裸 `reload()`,同时会清掉各类 `__mcp_*_log`
---
+6 -6
View File
@@ -6,11 +6,11 @@ JSVMP(JavaScript Virtual Machine Protection)是一种高级 JS 代码保护
- 原始代码逻辑不再以 JS AST 形式存在,无法通过传统反混淆手段还原
- 代码以字节码数组 + 解释器循环的形式运行
- 常见于瑞数、极验、某数等商业级反爬方案
- 常见于RS、JY、某数等商业级反爬方案
**核心原则:不反编译字节码,用行为追踪法(Hook / 插桩 / 日志分析 / 源码级插桩四板斧)从 I/O 两端夹逼 + 中间层观察定位签名逻辑。**
> **v2.5.0 更新**:第四板斧「源码级插桩」由 camoufox-reverse MCP v0.4.0 的 `instrument_jsvmp_source` 提供支持,在 HTTP 层改写 VMP 源码,对每个 `obj[key]` 和 `fn(args)` 插入 tap,捕获 VM 内部 switch/case 调度——是瑞数 5/6、Akamai sensor_data、webmssdk、obfuscator.io 这类"VM 自包含"场景的通用武器。详见 [`jsvmp-source-instrumentation.md`](./jsvmp-source-instrumentation.md)。
> **v2.5.0 更新**:第四板斧「源码级插桩」由 camoufox-reverse MCP v0.4.0 的 `instrument_jsvmp_source` 提供支持,在 HTTP 层改写 VMP 源码,对每个 `obj[key]` 和 `fn(args)` 插入 tap,捕获 VM 内部 switch/case 调度——是RS 5/6、Akamai sensor_data、webmssdk、obfuscator.io 这类"VM 自包含"场景的通用武器。详见 [`jsvmp-source-instrumentation.md`](./jsvmp-source-instrumentation.md)。
---
@@ -109,12 +109,12 @@ MCP 操作(推荐顺序):
|---------|-------------|
| 签名通过 CryptoJS / atob / MD5 等可 hook API 走 | 第一 + 第三(hot API hook + 日志反推) |
| VMP 通过 `Function.apply/call` 调子函数 | 第二 + 第三(`hook_jsvmp_interpreter` 多路径 + 日志) |
| VMP 自包含,算法全在 switch/case 内(瑞数 5/6、Akamai、webmssdk、obfuscator.io) | **第四板斧首选**,配合第一板斧做 I/O 边界 |
| VMP 自包含,算法全在 switch/case 内(RS 5/6、Akamai、webmssdk、obfuscator.io) | **第四板斧首选**,配合第一板斧做 I/O 边界 |
| VMP 深度绑定浏览器环境(compare_env 差异大 + 签名随环境变) | 路径 B 环境伪装(见 SKILL.md 场景 10),配第四板斧 `hot_keys` 定位指纹集 |
---
### 快速路径:v0.4.0 黄金 8 步流程(推荐先试,70%+ 瑞数/Akamai/webmssdk 场景直接搞定)
### 快速路径:v0.4.0 黄金 8 步流程(推荐先试,70%+ RS/Akamai/webmssdk 场景直接搞定)
```
Step 1 — find_dispatch_loops 确认 VMP + 记下 fn_name / char_range
@@ -514,10 +514,10 @@ MCP 操作:
```
navigate(url) 不加任何 hook 观察 redirect_chain
│
├─ 反复 412 后才到 200 → 签名型 JSVMP(瑞数/Akamai)
├─ 反复 412 后才到 200 → 签名型 JSVMP(RS/Akamai)
│ └─ 走"签名型专属路径"(见下文)
│
├─ 直接 200 但主请求链带签名参数 → 行为型 JSVMP(短视频平台/极验)
├─ 直接 200 但主请求链带签名参数 → 行为型 JSVMP(短视频平台/JY)
│ └─ 按原路径 A / 路径 B 决策树选择
│
└─ 直接 200 无签名参数 → 非 JSVMP 或 VMP 已被跳过
+6 -6
View File
@@ -10,7 +10,7 @@
### 1.1 传统 hook 的盲区
**`hook_jsvmp_interpreter`** 即使升级到 v0.4.0 的多路径版本(apply/call/bind + Reflect.*/Proxy 全局对象 + timing/random),仍然只能看到 VMP 路由到**可 hook JS API** 的部分。但瑞数 5/6、Akamai sensor_data v2/v3、webmssdk(短视频平台)、obfuscator.io 这类 VMP 的典型结构是:
**`hook_jsvmp_interpreter`** 即使升级到 v0.4.0 的多路径版本(apply/call/bind + Reflect.*/Proxy 全局对象 + timing/random),仍然只能看到 VMP 路由到**可 hook JS API** 的部分。但RS 5/6、Akamai sensor_data v2/v3、webmssdk(短视频平台)、obfuscator.io 这类 VMP 的典型结构是:
```js
// 典型的自包含 VMP 字节码分发循环
@@ -92,7 +92,7 @@ __mcp_tap_call(fn, null, [args[0], args[1], ...], 'vmp1');
> **v0.5.0 变化**:`mode="ast"` 的实现从 v0.4.x 的"页面内加载 acorn CDN"改为
> **MCP 侧 esprima-python 解析**。这意味着:
> - 挑战页(瑞数 412、Akamai sensor_data 挑战等)上 AST 模式**能用了**(旧实现因 CDN 被挑战拦住会静默失败)
> - 挑战页(RS 412、Akamai sensor_data 挑战等)上 AST 模式**能用了**(旧实现因 CDN 被挑战拦住会静默失败)
> - 零 JS 依赖,`instrument_jsvmp_source` 的 AST 模式现在**应成为默认选择**
> - 新增 `fallback_on_error=True`,esprima 解析失败时自动回落 regex
> - 旧的 "ast_page" 模式保留但标注为 deprecated,仅做 A/B 对比用
@@ -126,13 +126,13 @@ __mcp_tap_call(fn, null, [args[0], args[1], ...], 'vmp1');
2. 如果是 ES2022+ 的 private field / static block / top-level await 等新语法 → 手动 `mode="regex"`(~80% 覆盖)或 `mode="transparent"`(runtime 观察)兜底
3. 如果是 `SyntaxError: Unexpected token` 开头 → 可能 JS 被加了 BOM 或非标准前缀,可以本地用 `curl` 下来手动检查首 100 字节
一般来说,瑞数 sdenv*.js / Akamai acmescripts*.js / webmssdk 都能被 esprima 解析。如果出现持续 fallback,报告给 MCP 仓库 issue 区。
一般来说,RS sdenv*.js / Akamai acmescripts*.js / webmssdk 都能被 esprima 解析。如果出现持续 fallback,报告给 MCP 仓库 issue 区。
---
## 3. 黄金 8 步流程
> 这是面向瑞数 5/6、Akamai sensor_data、webmssdk、obfuscator.io 的通用流程。照抄 `Actions` 段即可,执行方需要替换的只有 `url_pattern` 和 `script_url`。
> 这是面向RS 5/6、Akamai sensor_data、webmssdk、obfuscator.io 的通用流程。照抄 `Actions` 段即可,执行方需要替换的只有 `url_pattern` 和 `script_url`。
### Step 1 — 启动 + 网络捕获
@@ -207,10 +207,10 @@ Actions:
reload_with_hooks(clear_log=True, wait_until="networkidle")
→ 注意 final_status:
· 200 → 正常
· 412 → 瑞数挑战页未过,需要等 challenge 完成
· 412 → RS挑战页未过,需要等 challenge 完成
· 403 → Akamai 拦截,检查指纹或 UA
特殊场景:若目标就是首屏挑战页(瑞数 412),用:
特殊场景:若目标就是首屏挑战页(RS 412),用:
navigate(
url="https://target.com/",
pre_inject_hooks=["xhr", "fetch", "cookie", "jsvmp_probe"],
+3 -3
View File
@@ -213,7 +213,7 @@
[camoufox-reverse] evaluate_js(expression="ws.send(JSON.stringify({...}))")
```
### 场景 6:通用 JSVMP 源码级插桩(瑞数/Akamai/webmssdk)[v2.5.0 新增]
### 场景 6:通用 JSVMP 源码级插桩(RS/Akamai/webmssdk)[v2.5.0 新增]
**目标**:定位 VMP 读取的环境指纹集与调用的加密原语,不依赖 VMP 具体实现
@@ -344,7 +344,7 @@
**关键洞察**:
> 对于瑞数、Akamai 这类"JS 算 token、服务端 Set-Cookie"的混合模式,单纯 `hook_function(Document.prototype.cookie)` 是抓不到最终 cookie 写入的——因为它是 HTTP header 写的,不经过 JS。`analyze_cookie_sources` 的价值就是 30 秒内消除这个盲区。
> 对于RS、Akamai 这类"JS 算 token、服务端 Set-Cookie"的混合模式,单纯 `hook_function(Document.prototype.cookie)` 是抓不到最终 cookie 写入的——因为它是 HTTP header 写的,不经过 JS。`analyze_cookie_sources` 的价值就是 30 秒内消除这个盲区。
## 高级技巧
@@ -587,7 +587,7 @@ await instrument_jsvmp_source("**/vmp.js", mode="ast_page")
### 使用 pre_inject_hooks 解决首屏挑战页(v2.5.0 新增)
```
# 瑞数 412 / Akamai 首包检测场景:
# RS 412 / Akamai 首包检测场景:
# 普通 navigate → launch_browser → navigate → 装 hook
# 但此时 challenge JS 已经跑完了,hook 完全漏掉第一次 VMP 执行
+1 -1
View File
@@ -228,6 +228,6 @@
| 实时对比 | `evaluate_js` | 在浏览器中执行还原后的签名函数,与脚本输出对比 |
| **Cookie 归因** [v2.5.0] | `analyze_cookie_sources` | 辨识 Cookie 是 HTTP Set-Cookie 还是 JS document.cookie 写的 |
| **源码级插桩** [v2.5.0] | `instrument_jsvmp_source` + `get_instrumentation_log` | 对 VMP 做 HTTP 层源码改写,hot_keys 暴露环境指纹集 |
| **首屏挑战** [v2.5.0] | `navigate(pre_inject_hooks=[...])` | 瑞数/Akamai 412 挑战页 hook 预注入 |
| **首屏挑战** [v2.5.0] | `navigate(pre_inject_hooks=[...])` | RS/Akamai 412 挑战页 hook 预注入 |
| **hook 重载** [v2.5.0] | `reload_with_hooks` | 重载使 persistent hook 先于页面 JS 执行 + 清日志 |
| **运行时探针** [v2.5.0] | `get_runtime_probe_log` | 快速摸底页面在读什么 / 调什么(低开销) |
+2 -2
View File
@@ -20,7 +20,7 @@
│ ├─ 服务端返回 JS 动态执行 → 模式B:VM 沙箱执行
│ ├─ WASM 二进制 → 模式C:WASM 加载
│ ├─ JSVMP 虚拟机保护 → 先走四板斧(Hook/插桩/日志/源码级插桩) → 失败则 → 模式D/E
│ │ · 瑞数 5/6、Akamai、webmssdk、obfuscator.io → 第四板斧源码级插桩最有效
│ │ · RS 5/6、Akamai、webmssdk、obfuscator.io → 第四板斧源码级插桩最有效
│ │ · 深度绑定环境指纹 → 模式E(jsdom 环境伪装)
│ └─ 无法脱离浏览器环境 → 模式D:浏览器自动化
│
@@ -139,7 +139,7 @@
1. launch_browser(headless=False) + start_network_capture(capture_body=True)
↓
2. 导航前判断是否首屏挑战
├─ 是(瑞数 412 / Akamai 403 等)
├─ 是(RS 412 / Akamai 403 等)
│ → navigate(url=..., pre_inject_hooks=["xhr","fetch","cookie","jsvmp_probe"], via_blank=True)
└─ 否
→ navigate(url=...) + 之后装 hook + reload_with_hooks()