Mitmproxy 常规功能介绍

发布时间 2023-07-05 17:29:22作者: 术科术

背景

mitmproxy是一个开源的中间人代理工具,用于拦截、修改和观察HTTP/HTTPS流量,并支持扩展功能。它包含三个功能模块:mitmproxy、mitmweb和mitmdump,每个模块提供不同的界面和功能。

  • mitmproxy:提供命令行界面,使用命令行进行操作和监控。
  • mitmweb:提供浏览器界面,通过Web界面进行操作和监控。
  • mitmdump:提供简单的终端输出,适用于自动化和脚本化的使用场景。

使用mitmproxy可以通过mitmdump模块编写扩展脚本,从而提高工作效率。下面是一些可以使用mitmdump解决的问题示例:

  1. 模拟接口返回数据以验证客户端是否出现UI异常或兼容性问题。
  2. 模拟接口返回数据延迟,验证客户端对接口加载状态的处理。
  3. 录制接口数据信息,用于回归测试接口功能是否正常。

mitmdump

mitmdump是mitmproxy的命令行版本,具有丰富的命令行参数,可以根据需求进行配置。可以使用以下命令查看参数选项:

mitmdump --help

录制与回放

mitmdump提供了录制和回放功能,可以通过规则将请求数据录制到二进制文件中,并使用回放功能对接口进行数据回放。

录制

使用以下命令进行录制,并将请求数据保存到文件中:

mitmdump -w filename

过滤

可以使用过滤规则对录制的数据进行过滤,只录制符合规则的数据:

mitmdump -nr filename -w filename2 "~s keyword"

上述命令将从filename中读取数据,过滤出包含关键字"keyword"的响应数据,并将过滤结果保存到filename2中。

回放

使用以下命令对录制的数据文件进行回放:

mitmdump -nC filename

参数说明

  • -s "script.py --bar":使用双引号命令执行脚本并传递参数。
  • -n:不启动代理,仅回放数据。
  • -r:读取文件内容。
  • -w:写入文件。
  • ~s:过滤响应数据。
  • ~q:过滤请求数据。

示例

下面是一些示例用法:

  1. 使用录制功能,本地开启8999端口代理并过滤响应数据"igetget",将结果保存到本地文件igetget.txt中:
mitmdump -p 8999 -w igetget.txt "~s igetget"
  1. 连接手机到代理端口8999,并操作手机应用程序。

  2. 录制结束后,注意igetget.txt是一个二进制文件,无法直接查看详细的接口信息。

  3. 使用回放功能,回放igetcool.txt文件中的接口数据:

mitmdump -nC igetcool.txt

在回放过程中,您将看到发送请求的信息与第一次录制的数据相同。

  1. 过滤录制的请求,仅保存包含"igetcool"关键字的数据:
mitmdump -nr igetcool.txt -w igetcool-test.txt "~s igetcool"

mitmdump 功能扩展

介绍

常用的 mitmdump 扩展功能,包括修改接口响应状态码、修改接口响应结果、加载本地数据和模拟接口响应延迟。

前提条件

首先,在本地创建 script.py 文件。

修改接口响应状态码

以下示例代码演示了如何使用 mitmdump 修改接口的响应状态码。

def response(flow: http.HTTPFlow):
    if "igetcool-gateway.igetcool.com" in str(flow.request.pretty_url):
        flow.response.status_code = 404

在上述示例中,我们在 response 函数中判断请求的 URL 是否满足特定条件,如果满足,则将响应状态码设置为 404。您可以根据需要修改过滤条件和状态码值。

修改接口响应结果

以下示例代码演示了如何使用 mitmdump 修改接口的响应结果。

import json

def response(flow: http.HTTPFlow):
    if "https://igetcool-gateway.igetcool.com/app-api-user-server/white/app/head/config.json" in str(flow.request.pretty_url):
        data = json.loads(flow.response.content)
        data['data']['isShow'] = 2
        flow.response.set_text(json.dumps(data))

在上述示例代码中,我们通过添加过滤条件来确定要修改响应结果的特定接口。然后,我们加载原始响应数据并进行修改。在示例中,我们修改了数据字段 data['data']['isShow'] 的值为 2。最后,我们将修改后的数据重新设置为响应结果,以确保返回给客户端的数据已被修改。

加载本地数据(Map Local)

以下示例代码演示了如何使用 mitmdump 将指定的网络请求重定向到本地文件,以实现加载本地数据的目的。

import json

def response(flow: http.HTTPFlow):
    if "igetcool" in str(flow.request.pretty_url):
        with open("/Users/xinxi/Documents/zhihu/mitmproxyRecode/igetget.json", 'r') as f:
            resp_info = json.loads(f.read())
        flow.response.set_text(json.dumps(resp_info))

在上述示例代码中,我们使用一个过滤条件来匹配需要加载本地数据的网络请求。例如,在过滤条件中,我们检查请求 URL 中是否包含 "igetcool" 字符串。然后,我们打开本地文件并将文件中的内容加载为 JSON 格式的数据。最后,我们将本地数据作为响应结果返回。

请根据您自己的实际情况,修改文件路径以及过滤条件。

模拟接口响应延迟的方法

在 mitmdump 中没有直接设置接口延迟的方法,但我们可以使用 time.sleep() 函数来实现该效果。以下示例代码可以模拟接口响应延迟。

import time
import random
from mitmproxy import http

def response(flow: http.HTTPFlow):
    if "igetcool" in str(flow.request.pretty_url):
        random_time = random.randint(100, 1000)
        time.sleep(random_time / 1000)

在上述示例代码中,我们添加了一个过滤条件,仅对特定请求进行延迟模拟。如果请求的 URL 中包含 "igetcool" 字符串,我们会生成一个介于 100 到 1000 之间的随机整数,表示延迟的毫秒数。然后,利用 time.sleep() 函数将程序暂停指定的毫秒数,模拟延迟。