什么是mitmproxy
mitmproxy 就是用于 mitm 的 proxy,mitm 即中间人攻击(man-in-the-middle attack)。不同于 fiddler ,charles或 wireshark 等抓包工具,mitmproxy 不仅可以抓取请求响应帮助开发者查看、分析,更可以通过自定义python脚本进行二次开发。
安装
pip安装
pip install mitmproxy # 验证 mitmproxy --version
安装证书
打开系统代理,将系统代理设置为127.0.0.1:8080(mitmproxy默认代理)或192.168.xxx.xxx:8080(本机ip,用于局域网)
cmd输入mitmproxy, 浏览器访问 http://mitm.it/,下载证书安装。
代码安装(自动化)
设置系统代理(win)
import ctypes import winreg def set_proxy(enable_proxy, proxy_address="http://127.0.0.1:8080"): try: # 代理服务器地址和端口 proxy_server = proxy_address # 打开注册表键 key_path = r"software\microsoft\windows\currentversion\internet settings" key = winreg.openkey(winreg.hkey_current_user, key_path, 0, winreg.key_set_value) # 设置代理服务器 if enable_proxy: winreg.setvalueex(key, "proxyserver", 0, winreg.reg_sz, proxy_server) winreg.setvalueex(key, "proxyenable", 0, winreg.reg_dword, 1) else: # 关闭代理 winreg.setvalueex(key, "proxyenable", 0, winreg.reg_dword, 0) # 刷新代理设置 internet_option_refresh = 37 internet_option_settings_changed = 39 internet_set_option = ctypes.windll.wininet.internetsetoptionw internet_set_option(0, internet_option_refresh, 0, 0) internet_set_option(0, internet_option_settings_changed, 0, 0) # 关闭注册表键 winreg.closekey(key) print("系统代理设置成功!") except exception as e: print(f"设置系统代理失败: {e}") if __name__ == "__main__": # 设置代理(启用代理) set_proxy(enable_proxy=true, proxy_address="http://127.0.0.1:8080") # 设置代理(关闭代理) # set_proxy(enable_proxy=false)
安装证书(certutil.exe -addstore root mitmproxy-ca-cert.cer)
import subprocess import platform def is_mitmproxy_cert_installed(): try: # 使用 powershell 检查证书是否存在 res = subprocess.check_output(['powershell', 'get-childitem -path cert:\currentuser\root | where-object {$_.subject -like "*mitmproxy*"}']) if res: return true return false except subprocess.calledprocesserror as e: return false def install_mitmproxy_certificate(cert_path): system_platform = platform.system() if system_platform == "windows": # windows系统下使用certutil命令 try: res = subprocess.run(["certutil.exe", "-addstore", "root", cert_path], check=true, capture_output=true, text=true) print(res) print("mitmproxy证书已成功安装到根证书存储中。") except subprocess.calledprocesserror as e: print(f"安装mitmproxy证书失败: {e}") if __name__ == "__main__": if is_mitmproxy_cert_installed(): print("mitmproxy证书已安装") else: print("mitmproxy证书未安装") # 替换为实际的证书路径 certificate_path = r"mitmproxy-ca-cert.cer" install_mitmproxy_certificate(certificate_path) # "certmgr.msc"
运行
可以用 mitmproxy
、mitmdump
、mitmweb
这三个命令中的任意一个
mitmproxy
(只能在命令行窗口)命令启动后,会提供一个命令行界面,用户可以实时看到发生的请求,并通过命令过滤请求,查看请求数据mitmweb
命令启动后,会提供一个 web 界面,用户可以实时看到发生的请求,并通过 gui 交互来过滤请求,查看请求数据mitmdump
命令启动后,没有界面,结合自定义脚本,默默工作
代码启动
方式一
import os import set_proxy if __name__ == '__main__': try: set_proxy(enable_proxy=true, proxy_address="http://127.0.0.1:8080") os.system("mitmweb") # os.system("mitmdump -s .\my_script.py") except keyboardinterrupt: set_proxy(enable_proxy=false)
方式二
import asyncio import os from mitmproxy import options from mitmproxy.tools.dump import dumpmaster import set_proxy import my_script async def start_mitmproxy(): opts = options.options(listen_host='0.0.0.0', listen_port=8080) master = dumpmaster(opts) master.addons.add(my_script) await master.run() if __name__ == '__main__': try: set_proxy(enable_proxy=true, proxy_address="http://127.0.0.1:8080") asyncio.run(start_mitmproxy()) except keyboardinterrupt: set_proxy(enable_proxy=false)
脚本
需要根据需求开发
- 查官方文档:https://docs.mitmproxy.org/stable/
- 脚本示例:https://github.com/mitmproxy/mitmproxy/tree/master/examples
方式一:编写一个 py 文件,文件中定义了若干钩子函数(可查 https://docs.mitmproxy.org/stable/api/events.html)
主要是request和response修改请求响应等
import logging import mitmproxy.http num = 0 def request(flow: mitmproxy.http.httpflow): global num num = num + 1 print("we've seen %d flows" % num)
方式二:编写一个 py文件,文件定义了变量 addons插件列表,addons 是个数组,每个元素是一个类实例,这些类有若干方法,这些方法实现了某些 mitmproxy 提供的钩子事件。
import logging class counter: def __init__(self): self.num = 0 def request(self, flow): self.num = self.num + 1 logging.info("we've seen %d flows" % self.num) addons = [counter()]
更多实例前往github查看 脚本示例。
这里记录一个重订向url的获取:用requests可以直接拿到resp.url 或者使用 flow.response.headers.get(“location”)
到此这篇关于python+mitmproxy抓包的实现的文章就介绍到这了,更多相关python mitmproxy抓包内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论