從零開始學mitmproxy抓包工具

測試開發剛哥發表於2022-02-17

Man In The Middle

mitm是Man In The Middle的首字母縮寫,意思是位於中間的人,表明mitmproxy是一個代理,可以攔截請求,實現網路抓包。知名的網路抓包工具有Fiddler、Charles、HttpWatch、WireShark、BurpSuite和Postman等,mitmproxy相對來說,沒有這麼高的知名度,它相比於以上工具的獨特優勢是,它提供了Python API,可以編寫Python程式碼對網路請求進行流量錄製,從而收集介面資訊以及轉化為介面自動化用例等。mitmproxy官方文件不但有mitmproxy工具使用介紹,還有代理實現原理,對我們學習掌握網路知識有很大幫助。

安裝與使用

pip安裝

pip install mitmproxy

mitmproxy是Python開發的,用pip就能安裝成功。官方給出了二進位制安裝包等方法,我覺得作為一款用Python開發的工具,用pip直接安裝是更Pythonic的。

命令啟動

可以通過3種命令啟動mitmproxy:

  • mitmproxy 控制檯

    mitmproxy

  • mitmweb 網頁

    mitmweb

  • mitmdump 命令列

它們的內容都是一樣的,只是UI不一樣而已。

手動設定代理

開啟以後mitmproxy預設會監聽http://localhost:8080,需要設定下代理,把代理伺服器設定為這個地址。

Windows可以這樣設定:

image-20220214224557765

設定後一定要記得點選儲存按鈕,否則代理不會生效。

實際上,Charles等網路抓包工具會自動配置代理,而mitmproxy需要手動設定代理,開發團隊的解釋是因為瀏覽器版本和配置經常會變化,所以他們建議在網上根據環境搜尋方法手動設定。

下載證照

訪問http://mitm.it/,如果代理配置沒有生效,開啟後會是這個介面:

image-20220214225512226

正常的話,會出現證照下載頁面:

image-20220214224902530

根據平臺選擇相應證照安裝就OK了。

使用

mitmproxy更其他抓包工具用法類似。

官方用視訊演示了mitmproxy如何使用:

https://docs.mitmproxy.org/stable/mitmproxytutorial-userinterface/

並且介紹了5種執行模式:

https://docs.mitmproxy.org/stable/concepts-modes/

讀者可以自行閱讀下。

mitmproxy工作原理

img

  1. 客戶端(本機)連線代理伺服器(http://127.0.0.1:8080),代理伺服器連線伺服器。
  2. 客戶端給代理伺服器發請求,代理伺服器把請求傳送到伺服器。

所有請求經過mitmproxy,就可以實現請求攔截。

對於HTTP來說,直接藉助mitmproxy傳遞請求就可以。而對於HTTPS來說,有個SSL/TLS安全認證,必須安裝證照,伺服器才會認為mitmproxy的請求是可信任的,請求才會成功傳遞。

img

HTTPS的代理過程就要複雜很多,客戶端先跟mitmproxy建立連線(12步),然後進行安全認證(36步),最後傳遞請求(7~8步)。

反向代理

假設在本機使用FastAPI啟動了個Mock服務,地址為http://127.0.0.1:5000,通過Postman調介面,怎麼使用mitmproxy來攔截請求呢?這就需要用到反向代理。

首先以反向代理模式執行mitmproxy,伺服器埠為5000,監聽埠為8000:

mitmproxy --mode reverse:http://127.0.0.1:5000 --listen-host 127.0.0.1 --listen-port 8000

然後把請求http://127.0.0.1:5000/login裡面的5000埠改成8000,訪問:

http://127.0.0.1:8000/login

就能在mitmproxy看到抓到請求了:

image-20220216221756565

這樣就能在本地使用Mock服務來除錯攔截請求的Python程式碼了。

反向代理,不需要在本機手動設定代理。

Python API

Python API是mitmproxy的特色功能:

image-20220216221930324

能夠在Python程式碼中對攔截的請求進行處理。

addons提供了很多hook函式,比如request:

"""
Basic skeleton of a mitmproxy addon.

Run as follows: mitmproxy -s anatomy.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()
]

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()
]

啟動時加上-s引數指定指令碼:

mitmdump -s ./anatomy.py

程式碼就會在請求攔截時生效了。

更多hook函式請參考官方說明:

https://docs.mitmproxy.org/stable/api/events.html

這裡就不再詳細說明了。

而關於如何使用mitmproxy錄製流量自動生成自動化用例的部分,我會開發完成後整合到tep新版本中,屆時再做介紹,敬請期待。

參考資料:

mitmproxy官方文件 https://docs.mitmproxy.org/stable/

相關文章