Exemplo n.º 1
0
    def test_split_multi(self):
        conn = SSLv30Connection(
            protocol_version=flextls.registry.version.SSLv3)
        assert conn.is_empty()

        data = server_hello_01
        data += server_certificate_01
        data += server_key_exchange_01
        data += server_hello_done_01

        for part in prepare_handshake_data_split(data, 50):
            conn.decode(part)
        assert not conn.is_empty()
        record = conn.pop_record()
        self._server_hello_01(record)

        assert not conn.is_empty()
        record = conn.pop_record()
        self._server_certificate_01(record)

        assert not conn.is_empty()
        record = conn.pop_record()
        self._server_key_exchange_01(record)

        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._server_hello_done_01(record)
Exemplo n.º 2
0
    def connect_tls(self, protocol_version, stop_condition=None):
        def _default_stop_condition(record, records):
            return isinstance(record, Handshake) and \
                isinstance(record.payload, ServerHelloDone)

        if stop_condition is None:
            stop_condition = _default_stop_condition

        conn = self._scanner.handler.connect()
        conn.settimeout(2.0)

        conn_tls = SSLv30Connection(protocol_version=protocol_version)

        record_handshake = self.build_tls_client_hello(protocol_version)

        conn.send_list(conn_tls.encode(record_handshake))

        time_start = datetime.now()

        records = []
        run = True
        while run:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                return records

            try:
                data = conn.recv(4096)
            except ConnectionError:
                return records
            except socket.timeout:
                conn.close()
                return records

            try:
                conn_tls.decode(data)
            except WrongProtocolVersion:
                # Send alert and close socket
                record_alert = Alert()
                record_alert.level = "fatal"
                record_alert.description = "protocol_version"
                conn.send_list(conn_tls.encode(record_alert))
                conn.close()
                return None

            while not conn_tls.is_empty():
                record = conn_tls.pop_record()
                self.parse_tls_server_records_hooks.call(record)

                if isinstance(record, Alert):
                    if record.level == 2:
                        return records

                records.append(record)
                if stop_condition(record, records):
                    run = False

        conn.close()
        return records
Exemplo n.º 3
0
    def test_single(self):
        conn = SSLv30Connection(
            protocol_version=flextls.registry.version.SSLv3)
        assert conn.is_empty()

        conn.decode(prepare_handshake_data(client_hello_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._client_hello_01(record)

        conn.decode(prepare_handshake_data(client_key_exchange_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._client_key_exchange_01(record)
Exemplo n.º 4
0
    def test_single(self):
        conn = SSLv30Connection(
            protocol_version=flextls.registry.version.SSLv3)
        assert conn.is_empty()

        conn.decode(prepare_handshake_data(server_hello_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._server_hello_01(record)

        conn.decode(prepare_handshake_data(server_certificate_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._server_certificate_01(record)

        conn.decode(prepare_handshake_data(server_key_exchange_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._server_key_exchange_01(record)

        conn.decode(prepare_handshake_data(server_hello_done_01))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._server_hello_done_01(record)

        self._connection_state(conn)

        # Change Cipher Spec, SSLv3.0, Length 1
        data = b"1403000001"
        # Change Cipher Spec Message
        data += b"01"
        conn.decode(binascii.unhexlify(data))
        assert not conn.is_empty()
        record = conn.pop_record()
        assert conn.is_empty()
        self._change_cipher_spec(record)
Exemplo n.º 5
0
    def _scan_elliptic_curves_tls(self,
                                  protocol_version,
                                  cipher_suites,
                                  elliptic_curves,
                                  limit=False):
        """
        Scan for supported elliptic curves

        :param protocol_version:
        :param cipher_suites: List of cipher suites.
        :param elliptic_curves: List of elliptic curves
        :param limit:
        :return: List of supported elliptic curve IDs
        """
        # Get IDs of allowed cipher suites
        tmp = []
        for cipher_suite in cipher_suites:
            tmp.append(cipher_suite.id)
        cipher_suites = tmp

        tmp = []
        for elliptic_curve in elliptic_curves:
            tmp.append(elliptic_curve.id)
        elliptic_curves = tmp

        detected_elliptic_curves = []
        count = 0

        while True:
            conn = self._scanner.handler.connect()
            conn.settimeout(2.0)

            conn_tls = SSLv30Connection(protocol_version=protocol_version)

            record_handshake = self._build_tls_base_client_hello(
                protocol_version,
                cipher_suites,
                elliptic_curves=elliptic_curves)

            conn.send_list(conn_tls.encode(record_handshake))

            time_start = datetime.now()
            server_key_exchange = None

            while server_key_exchange is None:
                tmp_time = datetime.now() - time_start
                if tmp_time.total_seconds() > 5.0:
                    return detected_elliptic_curves

                try:
                    data = conn.recv(4096)
                except ConnectionError:
                    return detected_elliptic_curves
                except socket.timeout:
                    conn.close()
                    return detected_elliptic_curves

                try:
                    conn_tls.decode(data)
                except WrongProtocolVersion:
                    # Send alert and close socket
                    record_alert = Alert()
                    record_alert.level = "fatal"
                    record_alert.description = "protocol_version"
                    conn.send_list(conn_tls.encode(record_alert))
                    conn.close()
                    return detected_elliptic_curves

                while not conn_tls.is_empty():
                    record = conn_tls.pop_record()
                    if isinstance(record, Handshake):
                        if isinstance(record.payload, ServerKeyExchange):
                            server_key_exchange = record.payload
                    elif isinstance(record, Alert):
                        if record.level == 2:
                            return detected_elliptic_curves

            conn.close()
            # stop if no ServerKeyExchange was sent
            if server_key_exchange is None:
                break

            # try to extract the ec id
            tmp_ec_id = None
            if isinstance(server_key_exchange.payload, ServerKeyExchangeECDSA):
                tmp_params = server_key_exchange.payload.params
                if isinstance(tmp_params, ServerECDHParamsField):
                    if isinstance(tmp_params.curve_params,
                                  ECParametersNamedCurveField):
                        tmp_ec_id = tmp_params.curve_params.namedcurve

            if tmp_ec_id is None:
                return detected_elliptic_curves

            # stop if we get an unexpected ec id
            if tmp_ec_id not in elliptic_curves:
                return detected_elliptic_curves
            detected_elliptic_curves.append(tmp_ec_id)
            elliptic_curves.remove(tmp_ec_id)

            count += 1
            if limit is not False and limit <= count:
                break

        return detected_elliptic_curves
Exemplo n.º 6
0
    def _scan_tls_cipher_suites(self,
                                protocol_version,
                                cipher_suites,
                                limit=False):
        kb = self._scanner.get_knowledge_base()

        # Get IDs of allowed cipher suites
        tmp = []
        for cipher_suite in cipher_suites:
            tmp.append(cipher_suite.id)
        cipher_suites = tmp

        detected_ciphers = []
        count = 0

        while True:
            conn = self._scanner.handler.connect()
            conn.settimeout(2.0)

            conn_tls = SSLv30Connection(protocol_version=protocol_version)

            record_handshake = self._build_tls_base_client_hello(
                protocol_version, cipher_suites)

            conn.send_list(conn_tls.encode(record_handshake))

            time_start = datetime.now()
            server_hello = None

            raw_certs = kb.get("server.certificate.raw")
            while server_hello is None or raw_certs is None:
                tmp_time = datetime.now() - time_start
                if tmp_time.total_seconds() > 5.0:
                    return detected_ciphers

                try:
                    data = conn.recv(4096)
                except ConnectionError:
                    return detected_ciphers
                except socket.timeout:
                    conn.close()
                    return detected_ciphers

                try:
                    conn_tls.decode(data)
                except WrongProtocolVersion:
                    # Send alert and close socket
                    record_alert = Alert()
                    record_alert.level = "fatal"
                    record_alert.description = "protocol_version"
                    conn.send_list(conn_tls.encode(record_alert))
                    conn.close()
                    return detected_ciphers

                while not conn_tls.is_empty():
                    record = conn_tls.pop_record()

                    if isinstance(record, Handshake):
                        if isinstance(record.payload, ServerHello):
                            server_hello = record.payload
                        elif raw_certs is None and isinstance(
                                record.payload, ServerCertificate):
                            raw_certs = []
                            for raw_cert in record.payload.certificate_list:
                                raw_certs.append(raw_cert.value)
                            kb.set("server.certificate.raw", raw_certs)
                    elif isinstance(record, Alert):
                        if record.level == 2:
                            return detected_ciphers

            conn.close()
            if server_hello is None:
                break

            # get compression method
            if kb.get("server.session.compression") is None:
                comp_method = flextls.registry.tls.compression_methods.get(
                    server_hello.compression_method)
                kb.set("server.session.compression", comp_method)

            for extension in server_hello.extensions:
                if isinstance(extension.payload, EcPointFormats):
                    tmp_formats = []
                    for format_id in extension.payload.point_format_list:
                        tmp_format = flextls.registry.ec.point_formats.get(
                            format_id.value)
                        tmp_formats.append(tmp_format)

                    if kb.get("server.ec.point_formats") is None:
                        kb.set("server.ec.point_formats", tmp_formats)

            detected_ciphers.append(server_hello.cipher_suite)
            cipher_suites.remove(server_hello.cipher_suite)
            count = count + 1
            if limit is not False and limit <= count:
                break

        return detected_ciphers