예제 #1
0
    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())
예제 #2
0
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())
예제 #4
0
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)
예제 #5
0
    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))
예제 #6
0
    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())
예제 #7
0
    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)
예제 #8
0
 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
예제 #9
0
    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)
예제 #10
0
    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
예제 #11
0
    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
예제 #13
0
 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())
예제 #15
0
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!")
예제 #16
0
    # 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(
예제 #17
0
    # 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