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 scan_serial(scanner, server_info, data, options): errors = 0 def run_scan(scan_type, command, errors): if (errors >= 2): return None, errors logging.debug("\t\t{} scan.".format(scan_type)) result = None try: result = scanner.run_scan_command(server_info, command) except Exception as err: logging.warning("{}: Error during {} scan.".format( server_info.hostname, scan_type)) logging.debug("{}: Exception during {} scan: {}".format( server_info.hostname, scan_type, err)) errors = errors + 1 return result, errors logging.debug("\tRunning scans in serial.") sslv2, errors = run_scan("SSLv2", Sslv20ScanCommand(), errors) sslv3, errors = run_scan("SSLv3", Sslv30ScanCommand(), errors) tlsv1, errors = run_scan("TLSv1.0", Tlsv10ScanCommand(), errors) tlsv1_1, errors = run_scan("TLSv1.1", Tlsv11ScanCommand(), errors) tlsv1_2, errors = run_scan("TLSv1.2", Tlsv12ScanCommand(), errors) tlsv1_3, errors = run_scan("TLSv1.3", Tlsv13ScanCommand(), errors) certs = None if errors < 2 and options.get("sslyze_certs", True) is True: try: logging.debug("\t\tCertificate information scan.") certs = scanner.run_scan_command( server_info, CertificateInfoScanCommand(ca_file=CA_FILE)) except idna.core.InvalidCodepoint: logging.warning(utils.format_last_exception()) data['errors'].append("Invalid certificate/OCSP for this domain.") certs = None except Exception as err: logging.warning( "{}: Error during certificate information scan.".format( server_info.hostname)) logging.debug( "{}: Exception during certificate information scan: {}".format( server_info.hostname, err)) else: certs = None reneg = None if options.get("sslyze_reneg", True) is True: reneg, errors = run_scan("Renegotiation", SessionRenegotiationScanCommand(), errors) else: reneg = None logging.debug("\tDone scanning.") return sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2, tlsv1_3, certs, reneg
def test_renegotiation_good(self): server_info = ServerConnectivityInfo(hostname=u'www.google.com') server_info.test_connectivity_to_server() 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())
def retrieve_ssl_vulnerabilities_for_tcp_service( self, org_uuid=None, service_uuid=None, scan_uuid=None, ): """ This performs various SSL vulnerability scans on the tcp service :param org_uuid: The UUID of the organization to collect information on behalf of. :param service_uuid: The UUID of the network service to retrieve the SSL certificate for. :param scan_uuid: The UUID of the network service scan that this SSL certificate retrieval is associated with. :return: None """ ip_address, port, protocol = self.get_endpoint_information(service_uuid) ssl_vulnerabilities_record = SslVulnerabilitiesModel.from_database_model_uuid( uuid=scan_uuid, db_session=self.db_session ) server_info = ServerConnectivityInfo(hostname=ip_address, ip_address=ip_address, port=port) try: server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server logger.error( "Error making an SSL connection to the server while looking for vulnerabilities, something went really wrong." ) synchronous_scanner = SynchronousScanner() fallback_scsv_command = FallbackScsvScanCommand() fallback_scsv_result = synchronous_scanner.run_scan_command(server_info, fallback_scsv_command) ssl_vulnerabilities_record.supports_fallback_scsv = fallback_scsv_result.supports_fallback_scsv heartbleed_command = HeartbleedScanCommand() heartbleed_result = synchronous_scanner.run_scan_command(server_info, heartbleed_command) ssl_vulnerabilities_record.is_vulnerable_to_heartbleed = heartbleed_result.is_vulnerable_to_heartbleed openssl_css_injection_command = OpenSslCcsInjectionScanCommand() openssl_css_injection_result = synchronous_scanner.run_scan_command(server_info, openssl_css_injection_command) ssl_vulnerabilities_record.is_vulnerable_to_ccs_injection = openssl_css_injection_result.is_vulnerable_to_ccs_injection session_renegotion_command = SessionRenegotiationScanCommand() session_renegotion_result = synchronous_scanner.run_scan_command(server_info, session_renegotion_command) ssl_vulnerabilities_record.accepts_client_renegotiation = session_renegotion_result.accepts_client_renegotiation ssl_vulnerabilities_record.supports_secure_renegotiation = session_renegotion_result.supports_secure_renegotiation session_resumption_support_command = SessionResumptionSupportScanCommand() session_resumption_support_result = synchronous_scanner.run_scan_command(server_info, session_resumption_support_command) ssl_vulnerabilities_record.is_ticket_resumption_supported = session_resumption_support_result.is_ticket_resumption_supported ssl_vulnerabilities_record.save(org_uuid)
def test_renegotiation_good(self): server_info = ServerConnectivityInfo(hostname='www.google.com') server_info.test_connectivity_to_server() 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))
def test_fails_when_client_auth_failed_session(self): # Given a server that requires client authentication with LegacyOpenSslServer( client_auth_config=ClientAuthConfigEnum.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 pytest.raises(ClientCertificateRequested): plugin.process_task(server_info, SessionRenegotiationScanCommand())
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()) assert not plugin_result.accepts_client_renegotiation assert plugin_result.supports_secure_renegotiation assert plugin_result.as_text() assert plugin_result.as_xml() # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue assert pickle.dumps(plugin_result)
def run_session_renegotiation_command(self, server_info, synchronous_scanner): command = SessionRenegotiationScanCommand() try: scan_result = synchronous_scanner.run_scan_command( server_info, command) #print('session_renegotiation obtained for ',server_info) return { "supports_secure_renegotiation": scan_result.supports_secure_renegotiation, "accepts_client_renegotiation": scan_result.accepts_client_renegotiation } except: #print('session_renegotiation obtained for ',server_info) return None
def test_concurrent_scanner(self): server_info = ServerConnectivityInfo(hostname='www.google.com') server_info.test_connectivity_to_server() # Queue some scan commands that are quick concurrent_scanner = ConcurrentScanner() concurrent_scanner.queue_scan_command(server_info, CertificateInfoScanCommand()) concurrent_scanner.queue_scan_command(server_info, SessionRenegotiationScanCommand()) concurrent_scanner.queue_scan_command(server_info, CompressionScanCommand()) # Process the results nb_results = 0 for plugin_result in concurrent_scanner.get_results(): self.assertTrue(plugin_result.as_text()) self.assertTrue(plugin_result.as_xml()) nb_results +=1 self.assertEquals(nb_results, 3)
def test_concurrent_scanner(self): server_test = ServerConnectivityTester(hostname='www.google.com') server_info = server_test.perform() # Queue some scan commands that are quick concurrent_scanner = ConcurrentScanner() concurrent_scanner.queue_scan_command(server_info, CertificateInfoScanCommand()) concurrent_scanner.queue_scan_command(server_info, SessionRenegotiationScanCommand()) concurrent_scanner.queue_scan_command(server_info, CompressionScanCommand()) # Process the results nb_results = 0 for plugin_result in concurrent_scanner.get_results(): assert plugin_result.as_text() assert plugin_result.as_xml() nb_results += 1 assert nb_results == 3
def executePerDomainAction(self, domain): """ This plugin's per-domain action is to run a barrage of sslyze certificate tests Params: domain (str) """ from sslyze.plugins.certificate_info_plugin import CertificateInfoScanCommand from sslyze.plugins.compression_plugin import CompressionScanCommand from sslyze.plugins.session_renegotiation_plugin import SessionRenegotiationScanCommand from sslyze.server_connectivity_tester import ServerConnectivityTester from sslyze.server_connectivity_tester import ServerConnectivityError from sslyze.synchronous_scanner import SynchronousScanner try: sslyze_conn_test = ServerConnectivityTester(hostname=domain) sslyze_server_info = sslyze_conn_test.perform() sslyze_scanner = SynchronousScanner() sslyze_results = sslyze_scanner.run_scan_command( sslyze_server_info, CertificateInfoScanCommand()) sslyze_result_lines = sslyze_results.as_text() for line in sslyze_result_lines: self.logger.info(line) sslyze_results = sslyze_scanner.run_scan_command( sslyze_server_info, SessionRenegotiationScanCommand()) sslyze_result_lines = sslyze_results.as_text() for line in sslyze_result_lines: self.logger.info(line) sslyze_results = sslyze_scanner.run_scan_command( sslyze_server_info, CompressionScanCommand()) sslyze_result_lines = sslyze_results.as_text() for line in sslyze_result_lines: self.logger.info(line) except ServerConnectivityError as e: # Could not establish a TLS/SSL connection to the server self.logger.error( f'sslyze ended early, could not connect to {e.server_info.hostname}: {e.error_message}' ) print( f'sslyze ended early, could not connect to {e.server_info.hostname}: {e.error_message}' )
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() # The plugin fails when a client cert was not supplied plugin = SessionRenegotiationPlugin() with self.assertRaises(ClientCertificateRequested): plugin.process_task(server_info, SessionRenegotiationScanCommand()) except NotOnLinux64Error: logging.warning('WARNING: Not on Linux - skipping test') return
def module_run(self, hostportsip): for host, port, ip_address in hostportsip: self.heading('{0}:{1} ({2})'.format(host, port, ip_address), level=0) port = int(port) try: tls_wrapped_protocol = self.STARTTLS_PROTOCOL_DICT[port] except KeyError: self.error("Protocol not found for port {}".format(port)) continue try: server_info = ServerConnectivityInfo(hostname=host, port=port, ip_address=ip_address, tls_wrapped_protocol=tls_wrapped_protocol) server_info.test_connectivity_to_server() except ServerConnectivityError as e: self.error("Could not connect to {0}:{1}: {2}".format(host, port, e)) continue concurrent_scanner = ConcurrentScanner() concurrent_scanner.queue_scan_command(server_info, SessionRenegotiationScanCommand()) concurrent_scanner.queue_scan_command(server_info, CompressionScanCommand()) concurrent_scanner.queue_scan_command(server_info, FallbackScsvScanCommand()) concurrent_scanner.queue_scan_command(server_info, HeartbleedScanCommand()) concurrent_scanner.queue_scan_command(server_info, RobotScanCommand()) concurrent_scanner.queue_scan_command(server_info, OpenSslCcsInjectionScanCommand()) concurrent_scanner.queue_scan_command(server_info, SessionResumptionSupportScanCommand()) for scan_result in concurrent_scanner.get_results(): data = None if isinstance(scan_result, HeartbleedScanResult): if scan_result.is_vulnerable_to_heartbleed: data = {'reference': 'VULNERABLE - HEARTBLEED - Server is vulnerable to Heartbleed', 'example': '\n'.join(scan_result.as_text())} elif isinstance(scan_result, RobotScanResult): if scan_result.robot_result_enum == RobotScanResultEnum.VULNERABLE_STRONG_ORACLE: data = {'reference': 'VULNERABLE - ROBOT - Strong oracle, a real attack is possible', 'example': '\n'.join(scan_result.as_text())} elif scan_result.robot_result_enum == RobotScanResultEnum.VULNERABLE_WEAK_ORACLE: data = {'reference': 'VULNERABLE - ROBOT - Weak oracle, the attack would take too long', 'example': '\n'.join(scan_result.as_text())} elif isinstance(scan_result, CompressionScanResult): if scan_result.compression_name: data = {'reference': "VULNERABLE - Server supports Deflate compression", 'example': '\n'.join(scan_result.as_text())} elif isinstance(scan_result, FallbackScsvScanResult): if scan_result.supports_fallback_scsv: data = {'reference': "VULNERABLE - Signaling cipher suite not supported", 'example': '\n'.join(scan_result.as_text())} data = None elif isinstance(scan_result, OpenSslCcsInjectionScanResult): if scan_result.is_vulnerable_to_ccs_injection: data = {'reference': 'VULNERABLE - Server is vulnerable to OpenSSL CCS injection', 'example': '\n'.join(scan_result.as_text())} elif isinstance(scan_result, SessionRenegotiationScanResult): if scan_result.accepts_client_renegotiation: data = {'reference': 'VULNERABLE - Server honors client-initiated renegotiations', 'example': '\n'.join(scan_result.as_text())} elif isinstance(scan_result, PluginRaisedExceptionScanResult): self.error('Scan command failed: {}'.format(scan_result.as_text())) continue if data: data['host'] = host data['category'] = 'TLS vulnerability' for key in sorted(data.keys()): self.output('%s: %s' % (key.title(), data[key])) self.add_vulnerabilities(**data) self.output(self.ruler*50)
def __init__(self): super().__init__(SessionRenegotiationScanCommand())
def main(): if len(sys.argv) < 2: print("Error: please provide a domain") exit(-1) hostname = sys.argv[1] """ Testing connectivity to the server """ try: server_info = ServerConnectivityInfo(hostname) server_info.test_connectivity_to_server() print( "[*] Connection established. \n[.] Starting tests on {} \n".format( hostname)) except ServerConnectivityError as e: raise RuntimeError("Error when connecting to {}: {}".format( hostname, e.error_msg)) scanner = SynchronousScanner() """ Creating an output file """ output = open("/root/PycharmProjects/SSL-TLS-Tool/output/" + hostname, "w") output.write("##############################################\n") output.write("Output result for host: {}\n".format(hostname)) output.write("Start {}\n".format(datetime.datetime.now())) output.write("##############################################\n\n") """ Certificate: """ scan_result = scanner.run_scan_command(server_info, CertificateInfoScanCommand()) for e in scan_result.as_text(): output.write(e + "\n") """ Protocols and Ciphers Suits: """ run_command(scanner, server_info, Tlsv10ScanCommand(), output) run_command(scanner, server_info, Tlsv11ScanCommand(), output) run_command(scanner, server_info, Tlsv12ScanCommand(), output) run_command(scanner, server_info, Sslv20ScanCommand(), output) run_command(scanner, server_info, Sslv30ScanCommand(), output) """ Testing vulnerabilities: """ run_command(scanner, server_info, DrownScanCommand(), output) run_command(scanner, server_info, PoodleSslScanCommand(), output) run_command(scanner, server_info, HeartbleedScanCommand(), output) run_command(scanner, server_info, OpenSslCcsInjectionScanCommand(), output) run_command(scanner, server_info, CompressionScanCommand(), output) run_command(scanner, server_info, FallbackScsvScanCommand(), output) run_command(scanner, server_info, SessionRenegotiationScanCommand(), output) run_command(scanner, server_info, SessionResumptionSupportScanCommand(), output) run_command(scanner, server_info, SessionResumptionRateScanCommand(), output) """ Closing """ output.close() print("\n[*] Check output file for more details") print("[*] Test completed!")
# Example 1: Run one scan command synchronously to list the server's TLS 1.0 cipher suites print('\nRunning one scan command synchronously...') synchronous_scanner = SynchronousScanner() command = Tlsv10ScanCommand() scan_result = synchronous_scanner.run_scan_command(server_info, command) for cipher in scan_result.accepted_cipher_list: print(' {}'.format(cipher.name)) # Example 2: Run multiple scan commands concurrently. It is of course much faster than the SynchronousScanner concurrent_scanner = ConcurrentScanner() # Queue some scan commands print('\nQueuing some commands...') concurrent_scanner.queue_scan_command(server_info, Tlsv12ScanCommand()) concurrent_scanner.queue_scan_command(server_info, SessionRenegotiationScanCommand()) concurrent_scanner.queue_scan_command(server_info, CertificateInfoScanCommand()) # Process the results reneg_result = None print('\nProcessing results...') for scan_result in concurrent_scanner.get_results(): # All scan results have the corresponding scan_command and server_info as an attribute print('\nReceived scan result for {} on host {}'.format( scan_result.scan_command.__class__.__name__, scan_result.server_info.hostname)) # Sometimes a scan command can unexpectedly fail (as a bug); it is returned as a PluginRaisedExceptionResult if isinstance(scan_result, PluginRaisedExceptionScanResult): raise RuntimeError('Scan command failed: {}'.format(
# Example 1: Run one scan command synchronously to list the server's TLS 1.0 cipher suites print('\nRunning one scan command synchronously...') synchronous_scanner = SynchronousScanner() command = Tlsv10ScanCommand() scan_result = synchronous_scanner.run_scan_command(server_info, command) for cipher in scan_result.accepted_cipher_list: print(' {}'.format(cipher.name)) # Example 2: Run multiple scan commands concurrently. It is of course much faster than the SynchronousScanner concurrent_scanner = ConcurrentScanner() # Queue some scan commands print('\nQueuing some commands...') concurrent_scanner.queue_scan_command(server_info, Tlsv12ScanCommand()) concurrent_scanner.queue_scan_command(server_info, SessionRenegotiationScanCommand()) concurrent_scanner.queue_scan_command(server_info, CertificateInfoScanCommand()) # Process the results reneg_result = None print('\nProcessing results...') for scan_result in concurrent_scanner.get_results(): # All scan results have the corresponding scan_command and server_info as an attribute print('\nReceived scan result for {} on host {}'.format(scan_result.scan_command.__class__.__name__, scan_result.server_info.hostname)) # Sometimes a scan command can unexpectedly fail (as a bug); it is returned as a PluginRaisedExceptionResult if isinstance(scan_result, PluginRaisedExceptionScanResult): raise RuntimeError('Scan command failed: {}'.format(scan_result.as_text())) # Each scan result has attributes with the information yo're looking for, specific to each scan command