詳細文檔:https://mitmproxy.readthedocs.io/en/v2.0.2/mitmdump.html
安裝:
sudo pip3 install mitmproxy
自定義解析規則
#!/usr/bin/python3 # -*- coding:UTF-8 -*- # mitmdump -s _00_mitmproxy.py -p 9000 --set block_global=false #linux # mitmdump -s _10_mitmproxy_filter.py -p 9000 #linux import mitmproxy.http from mitmproxy import ctx TARGET_URL = 'https://xxx.com/' class Counter: def __init__(self): self.num = 0 # def request(self, flow: mitmproxy.http.HTTPFlow): # if flow.request.method == 'CONNECT': # return # if flow.live: # proxy = ('http://xxx', 9000) # print(flow.request.host) # flow.live.change_upstream_proxy_server(proxy) def request(self, flow: mitmproxy.http.HTTPFlow): req = flow.request req.headers[ 'User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36' ctx.log.info('Mod request useragent') def response(self, flow: mitmproxy.http.HTTPFlow): if TARGET_URL in flow.request.url and flow.request.method == 'POST': print(flow.response.text) self.num += 1 print('get {} flows'.format(self.num)) ctx.log.error('get {} flows'.format(self.num)) addons = [Counter()]
命令行啟動代理,輸出到命令行:
mitmdump -s _00_mitmproxy.py -p 9000 --set block_global=false #linux允許其他主機使用代理 mitmdump -s _10_mitmproxy_filter.py -p 9000 #linux
此外,還有mitmproxy和mitmweb兩個命令。
查看代理后的請求情況,訪問以下網站,可查看修改請求頭之類的規則是否生效。
解析https需要添加證書信任,啟動代理后,設置瀏覽器使用該代理,在瀏覽器中打開mitm.it,官網有說明不同系統如何添加證書信任。
或在啟動時加參數
--disable-infobars --ignore-certificate-errors
https://blog.csdn.net/learner198461/article/details/83006628
部分HTTPS報錯,mitmproxy Cannot establish TLS with client時,規則文件中添加該文件
https://github.com/mitmproxy/mitmproxy/blob/master/examples/contrib/tls_passthrough.py
""" This inline script allows conditional TLS Interception based on a user-defined strategy. Example: > mitmdump -s tls_passthrough.py 1. curl --proxy http://localhost:8080 https://example.com --insecure // works - we'll also see the contents in mitmproxy 2. curl --proxy http://localhost:8080 https://example.com --insecure // still works - we'll also see the contents in mitmproxy 3. curl --proxy http://localhost:8080 https://example.com // fails with a certificate error, which we will also see in mitmproxy 4. curl --proxy http://localhost:8080 https://example.com // works again, but mitmproxy does not intercept and we do *not* see the contents Authors: Maximilian Hils, Matthew Tuusberg """ import collections import random from enum import Enum import mitmproxy from mitmproxy import ctx from mitmproxy.exceptions import TlsProtocolException from mitmproxy.proxy.protocol import TlsLayer, RawTCPLayer class InterceptionResult(Enum): success = True failure = False skipped = None class _TlsStrategy: """ Abstract base class for interception strategies. """ def __init__(self): # A server_address -> interception results mapping self.history = collections.defaultdict(lambda: collections.deque(maxlen=200)) def should_intercept(self, server_address): """ Returns: True, if we should attempt to intercept the connection. False, if we want to employ pass-through instead. """ raise NotImplementedError() def record_success(self, server_address): self.history[server_address].append(InterceptionResult.success) def record_failure(self, server_address): self.history[server_address].append(InterceptionResult.failure) def record_skipped(self, server_address): self.history[server_address].append(InterceptionResult.skipped) class ConservativeStrategy(_TlsStrategy): """ Conservative Interception Strategy - only intercept if there haven't been any failed attempts in the history. """ def should_intercept(self, server_address): if InterceptionResult.failure in self.history[server_address]: return False return True class ProbabilisticStrategy(_TlsStrategy): """ Fixed probability that we intercept a given connection. """ def __init__(self, p): self.p = p super(ProbabilisticStrategy, self).__init__() def should_intercept(self, server_address): return random.uniform(0, 1) < self.p class TlsFeedback(TlsLayer): """ Monkey-patch _establish_tls_with_client to get feedback if TLS could be established successfully on the client connection (which may fail due to cert pinning). """ def _establish_tls_with_client(self): server_address = self.server_conn.address try: super(TlsFeedback, self)._establish_tls_with_client() except TlsProtocolException as e: tls_strategy.record_failure(server_address) raise e else: tls_strategy.record_success(server_address) # inline script hooks below. tls_strategy = None def load(l): l.add_option( "tlsstrat", int, 0, "TLS passthrough strategy (0-100)", ) def configure(updated): global tls_strategy if ctx.options.tlsstrat > 0: tls_strategy = ProbabilisticStrategy(float(ctx.options.tlsstrat) / 100.0) else: tls_strategy = ConservativeStrategy() def next_layer(next_layer): """ This hook does the actual magic - if the next layer is planned to be a TLS layer, we check if we want to enter pass-through mode instead. """ if isinstance(next_layer, TlsLayer) and next_layer._client_tls: server_address = next_layer.server_conn.address if tls_strategy.should_intercept(server_address): # We try to intercept. # Monkey-Patch the layer to get feedback from the TLSLayer if interception worked. next_layer.__class__ = TlsFeedback else: # We don't intercept - reply with a pass-through layer and add a "skipped" entry. mitmproxy.ctx.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info") next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True) next_layer.reply.send(next_layer_replacement) tls_strategy.record_skipped(server_address)
規則文件中添加該文件啟動代理后,還報錯,很可能是網站使用http/2協議,mitmproxy對http/2不能全部支持。
要對http/2完全支持,可以使用anyproxy,使用node.js開發的,可二次開發,有WebUI。 http://anyproxy.io/
fiddle everywhere也支持http/2,可用作測試,分析。二次開發要使用C#,相對麻煩。
