簡介
mitmproxy 是一款開源、免費的代理工具,支持 mac、windows、linux。相比於其他代理工具,可以通過 python 和 mitmproxy 工具本身的插件機制實現通過腳本對 mitmproxy 的完全控制。強大的可拓展性和可定製性,可以讓測試工程師以 mitmproxy 工具為基礎,進行二次開發,打造更適合自己業務的 mock 工具。
官方網站:
https://mitmproxy.org/
操作步驟
安裝
mitmproxy 是一款跨平台工具,支持在 windows、linux、 mac 平台進行安裝。最推薦的安裝方式是直接通過 python 進行安裝。安裝步驟:
- 安裝好 python 環境(最低要求 python3.6)
- pip install pipx
- pipx install mitmproxy
輸入命令驗證是否安裝成功:
-
mitmdump --version
如果有如下的返回信息,證明環境已經安裝成功:
Mitmproxy: 5.2Python: 3.8.7OpenSSL: OpenSSL 1.1.1g 21 Apr 2020Platform: macOS-10.15-x86_64-i386-64bit
證書配置
mitmproxy 的證書配置過程與 charles 類似
pc 端證書
- 配置電腦代理,ip 配置 127.0.0.1 ,端口配置為 mitmproxy 監聽端口,默認 8080
- 啓動 mitmprxy
- 在瀏覽器輸入地址 mitm.it,顯示效果如果和下圖相同,證明前面的步驟都成功了
- 選擇對應系統下載證書並安裝。
- 信任證書:打開證書(Mac 系統為鑰匙串訪問)->點擊證書->雙擊名稱含有 charles 的選項->點擊信任->選擇始終信任。
windows 證書信任
手機端證書(安卓系統)
- 在手機配置代理,ip 配置為電腦的 ip 地址,端口配置為 mitmproxy 監聽端口,默認 8080。
- 啓動 mitmprxy。
- 在手機瀏覽器輸入地址 mitm.it。
- 選擇 Android,下載並安裝,即可成功抓取手機端的 https 的數據包。
三大核心工具
mitmproxy 有三大核心工具,分別為 mitmproxy、mitmweb、mitmdump。mitmdump 是 mitmproxy 相比於其他代理工具最獨一無二的部分,所以會以 mitmdump 的介紹為主。
- mitmproxy
是一款交互式的命令行工具,通過命令mitmproxy啓動,需要注意的是 mitmproxy 不支持 windows 系統。下圖為 mitmproxy 啓動後的效果圖:
- mitmweb
在 mitmweb 的圖形界面中使用 mitmproxy 的主要功能,通過命令mitmweb啓動。它和 Chrome 開發者工具中的 network 比較類似。下圖為 mitmweb 啓動後的效果圖:
- mitmdump
用 mitmdump 編寫強大的插件和腳本。mitmproxy 腳本 API 提供了對 mitmproxy 的完全控制,可以自動修改消息、重定向流量、可視化消息或實現自定義命令。後面會通過實戰具體介紹 mitmdump 的使用。
mitmdump 實戰
- 命令
mitmdump 可以通過參數 -s 實現執行 python 腳本
通過下面這個示例每次再發起請求時都要打印 "this is a demo"
mitm_demo.py
from mitmproxy import http
def request(flow: http.HTTPFlow): #每次請求時都打印 this is a demo print("this is a demo")
通過命令 mitmdump 執行 python 腳本
-
mitmdump -s ./mitm_demo.py
執行效果
Loading script ./mitm_demo.pyProxy server listening at http://*:8080127.0.0.1:53741: clientconnect127.0.0.1:53758: clientconnect127.0.0.1:53759: clientconnect127.0.0.1:53760: clientconnectthis is a demo127.0.0.1:53758: Connection killed127.0.0.1:53758: clientdisconnectthis is a demo127.0.0.1:53759: Connection killed127.0.0.1:53759: clientdisconnect
- 插件
mitmproxy 是通過變量addons,將一個類的實例與 mitmproxy 進行關聯的。通過插件機制,可以指定在腳本運行中,與 mitmproxy 直接相關的實例。
mitm_addon.py
from mitmproxy import ctx
class Counter: def __init__(self): self.num = 0
def request(self, flow): self.num = self.num + 1 ctx.log.info("We've seen %d flows" % self.num)
addons = [ Counter()]
有幾點需要注意的是:
- Mitmproxy 是通過 addons 這個全局變量獲取以及加載插件組件。
- 每個插件都是一個實例對象,比如上面例子中的Counter()。
- 方法 requests 是一個事件的示例。在後面會有關於事件的具體介紹。
- 這個插件實現了在每一次請求的時候打印累計的請求 flow 數據。
執行命令
-
mitmdump -s ./mitm_demo.py
展示效果:
...省略..
127.0.0.1:49625: clientconnect
We've seen 9 flows
127.0.0.1:49600: GET https://www.baidu.com/content-search.xml
<< 200 OK 220b
We've seen 10 flows
127.0.0.1:49599: GET https://www.baidu.com/home/xman/data/tipspluslist?indextype=manht&_req_seqid=0xaf491b1700068f01&asyn=1&t=1618453717212&sid=33811_33816_33745_33344_31253_33849_33758_26350_22158
<< 200 OK 78b
- 事件
mitmproxy 有多個事件, 每個函數或方法代表一個事件,指每一次請求響應的過程中,都會自動調用相關的方法。每一個方法的名稱都是 mitmproxy 約定好的,都代表了 flow 的不同過程。
許多事件通過參數接收一個 flow 對象,通過修改這些對象,插件就可以即時改變流量。
import mitmproxy.http
class Events:
def request(self, flow: mitmproxy.http.HTTPFlow):
"""
每次http發起請求之後會調用這個方法
"""
def response(self, flow: mitmproxy.http.HTTPFlow):
"""
每次http返回響應之後會調用這個方法
"""
- mitmproxy 實現 map local
- 瀏覽器訪問
-
https://httpbin.testing-studio.com/get
- 響應結果如圖所示,成功實現 map local:
- 通過命令執行 python 腳本
-
mitmdump -s ./mitm_map_local.py - 編寫腳本,在請求事件中,給響應對象賦值為設定的模擬值
- mitm_map_local.py
-
import json from mitmproxy import ctx, http class Counter: def __init__(self): self.num = 0 def request(self, flow): if "https://httpbin.testing-studio.com/get" in flow.request.pretty_url: # 打開文件,讀取文件數據,作為響應,給返回 with open("./res.json", encoding="utf-8") as f: # 給flow.response屬性進行賦值, # 賦值調用mitmproxy 響應對象的 make方法 # 響應體在make函數裏面所需要的數據為str flow.response = http.HTTPResponse.make\ (200, # (optional) status code f.read(), # (optional) content {"Content-Type": "text/html"} # (optional) headers ) addons = [ Counter() ] 創建一個本地文件,響應數據設定為 { "status": "success" }
總結
- 安裝
- 證書配置
- 三大核心工具
- mitmdump 實戰