mitmdump实战指南:从抓包到自动化处理的全流程

在接口调试、数据采集、接口自动化测试、网络请求篡改等场景中,抓包工具是开发者和测试工程师的必备利器。市面上的抓包工具层出不穷,比如Fiddler、Charles、Wireshark,而**mitmproxy**(及其命令行工具mitmdump)凭借**开源免费、跨平台、强大的脚本扩展能力**,成为了自动化场景下的首选工具。

其中,**mitmdump**是mitmproxy的命令行版本,它不仅具备mitmproxy的核心抓包能力,还支持通过Python脚本自定义处理请求和响应------这意味着我们可以将抓包、修改、验证、存储等操作全部自动化,摆脱手动操作的繁琐。本文将从**基础入门**、**核心脚本开发**、**实战场景落地**三个维度,全面讲解mitmdump的使用方法,让你轻松玩转网络请求的自动化处理。

一、什么是mitmdump?

mitmdump是**mitmproxy**套件中的命令行工具,mitmproxy是一款基于Python的开源中间人攻击(MITM)工具,能够捕获HTTP/HTTPS、WebSocket等协议的网络请求。

核心优势

  1. 命令行操作:无需图形界面,适合服务器环境、自动化脚本执行;

  2. Python脚本扩展:通过自定义Python脚本,可实现请求/响应的修改、过滤、验证、存储等任意逻辑;

  3. 跨平台:支持Windows、macOS、Linux,还能捕获手机、模拟器的网络请求;

  4. 支持多种协议:HTTP/1.1、HTTP/2、HTTPS、WebSocket、TCP等;

  5. 数据持久化:可将抓包数据保存为文件,也可从文件读取并重放请求。

工作原理

mitmdump的核心是**中间人攻击**:

  1. 启动mitmdump后,它会在本地开启一个代理服务器(默认端口8080);

  2. 客户端(浏览器、手机、程序)将代理设置为mitmdump的地址和端口;

  3. 客户端发送的请求会先经过mitmdump,再由mitmdump转发给目标服务器;

  4. 目标服务器的响应会先经过mitmdump,再由mitmdump转发给客户端;

  5. 在这个过程中,mitmdump可以拦截、修改、记录所有的请求和响应。

注:对于HTTPS请求,需要安装mitmdump的CA证书,否则无法解密请求内容。

二、环境准备:安装与证书配置

1. 安装mitmdump

mitmdump基于Python,推荐使用pip安装:

复制代码
bash 复制代码
# 安装最新版本
pip install mitmproxy

验证安装成功:

bash 复制代码
# 查看版本
mitmdump --version
# 查看帮助
mitmdump --help

2. 配置CA证书(关键:抓HTTPS请求)

mitmdump默认无法解密HTTPS请求,需要安装并信任mitmdump的CA证书。

步骤1:生成CA证书

启动一次mitmdump(无需参数),然后关闭,mitmdump会自动在用户目录下生成CA证书:

bash 复制代码
# 启动mitmdump,然后按Ctrl+C关闭
mitmdump

证书默认存储路径:

  • WindowsC:\Users\<用户名>\.mitmproxy

  • macOS/Linux~/.mitmproxy

路径下的核心证书文件:

  • mitmproxy-ca.pem:PEM格式的根证书

  • mitmproxy-ca-cert.pem:用于导入浏览器/系统的证书

  • mitmproxy-ca-cert.cer:Windows系统的证书格式

步骤2:安装系统证书(以macOS为例)
  1. 打开~/.mitmproxy目录,双击mitmproxy-ca-cert.pem

  2. 在弹出的"钥匙串访问"中,选择"登录"钥匙串,点击"添加";

  3. 找到"mitmproxy"证书,右键选择"显示简介";

  4. 在"信任"选项卡中,设置"使用此证书时"为"始终信任"。

步骤3:安装手机证书(捕获手机请求)
  1. 确保手机和电脑在同一局域网;

  2. 电脑启动mitmdump:mitmdump -p 8080

  3. 手机设置代理:IP为电脑的局域网IP,端口为8080;

  4. 手机浏览器访问mitm.it,根据系统(iOS/Android)下载并安装证书;

  5. iOS需在"设置→通用→关于本机→证书信任设置"中开启信任;Android需在设置中找到证书并设为信任。

三、mitmdump基础使用:命令行操作

mitmdump的基础命令主要用于启动代理、保存抓包数据、读取抓包数据,以下是常用命令:

1. 启动基础代理

bash 复制代码
# 默认端口8080启动
mitmdump

# 指定端口启动(如8888)
mitmdump -p 8888

# 启动时显示详细日志(调试用)
mitmdump -v

2. 保存抓包数据到文件

bash 复制代码
# 将抓包数据保存为mitmdump格式(.mitm)
mitmdump -w capture.mitm

# 指定端口并保存,同时过滤只保存指定域名的请求(如baidu.com)
mitmdump -p 8080 -w baidu_capture.mitm -q "~d baidu.com"

其中-q参数用于过滤请求,支持的过滤规则如下(常用):

  • ~d domain:匹配域名(如~d baidu.com

  • ~p port:匹配端口(如~p 8080

  • ~m method:匹配请求方法(如~m GET~m POST

  • ~u url:匹配URL(如~u /api/login

  • ~s status:匹配响应状态码(如~s 200

  • 组合过滤:~m POST ~d api.example.comPOST请求且域名为api.example.com

3. 从文件读取抓包数据

bash 复制代码
# 读取抓包文件并显示
mitmdump -r capture.mitm

# 读取文件并过滤请求(只显示POST请求)
mitmdump -r capture.mitm -q "~m POST"

# 读取文件并重放请求(将抓包的请求重新发送)
mitmdump -r capture.mitm --replay

4. 其他常用参数

bash 复制代码
# 忽略指定域名的请求(如忽略google.com)
mitmdump --ignore-hosts google.com

# 设置反向代理(将请求转发到目标服务器)
mitmdump -p 8080 --reverse-proxy http://localhost:8000

四、核心能力:Python脚本自定义处理请求/响应

mitmdump的真正强大之处在于**支持Python脚本扩展**。我们可以编写脚本,对拦截到的请求和响应进行任意处理,比如修改参数、篡改响应、自动验证、数据存储等。

1. 脚本的基本结构

mitmdump的Python脚本通过定义特定的函数来处理请求和响应,核心函数有:

  • request(flow):处理请求(请求发送到服务器前触发)

  • response(flow):处理响应(服务器响应后发送到客户端前触发)

  • start():脚本启动时执行(初始化操作,如连接数据库)

  • done():脚本结束时执行(清理操作,如关闭数据库连接)

其中,flow是核心对象,包含了请求和响应的所有信息:

  • flow.request:请求对象(包含URL、方法、头、参数、请求体等)

  • flow.response:响应对象(包含状态码、头、响应体等)

2. 实战案例1:修改GET请求参数

需求:拦截所有访问https://api.example.com/user的GET请求,将参数id=1改为id=100

编写脚本modify_get_param.py

复制代码
python 复制代码
from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    # 过滤指定URL的GET请求
    if flow.request.pretty_url.startswith("https://api.example.com/user") and flow.request.method == "GET":
        # 获取请求参数
        params = flow.request.query
        # 修改参数id的值
        if "id" in params:
            params["id"] = "100"
            print(f"修改GET参数:id从{params.get('id', '原数值')}改为100")
        # 重新设置参数(可选,因为params是引用类型,修改后自动生效)
        flow.request.query = params

启动mitmdump并加载脚本:

复制代码
bash 复制代码
mitmdump -p 8080 -s modify_get_param.py

3. 实战案例2:修改POST请求的JSON请求体

需求:拦截https://api.example.com/login的POST请求,将请求体中的password改为123456

编写脚本modify_post_body.py

复制代码
python 复制代码
import json
from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    # 过滤指定URL的POST请求
    if flow.request.pretty_url == "https://api.example.com/login" and flow.request.method == "POST":
        try:
            # 解析JSON请求体
            request_body = json.loads(flow.request.content.decode("utf-8"))
            # 修改password
            if "password" in request_body:
                original_pwd = request_body["password"]
                request_body["password"] = "123456"
                print(f"修改POST请求体:password从{original_pwd}改为123456")
            # 重新设置请求体
            flow.request.content = json.dumps(request_body).encode("utf-8")
        except json.JSONDecodeError:
            # 非JSON请求体,跳过
            pass

启动脚本:

python 复制代码
mitmdump -p 8080 -s modify_post_body.py

4. 实战案例3:修改响应内容(篡改JSON数据)

需求:拦截https://api.example.com/user/info的响应,将username改为test_user

编写脚本modify_response.py

python 复制代码
import json
from mitmproxy import http

def response(flow: http.HTTPFlow) -> None:
    # 过滤指定URL的响应
    if flow.request.pretty_url == "https://api.example.com/user/info":
        try:
            # 解析JSON响应体
            response_body = json.loads(flow.response.content.decode("utf-8"))
            # 修改username
            if "username" in response_body:
                original_name = response_body["username"]
                response_body["username"] = "test_user"
                print(f"修改响应体:username从{original_name}改为test_user")
            # 重新设置响应体
            flow.response.content = json.dumps(response_body).encode("utf-8")
            # 可选:修改响应状态码
            # flow.response.status_code = 404
        except json.JSONDecodeError:
            pass

5. 实战案例4:过滤并保存特定响应数据(如图片)

需求:拦截所有图片请求(后缀为.jpg/.png),并保存到本地文件夹。

编写脚本save_images.py

python 复制代码
import os
from mitmproxy import http

# 初始化:创建保存图片的文件夹
def start() -> None:
    if not os.path.exists("captured_images"):
        os.makedirs("captured_images")
    print("图片保存文件夹已创建:captured_images")

def response(flow: http.HTTPFlow) -> None:
    # 过滤图片请求(通过后缀或Content-Type)
    url = flow.request.pretty_url
    if url.endswith((".jpg", ".png", ".jpeg")) or "image/" in flow.response.headers.get("Content-Type", ""):
        # 获取图片名称(从URL中提取)
        image_name = url.split("/")[-1]
        # 处理特殊字符(避免文件名错误)
        image_name = image_name.replace("?", "_").replace("&", "_")
        # 保存图片
        with open(f"captured_images/{image_name}", "wb") as f:
            f.write(flow.response.content)
        print(f"保存图片:{image_name}")

6. 实战案例5:接口自动化测试(自动断言响应)

需求:拦截https://api.example.com/order/list的响应,自动验证状态码为200,且响应体中包含data字段。

编写脚本api_test.py

python 复制代码
import json
from mitmproxy import http
from mitmproxy.log import log

def response(flow: http.HTTPFlow) -> None:
    # 过滤指定接口
    if flow.request.pretty_url == "https://api.example.com/order/list":
        # 断言1:响应状态码为200
        assert flow.response.status_code == 200, f"状态码断言失败:预期200,实际{flow.response.status_code}"
        # 断言2:响应体包含data字段
        try:
            response_body = json.loads(flow.response.content.decode("utf-8"))
            assert "data" in response_body, "响应体缺少data字段"
            print("接口断言通过!")
        except json.JSONDecodeError:
            log.error("响应体不是JSON格式,断言失败")
        except AssertionError as e:
            log.error(f"接口断言失败:{e}")

注:断言失败时,mitmdump会抛出异常并记录日志,可结合CI/CD工具实现自动化测试告警。

五、进阶技巧:提升mitmdump使用效率

1. 结合JSONPath提取响应数据

对于复杂的JSON响应,可使用jsonpath-ng库提取特定字段,需先安装:

python 复制代码
pip install jsonpath-ng

示例:提取响应中所有订单的ID:

python 复制代码
import json
from jsonpath_ng import parse
from mitmproxy import http

def response(flow: http.HTTPFlow) -> None:
    if "order/list" in flow.request.pretty_url:
        response_body = json.loads(flow.response.content.decode("utf-8"))
        # 定义JSONPath表达式:提取data.list中的所有id
        jsonpath_expr = parse("$.data.list[*].id")
        # 提取数据
        order_ids = [match.value for match in jsonpath_expr.find(response_body)]
        print(f"提取的订单ID:{order_ids}")

2. 多脚本组合使用

mitmdump支持同时加载多个脚本,按顺序执行:

python 复制代码
mitmdump -p 8080 -s script1.py -s script2.py -s script3.py

适合将不同功能拆分到不同脚本中,便于维护。

3. 忽略特定域名,提升性能

当抓包时不需要处理某些域名(如广告、统计域名),可忽略以提升性能:

python 复制代码
from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    # 忽略google-analytics和baidu统计的请求
    if "google-analytics.com" in flow.request.pretty_url or "hm.baidu.com" in flow.request.pretty_url:
        # 终止请求,不转发到服务器
        flow.kill()

4. 结合数据库存储抓包数据

将抓包的关键数据(如接口请求参数、响应结果)存储到MySQL/Redis中,便于后续分析:

python 复制代码
import json
import pymysql
from mitmproxy import http

# 初始化数据库连接
def start() -> None:
    global db_conn, cursor
    db_conn = pymysql.connect(
        host="localhost",
        user="root",
        password="123456",
        database="mitm_data"
    )
    cursor = db_conn.cursor()
    # 创建表
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS api_requests (
            id INT AUTO_INCREMENT PRIMARY KEY,
            url VARCHAR(255) NOT NULL,
            method VARCHAR(10) NOT NULL,
            request_body TEXT,
            response_body TEXT,
            create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    """)
    db_conn.commit()

def response(flow: http.HTTPFlow) -> None:
    # 过滤需要存储的接口
    if "api.example.com" in flow.request.pretty_url:
        # 提取数据
        url = flow.request.pretty_url
        method = flow.request.method
        request_body = flow.request.content.decode("utf-8") if flow.request.content else ""
        response_body = flow.response.content.decode("utf-8") if flow.response.content else ""
        # 插入数据库
        cursor.execute("""
            INSERT INTO api_requests (url, method, request_body, response_body)
            VALUES (%s, %s, %s, %s)
        """, (url, method, request_body, response_body))
        db_conn.commit()
        print(f"数据已存入数据库:{url}")

# 结束时关闭数据库连接
def done() -> None:
    cursor.close()
    db_conn.close()
    print("数据库连接已关闭")

5. mitmdump与CI/CD集成

将mitmdump的脚本作为接口测试的一部分,集成到Jenkins/GitLab CI中:

  1. 在CI环境中安装mitmdump和依赖库;

  2. 启动mitmdump并加载测试脚本,同时运行被测应用;

  3. 执行接口请求(如通过curl/requests);

  4. 捕获mitmdump的日志,判断断言是否通过;

  5. 根据结果输出测试报告。

六、注意事项与避坑指南

1. HTTPS抓包失败的常见原因

  • 未安装或未信任CA证书;

  • 客户端使用了证书固定(Certificate Pinning)技术(如部分APP会验证服务器证书的指纹,mitmdump的证书会被拒绝);

  • 系统时间与证书有效期不匹配(需同步系统时间)。

2. 脚本执行顺序问题

  • 多个脚本的requestresponse函数按加载顺序执行;

  • 单个脚本中,若在request函数中修改了请求,后续的脚本会看到修改后的请求。

3. 性能问题

  • 当抓包数据量过大时,避免在脚本中执行耗时操作(如大量IO、复杂计算);

  • 合理使用过滤规则,只处理需要的请求,减少不必要的开销。

4. 合法性问题

  • mitmdump仅用于合法的测试、调试、个人学习场景;

  • 未经授权抓取他人网络请求、篡改数据属于违法行为,需遵守相关法律法规。

5. 大文件请求处理

  • 对于大文件(如视频、大文件下载),mitmdump可能会占用大量内存,可通过flow.response.stream流式处理,或直接忽略。

七、总结

mitmdump不仅是一款抓包工具,更是**网络请求自动化处理的平台**。通过命令行操作,我们可以快速完成抓包和数据保存;通过Python脚本,我们可以实现请求/响应的任意修改、数据自动存储、接口自动化测试等复杂功能。

其适用场景覆盖:

  • 接口调试:快速修改参数和响应,验证不同场景的接口表现;

  • 数据采集:自动抓取网页/APP的图片、接口数据并存储;

  • 接口自动化测试:自动断言响应,集成到CI/CD流程;

  • 安全测试:模拟请求篡改,检测接口的安全性;

  • APP调试:捕获手机APP的网络请求,定位接口问题。

随着技术的发展,我们还可以将mitmdump与大模型结合------比如让大模型解析响应数据并生成测试报告,或根据请求内容自动生成测试用例,进一步提升自动化处理的能力。掌握mitmdump,无疑会让你的网络请求处理工作效率翻倍!

相关推荐
tgethe2 小时前
Nginx笔记
运维·笔记·nginx
宠..2 小时前
为单选按钮绑定事件
运维·服务器·开发语言·数据库·c++·qt·microsoft
QC七哥2 小时前
基于vnstat监控服务器的网卡流量
运维·服务器·监控·vnstat
怀旧,2 小时前
【Linux系统编程】14. 库使用与原理(上)
linux·运维·服务器
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之locate命令(实操篇)
linux·运维·服务器·chrome·笔记
阿方索2 小时前
Docker
运维·docker·容器
风好衣轻3 小时前
Ubuntu单卡5090部署VeRL:从安装到运行
linux·运维·ubuntu
init_23613 小时前
Option B(MP-EBGP跨AS VRF)设备配置及ASBR标签转发原理
运维·服务器·网络
刚哥的进化路3 小时前
Kubernetes 集群部署详细教程:kubeadm 单 Master / 高可用部署实操
运维