Exemple #1
0
def test_upstream_https(tctx):
    """
    Test mitmproxy in HTTPS upstream mode with another mitmproxy instance upstream.
    In other words:

    mitmdump --mode upstream:https://localhost:8081 --ssl-insecure
    mitmdump -p 8081
    curl -x localhost:8080 -k http://example.com
    """
    tctx1 = Context(Client(("client", 1234), ("127.0.0.1", 8080), 1605699329),
                    copy.deepcopy(tctx.options))
    tctx1.options.mode = "upstream:https://example.mitmproxy.org:8081"
    tctx2 = Context(Client(("client", 4321), ("127.0.0.1", 8080), 1605699329),
                    copy.deepcopy(tctx.options))
    assert tctx2.options.mode == "regular"
    del tctx

    proxy1 = Playbook(modes.HttpProxy(tctx1), hooks=False)
    proxy2 = Playbook(modes.HttpProxy(tctx2), hooks=False)

    upstream = Placeholder(Server)
    server = Placeholder(Server)
    clienthello = Placeholder(bytes)
    serverhello = Placeholder(bytes)
    request = Placeholder(bytes)
    tls_finished = Placeholder(bytes)
    response = Placeholder(bytes)

    assert (
        proxy1 >> DataReceived(
            tctx1.client,
            b"GET http://example.com/ HTTP/1.1\r\nHost: example.com\r\n\r\n")
        << NextLayerHook(Placeholder(NextLayer)) >>
        reply_next_layer(lambda ctx: http.HttpLayer(ctx, HTTPMode.upstream)) <<
        OpenConnection(upstream) >> reply(None) << TlsStartServerHook(
            Placeholder()) >> reply_tls_start_server(alpn=b"http/1.1") <<
        SendData(upstream, clienthello))
    assert upstream().address == ("example.mitmproxy.org", 8081)
    assert upstream().sni == "example.mitmproxy.org"
    assert (proxy2 >> DataReceived(
        tctx2.client, clienthello()) << NextLayerHook(Placeholder(NextLayer))
            >> reply_next_layer(ClientTLSLayer) << TlsStartClientHook(
                Placeholder()) >> reply_tls_start_client(alpn=b"http/1.1") <<
            SendData(tctx2.client, serverhello))
    assert (proxy1 >> DataReceived(upstream, serverhello()) << SendData(
        upstream, request))
    assert (proxy2 >> DataReceived(tctx2.client, request()) << SendData(
        tctx2.client, tls_finished) << NextLayerHook(Placeholder(NextLayer)) >>
            reply_next_layer(lambda ctx: http.HttpLayer(ctx, HTTPMode.regular))
            << OpenConnection(server) >> reply(None) << SendData(
                server, b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n') >>
            DataReceived(server,
                         b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n") <<
            SendData(tctx2.client, response))
    assert server().address == ("example.com", 80)

    assert (proxy1 >> DataReceived(
        upstream,
        tls_finished() + response()) << SendData(
            tctx1.client, b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"))
Exemple #2
0
def test_reverse_proxy(tctx, keep_host_header):
    """Test mitmproxy in reverse proxy mode.

     - make sure that we connect to the right host
     - make sure that we respect keep_host_header
     - make sure that we include non-standard ports in the host header (#4280)
    """
    server = Placeholder(Server)
    tctx.options.mode = "reverse:http://localhost:8000"
    tctx.options.connection_strategy = "lazy"
    tctx.options.keep_host_header = keep_host_header
    assert (
        Playbook(modes.ReverseProxy(tctx), hooks=False) >> DataReceived(
            tctx.client, b"GET /foo HTTP/1.1\r\n"
            b"Host: example.com\r\n\r\n") << NextLayerHook(
                Placeholder(NextLayer)) >>
        reply_next_layer(lambda ctx: http.HttpLayer(ctx, HTTPMode.transparent))
        << OpenConnection(server) >> reply(None) << SendData(
            server, b"GET /foo HTTP/1.1\r\n"
            b"Host: " +
            (b"example.com" if keep_host_header else b"localhost:8000") +
            b"\r\n\r\n") >> DataReceived(
                server, b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n") <<
        SendData(tctx.client, b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"))
    assert server().address == ("localhost", 8000)
Exemple #3
0
def test_transparent_tcp(tctx: Context, monkeypatch, connection_strategy):
    monkeypatch.setattr(platform, "original_addr", lambda sock: ("address", 22))

    flow = Placeholder(TCPFlow)
    tctx.options.connection_strategy = connection_strategy

    sock = object()
    playbook = Playbook(modes.TransparentProxy(tctx))
    (
        playbook
        << GetSocket(tctx.client)
        >> reply(sock)
    )
    if connection_strategy == "lazy":
        assert playbook
    else:
        assert (
            playbook
            << OpenConnection(tctx.server)
            >> reply(None)
            >> DataReceived(tctx.server, b"hello")
            << NextLayerHook(Placeholder(NextLayer))
            >> reply_next_layer(tcp.TCPLayer)
            << TcpStartHook(flow)
            >> reply()
            << TcpMessageHook(flow)
            >> reply()
            << SendData(tctx.client, b"hello")
        )
        assert flow().messages[0].content == b"hello"
        assert not flow().messages[0].from_client

    assert tctx.server.address == ("address", 22)
Exemple #4
0
def test_socks5_success(address: str, packed: bytes, tctx: Context):
    tctx.options.connection_strategy = "eager"
    playbook = Playbook(modes.Socks5Proxy(tctx))
    server = Placeholder(Server)
    nextlayer = Placeholder(NextLayer)
    assert (playbook >> DataReceived(tctx.client, CLIENT_HELLO) << SendData(
        tctx.client, SERVER_HELLO) >> DataReceived(
            tctx.client, b"\x05\x01\x00" + packed + b"\x12\x34applicationdata")
            << OpenConnection(server) >> reply(None) << SendData(
                tctx.client, b"\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00") <<
            NextLayerHook(nextlayer))
    assert server().address == (address, 0x1234)
    assert nextlayer().data_client() == b"applicationdata"
Exemple #5
0
def test_reverse_proxy_tcp_over_tls(tctx: Context, monkeypatch, patch,
                                    connection_strategy):
    """
    Test
        client --TCP-- mitmproxy --TCP over TLS-- server
    reverse proxying.
    """

    if patch:
        monkeypatch.setattr(tls, "ServerTLSLayer", tls.MockTLSLayer)

    flow = Placeholder(TCPFlow)
    data = Placeholder(bytes)
    tctx.options.mode = "reverse:https://localhost:8000"
    tctx.options.connection_strategy = connection_strategy
    playbook = Playbook(modes.ReverseProxy(tctx))
    if connection_strategy == "eager":
        (playbook << OpenConnection(tctx.server) >> DataReceived(
            tctx.client, b"\x01\x02\x03") >> reply(
                None, to=OpenConnection(tctx.server)))
    else:
        (playbook >> DataReceived(tctx.client, b"\x01\x02\x03"))
    if patch:
        (playbook << NextLayerHook(Placeholder(NextLayer)) >> reply_next_layer(
            tcp.TCPLayer) << TcpStartHook(flow) >> reply())
        if connection_strategy == "lazy":
            (playbook << OpenConnection(tctx.server) >> reply(None))
        assert (playbook << TcpMessageHook(flow) >> reply() << SendData(
            tctx.server, data))
        assert data() == b"\x01\x02\x03"
    else:
        if connection_strategy == "lazy":
            (playbook << NextLayerHook(Placeholder(NextLayer)) >>
             reply_next_layer(tcp.TCPLayer) << TcpStartHook(flow) >> reply() <<
             OpenConnection(tctx.server) >> reply(None))
        assert (playbook << TlsStartHook(Placeholder()) >> reply_tls_start() <<
                SendData(tctx.server, data))
        assert tls.parse_client_hello(data()).sni == "localhost"
Exemple #6
0
def test_socks5_auth_success(client_greeting: bytes, server_choice: bytes,
                             client_auth: bytes, server_resp: bytes,
                             address: bytes, packed: bytes, tctx: Context):
    ProxyAuth().load(tctx.options)
    tctx.options.proxyauth = "user:password"
    server = Placeholder(Server)
    nextlayer = Placeholder(NextLayer)
    playbook = (Playbook(modes.Socks5Proxy(tctx), logs=True) >> DataReceived(
        tctx.client, client_greeting) << SendData(tctx.client, server_choice)
                >> DataReceived(tctx.client, client_auth) <<
                modes.Socks5AuthHook(Placeholder(modes.Socks5AuthData)) >>
                reply(side_effect=_valid_socks_auth) << SendData(
                    tctx.client, server_resp) >> DataReceived(
                        tctx.client,
                        b"\x05\x01\x00" + packed + b"\x12\x34applicationdata")
                << OpenConnection(server) >> reply(None) << SendData(
                    tctx.client, b"\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00")
                << NextLayerHook(nextlayer))
    assert playbook
    assert server().address == (address, 0x1234)
    assert nextlayer().data_client() == b"applicationdata"