這一節教大家編寫 Mitmproxy 自定義腳本,這才是 Mitmproxy 真正強大的在方。
Mitmproxy官方給了很多例子:
https://docs.mitmproxy.org/stable/addons-examples/
我們演示一個簡單的例子 http-add-header.py, 為每一個 response 中增一個數字,標明是當前是第幾個請求。
"""Add an HTTP header to each response."""
class AddHeader:
def __init__(self):
self.num = 0
def response(self, flow):
self.num = self.num + 1
flow.response.headers["count"] = str(self.num)
addons = [
AddHeader()
]
mitmweb
為了直觀的看到請求和響應的數據,我們使用 mitmweb 命令運行腳本。
> mitmweb -s .\http-add-header.py
Web server listening at http://127.0.0.1:8081/
Loading script .\http-add-header.py
Proxy server listening at http://*:8080
...
這個命令就比較厲害了,它啟動默認瀏覽器,並打開一個web版的抓包工具。

打開postman 或其他任何接口調用工具,隨便訪問一個接口。例如

然后,你會發現mitmproxy已經抓取到請求了,並且為每一個請求的response的響應頭增加了一個字段。

有沒有很強大。那么我們可以用它來干啥。
- 修改request/response 參數。
- 打斷點,解析某個請求的結果並修改里面的參數。
- 過濾請求,只記錄某個 host 的請求信息。
- 將某些接口的數據攔截-解析-保存到數據庫。
當然,我上面這些大部分你用 fiddler/charles 工具也能完成,但Mitmproxy 可玩性更高,也更加強大。
HTTP生命周期
我們工作中測試的大部分接口都是HTTP的。所以,我們要了解一個HTTP的生命周期。
def http_connect(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 收到了來自客戶端的 HTTP CONNECT 請求。在 flow 上設置非 2xx 響應將返回該響應並斷開連接。CONNECT 不是常用的 HTTP 請求方法,目的是與服務器建立代理連接,僅是 client 與 proxy 的之間的交流,所以 CONNECT 請求不會觸發 request、response 等其他常規的 HTTP 事件。
def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 來自客戶端的 HTTP 請求的頭部被成功讀取。此時 flow 中的 request 的 body 是空的。
def request(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 來自客戶端的 HTTP 請求被成功完整讀取。
def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 來自服務端的 HTTP 響應的頭部被成功讀取。此時 flow 中的 response 的 body 是空的。
def response(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 來自服務端端的 HTTP 響應被成功完整讀取。
def error(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 發生了一個 HTTP 錯誤。比如無效的服務端響應、連接斷開等。注意與“有效的 HTTP 錯誤返回”不是一回事,后者是一個正確的服務端響應,只是 HTTP code 表示錯誤而已。
