Ejemplo n.º 1
0
    def decode(self, data):
        self._raw_stream_data += data
        while True:
            try:
                (obj, data) = SSLv3Record.decode(
                    self._raw_stream_data,
                    connection=self,
                    payload_auto_decode=False
                )
                version = helper.get_version_by_version_id((
                    obj.version.major,
                    obj.version.minor
                ))

                self._raw_stream_data = data

                if version != self._cur_protocol_version:
                    raise WrongProtocolVersion(
                        record=obj
                    )

                if self._cur_record_type is None:
                    self._cur_record_type = obj.content_Type

                if self._cur_record_type != obj.content_type:
                    self._decode_record_payload()
                    self._cur_record_data = b""
                    self._cur_record_type = obj.content_type

                self._cur_record_data += obj.payload

                self._decode_record_payload()

            except NotEnoughData:
                break
Ejemplo n.º 2
0
    def test_decode(self):
        (record, data) = SSLv3Record.decode(binascii.unhexlify(self.alert_01))
        assert len(data) == 0

        assert isinstance(record, SSLv3Record)
        assert record.version.major == 3
        assert record.version.minor == 0
        assert record.length == 2

        alert = record.payload
        assert isinstance(alert, Alert)
        assert alert.level == 1
        assert alert.description == 2
Ejemplo n.º 3
0
    def _connect_with_scsv(self, protocol_version, cipher_suites):
        cipher_suites = cipher_suites[:]
        cipher_suites.append(0x5600)

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

        record_tls_hello = self._build_tls_base_client_hello(
            protocol_version, cipher_suites)

        conn.send(record_tls_hello.encode())

        time_start = datetime.now()
        data = b""
        proto_version = (record_tls_hello.version.major,
                         record_tls_hello.version.minor)
        while True:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                conn.close()
                return None

            try:
                tmp_data = conn.recv(4096)
            except ConnectionError:
                conn.close()
                return None

            data += tmp_data
            while True:
                try:
                    (record, data) = SSLv3Record.decode(data)
                except NotEnoughData:
                    break

                if isinstance(record.payload, Handshake):
                    if isinstance(record.payload.payload, ServerHello):
                        conn.close()
                        if proto_version[0] == record.version.major \
                            and proto_version[1] == record.version.minor:
                            return False
                        return None

                elif isinstance(record.payload, Alert):
                    conn.close()
                    if record.payload.level == 2 and \
                        record.payload.description == 86:
                        return True
                    return None
Ejemplo n.º 4
0
    def test_decode(self):
        (record, data) = SSLv3Record.decode(
            binascii.unhexlify(
                self.alert_01
            )
        )
        assert len(data) == 0

        assert isinstance(record, SSLv3Record)
        assert record.version.major == 3
        assert record.version.minor == 0
        assert record.length == 2

        alert = record.payload
        assert isinstance(alert, Alert)
        assert alert.level == 1
        assert alert.description == 2
Ejemplo n.º 5
0
    def _connect_with_scsv(self, protocol_version, cipher_suites):
        cipher_suites = cipher_suites[:]
        cipher_suites.append(0x5600)

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

        record_tls_hello = self._build_tls_base_client_hello(protocol_version, cipher_suites)

        conn.send(record_tls_hello.encode())

        time_start = datetime.now()
        data = b""
        proto_version = (record_tls_hello.version.major, record_tls_hello.version.minor)
        while True:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                conn.close()
                return None

            try:
                tmp_data = conn.recv(4096)
            except ConnectionError:
                conn.close()
                return None

            data += tmp_data
            while True:
                try:
                    (record, data) = SSLv3Record.decode(data)
                except NotEnoughData:
                    break

                if isinstance(record.payload, Handshake):
                    if isinstance(record.payload.payload, ServerHello):
                        conn.close()
                        if proto_version[0] == record.version.major and proto_version[1] == record.version.minor:
                            return False
                        return None

                elif isinstance(record.payload, Alert):
                    conn.close()
                    if record.payload.level == 2 and record.payload.description == 86:
                        return True
                    return None
Ejemplo n.º 6
0
    def _send_heartbeat(self, protocol_version, cipher_suites):

        record_tls = self._build_tls_base_client_hello(
            protocol_version,
            cipher_suites
        )

        ext_hb = HeartbeatExtension()
        ext_hb.mode = 1
        record_client_hello = record_tls.payload
        record_client_hello.extensions.append(Extension() + ext_hb)

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

        conn.send(record_tls.encode())

        time_start = datetime.now()
        server_hello_done = False
        heartbeat_supported = False
        data = b""
        while server_hello_done is False:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                return False

            try:
                tmp_data = conn.recv(4096)
            except:
                return None

            data += tmp_data
            while True:
                try:
                    (record, data) = SSLv3Record.decode(data)
                except NotEnoughData:
                    break

                if isinstance(record.payload, Handshake):
                    if isinstance(record.payload.payload, ServerHello):
                        server_hello = record.payload.payload
                        for ext in server_hello.extensions:
                            if isinstance(ext.payload, HeartbeatExtension):
                                heartbeat_supported = True

                    if isinstance(record.payload.payload, ServerHelloDone):
                        server_hello_done = True

                elif isinstance(record.payload, Alert):
                    if record.payload.level == 2:
                        return None

        # ToDo: use connection state
        if protocol_version == flextls.registry.version.SSLv3:
            ver_minor = 0
        elif protocol_version == flextls.registry.version.TLSv10:
            ver_minor = 1
        elif protocol_version == flextls.registry.version.TLSv11:
            ver_minor = 2
        elif protocol_version == flextls.registry.version.TLSv12:
            ver_minor = 3

        record = SSLv3Record()
        record.version.major = 3
        record.version.minor = ver_minor

        record.payload = binascii.unhexlify(b"014000")
        record.length = 3
        record.content_type = 24

        conn.send(record.encode())
        time_start = datetime.now()
        record_with_heartbeat = None
        data = b""
        while record_with_heartbeat is None:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                return heartbeat_supported

            try:
                tmp_data = conn.recv(4096)
            except:
                return heartbeat_supported

            data += tmp_data
            while True:
                try:
                    (record, data) = SSLv3Record.decode(
                        data,
                        payload_auto_decode=False
                    )
                except NotEnoughData:
                    break

                if record.content_type == record.get_payload_pattern(Heartbeat):
                    record_with_heartbeat = record

                elif isinstance(record.payload, Alert):
                    if record.payload.level == 2:
                        return heartbeat_supported

        return record_with_heartbeat
Ejemplo n.º 7
0
    def _send_heartbeat(self, protocol_version, cipher_suites):

        record_tls = self._build_tls_base_client_hello(protocol_version,
                                                       cipher_suites)

        ext_hb = HeartbeatExtension()
        ext_hb.mode = 1
        record_client_hello = record_tls.payload
        record_client_hello.extensions.append(Extension() + ext_hb)

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

        conn.send(record_tls.encode())

        time_start = datetime.now()
        server_hello_done = False
        heartbeat_supported = False
        data = b""
        while server_hello_done is False:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                return False

            try:
                tmp_data = conn.recv(4096)
            except:
                return None

            data += tmp_data
            while True:
                try:
                    (record, data) = SSLv3Record.decode(data)
                except NotEnoughData:
                    break

                if isinstance(record.payload, Handshake):
                    if isinstance(record.payload.payload, ServerHello):
                        server_hello = record.payload.payload
                        for ext in server_hello.extensions:
                            if isinstance(ext.payload, HeartbeatExtension):
                                heartbeat_supported = True

                    if isinstance(record.payload.payload, ServerHelloDone):
                        server_hello_done = True

                elif isinstance(record.payload, Alert):
                    if record.payload.level == 2:
                        return None

        # ToDo: use connection state
        if protocol_version == flextls.registry.version.SSLv3:
            ver_minor = 0
        elif protocol_version == flextls.registry.version.TLSv10:
            ver_minor = 1
        elif protocol_version == flextls.registry.version.TLSv11:
            ver_minor = 2
        elif protocol_version == flextls.registry.version.TLSv12:
            ver_minor = 3

        record = SSLv3Record()
        record.version.major = 3
        record.version.minor = ver_minor

        record.payload = binascii.unhexlify(b"014000")
        record.length = 3
        record.content_type = 24

        conn.send(record.encode())
        time_start = datetime.now()
        record_with_heartbeat = None
        data = b""
        while record_with_heartbeat is None:
            tmp_time = datetime.now() - time_start
            if tmp_time.total_seconds() > 5.0:
                return heartbeat_supported

            try:
                tmp_data = conn.recv(4096)
            except:
                return heartbeat_supported

            data += tmp_data
            while True:
                try:
                    (record,
                     data) = SSLv3Record.decode(data,
                                                payload_auto_decode=False)
                except NotEnoughData:
                    break

                if record.content_type == record.get_payload_pattern(
                        Heartbeat):
                    record_with_heartbeat = record

                elif isinstance(record.payload, Alert):
                    if record.payload.level == 2:
                        return heartbeat_supported

        return record_with_heartbeat