使用 mitmproxy 录制和回放流量到 CSV 的完整解决方案

news/2025/3/31 3:48:02/文章来源:https://www.cnblogs.com/zgq123456/p/18797196

下面是一个完整的系统,包含两个脚本:

  1. mitmproxy_recorder.py - 录制流量到 CSV 文件

  2. mitmproxy_replayer.py - 从 CSV 文件回放流量并记录结果

第一部分:流量录制脚本 (mitmproxy_recorder.py)

python
复制
import csv
import time
import os
import json
from datetime import datetime
from mitmproxy import http, ctx
from urllib.parse import urlparse, parse_qsclass TrafficRecorder:def __init__(self):self.output_dir = "mitmproxy_records"os.makedirs(self.output_dir, exist_ok=True)timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")self.record_file = os.path.join(self.output_dir, f"record_{timestamp}.csv")self.summary_file = os.path.join(self.output_dir, f"summary_{timestamp}.csv")# CSV 文件头self.record_headers = ["timestamp", "request_method", "request_url", "request_headers", "request_params", "request_body","response_status", "response_headers", "response_body","response_time_ms", "content_type"]self.summary_headers = ["timestamp", "request_url", "request_method","response_status", "response_time_ms", "success"]# 初始化文件with open(self.record_file, 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(self.record_headers)with open(self.summary_file, 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(self.summary_headers)ctx.log.info(f"Recording traffic to {self.record_file}")ctx.log.info(f"Summary will be saved to {self.summary_file}")def _get_params(self, url):parsed = urlparse(url)return parse_qs(parsed.query)def _format_headers(self, headers):return json.dumps(dict(headers))def request(self, flow: http.HTTPFlow):flow.start_time = time.time()def response(self, flow: http.HTTPFlow):try:response_time = (time.time() - flow.start_time) * 1000# 准备详细记录record_row = [datetime.now().isoformat(),flow.request.method,flow.request.url,self._format_headers(flow.request.headers),json.dumps(self._get_params(flow.request.url)),flow.request.content.decode('utf-8', errors='replace') if flow.request.content else "",flow.response.status_code,self._format_headers(flow.response.headers),flow.response.content.decode('utf-8', errors='replace') if flow.response.content else "",f"{response_time:.2f}",flow.response.headers.get("Content-Type", "")]# 准备摘要记录summary_row = [datetime.now().isoformat(),flow.request.url,flow.request.method,flow.response.status_code,f"{response_time:.2f}",flow.response.status_code < 400]# 写入文件with open(self.record_file, 'a', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(record_row)with open(self.summary_file, 'a', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(summary_row)except Exception as e:ctx.log.error(f"Error recording request: {e}")recorder = TrafficRecorder()def request(flow: http.HTTPFlow):recorder.request(flow)def response(flow: http.HTTPFlow):recorder.response(flow)

第二部分:流量回放脚本 (mitmproxy_replayer.py)

python
复制
import csv
import time
import os
import json
import requests
from datetime import datetime
from urllib.parse import parse_qsclass TrafficReplayer:def __init__(self, input_csv, output_csv):self.input_csv = input_csvself.output_csv = output_csv# 准备输出文件self.output_headers = ["replay_timestamp", "original_timestamp", "request_url", "request_method", "response_status", "response_time_ms","success", "error_message", "status_match", "response_diff"]with open(self.output_csv, 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(self.output_headers)print(f"Replaying from {self.input_csv}, saving results to {self.output_csv}")def replay(self):with open(self.input_csv, 'r', encoding='utf-8') as f:reader = csv.DictReader(f)for row in reader:try:start_time = time.time()# 准备请求method = row['request_method']url = row['request_url']headers = json.loads(row['request_headers'])params = json.loads(row['request_params'])data = row['request_body']# 发送请求response = requests.request(method=method,url=url,headers=headers,params=params,data=data,verify=False  # 忽略SSL证书验证)response_time = (time.time() - start_time) * 1000# 比较响应original_status = int(row['response_status'])status_match = original_status == response.status_code# 比较响应体 (简化比较)original_body = row['response_body']response_diff = "N/A"  # 这里可以添加更详细的比较逻辑# 记录结果result_row = [datetime.now().isoformat(),row['timestamp'],url,method,response.status_code,f"{response_time:.2f}",response.ok,"",status_match,response_diff]except Exception as e:result_row = [datetime.now().isoformat(),row['timestamp'],row['request_url'],row['request_method'],"0","0",False,str(e),False,"Error"]# 写入结果with open(self.output_csv, 'a', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(result_row)if __name__ == "__main__":import argparseparser = argparse.ArgumentParser(description='Replay recorded HTTP traffic from CSV')parser.add_argument('input', help='Input CSV file containing recorded traffic')parser.add_argument('output', help='Output CSV file for replay results')args = parser.parse_args()replayer = TrafficReplayer(args.input, args.output)replayer.replay()

使用说明

1. 录制流量

bash
复制
mitmproxy -s mitmproxy_recorder.py

录制完成后,会在 mitmproxy_records 目录下生成两个文件:

  • record_<timestamp>.csv - 包含完整的请求/响应详细信息

  • summary_<timestamp>.csv - 包含简化的摘要信息

2. 回放流量

bash
复制
python mitmproxy_replayer.py mitmproxy_records/record_20230101_120000.csv replay_results.csv

回放结果将保存到 replay_results.csv,包含以下信息:

  • 回放时间戳

  • 原始记录时间戳

  • 请求URL和方法

  • 响应状态码和时间

  • 是否成功

  • 错误信息(如果有)

  • 状态码是否匹配原始记录

  • 响应体差异(简化版)

高级功能扩展

  1. 添加过滤功能

    • 在录制脚本中添加域名/URL过滤

    • 在回放脚本中添加选择性回放

  2. 增强比较功能

    python
    复制
    # 在replayer.py中添加更详细的响应比较
    def compare_responses(original, new):# 比较状态码status_match = original['status'] == new.status_code# 比较头信息headers_diff = set(original['headers'].items()) - set(new.headers.items())# 比较正文 (可以使用difflib进行详细比较)body_diff = "..." if original['body'] != new.text else ""return {'status_match': status_match,'headers_diff': headers_diff,'body_diff': body_diff}
  3. 添加性能统计

    python
    复制
    # 在replayer.py结束时添加统计信息
    def print_stats(self):with open(self.output_csv, 'r') as f:reader = csv.DictReader(f)results = list(reader)total = len(results)success = sum(1 for r in results if r['success'] == 'True')avg_time = sum(float(r['response_time_ms']) for r in results) / totalprint(f"\nReplay Summary:")print(f"Total requests: {total}")print(f"Success rate: {success/total:.2%}")print(f"Average response time: {avg_time:.2f}ms")
  4. 支持变量参数化

    python
    复制
    # 在回放前替换动态值
    def prepare_request(self, row):url = row['request_url']# 替换时间戳变量url = url.replace('${timestamp}', str(int(time.time())))return url

这个完整的解决方案可以满足流量录制、回放和结果分析的需求,适用于API测试、性能基准测试和回归测试等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/906944.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux上利用sunshine串流和虚拟显示器实现副屏扩展

场景Linux + Wayland,尝试将空闲的android平板作为扩展显示屏方法根据 https://www.w568w.eu.org/spacedesk-on-linux.html 中的描述,利用 sunshine + moonlight 串流以及虚拟显示器欺骗实现副屏扩展虚拟显示器查看当前系统记录的显示器设备接口的连接情况,使用命令for p in…

Go红队开发—CLI框架(二)

Go红队开发—CLI命令行工具编写基础学习(二)。目录CLI开发框架cobra 集成库目录规范搭建框架根命令参数添加子命令帮助信息爬虫功能(趁热打铁)Goquery处理响应编码处理收集百度热搜榜爬虫功能所有源码 CLI开发框架 师傅们久等了,为了加快进度,这章节添加了一个爬虫功能,也是…

APP性能测试工具-GT

GT(随身调)是腾讯研发的一款可以用来做App性能测试的工具,可以对APP进行快速的性能测试,检测App的CPU、内存、流量、电量、帧率/流畅度等等、还能开启日志的查看、Crash日志查看、网络数据包的抓取、APP内部参数的调试、真机代码耗时统计等。 虽然现在该项目已经停止维护了…

一文速通Python并行计算:04 Python多线程编程-多线程同步(上)—基于条件变量、事件和屏障

本文介绍了Python多线程同步的三种机制:条件变量(Condition)、事件(Event)和屏障(Barrier),条件变量指的是线程等待特定条件满足后执行,适用于生产者-消费者模型;Event指的是线程通过事件标志进行同步,适用于线程间简单通信;Barrier指的是多个线程需同步到同一阶段…

docker desktop windows安装

我的机器windows 11 家庭版 下载docker desktop for windows 就直接安装了。安装后打开,遇到了界面转圈圈加载不出来问题,docker engine也是stopped. 病急乱投医,先是说要启用hyper-v,控制面板=》程序和功能里没有发现有hyper-v,一看是家庭版,网上倒是有一个脚本可以在家…

C语言打卡学习第6天(2025.3.25)(补发)

只做了一些有关循环分支函数求值的题,感觉循环函数其实差不多,只有一些细微差别,可能是做的题还不够多或者看运用场景吧

C语言打卡学习第5天(2025.3.24)(补发)

1、把char,getchar,putchar简单看了一下,求ascii值之类的 之类的简单看了一下 2、交换值那一题很奇怪,结果我输出的跟答案要求是一样的,交过去之后显示答案错误,白天的时候问一下

Vulnstack红日靶场通关(持续更新)

带你速通内网渗透相关知识点!!!Vulnstack通关 来源于《内网渗透实战攻略》实战部分 个人是写下自己的笔记 攻击链:探索发现阶段->入侵和感染阶段->攻击和利用阶段->探索感知阶段->传播阶段->持久化和恢复阶段 Windows权限级别前置知识:权限层级 账户类型 权…

Ubuntu 24.04安装MySQL,并且配置外网访问

安装启动更新软件包列表sudo apt update安装MySQL软件包sudo apt install mysql-server启动MySQL服务sudo systemctl start mysql重启命令:systemctl restart mysql配置外网访问 需要修改一个配置 vim /etc/mysql/mysql.conf.d/mysqld.cnf注释掉 这行 配置 bind-address …

2022CCPC Online Contest G - Name the Puppy

对正串和反串分别建立 Trie 树,定义 \(dp[i][j]\) 表示正串 Trie 树上编号为 \(i\) 的点匹配反串 Trie 树上编号为 \(j\) 的点所能拼出最长 anti-border 的长度。 如此,从根节点开始搜索,直到无法匹配为止都可以搜,搜到底后回到根节点继续匹配,可以证明,拼出来的 anti-bo…

互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp智能体框架开发语音交互

前言 前段时间太忙了博客一直都没来得及更新,但是不代表我已经停止开发了,刚好最近把语音部分给调整了一下,所以就来分享一下具体的内容了。我想说一下,更新晚还是有好处的,社区已经有很多的小伙伴自己实现了一些语音对话功能的案例,比如小智也有.NET客户端了,还有就是一…

【AI News | 20250327】每日AI进展

AI Repos 1、playwright-mcp 使用Playwright提供浏览器自动化功能的MCP服务,核心是让LLM通过结构化的可访问性快照与网页交互,不需要依赖截图或视觉模型。可以用来自动填写网页表单、自动收集网页信息、自动进行网页测试等。支持两种模式:快照模式(默认):使用可访问性快照…