This repository has been archived on 2026-05-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
obsidian/CS/TOOLS/网络抓包.md
T
2026-04-20 22:47:51 +08:00

577 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [network, tools, whistle, packet-capture, proxy]
create time: 2026-04-17 12:20
---
# 网络抓包
## 概述
网络抓包是调试和分析网络请求的核心技术。本文档以 whistle 支持的抓包功能为核心,介绍网络请求的抓取、分析、修改和重放方法。
理论性的协议分析内容请参考 [[CS/NET/网络协议分析基础]]。
## 正文
### 代理状态下的网络请求流程
在配置代理后,网络请求会经过代理服务器转发。以下是完整的请求流程:
```mermaid
sequenceDiagram
participant Client as 客户端 (浏览器/应用)
participant Proxy as 代理服务器 (Whistle)
participant Target as 目标服务器
%% 1. 客户端发起请求
Client->>Proxy: ✅ 1. 发起 HTTP/HTTPS 请求
Note over Client,Proxy: URL: https://api.example.com/data<br/>Method: GET<br/>Headers: {...}
%% 2. 代理接收并解析
Proxy->>Proxy: 🔍 2. 接收请求并解析
Note over Proxy: 检查规则匹配<br/>- 规则: reqHeaders?<br/>- 规则: resBody?<br/>- 规则: 映射?
%% 分支: 是否有转发规则
alt 有转发规则
Proxy->>Proxy: 📝 3. 应用转发规则
Note over Proxy: 执行修改操作<br/>- 修改请求头<br/>- 替换域名<br/>- 重写路径
end
%% 分支: HTTPS 请求
alt HTTPS 请求
Proxy->>Proxy: 🔒 4. SSL/TLS 握手
Note over Proxy: - 代理充当中间人<br/>- 使用自签名证书<br/>- 解密请求内容
end
%% 3. 代理转发请求
Proxy->>Target: ⬆️ 5. 转发请求到目标服务器
Note over Proxy,Target: 处理后的请求<br/>Header + Body
%% 4. 目标服务器处理
Target->>Target: ⚙️ 6. 处理请求
Note over Target: 业务逻辑处理<br/>生成响应数据
%% 5. 目标服务器返回响应
Target-->>Proxy: ⬇️ 7. 返回响应
Note over Target,Proxy: Status: 200<br/>Headers: {...}<br/>Body: {...}
%% 6. 代理接收并记录
Proxy->>Proxy: 💾 8. 接收并记录响应
Note over Proxy: - 记录到抓包列表<br/>- 计算耗时<br/>- 保存完整信息
%% 分支: 是否有响应修改规则
alt 有响应修改规则
Proxy->>Proxy: 🎭 9. 应用响应规则
Note over Proxy: - 修改响应头<br/>- 替换响应体<br/>- 修改状态码<br/>- Mock 数据
end
%% 7. 代理转发响应
Proxy-->>Client: ✅ 10. 返回响应给客户端
Note over Proxy,Client: 最终的响应数据<br/>Client 可以正常处理
%% 循环: 请求重放
rect rgba(0, 255, 0, 0.1)
Client->>Proxy: 🔄 11. 重放请求 (可选)
Proxy->>Client: 📤 12. 返回重放结果
Note over Client,Proxy: 复现 Bug<br/>接口调试<br/>压力测试
end
```
**流程说明:**
1. **请求发起**: 客户端(浏览器或应用)向配置的代理服务器发送请求
2. **代理解析**: 代理服务器接收请求,解析 URL、方法、头部等信息
3. **规则匹配**: 代理检查配置的转发规则,包括请求/响应修改、域名映射等
4. **HTTPS 处理**: 对于 HTTPS 请求,代理通过中间人模式解密和重新加密请求
5. **转发请求**: 代理将处理后的请求转发到目标服务器
6. **响应处理**: 目标服务器处理请求并返回响应
7. **记录数据**: 代理记录完整的请求/响应信息到抓包列表
8. **应用规则**: 如果配置了响应修改规则,代理会修改响应内容
9. **返回响应**: 代理将最终响应返回给客户端
10. **请求重放**: 可以对已记录的请求进行重放,用于调试和测试
**Whistle 的核心作用:**
- 🔍 **可见性**: 记录所有经过代理的请求
- 🎭 **可控性**: 可以修改和重放请求
- 🔄 **灵活性**: 支持域名映射和数据 Mock
- 📊 **调试性**: 提供详细的请求/响应分析
### Whistle 工具介绍
#### 为什么选择 Whistle
Whistle 是一款基于 HTTP 代理的跨平台调试工具,相比传统抓包工具具有以下优势:
- 跨平台支持 (Windows, Mac, Linux)
- 内置抓包功能,支持 HTTP/HTTPS
- 便捷的请求修改和重放
- 支持域名映射、远程调试
- 界面友好,操作简单
- 支持插件扩展
- 配置灵活,规则强大
#### 安装与启动
```bash
# 全局安装
npm install -g whistle
# 启动服务
w2 start
# 启动指定端口
w2 start -p 8899
# 停止服务
w2 stop
# 重启服务
w2 restart
```
![[Pasted image 20260417125039.png]]
![[Pasted image 20260417125713.png]]
**访问界面:**
- 默认地址: http://127.0.0.1:8899
- 默认账号: whistle (首次安装无密码)
#### 代理配置
**命令行配置:**
```bash
# Mac/Linux
export http_proxy=http://127.0.0.1:8899
export https_proxy=http://127.0.0.1:8899
# Windows
set http_proxy=http://127.0.0.1:8899
set https_proxy=http://127.0.0.1:8899
```
**系统代理配置:**
1. 打开系统网络设置
2. 配置 HTTP/HTTPS 代理为 127.0.0.1:8899
3. 应用并保存
**手机代理配置:**
1. 确保手机和电脑在同一局域网
2. 查看电脑 IP 地址 (如 192.168.1.100)
3. 手机 WiFi 设置中配置代理:
- 服务器: 192.168.1.100
- 端口: 8899
4. 浏览器访问 https://rootca.pro 安装信任证书
### 核心功能
#### 1. 抓包查看
**功能特性:**
- 显示所有 HTTP/HTTPS 请求
- 显示请求/响应头和内容
- 支持 WebSocket 抓包
- 支持长连接和断点续传
- 按域名、状态码、方式筛选
**界面说明:**
- **请求列表**: 显示所有请求的摘要信息 (URL、方法、状态码、耗时)
- **请求详情**: 点击请求查看完整信息 (请求头、响应头、请求体、响应体)
- **时间线**: 显示请求的时间顺序和耗时
- **统计**: 显示请求总数、成功数、失败数等统计信息
#### 2. 请求修改
**修改方法:**
1. **Values 方式 (规则面板)**:
```
# 修改请求头
example.com reqHeaders://{test}
# 在 Values 中定义变量
test:
x-custom-header: custom-value
x-another-header: another-value
```
2. **正则匹配修改**:
```
# 修改所有匹配的请求
/^https:\/\/example\.com\/(.*)/ reqHeaders://{test}
```
3. **修改请求体**:
```
example.com reqBody://{test-body}
# Values
test-body:
{"modified": "data"}
```
4. **修改响应**:
```
# 修改响应头
example.com resHeaders://{test-res}
# 修改响应体
example.com resBody://{test-body}
# 修改响应状态码
example.com statusCode://404
```
#### 3. 请求重放
**功能作用:**
- 复现问题 bug
- 压力测试
- 接口调试
- 自动化脚本测试
**操作步骤:**
1. 在请求列表中选择要重放的请求
2. 点击"重放"按钮
3. 选择重放次数
4. 开始重放
**批量重放:**
- 支持选中多个请求批量重放
- 支持导出请求列表为脚本
- 支持自定义重放间隔
#### 4. 域名映射
**本地开发映射:**
```
# 映射到本地服务
api.example.com 127.0.0.1:3000
# 映射到远程服务
api.example.com www.test-api.com
# 路径映射
example.com/api local.path/to/api
```
**多环境切换:**
```
# 开发环境
dev.example.com api-dev.example.com
# 测试环境
test.example.com api-test.example.com
# 生产环境
prod.example.com api.example.com
```
#### 5. 接口 Mock
**数据 Mock:**
```
# Mock 接口响应
api.example.com/user/info resBody://{mock-user}
# Values 中定义 Mock 数据
mock-user:
{
"code": 200,
"data": {
"name": "测试用户",
"age": 25,
"avatar": "https://example.com/avatar.png"
},
"message": "success"
}
```
**Mock 模板:**
```
# 文件 Mock
api.example.com/list resBody://{./mock/list.json}
# 使用 mockjs 语法
api.example.com/list resBody://{./mock/list.js}
```
### 高级用法
#### 1. Bypass 跳过代理
**配置跳过规则:**
```
# 跳过特定域名
www.google.com bypass://*
# 跳过 IP 地址
192.168.1.100 bypass://*
# 跳过本地地址
192.168.* bypass://*
10.* bypass://*
```
#### 2. 插件使用
**常用插件:**
```
# 安装插件
w2 install whot
# 使用插件
example.com whot://
# 查看插件
w2 list
```
#### 3. WebSocket 调试
**WebSocket 抓包:**
1. 在网络列表中找到 WebSocket 请求
2. 点击查看连接详情
3. 实时查看发送和接收的消息
4. 支持文本和二进制消息
#### 4. HTTPS 处理
**自签名证书概念:**
**什么是自签名证书?**
自签名证书是指不由受信任的证书颁发机构(CA,如 DigiCert、Let's Encrypt 等)签发的 SSL/TLS 证书,而是由服务器自己生成并签名的证书。
**与传统证书的区别:**
| 特性 | 受信任证书 | 自签名证书 |
|------|------------|------------|
| **签发者** | 受信任的 CA 机构 | 服务器自己 |
| **浏览器信任** | ✅ 自动信任 | ❌ 警告不安全 |
| **成本** | 付费(免费付费都有) | 免费 |
| **验证流程** | CA 验证身份 | 无验证 |
| **适用场景** | 生产环境、对外服务 | 开发测试、内网代理 |
**为什么代理抓包需要自签名证书?**
在 HTTPS 抓包中,代理服务器使用自签名证书的原理:
```mermaid
flowchart TD
subgraph 正常HTTPS流程
A1[客户端] -->|建立加密连接| B1[目标服务器]
B1 -->|发送官方证书<br>由CA签发| A1
A1 -->|验证CA信任| B1
end
subgraph 代理抓包流程
A2[客户端] -->|建立加密连接| B2[代理服务器]
B2 -->|发送自签名证书<br>代理自己签发| A2
A2 -->|❓ 证书无效?|
A2 -->|⚠️ 需要手动信任| C{是否信任代理证书}
C -->|是| B2
C -->|否| D[连接失败]
B2 -->|解密查看内容| E[代理检查内容<br/>应用修改规则]
E -->|重新加密| B2
B2 -->|转发到真实服务器| F[目标服务器]
F -->|响应| B2
B2 -->|返回给客户端| A2
end
```
**代理使用自签名证书的原因:**
1. **中间人攻击(MITM)的本质**:
- HTTPS 的目的是防止中间人攻击
- 代理抓包本质上就是"合法的中间人"
- 需要解密 HTTPS 流量才能查看和修改
2. **无法动态生成官方证书**:
- 代理无法为每个域名申请真实证书
- 代理需要处理成千上万个不同域名的请求
- 自签名证书是最灵活的解决方案
3. **时间成本和工作效率**:
- 为每个抓包域名单独申请证书不现实
- 自签名证书可以立即生成和使用
**Whistle 证书工作原理:**
```
1. 用户访问 https://api.example.com
↓
2. Whistle 拦截请求
↓
3. Whistle 为 api.example.com 动态生成自签名证书
(证书上的域名是 api.example.com)
↓
4. Whistle 将此证书发送给浏览器
↓
5. 浏览器识别出这不是受信任的 CA 签发的证书
(因为根证书不在浏览器信任列表中)
↓
6. 如果用户手动导入了 Whistle 的根证书并信任
↓
7. 浏览器信任该证书,连接建立成功
↓
8. Whistle 可以解密并查看 HTTPS 内容
```
**信任证书:**
1. 访问 https://rootca.pro 下载证书
2. 安装到系统信任根证书
3. 移动端需要额外配置
**SSL Pinning 绕过:**
- 开发环境可以关闭 SSL Pinning
- 使用测试证书配置
- 使用移动端调试工具 (如 Frida)
### 实践场景
#### 场景 1: 前端开发调试
**需求:**
- 查看接口请求和响应
- 修改接口数据进行测试
- Mock 接口用于前端开发
**配置:**
```
# 查看接口日志
api.example.com log://
# 修改接口响应
api.example.com resBody://{mock-data}
# 映射到本地服务
api.example.com 127.0.0.1:8080
```
#### 场景 2: 移动端开发调试
**需求:**
- 抓取手机应用的网络请求
- 查看和修改接口数据
- 解决跨域问题
**配置:**
```
# 启用 CORS
api.example.com resCors:// *
# 允许所有域
api.example.com reqHeaders://{test}
test:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
```
#### 场景 3: 接口测试和压测
**需求:**
- 重复某接口的请求
- 测试并发请求
- 验证接口性能
**操作:**
1. 选择目标接口
2. 点击"重放" → "多次重放"
3. 设置重放次数和间隔
4. 查看结果和统计
#### 场景 4: 问题复现
**需求:**
- 在本地复现线上问题
- 使用线上数据调试
- 分离前端和后端问题
**配置:**
```
# 使用线上接口,本地前端
localhost:8080/api online.example.com/api
# 使用本地接口,线上前端
www.example.com/api 127.0.0.1:8080/api
```
### 常见问题
#### 1. 抓不到 HTTPS 请求
**解决方法:**
- 确认已安装并信任根证书
- 检查系统代理是否配置正确
- 重启浏览器和应用
- 清除浏览器缓存
#### 2. 证书不信任
**解决方法:**
- Windows: 安装到"受信任的根证书颁发机构"
- Mac: 安装钥匙串并设置为"始终信任"
- 移动端: 进入设置 → 通用 → 关于本机 → 证书信任设置
#### 3. 代理配置后无法上网
**解决方法:**
- 检查 whistle 是否启动
- 确认代理地址和端口正确
- 检查防火墙设置
- 尝试使用 bypass:// 规则
#### 4. 规则不生效
**排查步骤:**
1. 检查规则语法是否正确
2. 确认规则没有冲突
3. 查看规则优先级
4. 使用 log:// 查看匹配情况
### 最佳实践
#### 1. 规则组织
```
# 按功能分类
# ----- 本地开发 -----
api-dev.example.com 127.0.0.1:3000
static-dev.example.com 127.0.0.1:8080
# ----- 测试环境 -----
api-test.example.com test-api.example.com
# ----- Mock 数据 -----
api.example.com/user resBody://{./mock/user.json}
api.example.com/list resBody://{./mock/list.json}
# ----- 特殊规则 -----
google.com bypass://*
```
#### 2. 性能优化
- 及时清理过多的抓包记录
- 使用过滤器只关注相关请求
- 对于高流量场景使用 bypass:// 规则
#### 3. 安全建议
- 不要在公共WiFi下使用代理抓包
- 及时清理缓存中的敏感信息
- 不要在生产环境使用长时间的代理
- 定期备份重要的配置和规则
## 关联笔记
- [[CS/NET/网络协议分析基础]]
- [[CS/SECURITY/网络安全基础]]
- [[DEV/DEBUG/调试技巧总结]]
## 参考资源
- Whistle 官方文档: https://wproxy.org/whistle/
- Whistle GitHub: https://github.com/avwo/whistle