class ClientAuthenticationTestCase(unittest.TestCase): @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_optional_client_auth(self): # Given a server that supports optional client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. OPTIONAL) as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # SSLyze correctly detects that client auth is optional self.assertEqual(server_info.client_auth_requirement, ClientAuthenticationServerConfigurationEnum.OPTIONAL) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_required_client_auth(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # SSLyze correctly detects that client auth is required self.assertEqual(server_info.client_auth_requirement, ClientAuthenticationServerConfigurationEnum.REQUIRED)
class HeartbleedPluginTestCase(unittest.TestCase): def test_heartbleed_good(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = HeartbleedPlugin() plugin_result = plugin.process_task(server_info, HeartbleedScanCommand()) self.assertFalse(plugin_result.is_vulnerable_to_heartbleed) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_heartbleed_bad(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester(hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = HeartbleedPlugin() plugin_result = plugin.process_task(server_info, HeartbleedScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_heartbleed) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port ) server_info = server_test.perform() # The plugin works even when a client cert was not supplied plugin = HeartbleedPlugin() plugin_result = plugin.process_task(server_info, HeartbleedScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_heartbleed) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
class OpenSslCcsInjectionPluginTestCase(unittest.TestCase): def test_ccs_injection_good(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCcsInjectionPlugin() plugin_result = plugin.process_task(server_info, OpenSslCcsInjectionScanCommand()) self.assertFalse(plugin_result.is_vulnerable_to_ccs_injection) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_ccs_injection_bad(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCcsInjectionPlugin() plugin_result = plugin.process_task( server_info, OpenSslCcsInjectionScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_ccs_injection) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # OpenSslCcsInjectionPlugin works even when a client cert was not supplied plugin = OpenSslCcsInjectionPlugin() plugin_result = plugin.process_task( server_info, OpenSslCcsInjectionScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_ccs_injection) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_works_when_client_auth_succeeded(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client provides a client certificate client_creds = ClientAuthenticationCredentials( client_certificate_chain_path=server. get_client_certificate_path(), client_key_path=server.get_client_key_path(), ) server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port, client_auth_credentials=client_creds, ) server_info = server_test.perform() # The plugin works fine plugin = SessionRenegotiationPlugin() plugin_result = plugin.process_task( server_info, SessionRenegotiationScanCommand()) self.assertTrue(plugin_result.accepts_client_renegotiation) self.assertTrue(plugin_result.supports_secure_renegotiation) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_works_when_client_auth_succeeded(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client provides a client certificate client_creds = ClientAuthenticationCredentials( client_certificate_chain_path=server. get_client_certificate_path(), client_key_path=server.get_client_key_path(), ) server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port, client_auth_credentials=client_creds, ) server_info = server_test.perform() # The plugin works fine plugin = FallbackScsvPlugin() plugin_result = plugin.process_task(server_info, FallbackScsvScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return self.assertFalse(plugin_result.supports_fallback_scsv) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # CertificateInfoPlugin works even when a client cert was not supplied plugin = CertificateInfoPlugin() plugin_result = plugin.process_task( server_info, CertificateInfoScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return self.assertTrue(plugin_result.certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_client_authentication_no_certificate_supplied_but_ignore(self): # Given a server that accepts optional client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.OPTIONAL ) as server: # And the client does NOT provide a client cert but is configured to ignore the client auth request sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((server.hostname, server.port)) ssl_client = self._SSL_CLIENT_CLS( ssl_version=OpenSslVersionEnum.SSLV23, underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE, ignore_client_authentication_requests=True, ) # When doing the handshake try: ssl_client.do_handshake() # It succeeds self.assertTrue(ssl_client) finally: ssl_client.shutdown() sock.close() except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def test_fails_when_client_auth_failed_session(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port ) server_info = server_test.perform() # SessionResumptionPlugin fails even when a client cert was not supplied plugin = SessionResumptionPlugin() plugin_result = plugin.process_task(server_info, SessionResumptionSupportScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return # All session resumption attempts returned an error because of client authentication self.assertEqual(len(plugin_result.errored_resumptions_list), 5) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_client_authentication_succeeds(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client provides a client certificate sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((server.hostname, server.port)) ssl_client = self._SSL_CLIENT_CLS( ssl_version=OpenSslVersionEnum.SSLV23, underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE, client_certchain_file=server.get_client_certificate_path(), client_key_file=server.get_client_key_path(), ) # When doing the handshake, it succeeds try: ssl_client.do_handshake() finally: ssl_client.shutdown() sock.close() except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def test_client_authentication_no_certificate_supplied(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client does NOT provide a client certificate sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((server.hostname, server.port)) ssl_client = self._SSL_CLIENT_CLS( ssl_version=OpenSslVersionEnum.SSLV23, underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE, ) # When doing the handshake the right error is returned self.assertRaisesRegexp( ClientCertificateRequested, 'Server requested a client certificate', ssl_client.do_handshake) sock.close() except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def test_ssl_2(self): # Given a server that supports SSL 2.0 try: with VulnerableOpenSslServer() as server: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((server.hostname, server.port)) ssl_client = LegacySslClient( ssl_version=OpenSslVersionEnum.SSLV2, underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE, ignore_client_authentication_requests=True, ) # When doing the special SSL 2.0 handshake, it succeeds try: ssl_client.do_handshake() self.assertTrue(ssl_client) finally: ssl_client.shutdown() sock.close() except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def test_sslv3_enabled(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv30ScanCommand()) # The embedded server does not have a preference self.assertFalse(plugin_result.preferred_cipher) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_DH_anon_WITH_AES_128_CBC_SHA', 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_SEED_CBC_SHA', 'TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5', 'TLS_ECDHE_RSA_WITH_NULL_SHA', 'TLS_ECDHE_RSA_WITH_RC4_128_SHA', 'TLS_DH_anon_WITH_AES_256_CBC_SHA', 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA', 'TLS_ECDH_anon_WITH_RC4_128_SHA', 'TLS_DH_anon_WITH_3DES_EDE_CBC_SHA', 'TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA', 'TLS_DH_anon_EXPORT_WITH_RC4_40_MD5', 'TLS_RSA_EXPORT_WITH_DES40_CBC_SHA', 'TLS_ECDH_anon_WITH_NULL_SHA', 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA', 'TLS_RSA_WITH_RC4_128_SHA', 'TLS_RSA_EXPORT_WITH_RC4_40_MD5', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_NULL_MD5', 'TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA', 'TLS_DH_anon_WITH_DES_CBC_SHA', 'TLS_RSA_WITH_SEED_CBC_SHA', 'TLS_RSA_WITH_DES_CBC_SHA', 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_RC4_128_MD5', 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_NULL_SHA', 'TLS_RSA_WITH_IDEA_CBC_SHA', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_RC4_128_MD5' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
def test_required_client_auth(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # SSLyze correctly detects that client auth is required self.assertEqual(server_info.client_auth_requirement, ClientAuthenticationServerConfigurationEnum.REQUIRED)
def test_ccs_injection_bad(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCcsInjectionPlugin() plugin_result = plugin.process_task( server_info, OpenSslCcsInjectionScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_ccs_injection) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_heartbleed_bad(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester(hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = HeartbleedPlugin() plugin_result = plugin.process_task(server_info, HeartbleedScanCommand()) self.assertTrue(plugin_result.is_vulnerable_to_heartbleed) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
def test_fails_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # The plugin fails when a client cert was not supplied plugin = HttpHeadersPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, HttpHeadersScanCommand())
class RobotPluginPluginTestCase(unittest.TestCase): def test_robot_attack_good(self): # Validate the bug fix for https://github.com/nabla-c0d3/sslyze/issues/282 server_test = ServerConnectivityTester(hostname='guide.duo.com') server_info = server_test.perform() plugin = RobotPlugin() plugin_result = plugin.process_task(server_info, RobotScanCommand()) # On Travis CI we sometimes get inconsistent results if IS_RUNNING_ON_TRAVIS: self.assertIn(plugin_result.robot_result_enum, [ RobotScanResultEnum.NOT_VULNERABLE_NO_ORACLE, RobotScanResultEnum.UNKNOWN_INCONSISTENT_RESULTS ]) else: self.assertEqual(plugin_result.robot_result_enum, RobotScanResultEnum.NOT_VULNERABLE_NO_ORACLE) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) @unittest.skip('Not implemented') def test_robot_attack_bad(self): # TODO(AD): Find a vulnerable server? pass @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_fails_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # The plugin fails when a client cert was not supplied plugin = RobotPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, RobotScanCommand())
def test_fallback_bad(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = FallbackScsvPlugin() plugin_result = plugin.process_task(server_info, FallbackScsvScanCommand()) self.assertFalse(plugin_result.supports_fallback_scsv) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
def test_required_client_auth(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return # SSLyze correctly detects that client auth is required self.assertEqual(server_info.client_auth_requirement, ClientAuthenticationServerConfigurationEnum.REQUIRED)
def test_sslv2_enabled(self): try: with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv20ScanCommand()) except NotOnLinux64Error: # The test suite only has the vulnerable OpenSSL version compiled for Linux 64 bits logging.warning('WARNING: Not on Linux - skipping test') return # The embedded server does not have a preference self.assertFalse(plugin_result.preferred_cipher) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'SSL_CK_RC4_128_EXPORT40_WITH_MD5', 'SSL_CK_IDEA_128_CBC_WITH_MD5', 'SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5', 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5', 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5', 'SSL_CK_RC4_128_WITH_MD5', 'SSL_CK_RC2_128_CBC_WITH_MD5', 'SSL_CK_DES_64_CBC_WITH_MD5' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.accepted_cipher_list) self.assertFalse(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # OpenSslCipherSuitesPlugin works even when a client cert was not supplied plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv30ScanCommand()) self.assertTrue(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
def test_fails_when_client_auth_failed(self): # Given a server that requires client authentication try: with VulnerableOpenSslServer( client_auth_config= ClientAuthenticationServerConfigurationEnum.REQUIRED ) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # The plugin fails when a client cert was not supplied plugin = FallbackScsvPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, FallbackScsvScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def test_heartbleed_bad(self): try: with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = HeartbleedPlugin() plugin_result = plugin.process_task(server_info, HeartbleedScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return self.assertTrue(plugin_result.is_vulnerable_to_heartbleed) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
def test_fallback_bad(self): try: with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = FallbackScsvPlugin() plugin_result = plugin.process_task(server_info, FallbackScsvScanCommand()) except NotOnLinux64Error: # The test suite only has the vulnerable OpenSSL version compiled for Linux 64 bits logging.warning( 'WARNING: Not on Linux - skipping test_fallback_bad() test') return self.assertFalse(plugin_result.supports_fallback_scsv) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result))
class SessionRenegotiationPluginTestCase(unittest.TestCase): def test_renegotiation_good(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = SessionRenegotiationPlugin() plugin_result = plugin.process_task(server_info, SessionRenegotiationScanCommand()) self.assertFalse(plugin_result.accepts_client_renegotiation) self.assertTrue(plugin_result.supports_secure_renegotiation) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_fails_when_client_auth_failed_session(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # The plugin fails when a client cert was not supplied plugin = SessionRenegotiationPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, SessionRenegotiationScanCommand()) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_works_when_client_auth_succeeded(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client provides a client certificate client_creds = ClientAuthenticationCredentials( client_certificate_chain_path=server. get_client_certificate_path(), client_key_path=server.get_client_key_path(), ) server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port, client_auth_credentials=client_creds, ) server_info = server_test.perform() # The plugin works fine plugin = SessionRenegotiationPlugin() plugin_result = plugin.process_task( server_info, SessionRenegotiationScanCommand()) self.assertTrue(plugin_result.accepts_client_renegotiation) self.assertTrue(plugin_result.supports_secure_renegotiation) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
class CertificateInfoPluginTestCase(unittest.TestCase): def test_ca_file_bad_file(self): server_test = ServerConnectivityTester(hostname='www.hotmail.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() with self.assertRaises(ValueError): plugin.process_task( server_info, CertificateInfoScanCommand(ca_file='doesntexist')) def test_ca_file(self): server_test = ServerConnectivityTester(hostname='www.hotmail.com') server_info = server_test.perform() ca_file_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'wildcard-self-signed.pem') plugin = CertificateInfoPlugin() plugin_result = plugin.process_task( server_info, CertificateInfoScanCommand(ca_file=ca_file_path)) self.assertGreaterEqual(len(plugin_result.path_validation_result_list), 6) for path_validation_result in plugin_result.path_validation_result_list: if path_validation_result.trust_store.name == 'Custom --ca_file': self.assertFalse(path_validation_result.is_certificate_trusted) else: self.assertTrue(path_validation_result.is_certificate_trusted) @unittest.skip('Not implemented - find a server that has must-staple') def test_valid_chain_with_ocsp_stapling_and_must_staple(self): server_test = ServerConnectivityTester(hostname='www.scotthelme.co.uk') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.ocsp_response) self.assertEqual(plugin_result.ocsp_response_status, OcspResponseStatusEnum.SUCCESSFUL) self.assertTrue(plugin_result.is_ocsp_response_trusted) self.assertTrue(plugin_result.certificate_has_must_staple_extension) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_valid_chain_with_ev_cert(self): server_test = ServerConnectivityTester(hostname='www.comodo.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.is_leaf_certificate_ev) self.assertEqual(len(plugin_result.certificate_chain), 4) self.assertEqual(len(plugin_result.verified_certificate_chain), 3) self.assertFalse(plugin_result.has_anchor_in_certificate_chain) self.assertGreaterEqual(len(plugin_result.path_validation_result_list), 5) for path_validation_result in plugin_result.path_validation_result_list: self.assertTrue(path_validation_result.is_certificate_trusted) self.assertEqual(len(plugin_result.path_validation_error_list), 0) self.assertEqual(plugin_result.certificate_matches_hostname, True) self.assertTrue(plugin_result.is_certificate_chain_order_valid) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_invalid_chain(self): server_test = ServerConnectivityTester( hostname='self-signed.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertIsNone(plugin_result.ocsp_response) self.assertEqual(len(plugin_result.certificate_chain), 1) self.assertGreaterEqual(len(plugin_result.path_validation_result_list), 5) for path_validation_result in plugin_result.path_validation_result_list: self.assertFalse(path_validation_result.is_certificate_trusted) self.assertEqual(plugin_result.certificate_included_scts_count, 0) self.assertEqual(len(plugin_result.path_validation_error_list), 0) self.assertEqual(plugin_result.certificate_matches_hostname, True) self.assertTrue(plugin_result.is_certificate_chain_order_valid) self.assertIsNone(plugin_result.has_anchor_in_certificate_chain) self.assertIsNone(plugin_result.has_sha1_in_certificate_chain) self.assertFalse(plugin_result.verified_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_1000_sans_chain(self): # Ensure SSLyze can process a leaf cert with 1000 SANs server_test = ServerConnectivityTester(hostname='1000-sans.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin.process_task(server_info, CertificateInfoScanCommand()) def test_sha1_chain(self): server_test = ServerConnectivityTester( hostname='sha1-intermediate.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.has_sha1_in_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) def test_sha256_chain(self): server_test = ServerConnectivityTester(hostname='sha256.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertFalse(plugin_result.has_sha1_in_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_unicode_certificate(self): server_test = ServerConnectivityTester(hostname='เพย์สบาย.th') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertGreaterEqual(len(plugin_result.certificate_chain), 1) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_ecdsa_certificate(self): server_test = ServerConnectivityTester(hostname='www.cloudflare.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertGreaterEqual(len(plugin_result.certificate_chain), 1) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_chain_with_anchor(self): server_test = ServerConnectivityTester(hostname='www.verizon.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.has_anchor_in_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_not_trusted_by_mozilla_but_trusted_by_microsoft(self): server_test = ServerConnectivityTester( hostname='webmail.russia.nasa.gov') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertEqual(plugin_result.successful_trust_store.name, 'Windows') self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_only_trusted_by_custom_ca_file(self): server_test = ServerConnectivityTester( hostname='self-signed.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() ca_file_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'self-signed.badssl.com.pem') plugin_result = plugin.process_task( server_info, CertificateInfoScanCommand(ca_file=ca_file_path)) self.assertEqual(plugin_result.successful_trust_store.name, 'Custom --ca_file') self.assertTrue(plugin_result.verified_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_certificate_with_no_cn(self): server_test = ServerConnectivityTester( hostname='no-common-name.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.verified_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_certificate_with_no_subject(self): server_test = ServerConnectivityTester( hostname='no-subject.badssl.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.verified_certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_certificate_with_scts(self): server_test = ServerConnectivityTester(hostname='www.apple.com') server_info = server_test.perform() plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertGreater(plugin_result.certificate_included_scts_count, 1) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # CertificateInfoPlugin works even when a client cert was not supplied plugin = CertificateInfoPlugin() plugin_result = plugin.process_task(server_info, CertificateInfoScanCommand()) self.assertTrue(plugin_result.certificate_chain) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
class OpenSslCipherSuitesPluginTestCase(unittest.TestCase): @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_sslv2_enabled(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv20ScanCommand()) # The embedded server does not have a preference self.assertFalse(plugin_result.preferred_cipher) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'SSL_CK_RC4_128_EXPORT40_WITH_MD5', 'SSL_CK_IDEA_128_CBC_WITH_MD5', 'SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5', 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5', 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5', 'SSL_CK_RC4_128_WITH_MD5', 'SSL_CK_RC2_128_CBC_WITH_MD5', 'SSL_CK_DES_64_CBC_WITH_MD5' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.accepted_cipher_list) self.assertFalse(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_sslv2_disabled(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv20ScanCommand()) self.assertIsNone(plugin_result.preferred_cipher) self.assertFalse(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_sslv3_enabled(self): with VulnerableOpenSslServer() as server: server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv30ScanCommand()) # The embedded server does not have a preference self.assertFalse(plugin_result.preferred_cipher) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_DH_anon_WITH_AES_128_CBC_SHA', 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_SEED_CBC_SHA', 'TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5', 'TLS_ECDHE_RSA_WITH_NULL_SHA', 'TLS_ECDHE_RSA_WITH_RC4_128_SHA', 'TLS_DH_anon_WITH_AES_256_CBC_SHA', 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA', 'TLS_ECDH_anon_WITH_RC4_128_SHA', 'TLS_DH_anon_WITH_3DES_EDE_CBC_SHA', 'TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA', 'TLS_DH_anon_EXPORT_WITH_RC4_40_MD5', 'TLS_RSA_EXPORT_WITH_DES40_CBC_SHA', 'TLS_ECDH_anon_WITH_NULL_SHA', 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA', 'TLS_RSA_WITH_RC4_128_SHA', 'TLS_RSA_EXPORT_WITH_RC4_40_MD5', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_NULL_MD5', 'TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA', 'TLS_DH_anon_WITH_DES_CBC_SHA', 'TLS_RSA_WITH_SEED_CBC_SHA', 'TLS_RSA_WITH_DES_CBC_SHA', 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_RC4_128_MD5', 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_NULL_SHA', 'TLS_RSA_WITH_IDEA_CBC_SHA', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_RC4_128_MD5' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_sslv3_disabled(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv30ScanCommand()) self.assertIsNone(plugin_result.preferred_cipher) self.assertFalse(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_tlsv1_0_enabled(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv10ScanCommand()) self.assertTrue(plugin_result.preferred_cipher) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_tlsv1_0_disabled(self): server_test = ServerConnectivityTester( hostname='success.trendmicro.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv10ScanCommand()) self.assertIsNone(plugin_result.preferred_cipher) self.assertFalse(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_tlsv1_1_enabled(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv11ScanCommand()) self.assertTrue(plugin_result.preferred_cipher) self.assertTrue(plugin_result.accepted_cipher_list) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_tlsv1_2_enabled(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() # Also do full HTTP connections plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand(http_get=True)) self.assertTrue(plugin_result.preferred_cipher) self.assertTrue(plugin_result.accepted_cipher_list) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_AES_256_GCM_SHA384', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_RSA_WITH_AES_128_GCM_SHA256', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.rejected_cipher_list) self.assertFalse(plugin_result.errored_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_null_cipher_suites(self): server_test = ServerConnectivityTester(hostname='null.badssl.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA', 'TLS_DH_anon_WITH_AES_256_CBC_SHA256', 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA', 'TLS_DH_anon_WITH_AES_256_GCM_SHA384', 'TLS_DH_anon_WITH_AES_256_CBC_SHA', 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_AES_128_CBC_SHA256', 'TLS_DH_anon_WITH_AES_128_CBC_SHA', 'TLS_DH_anon_WITH_AES_128_GCM_SHA256', 'TLS_DH_anon_WITH_SEED_CBC_SHA', 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_NULL_SHA', 'TLS_ECDH_anon_WITH_NULL_SHA', 'TLS_RSA_WITH_NULL_SHA256', 'TLS_RSA_WITH_NULL_SHA' }, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_rc4_cipher_suites(self): server_test = ServerConnectivityTester(hostname='rc4.badssl.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( {'TLS_ECDHE_RSA_WITH_RC4_128_SHA', 'TLS_RSA_WITH_RC4_128_SHA'}, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_rc4_md5_cipher_suites(self): server_test = ServerConnectivityTester(hostname='rc4-md5.badssl.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual({'TLS_RSA_WITH_RC4_128_MD5'}, set(accepted_cipher_name_list)) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_follows_client_cipher_suite_preference(self): # Google.com does not follow client cipher suite preference server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) self.assertTrue(plugin_result.preferred_cipher) self.assertTrue(plugin_result.accepted_cipher_list) # Sogou.com follows client cipher suite preference server_test = ServerConnectivityTester(hostname='www.sogou.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) self.assertIsNone(plugin_result.preferred_cipher) self.assertTrue(plugin_result.accepted_cipher_list) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_smtp_post_handshake_response(self): server_test = ServerConnectivityTester( hostname='smtp.gmail.com', port=587, tls_wrapped_protocol=TlsWrappedProtocolEnum.STARTTLS_SMTP) server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand()) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) def test_tls_1_3_cipher_suites(self): server_test = ServerConnectivityTester(hostname='www.cloudflare.com') server_info = server_test.perform() plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Tlsv13ScanCommand()) accepted_cipher_name_list = [ cipher.name for cipher in plugin_result.accepted_cipher_list ] self.assertEqual( { 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_AES_256_GCM_SHA384', 'TLS_AES_128_GCM_SHA256' }, set(accepted_cipher_name_list)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_succeeds_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # OpenSslCipherSuitesPlugin works even when a client cert was not supplied plugin = OpenSslCipherSuitesPlugin() plugin_result = plugin.process_task(server_info, Sslv30ScanCommand()) self.assertTrue(plugin_result.accepted_cipher_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
class HttpHeadersPluginTestCase(unittest.TestCase): def test_hsts_enabled(self): server_test = ServerConnectivityTester(hostname='hsts.badssl.com') server_info = server_test.perform() plugin = HttpHeadersPlugin() plugin_result = plugin.process_task(server_info, HttpHeadersScanCommand()) self.assertTrue(plugin_result.hsts_header) self.assertFalse(plugin_result.hpkp_header) self.assertIsNone(plugin_result.is_valid_pin_configured) self.assertIsNone(plugin_result.is_backup_pin_configured) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_hsts_and_hpkp_disabled(self): server_test = ServerConnectivityTester(hostname='expired.badssl.com') server_info = server_test.perform() plugin = HttpHeadersPlugin() plugin_result = plugin.process_task(server_info, HttpHeadersScanCommand()) self.assertFalse(plugin_result.hsts_header) self.assertFalse(plugin_result.hpkp_header) self.assertIsNone(plugin_result.is_valid_pin_configured) self.assertIsNone(plugin_result.is_backup_pin_configured) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_hpkp_enabled(self): # HPKP is being deprecated in Chrome - I couldn't find a website with the header set pass def test_expect_ct_disabled(self): server_test = ServerConnectivityTester(hostname='hsts.badssl.com') server_info = server_test.perform() plugin = HttpHeadersPlugin() plugin_result = plugin.process_task(server_info, HttpHeadersScanCommand()) self.assertFalse(plugin_result.expect_ct_header) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) self.assertTrue(pickle.dumps(plugin_result)) def test_expect_ct_enabled(self): # Github was the only server I could find with expect-ct header set server_test = ServerConnectivityTester(hostname='github.com') server_info = server_test.perform() plugin = HttpHeadersPlugin() plugin_result = plugin.process_task(server_info, HttpHeadersScanCommand()) self.assertTrue(plugin_result.expect_ct_header) self.assertTrue(plugin_result.expect_ct_header.max_age >= 0) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_fails_when_client_auth_failed(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # The plugin fails when a client cert was not supplied plugin = HttpHeadersPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, HttpHeadersScanCommand()) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_works_when_client_auth_succeeded(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client provides a client certificate client_creds = ClientAuthenticationCredentials( client_certificate_chain_path=server. get_client_certificate_path(), client_key_path=server.get_client_key_path(), ) server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port, client_auth_credentials=client_creds, ) server_info = server_test.perform() # The plugin works fine plugin = HttpHeadersPlugin() plugin_result = plugin.process_task(server_info, HttpHeadersScanCommand()) self.assertIsNone(plugin_result.expect_ct_header) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())
class SessionResumptionPluginTestCase(unittest.TestCase): def test_resumption_support(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = SessionResumptionPlugin() plugin_result = plugin.process_task( server_info, SessionResumptionSupportScanCommand()) self.assertTrue(plugin_result.is_ticket_resumption_supported) self.assertTrue(plugin_result.attempted_resumptions_nb) self.assertTrue(plugin_result.successful_resumptions_nb) self.assertFalse(plugin_result.errored_resumptions_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) def test_resumption_rate(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() plugin = SessionResumptionPlugin() plugin_result = plugin.process_task(server_info, SessionResumptionRateScanCommand()) self.assertTrue(plugin_result.attempted_resumptions_nb) self.assertTrue(plugin_result.successful_resumptions_nb) self.assertFalse(plugin_result.errored_resumptions_list) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue self.assertTrue(pickle.dumps(plugin_result)) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_fails_when_client_auth_failed_session(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client does NOT provide a client certificate server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port) server_info = server_test.perform() # SessionResumptionPlugin fails even when a client cert was not supplied plugin = SessionResumptionPlugin() plugin_result = plugin.process_task( server_info, SessionResumptionSupportScanCommand()) # All session resumption attempts returned an error because of client authentication self.assertEqual(len(plugin_result.errored_resumptions_list), 5) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) @unittest.skipIf(not VulnerableOpenSslServer.is_platform_supported(), 'Not on Linux 64') def test_works_when_client_auth_succeeded(self): # Given a server that requires client authentication with VulnerableOpenSslServer( client_auth_config=ClientAuthenticationServerConfigurationEnum. REQUIRED) as server: # And the client provides a client certificate client_creds = ClientAuthenticationCredentials( client_certificate_chain_path=server. get_client_certificate_path(), client_key_path=server.get_client_key_path(), ) server_test = ServerConnectivityTester( hostname=server.hostname, ip_address=server.ip_address, port=server.port, client_auth_credentials=client_creds, ) server_info = server_test.perform() # SessionResumptionPlugin works fine plugin = SessionResumptionPlugin() plugin_result = plugin.process_task( server_info, SessionResumptionSupportScanCommand()) self.assertEqual(plugin_result.successful_resumptions_nb, 5) self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml())