Mitmproxy + Python 做拦截代理
在测试过程中,我们经常用到Charles、Fiddler等抓包工具,通过抓取http请求进行相关的测试、问题排查。但是在一些特殊场景下,例如我们的数据传输是加密的,可能需要抓取到数据后再进行解密,这个使用抓包工具就不能完全符合我们的需求。
mitmproxy是什么
mitmproxy 就是用于 MITM 的 proxy,MITM 即中间人攻击(Man-in-the-middle attack)。用于中间人攻击的代理首先会向正常的代理一样转发请求,保障服务端与客户端的通信,其次,会适时的查、记录其截获的数据,或篡改数据,引发服务端或客户端特定的行为。
不同于 fiddler、Charles 或 wireshark 等抓包工具,mitmproxy 不仅可以截获请求帮助开发者查看、分析,更可以通过自定义脚本进行二次开发。举例来说,利用 fiddler 可以过滤出浏览器对某个特定 url 的请求,并查看、分析其数据,但实现不了高度定制化的需求,类似于:“截获对浏览器对该 url 的请求,将返回内容置空,并将真实的返回内容存到某个数据库,出现异常时发出邮件通知”。而对于 mitmproxy,这样的需求可以通过载入自定义 python 脚本轻松实现。
但 mitmproxy 并不会真的对无辜的人发起中间人攻击,由于 mitmproxy 工作在 HTTP 层,而当前 HTTPS 的普及让客户端拥有了检测并规避中间人攻击的能力,所以要让 mitmproxy 能够正常工作,必须要让客户端(APP 或浏览器)主动信任 mitmproxy 的 SSL 证书,或忽略证书异常。
mitmproxy简单理解就是个抓包工具,它可以提供命令行界面、web界面,还可以通过python脚本实现自定义的请求拦截、篡改等自定义的操作。
mitmproxy模块安装
pip3 install mitmproxy
完成后,系统将拥有 mitmproxy
、mitmdump
、mitmweb
三个命令,由于 mitmproxy
命令不支持在 windows 系统中运行(这没关系,不用担心),我们可以拿 mitmdump
测试一下安装是否成功,执行:
mitmdump --version
出现下面提示即安装成功
Mitmproxy: 5.1.1 Python: 3.6.1 OpenSSL: OpenSSL 1.1.1g 21 Apr 2020 Platform: Darwin-16.7.0-x86_64-i386-64bit
mitmproxy启动
要启动 mitmproxy 用 mitmproxy
、mitmdump
、mitmweb
这三个命令中的任意一个即可,这三个命令功能一致,且都可以加载自定义脚本,唯一的区别是交互界面的不同。
启动命令:
mitmdump -p 8889 -s run.py
-p 指定代理端口
-s 指定要执行的脚本文件
如果是启动web界面, 可以在127.0.0.1:8081上看到
mitmproxy脚本
在启动mitmproxy的时候可以指定脚本,脚本的使用规则如下:
import mitmproxy.http from mitmproxy import ctx class Counter(): def __init__(self): self.num=0 def request(self, flow: mitmproxy.http.HTTPFlow): self.num+=1 if "api.pre.sanjieke.cn" in flow.request.url: ctx.log.info("we have seen %d flow " % self.num) def response(self, flow: mitmproxy.http.HTTPFlow): if "api.pre.sanjieke.cn" in flow.request.url: import json data = json.loads(str(flow.response.content, encoding='utf-8')) ctx.log.info("data = {}".format(data)) addons = [ Counter() ]
1. 定义一个规则类,可以通过设置http生命周期方法来自定义相关代理设置,例如counter类中的request和response,即在http请求中的请求和返回
2.将类加入到addons数组中,启动mitmproxy时带上该py文件即可
当然除了request和response还有其它的阶段,这两个是常用的。
mitmproxy除了可以定义处理http请求生命周期各个阶段,还可以处理tcp链接生命周期、websocket生命周期等
详见:https://blog.wolfogre.com/posts/usage-of-mitmproxy/
基本常用的就是request、response这两个。
脚本中可以通过ctx进行相关日志打印。
以上就是mitmproxy的简单使用。