def test_sendMessageBlocking(self): sock = MockSocket(bytearray(), blockEveryOther=True) sock.blockWrite = True msgSock = MessageSocket(sock, None) msgSock.version = (3, 3) msg = Message(ContentType.handshake, bytearray(b'\xaa\xaa\xaa')) blocked = False for res in msgSock.queueMessage(msg): if res in (0, 1): blocked = True else: break # no write so no blocking self.assertFalse(blocked) self.assertEqual(len(sock.sent), 0) msg = Message(ContentType.alert, bytearray(b'\x02\x01')) msgSock.sendMessageBlocking(msg) self.assertEqual(len(sock.sent), 2) self.assertEqual(bytearray( b'\x16' + b'\x03\x03' + b'\x00\x03' + b'\xaa'*3), sock.sent[0]) self.assertEqual(bytearray( b'\x15' + b'\x03\x03' + b'\x00\x02' + b'\x02\x01'), sock.sent[1])
def test_queueMessage_with_conflicting_types(self): sock = MockSocket(bytearray()) msgSock = MessageSocket(sock, None) msgSock.version = (3, 3) msg = Message(ContentType.handshake, bytearray(b'\xaa\xaa\xaa')) for res in msgSock.queueMessage(msg): if res in (0, 1): self.assertTrue(False, "Blocking queue") else: break self.assertEqual(len(sock.sent), 0) msg = Message(ContentType.alert, bytearray(b'\x02\x01')) for res in msgSock.queueMessage(msg): if res in (0, 1): self.assertTrue(False, "Blocking queue") else: break self.assertEqual(len(sock.sent), 1) self.assertEqual(bytearray( b'\x16' + b'\x03\x03' + b'\x00\x03' + b'\xaa'*3), sock.sent[0]) for res in msgSock.flush(): if res in (0, 1): self.assertTrue(False, "Blocking flush") else: break self.assertEqual(len(sock.sent), 2) self.assertEqual(bytearray( b'\x15' + b'\x03\x03' + b'\x00\x02' + b'\x02\x01'), sock.sent[1])
def test_flushBlocking_with_data(self): sock = MockSocket(bytearray(), blockEveryOther=True) sock.blockWrite = True msgSock = MessageSocket(sock, None) msgSock.version = (3, 3) msg = Message(ContentType.handshake, bytearray(b'\xaa\xaa\xaa')) msgSock.queueMessageBlocking(msg) self.assertEqual(len(sock.sent), 0) msgSock.flushBlocking() self.assertEqual(len(sock.sent), 1) self.assertEqual( bytearray(b'\x16' + b'\x03\x03' + b'\x00\x03' + b'\xaa' * 3), sock.sent[0])
def test_flushBlocking_with_data(self): sock = MockSocket(bytearray(), blockEveryOther=True) sock.blockWrite = True msgSock = MessageSocket(sock, None) msgSock.version = (3, 3) msg = Message(ContentType.handshake, bytearray(b'\xaa\xaa\xaa')) msgSock.queueMessageBlocking(msg) self.assertEqual(len(sock.sent), 0) msgSock.flushBlocking() self.assertEqual(len(sock.sent), 1) self.assertEqual(bytearray( b'\x16' + b'\x03\x03' + b'\x00\x03' + b'\xaa'*3), sock.sent[0])
def scan(self): """Perform a scan on server.""" defragger = Defragmenter() defragger.addStaticSize(ContentType.change_cipher_spec, 1) defragger.addStaticSize(ContentType.alert, 2) defragger.addDynamicSize(ContentType.handshake, 1, 3) try: raw_sock = socket.create_connection((self.host, self.port), 5) except socket.error as e: return [e] sock = MessageSocket(raw_sock, defragger) if self.hostname is not None: client_hello = self.hello_gen(bytearray(self.hostname, 'utf-8')) else: client_hello = self.hello_gen(None) # record layer version - TLSv1.x # use the version from configuration, if present, or default to the # RFC recommended (3, 1) for TLS and (3, 0) for SSLv3 if hasattr(client_hello, 'record_version'): sock.version = client_hello.record_version elif hasattr(self.hello_gen, 'record_version'): sock.version = self.hello_gen.record_version elif client_hello.client_version > (3, 1): # TLS1.0 sock.version = (3, 1) else: sock.version = client_hello.client_version # we don't want to send invalid messages (SSLv2 hello in SSL record # layer), so set the record layer version to SSLv2 if the hello is # of SSLv2 format if client_hello.ssl2: sock.version = (0, 2) # save the record version used in the end for later analysis client_hello.record_version = sock.version messages = [client_hello] handshake_parser = HandshakeParser() try: sock.sendMessageBlocking(client_hello) except socket.error as e: messages.append(e) return messages except TLSAbruptCloseError as e: sock.sock.close() messages.append(e) return messages # get all the server messages that affect connection, abort as soon # as they've been read try: while True: header, parser = sock.recvMessageBlocking() if header.type == ContentType.alert: alert = Alert() alert.parse(parser) alert.record_version = header.version messages += [alert] elif header.type == ContentType.handshake: msg = handshake_parser.parse(parser) msg.record_version = header.version messages += [msg] if isinstance(msg, ServerHelloDone): return messages else: raise TypeError("Unknown content type: {0}".format( header.type)) except (TLSAbruptCloseError, TLSIllegalParameterException, ValueError, TypeError, socket.error, SyntaxError) as e: messages += [e] return messages finally: try: sock.sock.close() except (socket.error, OSError): pass
def scan(self): """Perform a scan on server.""" defragger = Defragmenter() defragger.addStaticSize(ContentType.change_cipher_spec, 1) defragger.addStaticSize(ContentType.alert, 2) defragger.addDynamicSize(ContentType.handshake, 1, 3) try: raw_sock = socket.create_connection((self.host, self.port), 5) except socket.error as e: return [e] sock = MessageSocket(raw_sock, defragger) if self.hostname is not None: client_hello = self.hello_gen(bytearray(self.hostname, 'utf-8')) else: client_hello = self.hello_gen(None) # record layer version - TLSv1.x # use the version from configuration, if present, or default to the # RFC recommended (3, 1) for TLS and (3, 0) for SSLv3 if hasattr(client_hello, 'record_version'): sock.version = client_hello.record_version elif hasattr(self.hello_gen, 'record_version'): sock.version = self.hello_gen.record_version elif client_hello.client_version > (3, 1): # TLS1.0 sock.version = (3, 1) else: sock.version = client_hello.client_version # we don't want to send invalid messages (SSLv2 hello in SSL record # layer), so set the record layer version to SSLv2 if the hello is # of SSLv2 format if client_hello.ssl2: sock.version = (0, 2) # save the record version used in the end for later analysis client_hello.record_version = sock.version messages = [client_hello] handshake_parser = HandshakeParser() try: sock.sendMessageBlocking(client_hello) except socket.error as e: messages.append(e) return messages except TLSAbruptCloseError as e: sock.sock.close() messages.append(e) return messages # get all the server messages that affect connection, abort as soon # as they've been read try: while True: header, parser = sock.recvMessageBlocking() if header.type == ContentType.alert: alert = Alert() alert.parse(parser) alert.record_version = header.version messages += [alert] elif header.type == ContentType.handshake: msg = handshake_parser.parse(parser) msg.record_version = header.version messages += [msg] if isinstance(msg, ServerHelloDone): return messages else: raise TypeError("Unknown content type: {0}" .format(header.type)) except (TLSAbruptCloseError, TLSIllegalParameterException, ValueError, TypeError, socket.error, SyntaxError) as e: messages += [e] return messages finally: try: sock.sock.close() except (socket.error, OSError): pass