mitmproxy 相比Charles、fiddler的優點在於,它可以命令列方式或指令碼的方式進行mock
mitmproxy不僅可以像Charles那樣抓包,還可以對請求資料進行二次開發,進入高度二次定製
大家可以先檢視下官網的相關文件
- mitmproxy 官網:https://www.mitmproxy.org/
- mitmproxy 官方文件:https://docs.mitmproxy.org/stable/
- mitmproxy 官方指令碼 demo:https://docs.mitmproxy.org/stable/addons-examples/
mitmproxy安裝
Mac安裝
brew install mitmproxy
Windows安裝
該方法同樣適用於Mac,是利用Python安裝的
pip install pipx
pipx install mitmproxy
也可以直接使用 pip install mitmproxy
命令安裝
如果是Mac,通過這2條命令安裝完後,會自動新增好環境變數。
但對於Windows來說,就需要我們手動新增環境變數了,Windows安裝成功的提示中會給出需要配置的目錄,將其配置到path環境變數中即可
推薦使用Python進行安裝,注意Python版本需大於等於3.6
安裝並配置完環境變數後,可以通過檢視版命令本mitmproxy --version
驗證我們是否安裝並配置好環境變數
mirmproxy使用
同Charles一樣,在使用mitmproxy之前,我們需要先安裝整數
在連線mitmproxy代理之後,通過訪問連線:http://mitm.it/ 來安裝證照
選擇相應版本安裝即可,注意安裝完證照後需要信任證照後才能正常進行抓包
mitmproxy 工具有以下三部分組成
- mitmproxy -> 命令列工具(win不支援)
- mitmdump -> 載入 python 指令碼
- mitmweb -> web 介面工具
常用引數
-h 幫助資訊
-p 修改監聽埠
-s 載入 python 指令碼
預設監聽埠8080
mitmproxy
mitmproxy是已命令列的方式執行的
例:監聽8999埠進行抓包
mitmproxy -p 8999
可以通過上下移動滑鼠滾輪的切換請求,選中某一請求後單擊可檢視請求詳情
然後通過q
命令可以返回到主介面,然後通過f
命令加上要過濾的引數可以過濾請求,如下是隻展示包含mitmproxy的請求
最後可以通過q
命令退出
mitmweb
mitmweb是啟動同mitmproxy啟動方式一樣,與mitmproxy不同的是,mitmweb是有web頁面的
例:啟動mitmweb並指定監聽8999埠
mitmweb -p 8999
遇到的坑,當我通過命令mitmweb -p 8999
啟動時,報OSError: [Errno 48] Address already in use
的錯誤,報錯詳情如下:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/bin/mitmweb", line 8, in <module>
sys.exit(mitmweb())
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/mitmproxy/tools/main.py", line 168, in mitmweb
run(web.master.WebMaster, cmdline.mitmweb, args)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/mitmproxy/tools/main.py", line 127, in run
master.run()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/mitmproxy/tools/web/master.py", line 108, in run
http_server.listen(self.options.web_port, self.options.web_host)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/tornado/tcpserver.py", line 151, in listen
sockets = bind_sockets(port, address=address)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/tornado/netutil.py", line 174, in bind_sockets
sock.bind(sockaddr)
OSError: [Errno 48] Address already in use
以上報錯是因為,mitmweb啟動需要使用8081埠,而我的8081埠已經被佔用了,終止佔用的程式之後,啟動成功
chenshifengdeMacBook-Pro:~ chenshifeng$ lsof -i:8081
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 456 chenshifeng 128u IPv6 0xfe3ce857c44c2c7d 0t0 TCP localhost:sunproxyadmin (LISTEN)
chenshifengdeMacBook-Pro:~ chenshifeng$ kill 456
chenshifengdeMacBook-Pro:~ chenshifeng$ mitmweb -p 8999
Web server listening at http://127.0.0.1:8081/
Proxy server listening at http://*:8999
頁面功能介紹:
miemweb mock資料使用:
mitmdump
mitmdump是核心,需要重點掌握
mitmdump 是 mitmproxy 的命令列版本。將 tcpdump 用於 HTT
近似於 charles 的命令列版本
python:mitmproxy
功能和 charles、fiddler 相似,強大之處在於它的工具 mitmdump 可以直接對接 python 對請求做處理
mitmdump 是 mitmproxy 的命令列視窗,同時還可對接 python 對請求進行處理,因此就不用手動截獲和分析 http 請求和響應,只需要寫好請求和響應的處理邏輯即可
錄製與回放
- 錄製:mitmdump -w 檔名
- 過濾:mitmdump -nr 檔名 -w 檔名2 "~s hogwarts"
- 回放:mitmdump -nC 檔名
引數
- -s "script.py --bar" # 執行指令碼,通過雙引號來新增引數
- -n 不啟動代理
- -r 讀取檔案內容
- -w 寫入檔案
- ~s 過濾響應資料
- ~q 過濾請求資料
- 更多引數見:https://docs.mitmproxy.org/stable/concepts-filters/
例1:監聽8999埠,並錄製請求資料,儲存到baidu.txt檔案
mitmdump -p 8999 -w baidu.txt
開啟百度搜尋,依次搜尋mitmproxy、mitmweb、mitmdump,然後結束錄製。錄製結束後,會在當前目錄下生成二進位制錄製檔案baudu.txt
例2:過濾上面錄製的請求,只儲存搜尋mitmdump的資料
mitmdump -nr baidu.txt -w mitmdump.txt "~s mitmdump"
chenshifengdeMacBook-Pro:mitm chenshifeng$ mitmdump -nr baidu.txt -w mitmdump.txt "~s mitmdump"
Only processing flows that match "~s mitmdump"
127.0.0.1:54144: GET https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=33423,33429…
<< 200 OK 675b
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&mod=11&isbd=1&isid=fdb4c9fa0004968c&ie=utf-8&f=8&rsv_bp=1&tn…
<< 200 OK 214b
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&mod=1&isbd=1&isid=fdb4c9fa0004968c&ie=utf-8&f=8&rsv_bp=1&tn=…
<< 200 OK 24.8k
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&csq=1&pstg=20&mod=2&isbd=1&cqid=eaf04f36001734b3&istc=361&ve…
<< 200 OK 78b
127.0.0.1:54153: GET https://sp0.baidu.com/5bU_dTmfKgQFm2e88IuM_a/w.gif?q=mitmdump&fm=se&T=1612592652&y=9FD1FDF9&r…
<< 200 OK 0b
127.0.0.1:54149: GET https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/wb.gif?type=3&fm=flow_monitor&data=%5B%7B%7D%5D&…
<< 200 OK 0b
chenshifengdeMacBook-Pro:mitm chenshifeng$ ls
baidu.txt mitmdump.txt
例3:回放mitmdump.txt 檔案介面
mitmdump -nC mitmdump.txt
chenshifengdeMacBook-Pro:mitm chenshifeng$ mitmdump -nC mitmdump.txt
127.0.0.1:54144: GET https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=33423,33429…
<< 200 OK 676b
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&mod=11&isbd=1&isid=fdb4c9fa0004968c&ie=utf-8&f=8&rsv_bp=1&tn…
<< 200 OK 214b
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&mod=1&isbd=1&isid=fdb4c9fa0004968c&ie=utf-8&f=8&rsv_bp=1&tn=…
<< 200 OK 25k
127.0.0.1:54140: GET https://www.baidu.com/s?ie=utf-8&csq=1&pstg=20&mod=2&isbd=1&cqid=eaf04f36001734b3&istc=361&ve…
<< 200 OK 78b
127.0.0.1:54153: GET https://sp0.baidu.com/5bU_dTmfKgQFm2e88IuM_a/w.gif?q=mitmdump&fm=se&T=1612592652&y=9FD1FDF9&r…
<< 200 OK 0b
127.0.0.1:54149: GET https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/wb.gif?type=3&fm=flow_monitor&data=%5B%7B%7D%5D&…
<< 200 OK 0b
chenshifengdeMacBook-Pro:mitm chenshifeng$
mitmdump 指令碼
例1:增加請求的頭資訊
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:test_mitm.py
@time:2020/11/29
"""
from mitmproxy import http
def request(flow: http.HTTPFlow):
# 增加請求的頭資訊
flow.request.headers["myheader"] = "shifeng"
print(flow.request.headers)
載入指令碼:mitmdump -p 8999 -s /Users/chenshifeng/MyCode/PythonCode/SFDSZL/interface/test_mitm.py
例2:實現Charles中的MapLocal功能
修改返回值:
mitmdump指令碼
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:test_maplocal.py
@time:2020/11/29
"""
from mitmproxy import http
def request(flow: http.HTTPFlow):
# 修改判斷條件
if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
# 開啟儲存在本地的資料檔案
with open("/Users/chenshifeng/MyCode/PythonCode/SFDSZL/interface/quote.json") as f:
# 創造一個 response
flow.response = http.HTTPResponse.make(
200, # (optional) status code
# 讀取檔案中資料作為返回內容
f.read(),
# 指定返回資料的型別
{"Content-Type": "application/json"} # (optional) headers
)
載入指令碼: mitmdump -p 8999 -s /Users/chenshifeng/MyCode/PythonCode/SFDSZL/interface/test_maplocal.py
例3:實現Charles中的MapRemote功能
mitmdump指令碼
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:test_rewrite.py
@time:2020/11/29
"""
import json
from mitmproxy import http
def response(flow: http.HTTPFlow):
# 加上過濾條件
if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
# 把響應資料轉化成python物件,儲存到data中
data = json.loads(flow.response.content)
# 對第一個股票保持原樣
data['data']['items'][0] = data['data']['items'][0]
# 對第二個股票名字加長一倍
data['data']['items'][1]['quote']['name'] = data['data']['items'][1]['quote']['name'] * 2
# 對第三個股票名字變成空
data['data']['items'][2]['quote']['name'] = None
# 把修改後的內容賦值給 response 原始資料格式
flow.response.text = json.dumps(data)
載入指令碼: mitmdump -p 8999 -s /Users/chenshifeng/MyCode/PythonCode/SFDSZL/interface/test_rewrite.py
更多例子詳見官網介紹:https://docs.mitmproxy.org/stable/addons-scripting/