第18章 mitmproxy:抓包、改包、脚本化调试

学习目标

  • 掌握 mitmproxy 三件套(mitmproxy/mitmweb/mitmdump)与五种工作模式
  • 用它拦截、查看、修改 HTTPS 明文流量,做 API 调试与移动端抓包
  • 用 Python addon 脚本化改包:自动改请求头、篡改响应、Mock
  • 理解它与 tcpdump 的分工:一个看应用层明文,一个看字节

前置知识


原理

定位:开发者的 HTTPS 调试神器

第17章 的 SSL Bump 是"企业审计"视角的 MITM;mitmproxy 是**"开发调试"视角的同一技术。它是一个交互式的中间人代理,让你能实时看到、修改、重放** HTTPS 流量——调 API、抓移动端、做安全测试的利器。

三件套

工具形态用途
mitmproxy终端 TUI交互式查看/拦截,键盘操作
mitmweb浏览器 Web UI可视化,适合不熟终端的人
mitmdump命令行(类 tcpdump)脚本化、自动化、CI

五种工作模式

regular(默认)  :标准正向代理,客户端配 proxy(第01章)
transparent     :透明代理,配 iptables 劫持(第11章)
reverse         :反向代理,固定转发到某后端(调试线上服务)
upstream        :串联到上游代理(代理链)
socks5          :作为 SOCKS5 代理(第06章)

MITM 原理回顾(来自第05章)

mitmproxy 能看 HTTPS 明文,靠的是 第05章 的 MITM:

客户端 ──CONNECT example.com:443──▶ mitmproxy
        ◀── mitmproxy 用自己的 CA 现签一张 example.com 证书 ──
客户端 ══TLS(信任了 mitm CA)══▶ mitmproxy(解密看明文)══真TLS══▶ example.com

铁律:客户端必须信任 mitmproxy 的 CA(首次运行生成在 ~/.mitmproxy/)。不装 CA 就会证书报错——这正是 第05章 强调的 MITM 安全边界。HSTS 和证书锁定的 App 抓不到,是正常的安全机制。

脚本化:addon 的请求/响应钩子

mitmproxy 用 Python addon 在流量经过时插入逻辑——本质是给代理装"可编程 filter"(呼应 第30章):

# 几个核心钩子,按流量阶段触发
def request(flow):   # 请求即将发往服务器前
    ...
def response(flow):  # 响应从服务器返回后
    ...

flow.request / flow.response 可读可改——改头、改体、改状态码、Mock 整个响应,全在几行 Python 里。


️ 实现 / 命令

实验一:起 mitmproxy 看 HTTPS 明文

mitmproxy --listen-port 8080            # 启动 TUI

# 另一终端:装 CA 后走它(演示用)
curl -x http://127.0.0.1:8080 \
     --cacert ~/.mitmproxy/mitmproxy-ca-cert.pem \
     https://httpbin.org/get
# mitmproxy 界面里实时出现这条请求,按回车可看完整明文请求/响应

实验二:mitmdump 脚本自动改包

# addon.py —— 给所有请求加一个头,把响应里的 foo 替换成 bar
def request(flow):
    flow.request.headers["X-Debug"] = "mitm"          # 注入请求头

def response(flow):
    if flow.response.text:
        flow.response.text = flow.response.text.replace("foo", "bar")  # 篡改响应体
mitmdump -s addon.py --listen-port 8080
# 此后所有经过的请求被加头、响应被替换——可用于调试、Mock、注入测试

实验三:Mock 一个接口(不碰真后端)

# 拦截特定路径,直接返回伪造响应,根本不发往后端
from mitmproxy import http

def request(flow):
    if flow.request.path == "/api/user":
        flow.response = http.Response.make(
            200,
            b'{"id": 1, "name": "mock-user"}',
            {"Content-Type": "application/json"},
        )

前端联调时,后端还没好?用这招直接 Mock。

实验四:移动端抓包

# 1. 手机和电脑同一 WiFi;手机 WiFi 代理设为 电脑IP:8080
# 2. 手机浏览器访问 http://mit.it 下载并信任 mitmproxy CA
# 3. mitmweb 在电脑上可视化手机流量
mitmweb --listen-port 8080
# 注意:做了证书锁定的 App(银行/大厂)抓不到——锁定就是为防这个(第05章)

实验五:与 tcpdump 的分工

# tcpdump:看字节流(TLS 是密文,看不懂应用层)
sudo tcpdump -i any -n 'tcp port 443'        # 只能看到加密字节

# mitmproxy:看应用层明文(解密后的 HTTP)
mitmproxy --listen-port 8080                 # 看到完整 URL/头/体

分工:排查"连不连得通、握手对不对" → tcpdump(第01章 起就在用);排查"请求内容对不对" → mitmproxy。 两者互补。


排错

现象根因解决
certificate problem客户端没信任 mitm CA装 ~/.mitmproxy/mitmproxy-ca-cert.pem
App 流量抓不到证书锁定(第05章)锁定无法绕过;用 debug 构建/越狱环境
HSTS 站点失败浏览器对 HSTS 拒绝异常证书设计如此
HTTP/2 流量异常个别老配置 h2 支持问题升级 mitmproxy,或强制 h1
透明模式不拦截没配 iptables/--mode transparent参考 第11章
改了响应体长度对不上没更新 Content-Length改 flow.response.text 时框架会自动算长度,改 raw 要手动

本章小结

  • mitmproxy 三件套:mitmproxy(TUI) / mitmweb(Web) / mitmdump(脚本),五模式(regular/transparent/reverse/upstream/socks5)。
  • 它是"开发调试视角"的 MITM,原理同 第05章:动态签证书 + 客户端信任 CA;HSTS/锁定可反制。
  • Python addon 用 request/response 钩子脚本化改包、Mock,是可编程代理的轻量形态。
  • 与 tcpdump 分工:tcpdump 看字节/握手,mitmproxy 看应用层明文/内容。

下一章 第19章 内网穿透与隧道,换个问题:内网服务没有公网 IP,如何让外部访问?frp、gost、SSH 反向隧道、ngrok 各显神通。