344 lines
8.6 KiB
Markdown
344 lines
8.6 KiB
Markdown
# API验签参数逆向分析工具集
|
||
|
||
这个工具集帮助您分析和捕获巨量百应API的验签参数。
|
||
|
||
## 工具列表
|
||
|
||
### 1. capture_params.py - Python参数捕获工具
|
||
|
||
**功能:** 使用Playwright自动监听并捕获API请求的所有参数
|
||
|
||
**使用方法:**
|
||
|
||
```bash
|
||
# 安装依赖
|
||
pip install playwright
|
||
playwright install chromium
|
||
|
||
# 运行工具(使用默认URL和API)
|
||
python tools/capture_params.py
|
||
|
||
# 自定义目标URL和API接口
|
||
python tools/capture_params.py "https://buyin.jinritemai.com/dashboard" "getInstituteDarenData"
|
||
```
|
||
|
||
**输出示例:**
|
||
|
||
```
|
||
🔍 捕获到API请求
|
||
================================================================================
|
||
|
||
📍 URL: https://buyin.jinritemai.com/api/authorTradeData/getInstituteDarenData
|
||
|
||
🔑 关键验签参数:
|
||
verifyFp = verify_millxb4n_b5lvAUK8_0SU3_4NHS_9B2f_mO7PPJowv2Hb
|
||
fp = verify_millxb4n_b5lvAUK8_0SU3_4NHS_9B2f_mO7PPJowv2Hb
|
||
msToken = u9l7geNk7XjY4PmBKfEJlyLcbDA0LC1gp9U4XpDpEgCrGGLVxV_f8xU...
|
||
a_bogus = Q70fhHyyxNQVaplSmOkjeRAlAggMNBWjBMiObnnPtFTTcZtaY9Bp...
|
||
|
||
📋 业务参数:
|
||
page = 1
|
||
pageSize = 20
|
||
start_time = 2025/11/29
|
||
end_time = 2025/11/29
|
||
```
|
||
|
||
### 2. browser_hook.js - 浏览器Hook脚本
|
||
|
||
**功能:** 在浏览器Console中拦截所有API请求,实时显示参数和调用栈
|
||
|
||
**使用方法:**
|
||
|
||
1. 打开Chrome浏览器,访问目标网站
|
||
2. 按F12打开开发者工具
|
||
3. 切换到Console标签
|
||
4. 复制 `tools/browser_hook.js` 的全部内容
|
||
5. 粘贴到Console并回车
|
||
6. 进行正常操作,脚本会自动捕获请求
|
||
|
||
**可用命令:**
|
||
|
||
```javascript
|
||
// 查看所有捕获的请求
|
||
window._showCapturedRequests()
|
||
|
||
// 查看第一个请求的详细信息
|
||
window._capturedRequests[0]
|
||
|
||
// 导出所有请求为JSON文件
|
||
window._exportCapturedRequests()
|
||
|
||
// 清空捕获记录
|
||
window._clearCapturedRequests()
|
||
```
|
||
|
||
**输出示例:**
|
||
|
||
```javascript
|
||
🔍 捕获到 GET 请求
|
||
================================================================================
|
||
|
||
📍 URL: https://buyin.jinritemai.com/api/authorTradeData/getInstituteDarenData
|
||
|
||
🔑 验签参数:
|
||
┌─────────┬──────────────────────────────────────────┐
|
||
│ (index) │ Values │
|
||
├─────────┼──────────────────────────────────────────┤
|
||
│ verifyFp│ verify_millxb4n_b5lvAUK8_0SU3_4NHS... │
|
||
│ fp │ verify_millxb4n_b5lvAUK8_0SU3_4NHS... │
|
||
│ msToken │ u9l7geNk7XjY4PmBKfEJlyLcbDA0LC1gp9... │
|
||
│ a_bogus │ Q70fhHyyxNQVaplSmOkjeRAlAggMNBWjBM... │
|
||
└─────────┴──────────────────────────────────────────┘
|
||
|
||
📚 调用栈:
|
||
at XMLHttpRequest.send (hook.js:123)
|
||
at request (app.js:456)
|
||
at getData (component.js:789)
|
||
```
|
||
|
||
## 完整逆向流程
|
||
|
||
### 方法1: 使用Chrome DevTools(推荐新手)
|
||
|
||
1. **打开开发者工具**
|
||
```
|
||
F12 或 右键 -> 检查
|
||
```
|
||
|
||
2. **切换到Network标签**
|
||
- 勾选 "Preserve log" (保留日志)
|
||
- 筛选 Fetch/XHR
|
||
|
||
3. **触发API请求**
|
||
- 在页面上进行操作(如切换页面、点击按钮)
|
||
- 找到 `getInstituteDarenData` 请求
|
||
|
||
4. **查看请求详情**
|
||
- 点击请求
|
||
- 查看 Headers、Payload、Preview、Response
|
||
|
||
5. **找到参数生成位置**
|
||
- 右键请求 -> Copy -> Copy as fetch
|
||
- 在Sources标签中搜索参数名(如 `a_bogus`)
|
||
|
||
### 方法2: 使用capture_params.py(推荐进阶)
|
||
|
||
```bash
|
||
# 1. 运行捕获工具
|
||
python tools/capture_params.py
|
||
|
||
# 2. 在打开的浏览器中登录并操作
|
||
# 工具会自动显示所有参数
|
||
|
||
# 3. 按Ctrl+C停止
|
||
```
|
||
|
||
### 方法3: 使用browser_hook.js(推荐专业)
|
||
|
||
```javascript
|
||
// 1. 打开Console,运行hook脚本
|
||
|
||
// 2. 进行操作,查看实时捕获
|
||
|
||
// 3. 导出数据分析
|
||
window._exportCapturedRequests()
|
||
```
|
||
|
||
## 参数说明
|
||
|
||
### verifyFp / fp (设备指纹)
|
||
- **长度:** 约40字符
|
||
- **格式:** `verify_` 开头
|
||
- **特点:** 同一设备相对固定
|
||
- **生成位置:** 通常在主JS包中
|
||
- **搜索关键词:** `fingerprint`, `canvas`, `webgl`
|
||
|
||
### msToken (会话Token)
|
||
- **长度:** 约150+字符
|
||
- **格式:** Base64编码
|
||
- **特点:** 每次会话不同
|
||
- **生成位置:** Cookie或JS生成
|
||
- **搜索关键词:** `msToken`, `_signature`
|
||
|
||
### a_bogus (反爬虫签名)
|
||
- **长度:** 约80字符
|
||
- **格式:** Base64编码
|
||
- **特点:** 每个请求不同
|
||
- **生成位置:** 通常在webmssdk.js中
|
||
- **搜索关键词:** `bogus`, `sign`, `_webmsdk`
|
||
|
||
## 实战示例
|
||
|
||
### 示例1: 快速测试是否需要验签
|
||
|
||
```python
|
||
import requests
|
||
|
||
# 方法A: 只带Cookie
|
||
cookies = {'sessionid': 'xxx', ...}
|
||
response = requests.get(url, cookies=cookies)
|
||
|
||
# 方法B: 完整参数
|
||
params = {
|
||
'page': 1,
|
||
'verifyFp': 'xxx',
|
||
'msToken': 'xxx',
|
||
'a_bogus': 'xxx'
|
||
}
|
||
response = requests.get(url, params=params, cookies=cookies)
|
||
|
||
# 对比两种方法的响应,确定哪些参数是必需的
|
||
```
|
||
|
||
### 示例2: 提取JS中的签名算法
|
||
|
||
```bash
|
||
# 1. 在Sources标签中找到包含签名的JS文件
|
||
# 2. 格式化代码(点击左下角{})
|
||
# 3. 搜索关键词
|
||
Ctrl+F -> "a_bogus" 或 "sign" 或 "_webmsdk"
|
||
|
||
# 4. 设置断点
|
||
点击行号 -> 刷新页面 -> 单步调试
|
||
|
||
# 5. 查看调用栈
|
||
Call Stack 面板查看完整调用链
|
||
```
|
||
|
||
### 示例3: 使用execjs执行JS代码
|
||
|
||
```python
|
||
import execjs
|
||
import requests
|
||
from pathlib import Path
|
||
|
||
# 1. 提取JS代码(假设保存为sign.js)
|
||
js_code = Path('sign.js').read_text(encoding='utf-8')
|
||
|
||
# 2. 编译JS环境
|
||
ctx = execjs.compile(js_code)
|
||
|
||
# 3. 调用JS函数生成签名
|
||
url = "https://buyin.jinritemai.com/api/authorTradeData/getInstituteDarenData"
|
||
params = {'page': 1, 'pageSize': 20}
|
||
|
||
# 假设JS中有generateSign函数
|
||
a_bogus = ctx.call('generateSign', url, params)
|
||
|
||
# 4. 使用签名发送请求
|
||
params['a_bogus'] = a_bogus
|
||
response = requests.get(url, params=params)
|
||
print(response.json())
|
||
```
|
||
|
||
### 示例4: 使用Selenium获取参数
|
||
|
||
```python
|
||
from selenium import webdriver
|
||
from selenium.webdriver.common.by import By
|
||
import time
|
||
|
||
driver = webdriver.Chrome()
|
||
driver.get("https://buyin.jinritemai.com/...")
|
||
|
||
# 登录等操作...
|
||
|
||
# 执行JS获取参数
|
||
a_bogus = driver.execute_script("""
|
||
// 查找全局签名函数
|
||
if (window._webmsdk && window._webmsdk.sign) {
|
||
return window._webmsdk.sign(arguments[0]);
|
||
}
|
||
return null;
|
||
""", url)
|
||
|
||
print(f"a_bogus: {a_bogus}")
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 捕获不到请求?
|
||
|
||
**A:**
|
||
- 确保API接口名称正确
|
||
- 检查是否在页面加载完成后才触发操作
|
||
- 尝试手动刷新页面
|
||
|
||
### Q2: 参数生成算法找不到?
|
||
|
||
**A:**
|
||
- 使用全局搜索(Ctrl+Shift+F)
|
||
- 搜索多个关键词:`sign`, `bogus`, `token`, `encrypt`
|
||
- 查看网络请求的Initiator(发起者)
|
||
|
||
### Q3: 逆向的算法不工作?
|
||
|
||
**A:**
|
||
- 检查是否缺少依赖(如window对象、其他函数)
|
||
- 使用execjs时确保JS环境完整
|
||
- 对比浏览器执行结果和Python执行结果
|
||
|
||
### Q4: 参数总是变化怎么办?
|
||
|
||
**A:**
|
||
- 这是正常的,签名通常包含时间戳
|
||
- 使用真实浏览器环境(Selenium/Playwright)
|
||
- 或者完全逆向算法并在Python中实现
|
||
|
||
## 推荐方案
|
||
|
||
根据不同场景选择:
|
||
|
||
### 场景1: 偶尔抓取(推荐:Cookie方案)
|
||
```python
|
||
# 优点:简单稳定
|
||
# 缺点:需要定期更新Cookie
|
||
|
||
from core.api_client import ByteDanceAPIClient
|
||
client = ByteDanceAPIClient()
|
||
data = client.request('GET', '/api/...')
|
||
```
|
||
|
||
### 场景2: 频繁抓取(推荐:Playwright方案)
|
||
```python
|
||
# 优点:稳定可靠
|
||
# 缺点:需要浏览器环境
|
||
|
||
from playwright.sync_api import sync_playwright
|
||
with sync_playwright() as p:
|
||
browser = p.chromium.launch()
|
||
# ... 自动操作
|
||
```
|
||
|
||
### 场景3: 高性能抓取(推荐:完全逆向)
|
||
```python
|
||
# 优点:速度快
|
||
# 缺点:维护成本高
|
||
|
||
def generate_sign(url, params):
|
||
# 实现签名算法
|
||
pass
|
||
|
||
params['a_bogus'] = generate_sign(url, params)
|
||
response = requests.get(url, params=params)
|
||
```
|
||
|
||
## 法律声明
|
||
|
||
⚠️ **重要提示**
|
||
|
||
- 本工具仅用于学习和研究目的
|
||
- 使用前请确保遵守目标网站的服务条款
|
||
- 不要用于商业用途或恶意攻击
|
||
- 控制访问频率,避免对服务器造成负担
|
||
- 账号被封风险自负
|
||
|
||
## 技术支持
|
||
|
||
如有问题,请查看:
|
||
- `逆向分析指南.md` - 详细的逆向分析教程
|
||
- 项目主README - 基本使用说明
|
||
|
||
祝您逆向顺利!🎉
|
||
|