protocol-analysis
对 $ARGUMENTS 执行协议逆向分析。
MCP 依赖:
js-reverse-mcp— WebSocket 分析、请求发起栈追踪、JS 内执行android_proxy_mcp— HTTP/HTTPS 流量捕获与搜索(Android 场景)
协议类型识别
首先判断目标使用的协议类型:
| 特征 | 协议类型 | 后续处理 |
|---|---|---|
Content-Type: application/json |
REST JSON API | → Stage A |
Upgrade: websocket |
WebSocket | → Stage B |
Content-Type: application/grpc |
gRPC | → Stage C |
Content-Type: application/x-protobuf |
Protobuf | → Stage C |
| 请求体为不可读二进制 | 自定义二进制协议 | → Stage D |
Content-Type: application/x-www-form-urlencoded |
表单编码 | → Stage A |
Content-Type: multipart/form-data |
多部分表单 | → Stage A |
Stage A: HTTP REST API 分析
A.1 请求结构分析
Web 场景 (js-reverse-mcp):
1. list_network_requests → 列出所有请求
2. get_request_initiator(reqid) → 获取请求发起的 JS 调用栈
3. search_in_sources("api/v1") → 在 JS 中搜索 API 端点定义
Android 场景 (android_proxy_mcp):
1. traffic_list(domain="api.target.com") → 按域名筛选
2. traffic_get_detail(reqid) → 查看请求/响应头
3. traffic_read_body(reqid) → 读取请求/响应体
4. traffic_search("sign") → 搜索包含签名的请求
A.2 参数分析
对比分析:
1. 收集多次相同接口的请求
2. 对比哪些字段固定、哪些变化
3. 变化字段分类:
- 时间戳类(值递增,通常 10 或 13 位数字)
- 随机数类(每次不同,无规律)
- 签名类(固定长度 hex/Base64,值随其他参数变化)
- 会话类(相同会话内固定,换设备/登录变化)
A.3 签名还原
找到签名参数后,转到 find-crypto-entry skill 定位加密入口。
A.4 请求重放验证
import requests
# 构造请求
headers = {
"User-Agent": "...",
"X-Sign": sign(params),
"X-Timestamp": str(int(time.time())),
}
resp = requests.get("https://api.target.com/v1/feed", headers=headers, params=params)
print(resp.status_code, resp.json())
Stage B: WebSocket 协议分析
B.1 连接发现
1. get_websocket_messages() → 列出所有 WebSocket 连接
返回: wsId, url, 消息数量, 连接状态
2. get_websocket_messages(wsId) → 查看消息概览
返回: 消息模式分析、方向(发送/接收)、时间
3. search_in_sources("new WebSocket") → 找到 WS 创建代码
B.2 消息格式识别
| 格式 | 识别方法 | 处理方式 |
|---|---|---|
| JSON | 可直接解析 | 直接分析字段含义 |
| 二进制 + JSON | 前几个字节是头部,后续是 JSON | 分析头部结构(消息类型/长度) |
| Protobuf | 二进制 + 字段编号 | → Stage C |
| 自定义二进制 | 不可读 | → Stage D |
| 文本协议 | 纯文本,有分隔符 | 分析分隔符和字段格式 |
B.3 消息追踪
1. 在 WebSocket.send 处设断点:
set_breakpoint_on_text(".send(")
2. 触发操作 → 断点命中 → evaluate_script 检查:
- 发送的消息内容
- 消息是如何构造的
- 是否有序列号/心跳机制
3. 在 onmessage 处设断点:
set_breakpoint_on_text("onmessage")
→ 分析接收到的消息如何被处理
B.4 心跳与认证
常见模式:
- 连接后发送认证消息(含 token/签名)
- 定时心跳(ping/pong 或自定义心跳包)
- 消息序列号(递增 ID)
- 订阅/取消订阅机制
Stage C: gRPC / Protobuf 分析
C.1 Protobuf 结构还原
方式 A: 有 .proto 文件
直接使用 protoc 编译生成代码
方式 B: 从二进制推断(无 .proto)
1. 安装 protobuf 工具:
pip install protobuf blackboxprotobuf
2. 使用 blackboxprotobuf 自动推断:
import blackboxprotobuf
message, typedef = blackboxprotobuf.decode_message(binary_data)
print(message) # 推断的字段结构
print(typedef) # 推断的类型定义
3. 手工还原 .proto:
根据推断结果编写 proto 文件
C.2 Protobuf 字段类型速查
| Wire Type | 类型 | 字段 |
|---|---|---|
| 0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
| 1 | 64-bit | fixed64, sfixed64, double |
| 2 | Length-delimited | string, bytes, embedded messages, repeated |
| 5 | 32-bit | fixed32, sfixed32, float |
C.3 gRPC 调用重放
# 使用 grpcurl 测试
# grpcurl -d '{"field": "value"}' -plaintext host:port package.Service/Method
# Python gRPC 客户端
import grpc
channel = grpc.insecure_channel('host:port')
# 无 .proto 时,用反射
from grpc_reflection.v1alpha import reflection_pb2_grpc
stub = reflection_pb2_grpc.ServerReflectionStub(channel)
# 通过反射获取服务列表和消息类型
Stage D: 自定义二进制协议分析
D.1 数据采集
收集多组请求/响应的原始二进制数据。
D.2 格式推断
分析步骤:
1. Hex 对比多组数据
2. 识别固定头部(magic number / 版本号)
3. 识别长度字段(通常在前 4-8 字节)
4. 识别消息类型字段
5. 推断字段边界和编码方式
常见结构:
[Magic 2B] [Version 1B] [Type 2B] [Length 4B] [Body NB] [Checksum 2B]
D.3 字段编码识别
| 特征 | 编码方式 |
|---|---|
| 前缀长度 + 数据 | Length-prefixed |
| 固定宽度 | Fixed-width fields |
| 0x00 结尾 | Null-terminated strings |
| TLV 结构 (Type-Length-Value) | 可扩展协议 |
| 大端序(高位在前) | 网络字节序 |
| 小端序(低位在前) | x86 原生序 |
D.4 动态分析辅助
JS 场景:
1. 在 ArrayBuffer / DataView 的构造处设断点
2. 追踪 setUint32 / setUint16 等调用序列
3. 还原二进制构造逻辑
Android 场景:
1. Frida hook ByteBuffer / DataOutputStream
2. 追踪序列化过程
反模式
- 不要假设 JSON 就是 REST — 有些协议用 JSON over WebSocket,或 JSON-RPC。先确认传输层。
- 不要忽略请求顺序 — 某些 API 需要先调用初始化接口获取 session,再调用业务接口。
- 不要只分析单次请求 — 对比多次请求才能区分固定字段和动态字段。
- 不要手动解析 Protobuf — 优先用
protoc --decode_raw或blackboxprotobuf,手工解析容易出错。
完成标准
协议分析结果:
- 目标:$ARGUMENTS
- 协议类型:[REST API | WebSocket | gRPC | Protobuf | 自定义二进制]
- 请求格式:[详细字段说明]
- 签名/加密:[算法 + 密钥来源]
- 认证方式:[Token | Cookie | 签名 | 证书]
- Python 重放脚本:output/api_client.py(已验证)
- 验证结果:请求成功 + 业务数据返回
References
| 文件 | 何时读取 |
|---|---|
references/protobuf-reverse.md |
Protobuf 二进制格式详解和手工还原技巧 |
references/websocket-analysis.md |
WebSocket 协议分析模式和常见框架(Socket.io/SignalR) |