Exemplo n.º 1
0
 def get_bytes(self):
     record_parts = []
     if Protocol.is_ssl3_tls(self.version):
         record_parts = [  # TLS/SSLv3 record: TYPE, LENGTH, VERSION, BODY (content)
             bytes([self.content_type]),
             bytes(self.version),
             struct.pack("!H", self.length), self.body
         ]
     elif Protocol.is_ssl2(
             self.version
     ) and self.content_type == HandshakeTypeSsl2.client_hello:
         record_parts = [  # SSLv2 record : LENGTH, TYPE, VERSION, BODY (content)
             struct.pack("!H", self.length),
             bytes([self.content_type]),
             bytes(self.version),  # tuple -> bytes
             self.body
         ]
     # ToDo raise exceptions
     elif Protocol.is_ssl2(
             self.version
     ) and self.content_type == HandshakeTypeSsl2.server_hello:
         print(
             "The byte representation of SSL2 server_hello is not implemented"
         )
     else:
         print("Byte representation of RecordType not implemented")
     return b''.join(record_parts)
Exemplo n.º 2
0
    def send_client_hello(self, version, ciphers_tls=ciphers_tls):
        response = None
        with TCP(self.target.host, self.target.port).connect() as tcp:
            if self.clear_text_layer:
                stls = StartTLS(self.clear_text_layer)
                stls.prepare_socket(tcp)
            tls = TLSConnection(
                tcp
            )  # Pass the socket object (connection) to start a TLSConnection instance
            if Protocol.is_tls1_3(versions[version]):
                # TLS1.3 should ignore ciphers not supported so we SHOULD be able to provide all TLS ciphers we know
                client_hello = self.create_tls13_extended_client_hello(
                    ciphers_tls)
                response = tls.send_record(client_hello)
            elif Protocol.is_ssl3_tls(versions[version]):
                client_hello = self.create_ecc_extended_client_hello(
                    versions[version], ciphers_tls)
                client_hello.set_compression(
                    bytearray(b'\x01\x00'))  # DEFLATE, null
                response = tls.send_record(client_hello)
            elif Protocol.is_ssl2(versions[version]):
                response = tls.send_record(
                    ClientHello(versions[version], ciphers_ssl2))

        return response
Exemplo n.º 3
0
    def __init__(self, version, ciphers_dict):
        self.cipher_suites = ciphers_dict
        self.extension_list = [
        ]  # ToDo: make a dict to prevent duplicate extensions
        try:
            if Protocol.is_ssl3_tls(version):
                if Protocol.is_tls1_3(version):
                    # TLS1.3 uses 'legacy version' TLS1.2 for the record layer
                    super(self.__class__,
                          self).__init__(versions['TLSv1_2'],
                                         ContentType.handshake)
                    self.handshake_version = versions['TLSv1_2']
                else:
                    # Record version set to TLSv1_0
                    super(self.__class__,
                          self).__init__(versions['TLSv1_0'],
                                         ContentType.handshake)
                    self.handshake_version = version
                self.compression = b'\x00'
                self.length = len(self.cipher_spec) + len(
                    self.compression) + 42  # 32 random + 4 length + ..
                self._set_tls_hello_body_bytes()

            elif Protocol.is_ssl2(version):
                super(self.__class__,
                      self).__init__(version, HandshakeTypeSsl2.client_hello)
                self.challenge = os.urandom(16)
                record_length = len(self.cipher_spec) + len(self.challenge) + 9
                self.length = RecordHelper.get_ssl2_record_len(
                    record_length, True)  # Set MSB (no padding)

                self._set_ssl2_hello_body_bytes()
        except:
            raise Exception("Failed to craft ClientHello")
Exemplo n.º 4
0
    def get_version_support(self, version_list):
        supported = []
        self.print_verbose(
            "Enumerating TLS/SSL version support for: {0} port {1}".format(
                self.target.host, self.target.port))
        for v in version_list:
            # try:
            with TCP(self.target.host, self.target.port).connect() as tcp:
                if self.clear_text_layer:
                    stls = StartTLS(self.clear_text_layer)
                    stls.prepare_socket(tcp)
                tls = TLSConnection(
                    tcp
                )  # Pass the socket object (connection) to start a TLSConnection instance
                if Protocol.is_tls1_3(versions[v]):
                    # TLS1.3 should ignore ciphers not supported so we SHOULD be able to provide all TLS ciphers we know
                    client_hello = self.get_tls13_extended_client_hello(
                        ciphers_tls)
                    response = tls.send_record(client_hello)
                elif Protocol.is_ssl3_tls(versions[v]):
                    client_hello = self.get_ecc_extended_client_hello(
                        versions[v], ciphers_tls)
                    client_hello.set_compression(
                        bytearray(b'\x01\x00'))  # DEFLATE, null
                    response = tls.send_record(client_hello)
                elif Protocol.is_ssl2(versions[v]):
                    response = tls.send_record(
                        ClientHello(versions[v], ciphers_ssl2))

                if len(
                        response
                ) > 0:  # ToDo: response may be referenced before assignment -> fix!
                    s_hello = None
                    # The ServerHello may not be the first Record received
                    for record in response:
                        if isinstance(record, ServerHello):
                            s_hello = record
                            break
                    if s_hello:
                        if s_hello.handshake_protocol == versions[v]:
                            supported.append(v)
                            self.print_verbose("  [+]: {0}".format(v))
                            if s_hello.compression_method is not None:
                                self.print_verbose(
                                    "      Compression: {0}".format(
                                        s_hello.compression_method.name))
                        if Protocol.is_tls1_3(
                                versions[v]
                        ):  # Need to see if extension is present
                            for extension in s_hello.extensions():
                                if extension.extension_type == ExtensionType.supported_versions:
                                    supported.append(v)
                                    self.print_verbose("  [+]: {0}".format(v))
            # except AttributeError:
            #    break
            # except:
            #    raise
        return supported
Exemplo n.º 5
0
 def __init__(self, version, body):
     if Protocol.is_ssl3_tls(version):
         super(self.__class__, self).__init__(version, ContentType.handshake)
     elif Protocol.is_ssl2(version):
         super(self.__class__, self).__init__(version, HandshakeTypeSsl2.server_hello)
     else:
         raise TypeError("Protocol unsupported")  # ToDo TLSException
     self.handshake_type = body[0]  # Check if applicable for SSL2
     self.length = len(body)
     self.body = body
Exemplo n.º 6
0
    def get_response_record(self, record):
        response = record
        buffer = self.TCP.receive_buffer(record.length)  # obtain the whole record
        if buffer:
            record.body = buffer
            if Protocol.is_ssl3_tls(record.version):
                if record.content_type == ContentType.handshake:
                    msg_start = 0
                    if record.body[0] == HandshakeType.server_hello:
                        response = ServerHello(record.version, record.body)
                        self.kex_algorithm = response.kex_algorithm()
                        # Workaround/hack for multiple messages inside the record_layer
                        while record.length > msg_start:
                            message = None
                            msg_len = struct.unpack('!I', b'\x00' + record.body[msg_start + 1:msg_start + 4])[0]
                            if record.body[msg_start] == HandshakeType.server_hello:
                                message = ServerHello(record.version, record.body[msg_start:msg_start+msg_len])
                                self.kex_algorithm = response.kex_algorithm()  # set the key exchange algo for the connection
                            elif record.body[msg_start] == HandshakeType.certificate:
                                message = Certificate(record.version, record.body[msg_start:msg_start+msg_len])
                            elif record.body[msg_start] == HandshakeType.server_key_exchange:
                                message = ServerKeyExchange(record.version, record.body[msg_start:msg_start+msg_len],
                                                            self.kex_algorithm)
                            if message:
                                response.messages.append(message)
                            # (handshake_type + length_field) 4 bytes
                            msg_start = msg_start + 4 + msg_len

                    elif record.body[0] == HandshakeType.certificate:
                        response = Certificate(record.version, record.body)
                    elif record.body[0] == HandshakeType.server_key_exchange:
                        response = ServerKeyExchange(record.version, record.body, self.kex_algorithm)
                elif record.content_type == ContentType.alert:
                    self.print_verbose("Received an alert!")  # TODO: return alert object
                else:
                    self.print_verbose("Unhandled response for TLS request record")
            elif Protocol.is_ssl2(record.version):
                if record.content_type == HandshakeTypeSsl2.server_hello:  # server hello
                    version = Protocol.version_from_bytes(response.body[2:4])  # For SSL2 version is part of the 'body'
                    response = ServerHello(version, record.body)
                    response.length = record.length
                else:
                    self.print_verbose("Unhandled response for SSL2 request record")
        else:
            self.print_verbose("No body received")
        return response
Exemplo n.º 7
0
 def send_record(self, record):  # TODO record instance
     response = []  # Create a list of record objects
     if not isinstance(record, Record):
         raise Exception(
             "send_record (TLS) was not passed a Record instance")
     try:
         self.TCP.send_all(record.get_bytes(
         ))  # Sending the byte representation of the object
         if Protocol.is_ssl3_tls(record.version):  # TLS/SSL
             header = self.get_header(5)  # TYPE(1), VERSION(2), LENGTH(2)
             while header:
                 if header and len(header) == 5:
                     rec = Record(Protocol.version_from_bytes(header[1:3]),
                                  struct.unpack('!B', header[0:1])[0])
                     rec.length = struct.unpack('!H', header[3:5])[0]
                     if 0 < rec.length:
                         response.append(self.get_response_record(rec))
                 next_header = self.TCP.receive_buffer(5)
                 if next_header:
                     header = next_header
                     del next_header
                 else:
                     break
         elif Protocol.is_ssl2(record.version):
             header = self.get_header(3)  # LENGTH(2), TYPE(1)
             if header and len(header) == 3:
                 rec = Record(
                     record.version,
                     struct.unpack('!B',
                                   header[2:3])[0])  # Version is assumed
                 rec.length = RecordHelper.get_ssl2_record_len(
                     struct.unpack('!H', header[0:2])[0] - 3)
                 if 0 < rec.length:
                     response.append(self.get_response_record(rec))
     except socket.error as e:
         # ToDo raise exception
         if e.errno == errno.ECONNRESET:  # 54; Microsoft sometimes just resets the connection
             msg = "Connection reset"  # Usually means: not supported or not an acceptable offer
             pass
         elif e.errno == errno.ECONNREFUSED:  # 61
             msg = "Connection refused"
         else:
             raise e
         # print(msg)
     return response
Exemplo n.º 8
0
    def send_client_hello(self, version, ciphers_tls=ciphers_tls):
        response = None
        with TCP(self.target.host, self.target.port).connect() as tcp:
            if self.clear_text_layer:
                stls = StartTLS(self.clear_text_layer)
                stls.prepare_socket(tcp)
            tls = TLSConnection(tcp)  # Pass the socket object (connection) to start a TLSConnection instance
            if Protocol.is_tls1_3(versions[version]):
                # TLS1.3 should ignore ciphers not supported so we SHOULD be able to provide all TLS ciphers we know
                client_hello = self.create_tls13_extended_client_hello(ciphers_tls)
                response = tls.send_record(client_hello)
            elif Protocol.is_ssl3_tls(versions[version]):
                client_hello = self.create_ecc_extended_client_hello(versions[version], ciphers_tls)
                client_hello.set_compression(bytearray(b'\x01\x00'))  # DEFLATE, null
                response = tls.send_record(client_hello)
            elif Protocol.is_ssl2(versions[version]):
                response = tls.send_record(ClientHello(versions[version], ciphers_ssl2))

        return response
Exemplo n.º 9
0
 def send_record(self, record):  # TODO record instance
     response = []  # Create a list of record objects
     if not isinstance(record, Record):
         raise Exception("send_record (TLS) was not passed a Record instance")
     try:
         self.TCP.send_all(record.get_bytes())  # Sending the byte representation of the object
         if Protocol.is_ssl3_tls(record.version):  # TLS/SSL
             header = self.get_header(5)  # TYPE(1), VERSION(2), LENGTH(2)
             while header:
                 if header and len(header) == 5:
                     rec = Record(Protocol.version_from_bytes(header[1:3]), struct.unpack('!B', header[0:1])[0])
                     rec.length = struct.unpack('!H', header[3:5])[0]
                     if 0 < rec.length:
                         response.append(self.get_response_record(rec))
                 next_header = self.TCP.receive_buffer(5)
                 if next_header:
                     header = next_header
                     del next_header
                 else:
                     break
         elif Protocol.is_ssl2(record.version):
             header = self.get_header(3)  # LENGTH(2), TYPE(1)
             if header and len(header) == 3:
                 rec = Record(record.version, struct.unpack('!B', header[2:3])[0])  # Version is assumed
                 rec.length = RecordHelper.get_ssl2_record_len(struct.unpack('!H', header[0:2])[0] - 3)
                 if 0 < rec.length:
                     response.append(self.get_response_record(rec))
     except socket.error as e:
         # ToDo raise exception
         if e.errno == errno.ECONNRESET:  # 54; Microsoft sometimes just resets the connection
             msg = "Connection reset"  # Usually means: not supported or not an acceptable offer
             pass
         elif e.errno == errno.ECONNREFUSED:  # 61
             msg = "Connection refused"
         else:
             raise e
         # print(msg)
     return response
Exemplo n.º 10
0
 def get_response_record(self, record):
     response = record
     buffer = self.TCP.receive_buffer(record.length)
     if buffer:
         record.body = buffer
         if Protocol.is_ssl3_tls(record.version):
             if record.content_type == ContentType.handshake:
                 if record.body[0] == HandshakeType.server_hello:
                     response = ServerHello(record.version, record.body)
                     self.kex_algorithm = response.kex_algorithm()
                 elif record.body[0] == HandshakeType.certificate:
                     response = Certificate(record.version, record.body)
                 elif record.body[0] == HandshakeType.server_key_exchange:
                     #    print("got server kex pre")
                     response = ServerKeyExchange(record.version,
                                                  record.body,
                                                  self.kex_algorithm)
                 #    print("got server kex post")
             elif record.content_type == ContentType.alert:
                 self.print_verbose(
                     "Received an alert!")  # TODO: return alert object
             else:
                 self.print_verbose(
                     "Unhandled response for TLS request record")
         elif Protocol.is_ssl2(record.version):
             if record.content_type == HandshakeTypeSsl2.server_hello:  # server hello
                 version = Protocol.version_from_bytes(
                     response.body[2:4]
                 )  # For SSL2 version is part of the 'body'
                 response = ServerHello(version, record.body)
                 response.length = record.length
             else:
                 self.print_verbose(
                     "Unhandled response for SSL2 request record")
     else:
         self.print_verbose("No body received")
     return response
Exemplo n.º 11
0
    def get_cipher_support(self, version):
        supported = []
        retries = 0
        cipher_list = None
        if Protocol.is_ssl3_tls(versions[version]):
            cipher_list = list(ciphers_tls)
        elif Protocol.is_ssl2(versions[version]):
            cipher_list = list(ciphers_ssl2)
        server_hello_cipher = True
        self.print_verbose("Enumerating supported ciphers for: {0}".format(version))
        while server_hello_cipher:
            for _ in cipher_list:
                try:
                    with TCP(self.target.host, self.target.port).connect() as tcp:
                        if self.clear_text_layer:
                            stls = StartTLS(self.clear_text_layer)
                            stls.prepare_socket(tcp)

                        tls = TLSConnection(tcp)

                        if Protocol.is_ssl3_tls(versions[version]):
                            if versions[version] == versions[Protocol.TLS1_3]:
                                response = tls.send_record(self.create_tls13_extended_client_hello(cipher_list))
                            else:
                                response = tls.send_record(self.create_ecc_extended_client_hello(versions[version],
                                                                                                 cipher_list))
                            if len(response) > 0:
                                s_hello = None
                                s_key_exchange = None
                                for record in response:
                                    if isinstance(record, ServerHello):
                                        s_hello = record
                                    elif isinstance(record, ServerKeyExchange):
                                        s_key_exchange = record
                                    for message in record.messages:
                                        if isinstance(message, ServerKeyExchange):
                                            s_key_exchange = message
                                            break
                                if s_hello:
                                    hello_cipher = s_hello.response_cipher
                                    if hello_cipher and hello_cipher in supported:
                                        server_hello_cipher = False
                                        break
                                    elif hello_cipher:
                                        supported.append(hello_cipher)
                                        self.print_cipher(hello_cipher, s_key_exchange)
                                        cipher_list.remove(hello_cipher.bytes)
                                        retries = 0
                                else:  # No hello received, could be an alert
                                    server_hello_cipher = False
                                    break
                            else:  # Bug-fix
                                if retries < 3:
                                    retries += 1
                                else:
                                    server_hello_cipher = False
                                    break
                        elif Protocol.is_ssl2(versions[version]):
                            response = tls.send_record(ClientHello(versions[version], cipher_list))
                            if len(response) > 0:
                                if isinstance(response[0], ServerHello):
                                    supported = response[0].ssl2_response_ciphers  # ssl2 returns all ciphers at once
                                    [self.print_verbose("  [+] {0}".format(s[1])) for s in supported]
                                server_hello_cipher = False
                                break
                            else:
                                server_hello_cipher = False
                                break
                except AttributeError:
                    break
                except:
                    raise
        return supported
Exemplo n.º 12
0
    def get_cipher_support(self, version):
        supported = []
        retries = 0
        cipher_list = None
        if Protocol.is_ssl3_tls(versions[version]):
            cipher_list = list(ciphers_tls)
        elif Protocol.is_ssl2(versions[version]):
            cipher_list = list(ciphers_ssl2)
        server_hello_cipher = True
        self.print_verbose(
            "Enumerating supported ciphers for: {0}".format(version))
        while server_hello_cipher:
            for _ in cipher_list:
                try:
                    with TCP(self.target.host,
                             self.target.port).connect() as tcp:
                        if self.clear_text_layer:
                            stls = StartTLS(self.clear_text_layer)
                            stls.prepare_socket(tcp)

                        tls = TLSConnection(tcp)

                        if Protocol.is_ssl3_tls(versions[version]):
                            if versions[version] == versions[Protocol.TLS1_3]:
                                response = tls.send_record(
                                    self.create_tls13_extended_client_hello(
                                        cipher_list))
                            else:
                                response = tls.send_record(
                                    self.create_ecc_extended_client_hello(
                                        versions[version], cipher_list))
                            if len(response) > 0:
                                s_hello = None
                                s_key_exchange = None
                                for record in response:
                                    if isinstance(record, ServerHello):
                                        s_hello = record
                                    elif isinstance(record, ServerKeyExchange):
                                        s_key_exchange = record
                                    for message in record.messages:
                                        if isinstance(message,
                                                      ServerKeyExchange):
                                            s_key_exchange = message
                                            break
                                if s_hello:
                                    hello_cipher = s_hello.response_cipher
                                    if hello_cipher and hello_cipher in supported:
                                        server_hello_cipher = False
                                        break
                                    elif hello_cipher:
                                        supported.append(hello_cipher)
                                        self.print_cipher(
                                            hello_cipher, s_key_exchange)
                                        cipher_list.remove(hello_cipher.bytes)
                                        retries = 0
                                else:  # No hello received, could be an alert
                                    server_hello_cipher = False
                                    break
                            else:  # Bug-fix
                                if retries < 3:
                                    retries += 1
                                else:
                                    server_hello_cipher = False
                                    break
                        elif Protocol.is_ssl2(versions[version]):
                            response = tls.send_record(
                                ClientHello(versions[version], cipher_list))
                            if len(response) > 0:
                                if isinstance(response[0], ServerHello):
                                    supported = response[
                                        0].ssl2_response_ciphers  # ssl2 returns all ciphers at once
                                    [
                                        self.print_verbose("  [+] {0}".format(
                                            s[1])) for s in supported
                                    ]
                                server_hello_cipher = False
                                break
                            else:
                                server_hello_cipher = False
                                break
                except AttributeError:
                    break
                except:
                    raise
        return supported
Exemplo n.º 13
0
    def get_response_record(self, record):
        response = record
        buffer = self.TCP.receive_buffer(
            record.length)  # obtain the whole record
        if buffer:
            record.body = buffer
            if Protocol.is_ssl3_tls(record.version):
                if record.content_type == ContentType.handshake:
                    msg_start = 0
                    if record.body[0] == HandshakeType.server_hello:
                        response = ServerHello(record.version, record.body)
                        self.kex_algorithm = response.kex_algorithm()
                        # Workaround/hack for multiple messages inside the record_layer
                        while record.length > msg_start:
                            message = None
                            msg_len = struct.unpack(
                                '!I', b'\x00' +
                                record.body[msg_start + 1:msg_start + 4])[0]
                            if record.body[
                                    msg_start] == HandshakeType.server_hello:
                                message = ServerHello(
                                    record.version,
                                    record.body[msg_start:msg_start + msg_len])
                                self.kex_algorithm = response.kex_algorithm(
                                )  # set the key exchange algo for the connection
                            elif record.body[
                                    msg_start] == HandshakeType.certificate:
                                message = Certificate(
                                    record.version,
                                    record.body[msg_start:msg_start + msg_len])
                            elif record.body[
                                    msg_start] == HandshakeType.server_key_exchange:
                                message = ServerKeyExchange(
                                    record.version,
                                    record.body[msg_start:msg_start + msg_len],
                                    self.kex_algorithm)
                            if message:
                                response.messages.append(message)
                            # (handshake_type + length_field) 4 bytes
                            msg_start = msg_start + 4 + msg_len

                    elif record.body[0] == HandshakeType.certificate:
                        response = Certificate(record.version, record.body)
                    elif record.body[0] == HandshakeType.server_key_exchange:
                        response = ServerKeyExchange(record.version,
                                                     record.body,
                                                     self.kex_algorithm)
                elif record.content_type == ContentType.alert:
                    self.print_verbose(
                        "Received an alert!")  # TODO: return alert object
                else:
                    self.print_verbose(
                        "Unhandled response for TLS request record")
            elif Protocol.is_ssl2(record.version):
                if record.content_type == HandshakeTypeSsl2.server_hello:  # server hello
                    version = Protocol.version_from_bytes(
                        response.body[2:4]
                    )  # For SSL2 version is part of the 'body'
                    response = ServerHello(version, record.body)
                    response.length = record.length
                else:
                    self.print_verbose(
                        "Unhandled response for SSL2 request record")
        else:
            self.print_verbose("No body received")
        return response
Exemplo n.º 14
0
    def get_cipher_support(self, version):
        supported = []
        retries = 0
        cipher_list = None
        if Protocol.is_ssl3_tls(versions[version]):
            cipher_list = list(
                ciphers_tls)  # TLS.get_cipher_list(TLS.Protocols.TLS)
        elif Protocol.is_ssl2(versions[version]):
            cipher_list = list(ciphers_ssl2)
        server_hello_cipher = True
        self.print_verbose("Enumerating ciphers for: {0}".format(version))
        while server_hello_cipher:
            for c in cipher_list:
                try:
                    with TCP(self.target.host,
                             self.target.port).connect() as tcp:
                        if self.clear_text_layer:
                            stls = StartTLS(self.clear_text_layer)
                            stls.prepare_socket(tcp)

                        tls = TLSConnection(tcp)

                        if Protocol.is_ssl3_tls(versions[version]):
                            if versions[version] == versions[Protocol.TLS1_3]:
                                response = tls.send_record(
                                    self.get_tls13_extended_client_hello(
                                        cipher_list))
                            else:
                                response = tls.send_record(
                                    self.get_ecc_extended_client_hello(
                                        versions[version], cipher_list))
                            if len(response) > 0:
                                s_hello = None
                                s_key_exchange = None
                                for record in response:
                                    if isinstance(record, ServerHello):
                                        s_hello = record
                                    elif isinstance(record, ServerKeyExchange):
                                        s_key_exchange = record
                                if s_hello:
                                    hello_cipher = s_hello.response_cipher
                                    if hello_cipher and hello_cipher in supported:
                                        server_hello_cipher = False
                                        break
                                    elif hello_cipher:
                                        # Should we check if the response is using TLSv1.3?
                                        '''if versions[version] == versions[Protocol.TLS1_3]:
                                            for extension in s_hello.extensions():
                                                if extension.extension_type == ExtensionType.supported_versions:
                                                    break
                                        '''
                                        supported.append(hello_cipher)
                                        # This is ugly but hey it's not the only thing...
                                        if s_key_exchange:
                                            self.print_verbose(
                                                "  [+] {0} ({1} bits) - {dh}{curve}{bits}"
                                                .format(
                                                    hello_cipher.name,
                                                    hello_cipher.bits,
                                                    bits="{} bits".format(
                                                        s_key_exchange.
                                                        key_length() * 8) if
                                                    not s_key_exchange.elliptic
                                                    else "",
                                                    dh="ECDH"
                                                    if s_key_exchange.elliptic
                                                    else "DH",
                                                    curve=" {} ".format(
                                                        s_key_exchange.
                                                        named_curve.name)
                                                    if s_key_exchange.elliptic
                                                    else " "))
                                        else:
                                            self.print_verbose(
                                                "  [+] {0} ({1} bits)".format(
                                                    hello_cipher.name,
                                                    hello_cipher.bits))
                                        cipher_list.remove(hello_cipher.bytes)
                                        retries = 0
                                else:  # No hello received, could be an alert
                                    server_hello_cipher = False
                                    break
                            else:  # Bug-fix
                                if retries < 3:
                                    retries += 1
                                else:
                                    server_hello_cipher = False
                                    break
                        elif Protocol.is_ssl2(versions[version]):
                            response = tls.send_record(
                                ClientHello(versions[version], cipher_list))
                            if len(response) > 0:
                                if isinstance(response[0], ServerHello):
                                    supported = response[
                                        0].ssl2_response_ciphers  # ssl2 returns all ciphers at once
                                    if self.verbose:
                                        [
                                            print("  [+] {0}".format(s[1]))
                                            for s in supported
                                        ]
                                server_hello_cipher = False
                                break
                            else:
                                server_hello_cipher = False
                                break
                except AttributeError:
                    break
                except:
                    raise
        return supported