1. 为什么选择mitmproxy进行网络抓包
在macOS环境下进行HTTP/HTTPS流量分析时,mitmproxy凭借其独特的优势成为我的首选工具。与Wireshark这类底层抓包工具不同,mitmproxy工作在应用层,专门针对HTTP/HTTPS协议设计,提供了更直观的交互界面和更丰富的功能特性。
我最初接触这个工具是在调试一个复杂的API调用链时,当时需要精确分析请求头和响应体的变化过程。传统的打印日志方式效率低下,而mitmproxy的实时拦截和修改功能完美解决了这个问题。它不仅能捕获HTTPS流量(这在其他工具中往往需要复杂的证书配置),还能以中间人(MITM)方式动态修改请求/响应。
2. 环境准备与基础配置
2.1 安装mitmproxy
在macOS上安装mitmproxy有多种方式,我推荐使用Homebrew进行安装:
bash复制brew install mitmproxy
这会同时安装三个组件:mitmproxy(命令行交互界面)、mitmdump(类似tcpdump的命令行工具)和mitmweb(基于Web的图形界面)。
注意:如果遇到证书相关错误,可能需要先更新Homebrew本身(brew update)或检查Xcode命令行工具是否已安装。
2.2 证书配置关键步骤
要让mitmproxy能够解密HTTPS流量,必须在系统中安装其CA证书:
- 启动mitmproxy:
mitmproxy - 在终端访问http://mitm.it
- 选择"macOS"图标下载证书
- 双击证书文件,在"钥匙串访问"中找到该证书
- 右键选择"显示简介" → "信任" → 将"使用此证书时"设为"始终信任"
我遇到过的一个典型问题是:即使安装了证书,某些应用(如Chrome)仍然会报证书错误。这是因为:
- Chrome使用了自己的证书存储
- 某些应用启用了证书固定(Certificate Pinning)
解决方法:
bash复制# 对于Chrome,启动时需要添加参数
open -a Google\ Chrome --args --ignore-certificate-errors
3. 核心功能实战演示
3.1 基础抓包操作
启动监听(默认端口8080):
bash复制mitmproxy -p 8080
配置系统或浏览器使用代理:
- 系统级:系统偏好设置 → 网络 → 高级 → 代理 → HTTP/HTTPS代理填127.0.0.1:8080
- 浏览器级:推荐使用SwitchyOmega等插件管理
在mitmproxy界面中:
- 方向键上下移动
- Enter查看详情
- q返回上级
- f过滤请求(如
~u baidu过滤百度相关请求)
3.2 高级过滤技巧
mitmproxy支持强大的过滤表达式:
bash复制# 只显示POST请求且包含"login"的URL
mitmproxy -p 8080 -f "~m POST & ~u login"
# 过滤特定域名的JSON响应
mitmproxy -p 8080 -f "~d example.com & ~t json"
我常用的过滤组合:
~a:只显示包含指定Accept头部的请求~b:按响应体内容过滤~c 404:按状态码过滤~q:只显示请求中包含指定参数的
3.3 请求/响应修改实战
通过编写Python脚本实现自动化修改(保存为modify.py):
python复制def request(flow):
if "example.com" in flow.request.url:
flow.request.headers["X-My-Header"] = "modified"
def response(flow):
if flow.response.status_code == 404:
flow.response.status_code = 200
flow.response.content = b"Custom 404 Page"
启动时加载脚本:
bash复制mitmproxy -s modify.py
4. 移动设备抓包全攻略
4.1 Android设备配置
- 确保电脑和手机在同一网络
- 在手机WiFi设置中配置手动代理:
- 主机:电脑的局域网IP
- 端口:8080
- 手机浏览器访问http://mitm.it下载安装证书
- 对于Android 7+,还需要:
bash复制# 将证书移动到系统证书目录 adb push ~/.mitmproxy/mitmproxy-ca-cert.cer /system/etc/security/cacerts/ adb shell chmod 664 /system/etc/security/cacerts/mitmproxy-ca-cert.cer
4.2 iOS设备配置
- 类似Android配置WiFi代理
- 访问http://mitm.it安装证书
- 进入设置 → 通用 → 关于 → 证书信任设置 → 启用mitmproxy证书
关键点:iOS应用默认不信任用户安装的证书,需要额外配置ATS例外或修改应用的Info.plist
5. 企业级应用抓包技巧
5.1 处理证书固定(Certificate Pinning)
当遇到类似银行类应用时,常规方法会失败。解决方案:
- 使用Frida进行动态注入:
javascript复制// frida脚本绕过证书检查 Java.perform(function() { var CertificatePinner = Java.use("okhttp3.CertificatePinner"); CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function() { console.log("Bypassing certificate pinning"); }; }); - 启动组合命令:
bash复制
frida -U -f com.target.app -l bypass.js --no-pause mitmproxy -p 8080
5.2 处理WebSocket流量
mitmproxy完美支持WebSocket:
python复制def websocket_message(flow):
if flow.websocket:
last_message = flow.websocket.messages[-1]
if last_message.from_client:
print("Client sent:", last_message.content)
else:
print("Server sent:", last_message.content)
6. 性能优化与高级技巧
6.1 流量存储与回放
保存流量到文件:
bash复制mitmdump -w traffic.mitm
回放流量:
bash复制mitmdump -n -r traffic.mitm
我常用的分析组合:
bash复制# 统计所有请求的域名分布
mitmdump -nr traffic.mitm -s 'print(flow.request.host)' | sort | uniq -c | sort -nr
# 提取所有图片到本地
mitmdump -nr traffic.mitm -s 'if flow.response.headers.get("content-type","").startswith("image/"): open(f"/tmp/images/{flow.request.path.split("/")[-1]}","wb").write(flow.response.content)'
6.2 与其他工具集成
结合Charles对比分析:
- 在Charles中设置上游代理为mitmproxy
- 利用Charles的Map Remote功能
- 使用mitmproxy做精细修改
结合Postman自动化测试:
bash复制# 将捕获的请求导出为Postman集合
mitmdump -ns export_postman.py -r traffic.mitm
7. 企业级部署方案
7.1 透明代理模式
对于需要监控整个网络流量的场景:
bash复制# 启用透明代理
mitmproxy -T --host
配合pfctl设置流量重定向:
bash复制echo "rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8080" | sudo pfctl -ef -
7.2 多用户协作方案
使用mitmproxy的API模式:
python复制from mitmproxy import http, options
from mitmproxy.tools.dump import DumpMaster
class Addon:
def request(self, flow: http.HTTPFlow):
flow.request.headers["X-Proxy-User"] = "analyst1"
addons = [Addon()]
opts = options.Options(listen_port=8080, mode="upstream:http://parent-proxy:8080")
m = DumpMaster(opts)
m.addons.add(addons)
m.run()
8. 安全防护与隐私考虑
8.1 敏感信息过滤
自动屏蔽敏感数据:
python复制def response(flow):
if flow.response.headers.get("content-type","").startswith("application/json"):
import json
try:
data = json.loads(flow.response.text)
if "password" in data:
data["password"] = "***REDACTED***"
flow.response.text = json.dumps(data)
except:
pass
8.2 合规使用建议
- 仅用于调试自有应用或授权测试
- 企业部署需明确告知员工
- 定期清理捕获的日志
- 对捕获的敏感数据加密存储
9. 疑难问题解决方案
9.1 常见错误排查
问题1:客户端报"证书无效"
- 检查证书是否安装到正确位置
- 确认系统时间正确
- 尝试重启客户端应用
问题2:无法捕获某些应用的流量
- 检查应用是否使用了自己的证书存储
- 确认应用没有使用证书固定
- 尝试使用透明代理模式
9.2 性能问题优化
当处理高流量时:
bash复制# 禁用不必要的功能提升性能
mitmproxy -p 8080 --no-http2 --no-websocket --tcp-hosts ""
内存优化配置:
bash复制mitmproxy -p 8080 --stream-larger-than 1m
10. 实际案例分享
10.1 调试OAuth2.0流程
通过mitmproxy捕获的完整OAuth流程:
- 客户端 → 授权端点(携带client_id等)
- 重定向到登录页面
- 用户认证后返回授权码
- 客户端用授权码换取访问令牌
典型问题诊断:
- 检查state参数是否匹配
- 验证PKCE代码挑战是否正确
- 确认令牌端点返回的scope符合预期
10.2 分析第三方SDK行为
某次发现应用启动时会向不明地址发送数据:
- 通过
~d过滤出所有第三方域名 - 发现某个analytics服务收集了过多信息
- 编写拦截脚本屏蔽该域名
python复制def request(flow):
if "unwanted-tracker.com" in flow.request.url:
flow.response = http.Response.make(204)