0%

使用 mitmproxy + python

概述

  • 本文来自这里

  • mitmproxy 相比Charles、fiddler的优点在于,它可以命令行方式或脚本的方式进行mock mitmproxy不仅可以像Charles那样抓包,还可以对请求数据进行二次开发,进入高度二次定制

安装

  • windows下安装,我本机的python版本为3.7
1
pip install mitmproxy
  • 完成后,系统将拥有 mitmproxymitmdumpmitmweb 三个命令,由于 mitmproxy 命令不支持在 windows 系统中运行(这没关系,不用担心),我们可以拿 mitmdump 测试一下安装是否成功,执行:
1
2
3
4
5
6
7
8
C:\Users\Administrator>mitmdump --version
Mitmproxy: 5.3.0
Python: 3.7.9
OpenSSL: OpenSSL 1.1.1h 22 Sep 2020
Platform: Windows-10-10.0.19041-SP0

C:\Users\Administrator>

  • 要启动 mitmproxymitmproxymitmdumpmitmweb 这三个命令中的任意一个即可,这三个命令功能一致,且都可以加载自定义脚本,唯一的区别是交互界面的不同。

生命周期

原文中介绍了HTTPTCP,Websocket 的生命周期,因为用http比较多,只需要用到 http_connectrequestresponse 三个事件就能完成大多数需求了。

实战

  • 启动mitmproxy
1
mitmweb
  • cmd中启动chrome(启动前,需要先关闭所有chrome)
1
"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe " --proxy-server=127.0.0.1:8080 --ignore-certificate-errors

新增三个代码文件分别为:

  • counter.py,这里代码比较简单,就是发送请求前打印信息
1
2
3
4
5
6
7
8
9
10
11
12
13
# counter.py

import mitmproxy.http
from mitmproxy import ctx


class Counter:
def __init__(self):
self.num = 0

def request(self, flow: mitmproxy.http.HTTPFlow):
self.num = self.num + 1
ctx.log.info("We've seen %d flows" % self.num)
  • joker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import mitmproxy.http
from mitmproxy import ctx, http


class Joker:
def request(self, flow: mitmproxy.http.HTTPFlow):
"""
对百度的搜索发送请求进行拦截,对wd参数修改为360搜索
:param flow:
:return:
"""
if flow.request.host != "www.baidu.com" or not flow.request.path.startswith("/s"):
return
# for i in flow.request.query.keys():
# print(i)
# 抓取请求参数可以看到wd传的是百度搜索的具体内容
if "wd" not in flow.request.query.keys():
ctx.log.warn("can not get search word from %s" % flow.request.pretty_url)
return

ctx.log.info("catch search word: %s" % flow.request.query.get("wd"))
flow.request.query.set_all("wd", ["360搜索"])

def response(self, flow: mitmproxy.http.HTTPFlow):
"""
点击百度搜索中的so搜索后,把当期网页标题修改
:param flow:
:return:
"""
if flow.request.host != "www.so.com":
return

text = flow.response.get_text()
# 网页标题修改
text = text.replace("搜索", "请使用谷歌")
flow.response.set_text(text)

def http_connect(self, flow: mitmproxy.http.HTTPFlow):
"""
连接的请求为google,则把状态码改为404
:param flow:
:return:
"""

if flow.request.host == "www.google.com":
flow.response = http.HTTPResponse.make(404)
# 打印是否设置成功
print(flow.response.status_code)
  • addons.py,这里代码比较简单,只是把自定义事件加载进来
1
2
3
4
5
6
7
import counter
import joker

addons = [
counter.Counter(),
joker.Joker(),
]
  • 运行mitmproxy
1
mitmweb -s addons.py
  • 输入你好,因为搜索关键字被替换为了so搜索,所以结果查到了so搜索

image-20221014183654649

  • 点击360搜索首页,标题被修改了

image-20221014184000637

image-20221014184051730