示例#1
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)
示例#2
0
def test_upgrade(tctx, proto):
    """Test a HTTP -> WebSocket upgrade with different protocols enabled"""
    if proto != "websocket":
        tctx.options.websocket = False
    if proto != "tcp":
        tctx.options.rawtcp = False

    tctx.server.address = ("example.com", 80)
    tctx.server.state = ConnectionState.OPEN
    http_flow = Placeholder(HTTPFlow)
    playbook = Playbook(http.HttpLayer(tctx, HTTPMode.transparent))
    (
            playbook
            >> DataReceived(tctx.client,
                            b"GET / HTTP/1.1\r\n"
                            b"Connection: upgrade\r\n"
                            b"Upgrade: websocket\r\n"
                            b"Sec-WebSocket-Version: 13\r\n"
                            b"\r\n")
            << http.HttpRequestHeadersHook(http_flow)
            >> reply()
            << http.HttpRequestHook(http_flow)
            >> reply()
            << SendData(tctx.server, b"GET / HTTP/1.1\r\n"
                                     b"Connection: upgrade\r\n"
                                     b"Upgrade: websocket\r\n"
                                     b"Sec-WebSocket-Version: 13\r\n"
                                     b"\r\n")
            >> DataReceived(tctx.server, b"HTTP/1.1 101 Switching Protocols\r\n"
                                         b"Upgrade: websocket\r\n"
                                         b"Connection: Upgrade\r\n"
                                         b"\r\n")
            << http.HttpResponseHeadersHook(http_flow)
            >> reply()
            << http.HttpResponseHook(http_flow)
            >> reply()
            << SendData(tctx.client, b"HTTP/1.1 101 Switching Protocols\r\n"
                                     b"Upgrade: websocket\r\n"
                                     b"Connection: Upgrade\r\n"
                                     b"\r\n")
    )
    if proto == "websocket":
        assert playbook << WebsocketStartHook(Placeholder(WebSocketFlow))
    elif proto == "tcp":
        assert playbook << TcpStartHook(Placeholder(TCPFlow))
    else:
        assert (
            playbook
            << Log("Sent HTTP 101 response, but no protocol is enabled to upgrade to.", "warn")
            << CloseConnection(tctx.client)
        )
示例#3
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"
示例#4
0
def test_http_proxy_tcp(tctx, mode, close_first):
    """Test TCP over HTTP CONNECT."""
    server = Placeholder(Server)
    f = Placeholder(TCPFlow)
    tctx.options.connection_strategy = "lazy"

    if mode == "upstream":
        tctx.options.mode = "upstream:http://proxy:8080"
        toplayer = http.HttpLayer(tctx, HTTPMode.upstream)
    else:
        tctx.options.mode = "regular"
        toplayer = http.HttpLayer(tctx, HTTPMode.regular)

    playbook = Playbook(toplayer, hooks=False)
    assert (playbook >> DataReceived(
        tctx.client, b"CONNECT example:443 HTTP/1.1\r\n\r\n") << SendData(
            tctx.client, b"HTTP/1.1 200 Connection established\r\n\r\n") >>
            DataReceived(tctx.client, b"this is not http") <<
            layer.NextLayerHook(Placeholder()) >>
            reply_next_layer(lambda ctx: TCPLayer(ctx, ignore=False)) <<
            TcpStartHook(f) >> reply() << OpenConnection(server))

    playbook >> reply(None)
    if mode == "upstream":
        playbook << SendData(server, b"CONNECT example:443 HTTP/1.1\r\n\r\n")
        playbook >> DataReceived(
            server, b"HTTP/1.1 200 Connection established\r\n\r\n")

    assert (playbook << SendData(server, b"this is not http") >> DataReceived(
        server, b"true that") << SendData(tctx.client, b"true that"))

    if mode == "regular":
        assert server().address == ("example", 443)
    else:
        assert server().address == ("proxy", 8080)

    assert (playbook >> TcpMessageInjected(
        f, TCPMessage(False,
                      b"fake news from your friendly man-in-the-middle")) <<
            SendData(tctx.client,
                     b"fake news from your friendly man-in-the-middle"))

    if close_first == "client":
        a, b = tctx.client, server
    else:
        a, b = server, tctx.client
    assert (playbook >> ConnectionClosed(a) << CloseConnection(b) >>
            ConnectionClosed(b) << CloseConnection(a))