Example #1
0
 def __check_self_connect(self):
     """
     We try to protect the proxy from _accidentally_ connecting to itself,
     e.g. because of a failed transparent lookup or an invalid configuration.
     """
     address = self.server_conn.address
     if address:
         self_connect = (address.port == self.config.options.listen_port and
                         address.host in ("localhost", "127.0.0.1", "::1"))
         if self_connect:
             raise exceptions.ProtocolException(
                 "Invalid server address: {}\r\n"
                 "The proxy shall not connect to itself.".format(
                     repr(address)))
    def _next_layer(self, top_layer):
        try:
            d = top_layer.client_conn.rfile.peek(3)
        except exceptions.TcpException as e:
            raise exceptions.ProtocolException(str(e))
        client_tls = tls.is_tls_record_magic(d)

        # 1. check for filter
        skipped_url = ""
        is_filtered = False

        if True:  #self.config.check_filter:
            if not top_layer.server_conn.address is None:
                is_filtered = (self.config.check_filter(
                    top_layer.server_conn.address)
                               or selfc.SelfCShared.isTrusted(
                                   top_layer.server_conn.address[0]))
            if is_filtered:
                skipped_url = top_layer.server_conn.address[0]

            if not is_filtered and client_tls:
                try:
                    client_hello = tls.ClientHello.from_file(
                        self.client_conn.rfile)
                except exceptions.TlsProtocolException as e:
                    self.log("Cannot parse Client Hello: %s" % repr(e),
                             "error")
                else:
                    sni_str = client_hello.sni and client_hello.sni.decode(
                        "idna")
                    if not sni_str is None:
                        is_filtered = self.config.check_filter(
                            (sni_str,
                             443)) or selfc.SelfCShared.isTrusted(sni_str)
                    if is_filtered:
                        skipped_url = sni_str
            if is_filtered:
                print("####### MITM Skip, Trusted: " + skipped_url)
                return protocol.RawTCPLayer(top_layer, ignore=True)

        # 2. Always insert a TLS layer, even if there's neither client nor server tls.
        # An inline script may upgrade from http to https,
        # in which case we need some form of TLS layer.
        if isinstance(top_layer, modes.ReverseProxy):
            return protocol.TlsLayer(top_layer, client_tls,
                                     top_layer.server_tls,
                                     top_layer.server_conn.address[0])
        if isinstance(top_layer, protocol.ServerConnectionMixin):
            return protocol.TlsLayer(top_layer, client_tls, client_tls)
        if isinstance(top_layer, protocol.UpstreamConnectLayer):
            # if the user manually sets a scheme for connect requests, we use this to decide if we
            # want TLS or not.
            if top_layer.connect_request.scheme:
                server_tls = top_layer.connect_request.scheme == "https"
            else:
                server_tls = client_tls
            return protocol.TlsLayer(top_layer, client_tls, server_tls)

        # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed.
        if isinstance(top_layer, protocol.TlsLayer):
            if isinstance(top_layer.ctx, modes.HttpProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.regular)
            if isinstance(top_layer.ctx, modes.HttpUpstreamProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.upstream)

        # 4. Check for other TLS cases (e.g. after CONNECT).
        if client_tls:
            return protocol.TlsLayer(top_layer, True, True)

        # 4. Check for --tcp
        if self.config.check_tcp(top_layer.server_conn.address):
            return protocol.RawTCPLayer(top_layer)

        # 5. Check for TLS ALPN (HTTP1/HTTP2)
        if isinstance(top_layer, protocol.TlsLayer):
            alpn = top_layer.client_conn.get_alpn_proto_negotiated()
            if alpn == b'h2':
                return protocol.Http2Layer(top_layer,
                                           http.HTTPMode.transparent)
            if alpn == b'http/1.1':
                return protocol.Http1Layer(top_layer,
                                           http.HTTPMode.transparent)

        # 6. Check for raw tcp mode
        is_ascii = (
            len(d) == 3 and
            # expect A-Za-z
            all(65 <= x <= 90 or 97 <= x <= 122 for x in d))
        if self.config.options.rawtcp and not is_ascii:
            return protocol.RawTCPLayer(top_layer)

        # 7. Assume HTTP1 by default
        return protocol.Http1Layer(top_layer, http.HTTPMode.transparent)
Example #3
0
    def _next_layer(self, top_layer):
        logging.info('root_context._next_layer(%s)', top_layer)
        try:
            d = top_layer.client_conn.rfile.peek(3)
        except exceptions.TcpException as e:
            logging.info('ignoring protocol: %s', e)
            raise exceptions.ProtocolException(str(e))
        client_tls = tls.is_tls_record_magic(d)
        host, port = '(unknown)', '(unknown)'

        # 1. check for filter
        if self.config.check_filter:
            if top_layer.server_conn.address:
                host, port = top_layer.server_conn.address
            is_filtered = self.config.check_filter(
                top_layer.server_conn.address)
            logging.info('_next_layer: %s is_filtered: %s',
                         vars(top_layer.server_conn), is_filtered)
            if not is_filtered and client_tls:
                try:
                    client_hello = tls.ClientHello.from_file(
                        self.client_conn.rfile)
                except exceptions.TlsProtocolException as e:
                    self.log("Cannot parse Client Hello: %s" % repr(e),
                             "error")
                else:
                    sni_str = client_hello.sni and client_hello.sni.decode(
                        "idna")
                    host, port = (sni_str, 443)
                    is_filtered = self.config.check_filter((host, port))
            logging.info('is_filtered: %s', is_filtered)
            if is_filtered:
                if self.config.options.block_not_ignore:
                    self.log(
                        '-> {}:{} {} blocked'.format(host, port,
                                                     datetime.now()), 'info')
                    raise exceptions.Kill(
                        f'blocked https request to filtered host {host}')
                else:
                    return protocol.RawTCPLayer(top_layer, ignore=True)
            else:
                self.log(
                    '-> {}:{} {} allowed'.format(host, port, datetime.now()),
                    'info')

        # 2. Always insert a TLS layer, even if there's neither client nor server tls.
        # An inline script may upgrade from http to https,
        # in which case we need some form of TLS layer.
        if isinstance(top_layer, modes.ReverseProxy):
            return protocol.TlsLayer(top_layer, client_tls,
                                     top_layer.server_tls,
                                     top_layer.server_conn.address[0])
        if isinstance(top_layer, protocol.ServerConnectionMixin):
            return protocol.TlsLayer(top_layer, client_tls, client_tls)
        if isinstance(top_layer, protocol.UpstreamConnectLayer):
            # if the user manually sets a scheme for connect requests, we use this to decide if we
            # want TLS or not.
            if top_layer.connect_request.scheme:
                server_tls = top_layer.connect_request.scheme == "https"
            else:
                server_tls = client_tls
            return protocol.TlsLayer(top_layer, client_tls, server_tls)

        # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed.
        if isinstance(top_layer, protocol.TlsLayer):
            if isinstance(top_layer.ctx, modes.HttpProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.regular)
            if isinstance(top_layer.ctx, modes.HttpUpstreamProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.upstream)

        # 4. Check for other TLS cases (e.g. after CONNECT).
        if client_tls:
            return protocol.TlsLayer(top_layer, True, True)

        # 4. Check for --tcp
        if self.config.check_tcp(top_layer.server_conn.address):
            return protocol.RawTCPLayer(top_layer)

        # 5. Check for TLS ALPN (HTTP1/HTTP2)
        if isinstance(top_layer, protocol.TlsLayer):
            alpn = top_layer.client_conn.get_alpn_proto_negotiated()
            if alpn == b'h2':
                return protocol.Http2Layer(top_layer,
                                           http.HTTPMode.transparent)
            if alpn == b'http/1.1':
                return protocol.Http1Layer(top_layer,
                                           http.HTTPMode.transparent)

        # 6. Check for raw tcp mode
        is_ascii = (
            len(d) == 3 and
            # expect A-Za-z
            all(65 <= x <= 90 or 97 <= x <= 122 for x in d))
        if self.config.options.rawtcp and not is_ascii:
            return protocol.RawTCPLayer(top_layer)

        # 7. Assume HTTP1 by default
        return protocol.Http1Layer(top_layer, http.HTTPMode.transparent)
Example #4
0
    def _next_layer(self, top_layer):
        try:
            d = top_layer.client_conn.rfile.peek(3)
        except exceptions.TcpException as e:
            raise exceptions.ProtocolException(str(e))
        client_tls = protocol.is_tls_record_magic(d)

        # 1. check for --ignore
        if self.config.check_ignore:
            ignore = self.config.check_ignore(top_layer.server_conn.address)
            if not ignore and client_tls:
                try:
                    client_hello = protocol.TlsClientHello.from_client_conn(self.client_conn)
                except exceptions.TlsProtocolException as e:
                    self.log("Cannot parse Client Hello: %s" % repr(e), "error")
                else:
                    ignore = self.config.check_ignore((client_hello.sni, 443))
            if ignore:
                return protocol.RawTCPLayer(top_layer, ignore=True)

        # 2. Always insert a TLS layer, even if there's neither client nor server tls.
        # An inline script may upgrade from http to https,
        # in which case we need some form of TLS layer.
        if isinstance(top_layer, modes.ReverseProxy):
            return protocol.TlsLayer(top_layer, client_tls, top_layer.server_tls, top_layer.server_conn.address.host)
        if isinstance(top_layer, protocol.ServerConnectionMixin) or isinstance(top_layer, protocol.UpstreamConnectLayer):
            return protocol.TlsLayer(top_layer, client_tls, client_tls)

        # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed.
        if isinstance(top_layer, protocol.TlsLayer):
            if isinstance(top_layer.ctx, modes.HttpProxy):
                return protocol.Http1Layer(top_layer, "regular")
            if isinstance(top_layer.ctx, modes.HttpUpstreamProxy):
                return protocol.Http1Layer(top_layer, "upstream")

        # 4. Check for other TLS cases (e.g. after CONNECT).
        if client_tls:
            return protocol.TlsLayer(top_layer, True, True)

        # 4. Check for --tcp
        if self.config.check_tcp(top_layer.server_conn.address):
            return protocol.RawTCPLayer(top_layer)

        # 5. Check for TLS ALPN (HTTP1/HTTP2)
        if isinstance(top_layer, protocol.TlsLayer):
            alpn = top_layer.client_conn.get_alpn_proto_negotiated()
            if alpn == b'h2':
                return protocol.Http2Layer(top_layer, 'transparent')
            if alpn == b'http/1.1':
                return protocol.Http1Layer(top_layer, 'transparent')

        # 6. Check for raw tcp mode
        is_ascii = (
            len(d) == 3 and
            # expect A-Za-z
            all(65 <= x <= 90 or 97 <= x <= 122 for x in d)
        )
        if self.config.options.rawtcp and not is_ascii:
            return protocol.RawTCPLayer(top_layer)

        # 7. Assume HTTP1 by default
        return protocol.Http1Layer(top_layer, 'transparent')
Example #5
0
    def _next_layer(self, top_layer):
        try:
            d = top_layer.client_conn.rfile.peek(3)
        except exceptions.TcpException as e:
            raise exceptions.ProtocolException(str(e))
        client_tls = protocol.is_tls_record_magic(d)

        # 1. check for --ignore
        if self.config.check_ignore:
            ignore = self.config.check_ignore(top_layer.server_conn.address)
            if not ignore and client_tls:
                try:
                    client_hello = protocol.TlsClientHello.from_client_conn(
                        self.client_conn)
                except exceptions.TlsProtocolException as e:
                    self.log("Cannot parse Client Hello: %s" % repr(e),
                             "error")
                else:
                    ignore = self.config.check_ignore((client_hello.sni, 443))
            if ignore:
                return protocol.RawTCPLayer(top_layer, ignore=True)

        # 2. Always insert a TLS layer, even if there's neither client nor server tls.
        # An inline script may upgrade from http to https,
        # in which case we need some form of TLS layer.
        if isinstance(top_layer, modes.ReverseProxy):
            return protocol.TlsLayer(top_layer, client_tls,
                                     top_layer.server_tls,
                                     top_layer.server_conn.address[0])
        if isinstance(top_layer, protocol.ServerConnectionMixin):
            return protocol.TlsLayer(top_layer, client_tls, client_tls)
        if isinstance(top_layer, protocol.UpstreamConnectLayer):
            # if the user manually sets a scheme for connect requests, we use this to decide if we
            # want TLS or not.
            if top_layer.connect_request.scheme:
                tls = top_layer.connect_request.scheme == "https"
            else:
                tls = client_tls
            return protocol.TlsLayer(top_layer, client_tls, tls)

        # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed.
        if isinstance(top_layer, protocol.TlsLayer):
            if isinstance(top_layer.ctx, modes.HttpProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.regular)
            if isinstance(top_layer.ctx, modes.HttpUpstreamProxy):
                return protocol.Http1Layer(top_layer, http.HTTPMode.upstream)

        # 4. Check for other TLS cases (e.g. after CONNECT).
        if client_tls:
            return protocol.TlsLayer(top_layer, True, True)

        # 4. Check for --tcp
        if self.config.check_tcp(top_layer.server_conn.address):
            return protocol.RawTCPLayer(top_layer)

        # 5. Check for TLS ALPN (HTTP1/HTTP2)
        if isinstance(top_layer, protocol.TlsLayer):
            alpn = top_layer.client_conn.get_alpn_proto_negotiated()
            if alpn == b'h2':
                return protocol.Http2Layer(top_layer,
                                           http.HTTPMode.transparent)
            if alpn == b'http/1.1':
                return protocol.Http1Layer(top_layer,
                                           http.HTTPMode.transparent)

        # 6. Assume HTTP1 by default
        return protocol.Http1Layer(top_layer, http.HTTPMode.transparent)