Perform protocol reverse engineering on $ARGUMENTS .
MCP dependencies:
js-reverse-mcp— WebSocket analysis, request initiation stack tracing, in-JS executionandroid_proxy_mcp— HTTP/HTTPS traffic capture and search (Android scenario)
Protocol type identification
First determine the protocol type used by the target:
| Feature | Protocol type | Subsequent handling |
|---|---|---|
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 |
| Request body is unreadable binary | Custom binary protocol | → Stage D |
Content-Type: application/x-www-form-urlencoded |
Form encoding | → Stage A |
Content-Type: multipart/form-data |
Multipart form | → Stage A |
Stage A: HTTP REST API analysis
A.1 Request structure analysis
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 Parameter analysis
对比分析:
1. 收集多次相同接口的请求
2. 对比哪些字段固定、哪些变化
3. 变化字段分类:
- 时间戳类(值递增,通常 10 或 13 位数字)
- 随机数类(每次不同,无规律)
- 签名类(固定长度 hex/Base64,值随其他参数变化)
- 会话类(相同会话内固定,换设备/登录变化)
A.3 Signature restoration
After finding the signature parameters, move to the find-crypto-entry skill to locate the encryption entry point.
A.4 Request replay verification
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 protocol analysis
B.1 Connection discovery
1. get_websocket_messages() → 列出所有 WebSocket 连接
返回: wsId, url, 消息数量, 连接状态
2. get_websocket_messages(wsId) → 查看消息概览
返回: 消息模式分析、方向(发送/接收)、时间
3. search_in_sources("new WebSocket") → 找到 WS 创建代码
B.2 Message format identification
| Format | Identification method | Handling method |
|---|---|---|
| JSON | Can be parsed directly | Directly analyze field meanings |
| Binary + JSON | The first few bytes are the header, followed by JSON | Analyze the header structure (message type/length) |
| Protobuf | Binary + field numbers | → Stage C |
| Custom binary | Unreadable | → Stage D |
| Text protocol | Plain text, with delimiters | Analyze delimiters and field format |
B.3 Message tracing
1. 在 WebSocket.send 处设断点:
set_breakpoint_on_text(".send(")
2. 触发操作 → 断点命中 → evaluate_script 检查:
- 发送的消息内容
- 消息是如何构造的
- 是否有序列号/心跳机制
3. 在 onmessage 处设断点:
set_breakpoint_on_text("onmessage")
→ 分析接收到的消息如何被处理
B.4 Heartbeat and authentication
常见模式:
- 连接后发送认证消息(含 token/签名)
- 定时心跳(ping/pong 或自定义心跳包)
- 消息序列号(递增 ID)
- 订阅/取消订阅机制
Stage C: gRPC / Protobuf analysis
C.1 Protobuf structure restoration
方式 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 field types quick reference
| Wire Type | Type | Field |
|---|---|---|
| 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 call replay
# 使用 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: Custom binary protocol analysis
D.1 Data collection
Collect multiple sets of raw binary data from requests/responses.
D.2 Format inference
分析步骤:
1. Hex 对比多组数据
2. 识别固定头部(magic number / 版本号)
3. 识别长度字段(通常在前 4-8 字节)
4. 识别消息类型字段
5. 推断字段边界和编码方式
常见结构:
[Magic 2B] [Version 1B] [Type 2B] [Length 4B] [Body NB] [Checksum 2B]
D.3 Field encoding identification
| Feature | Encoding method |
|---|---|
| Prefix length + data | Length-prefixed |
| Fixed width | Fixed-width fields |
| Terminated by 0x00 | Null-terminated strings |
| TLV structure (Type-Length-Value) | Extensible protocol |
| Big-endian (high byte first) | Network byte order |
| Little-endian (low byte first) | x86 native order |
D.4 Dynamic analysis assistance
JS 场景:
1. 在 ArrayBuffer / DataView 的构造处设断点
2. 追踪 setUint32 / setUint16 等调用序列
3. 还原二进制构造逻辑
Android 场景:
1. Frida hook ByteBuffer / DataOutputStream
2. 追踪序列化过程
Anti-patterns
- Do not assume JSON means REST — some protocols use JSON over WebSocket, or JSON-RPC. First confirm the transport layer.
- Do not ignore request order — some APIs require first calling an initialization interface to obtain a session, then calling business interfaces.
- Do not analyze only a single request — comparing multiple requests is the only way to distinguish fixed fields from dynamic fields.
- Do not parse Protobuf manually — prioritize using
protoc --decode_raworblackboxprotobufManual parsing is prone to errors.
Completion criteria
协议分析结果:
- 目标:$ARGUMENTS
- 协议类型:[REST API | WebSocket | gRPC | Protobuf | 自定义二进制]
- 请求格式:[详细字段说明]
- 签名/加密:[算法 + 密钥来源]
- 认证方式:[Token | Cookie | 签名 | 证书]
- Python 重放脚本:output/api_client.py(已验证)
- 验证结果:请求成功 + 业务数据返回
References
| File | When to read |
|---|---|
references/protobuf-reverse.md |
Detailed explanation of the Protobuf binary format and manual restoration techniques |
references/websocket-analysis.md |
WebSocket protocol analysis patterns and common frameworks (Socket.io/SignalR) |