python mitmproxy 代理


詳細文檔: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兩個命令。

 

查看代理后的請求情況,訪問以下網站,可查看修改請求頭之類的規則是否生效。

http://www.httpbin.org/

 

 

 

解析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#,相對麻煩。

參考:https://blog.csdn.net/weixin_40907382/article/details/80832677?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM