Пример #1
0
def scan_serial(scanner, server_info, data, options):

    logging.debug("\tRunning scans in serial.")
    logging.debug("\t\tSSLv2 scan.")
    sslv2 = scanner.run_scan_command(server_info, Sslv20ScanCommand())
    logging.debug("\t\tSSLv3 scan.")
    sslv3 = scanner.run_scan_command(server_info, Sslv30ScanCommand())
    logging.debug("\t\tTLSv1.0 scan.")
    tlsv1 = scanner.run_scan_command(server_info, Tlsv10ScanCommand())
    logging.debug("\t\tTLSv1.1 scan.")
    tlsv1_1 = scanner.run_scan_command(server_info, Tlsv11ScanCommand())
    logging.debug("\t\tTLSv1.2 scan.")
    tlsv1_2 = scanner.run_scan_command(server_info, Tlsv12ScanCommand())
    logging.debug("\t\tTLSv1.3 scan.")
    tlsv1_3 = scanner.run_scan_command(server_info, Tlsv13ScanCommand())

    certs = None
    if options.get("sslyze_certs", True) is True:

        try:
            logging.debug("\t\tCertificate information scan.")
            certs = scanner.run_scan_command(server_info,
                                             CertificateInfoScanCommand())
        # Let generic exceptions bubble up.
        except idna.core.InvalidCodepoint:
            logging.warn(utils.format_last_exception())
            data['errors'].append("Invalid certificate/OCSP for this domain.")
            certs = None
    else:
        certs = None

    logging.debug("\tDone scanning.")

    return sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2, tlsv1_3, certs
Пример #2
0
    def test_null_cipher_suites(self):
        server_info = ServerConnectivityInfo(hostname='null.badssl.com')
        server_info.test_connectivity_to_server()

        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))
Пример #3
0
    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())

        expected_ciphers = {
            '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'
        }
        assert expected_ciphers == set(
            [cipher.name for cipher in plugin_result.accepted_cipher_list])

        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)
Пример #4
0
    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))

        assert plugin_result.preferred_cipher
        assert plugin_result.accepted_cipher_list
        expected_ciphers = {
            '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'
        }
        assert expected_ciphers == set(
            [cipher.name for cipher in plugin_result.accepted_cipher_list])

        assert plugin_result.rejected_cipher_list
        assert not plugin_result.errored_cipher_list

        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 test_tlsv1_2_enabled(self):
        server_info = ServerConnectivityInfo(hostname=u'www.google.com')
        server_info.test_connectivity_to_server()

        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.assertEquals(
            {
                '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'
            }, 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())
Пример #6
0
    def __init__(self, host, port, proxy=None):
        """
        :param proxy: (dict) Default: None; Set this one up if you wish to use
                a proxy to hit your target host. E.g.:
                {
                    "server":"someproxy.com",
                    "port":6000,
                    "user":"******",
                    "pass":"******"
                }
        """
        self.host = host
        self.port = port
        self.policies = {
            "ssl2.0": {
                "allowed": False,
                "command": Sslv20ScanCommand()
            },
            "ssl3.0": {
                "allowed": False,
                "command": Sslv30ScanCommand()
            },
            "tls1.0": {
                "allowed": False,
                "command": Tlsv10ScanCommand()
            },
            "tls1.1": {
                "allowed": False,
                "command": Tlsv11ScanCommand()
            },
            "tls1.2": {
                "allowed": True,
                "command": Tlsv12ScanCommand()
            },
            "tls1.3": {
                "allowed": True,
                "command": Tlsv13ScanCommand()
            },
        }

        if not isinstance(host, str) or not isinstance(port, int):
            raise TypeError('EncryptionCheck class not properly initialized.')

        # Proxy setup
        if proxy is not None:
            if not ("server" in proxy and "port" in proxy):
                raise ValueError('Invalid proxy settings detected.')
            proxy_server = proxy['server']
            proxy_port = proxy['port']
            proxy_user = proxy.get('user', None)
            proxy_pass = proxy.get('pass', None)
            tunnel_settings = HttpConnectTunnelingSettings(
                proxy_server,
                proxy_port,
                basic_auth_user=proxy_user,
                basic_auth_password=proxy_pass)
        else:
            tunnel_settings = None
        self.tunnel = tunnel_settings
        self.proxy = proxy
Пример #7
0
    def test_server_cipher_ordering(self):
        configured_ciphers = [
            'ECDHE-RSA-CHACHA20-POLY1305', 'ECDHE-RSA-AES128-GCM-SHA256',
            'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES128-SHA256',
            'ECDHE-RSA-AES256-SHA384', 'ECDHE-RSA-AES128-SHA',
            'ECDHE-RSA-AES256-SHA', 'AES128-GCM-SHA256', 'AES256-GCM-SHA384',
            'AES128-SHA256', 'AES256-SHA256', 'AES128-SHA', 'AES256-SHA'
        ]
        random.shuffle(configured_ciphers)
        cipher_string = ":".join(configured_ciphers)

        with ModernOpenSslServer(cipher=cipher_string,
                                 prefer_server_order=True) 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,
                                                Tlsv12ScanCommand())

            detected_ciphers = [
                c.openssl_name for c in plugin_result.accepted_cipher_list
            ]

        assert configured_ciphers == detected_ciphers
Пример #8
0
    def test_tlsv1_2_enabled(self):
        server_info = ServerConnectivityInfo(hostname='www.google.com')
        server_info.test_connectivity_to_server()

        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))
Пример #9
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
Пример #10
0
    def test_smtp_post_handshake_response(self):
        server_info = ServerConnectivityInfo(hostname='smtp.gmail.com', port=587,
                                             tls_wrapped_protocol=TlsWrappedProtocolEnum.STARTTLS_SMTP)
        server_info.test_connectivity_to_server()

        plugin = OpenSslCipherSuitesPlugin()
        plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand())

        self.assertTrue(plugin_result.as_text())
        self.assertTrue(plugin_result.as_xml())
    def test_follows_client_cipher_suite_preference(self):
        # Google.com does not follow client cipher suite preference
        server_info = ServerConnectivityInfo(hostname=u'www.google.com')
        server_info.test_connectivity_to_server()

        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_info = ServerConnectivityInfo(hostname=u'www.sogou.com')
        server_info.test_connectivity_to_server()

        plugin = OpenSslCipherSuitesPlugin()
        plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand())

        self.assertIsNone(plugin_result.preferred_cipher)
        self.assertTrue(plugin_result.accepted_cipher_list)
    def test_dh_info(self):
        server_info = ServerConnectivityInfo(hostname=u'dh1024.badssl.com')
        server_info.test_connectivity_to_server()

        plugin = OpenSslCipherSuitesPlugin()
        plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand())

        self.assertTrue(plugin_result.preferred_cipher)
        self.assertEquals(plugin_result.preferred_cipher.dh_info['GroupSize'], u'1024')
        self.assertTrue(plugin_result.as_text())
        self.assertTrue(plugin_result.as_xml())
    def test_rc4_md5_cipher_suites(self):
        server_info = ServerConnectivityInfo(hostname=u'rc4-md5.badssl.com')
        server_info.test_connectivity_to_server()

        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.assertEquals({'TLS_RSA_WITH_RC4_128_MD5'},
                          set(accepted_cipher_name_list))

        self.assertTrue(plugin_result.as_text())
        self.assertTrue(plugin_result.as_xml())
Пример #14
0
def check_tcp_service_for_ssl_protocol_cipher_support(
        self,
        org_uuid=None,
        service_uuid=None,
        ssl_protocol=None,
        scan_uuid=None
):
    """
    Check to see what ciphers this TCP service supports for the given SSL protocol.
    :param org_uuid: The UUID of the organization to collect information on behalf of.
    :param service_uuid: The UUID of the network service to check for SSL support.
    :param ssl_protocol: The SSL protocol to check
    :param scan_uuid: The UUID of the network service scan that this SSL version check is associated
    with.
    :return: None
    """
    ip_address, port, protocol = self.get_endpoint_information(service_uuid)
    server_info = ServerConnectivityInfo(hostname=ip_address, ip_address=ip_address, port=port)
    synchronous_scanner = SynchronousScanner()
    command = None
    if ssl_protocol == 'PROTOCOL_TLSv1' or ssl_protocol == 'PROTOCOL_TLS':
        command = Tlsv10ScanCommand()
    elif ssl_protocol == 'PROTOCOL_TLSv1_1':
        command = Tlsv11ScanCommand()
    elif ssl_protocol == 'PROTOCOL_TLSv1_2':
        command = Tlsv12ScanCommand()
    elif ssl_protocol == 'PROTOCOL_SSLv23':
        command = Sslv20ScanCommand()
    elif ssl_protocol == 'PROTOCOL_SSLv3':
        command = Sslv30ScanCommand()
    else:
        raise ValueError(
            "Not sure how to run scan command for SSL protocol of %s."
            % (ssl_protocol,)
        )
    cipher_scan_result = synchronous_scanner.run_scan_command(server_info, command)
    ssl_support_record = SslSupportModel.from_database_model_uuid(
        uuid=scan_uuid,
        db_session=self.db_session,
        ssl_version=ssl_protocol,
        supported=True,
    )
    ssl_support_record.accepted_ciphers = [ cipher.name for cipher in cipher_scan_result.accepted_cipher_list ]
    ssl_support_record.rejected_ciphers = [ cipher.name for cipher in cipher_scan_result.rejected_cipher_list ]
    ssl_support_record.errored_ciphers = [ cipher.name for cipher in cipher_scan_result.errored_cipher_list ]
    if cipher_scan_result.preferred_cipher is not None:
        ssl_support_record.preferred_cipher = cipher_scan_result.preferred_cipher.name
    else:
        ssl_support_record.preferred_cipher = None
    ssl_support_record.save(org_uuid)
Пример #15
0
    def test_follows_client_cipher_suite_preference(self):
        # Google.com does not follow client cipher suite preference
        server_info = ServerConnectivityInfo(hostname='www.google.com')
        server_info.test_connectivity_to_server()

        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_info = ServerConnectivityInfo(hostname='www.sogou.com')
        server_info.test_connectivity_to_server()

        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))
Пример #16
0
    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())

        assert plugin_result.preferred_cipher
        assert 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())

        assert plugin_result.preferred_cipher is None
        assert plugin_result.accepted_cipher_list

        # Ensure the results are pickable so the ConcurrentScanner can receive them via a Queue
        assert pickle.dumps(plugin_result)
Пример #17
0
def concurrent_scan(site_info):
    # Setup the server to scan and ensure it is online/reachable
    server_info = server_connectivity_tester(site_info.name)

    if server_info:
        synchronous_scanner = SynchronousScanner()

        cert_info_plugin = CertificateInfoPlugin()
        plugin_result = cert_info_plugin.process_task(
            server_info, CertificateInfoScanCommand())
        #not plugin_result.verified_certificate_chain or
        #not plugin_result.leaf_certificate_subject_matches_hostname some sites' certs CN is with "www." so the result here is false
        if plugin_result.verified_certificate_chain and site_info.name not in str(
                plugin_result.verified_certificate_chain[0].subject):
            site_info.cert_trusted = "False"
            print("not trusted: " + site_info.name)
            print(plugin_result.__dict__)
        # elif not plugin_result.verified_certificate_chain:
        #     site_info.cert_trusted = "False"
        #     print("not trusted: " + site_info.name)
        #     print(plugin_result.__dict__)
        else:
            site_info.cert_trusted = "True"
            scan_result1 = synchronous_scanner.run_scan_command(
                server_info, Sslv20ScanCommand())
            if len(scan_result1.accepted_cipher_list) > 0:
                site_info.sslv2 = "True"
            scan_result2 = synchronous_scanner.run_scan_command(
                server_info, Sslv30ScanCommand())
            if len(scan_result2.accepted_cipher_list) > 0:
                site_info.sslv3 = "True"
            scan_result3 = synchronous_scanner.run_scan_command(
                server_info, Tlsv10ScanCommand())
            if len(scan_result3.accepted_cipher_list) > 0:
                site_info.tlsv1 = "True"
            scan_result4 = synchronous_scanner.run_scan_command(
                server_info, Tlsv11ScanCommand())
            if len(scan_result4.accepted_cipher_list) > 0:
                site_info.tlsv11 = "True"
            scan_result5 = synchronous_scanner.run_scan_command(
                server_info, Tlsv12ScanCommand())
            if len(scan_result5.accepted_cipher_list) > 0:
                site_info.tlsv12 = "True"
            scan_result6 = synchronous_scanner.run_scan_command(
                server_info, Tlsv13ScanCommand())
            if len(scan_result6.accepted_cipher_list) > 0:
                site_info.tlsv13 = "True"

            recheck_cert(site_info)
    def test_dh_info(self):
        server_info = ServerConnectivityInfo(hostname='dh1024.badssl.com')
        server_info.test_connectivity_to_server()

        plugin = OpenSslCipherSuitesPlugin()
        plugin_result = plugin.process_task(server_info, Tlsv12ScanCommand())

        self.assertTrue(plugin_result.preferred_cipher)
        self.assertEquals(plugin_result.preferred_cipher.dh_info['GroupSize'],
                          '1024')
        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))
Пример #19
0
    def ssl_scan(self):
        print("Running SSL Scan")
        try:
            server_info = ServerConnectivityInfo(
                hostname=self.options["TARGET"])
            server_info.test_connectivity_to_server()
            synchronous_scanner = SynchronousScanner()

            # TLS 1.0
            command = Tlsv10ScanCommand()
            scan_result = synchronous_scanner.run_scan_command(
                server_info, command)
            print("Available TLSv1.0 Ciphers:")
            for cipher in scan_result.accepted_cipher_list:
                print('    {}'.format(cipher.name))

            # TLSv1.2
            command = Tlsv12ScanCommand()
            scan_result = synchronous_scanner.run_scan_command(
                server_info, command)
            print("Available TLSv1.2 Ciphers:")
            for cipher in scan_result.accepted_cipher_list:
                print('    {}'.format(cipher.name))

            # Certificate information
            command = CertificateInfoScanCommand()
            scan_result = synchronous_scanner.run_scan_command(
                server_info, command)
            for entry in scan_result.as_text():
                print(entry)

            # Heartbleed vulnerability info
            command = HeartbleedScanCommand()
            scan_result = synchronous_scanner.run_scan_command(
                server_info, command)
            for entry in scan_result.as_text():
                print(entry)

            # HTTP Headers info
            command = HttpHeadersScanCommand()
            scan_result = synchronous_scanner.run_scan_command(
                server_info, command)
            for entry in scan_result.as_text():
                print(entry)

        except Exception as e:
            self.handle_exception(e, "Error running SSL scan")
            pass
Пример #20
0
    def test_rc4_md5_cipher_suites(self):
        server_info = ServerConnectivityInfo(hostname='rc4-md5.badssl.com')
        server_info.test_connectivity_to_server()

        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))
Пример #21
0
    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
        ]
        assert {'TLS_RSA_WITH_RC4_128_MD5'} == set(accepted_cipher_name_list)

        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)
Пример #22
0
    def test_succeeds_when_client_auth_failed_tls_1_2(self):
        # Given a TLS 1.2 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()

            # OpenSslCipherSuitesPlugin works even when a client cert was not supplied
            plugin = OpenSslCipherSuitesPlugin()
            plugin_result = plugin.process_task(server_info,
                                                Tlsv12ScanCommand())

        assert plugin_result.accepted_cipher_list
        assert plugin_result.as_text()
        assert plugin_result.as_xml()
Пример #23
0
def demo_concurrent_scanner():
    # Setup the server to scan and ensure it is online/reachable
    server_info = demo_server_connectivity_tester()

    # Run multiple scan commands concurrently. It is 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, CertificateInfoScanCommand())

    # Process the results
    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(f'\nReceived result for "{scan_result.scan_command.get_title()}" '
              f'on {scan_result.server_info.hostname}')

        # A scan command can fail (as a bug); it is returned as a PluginRaisedExceptionResult
        if isinstance(scan_result, PluginRaisedExceptionScanResult):
            raise RuntimeError(f'Scan command failed: {scan_result.scan_command.get_title()}')

        # Each scan result has attributes with the information yo're looking for
        # All these attributes are documented within each scan command's module
        if isinstance(scan_result.scan_command, Tlsv12ScanCommand):
            for cipher in scan_result.accepted_cipher_list:
                print(f'    {cipher.name}')

        elif isinstance(scan_result.scan_command, CertificateInfoScanCommand):
            # Print the Common Names within the verified certificate chain
            if not scan_result.verified_certificate_chain:
                print('Error: certificate chain is not trusted!')
            else:
                print('Certificate chain common names:')
                for cert in scan_result.verified_certificate_chain:
                    cert_common_names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
                    print(f'   {cert_common_names[0].value}')
Пример #24
0
 def run_cipher_suite_commands(self, server_info, synchronous_scanner):
     cipher_scan_results = {}
     commands = [
         Sslv20ScanCommand(),
         Sslv30ScanCommand(),
         Tlsv10ScanCommand(),
         Tlsv11ScanCommand(),
         Tlsv12ScanCommand(),
         Tlsv13ScanCommand()
     ]
     for command in commands:
         scan_result = synchronous_scanner.run_scan_command(
             server_info, command)
         ciphers = []
         for cipher in scan_result.accepted_cipher_list:
             ciphers.append({
                 "name": cipher.name,
                 "key_size": cipher.key_size,
                 "is_anonymous": cipher.is_anonymous
             })
         cipher_scan_results[scan_result.scan_command.get_title()] = ciphers
     #print('ciphers obtained for ',server_info)
     return cipher_scan_results
Пример #25
0
from .errors import ConnectionError

# Policy prohibits the use of SSL 2.0/3.0 and TLS 1.0
ciphersuites = {
    "policy": [
        Sslv20ScanCommand(),
        Sslv30ScanCommand(),
        Tlsv10ScanCommand(),
        Tlsv11ScanCommand()
    ],
    "full": [
        Sslv20ScanCommand(),
        Sslv30ScanCommand(),
        Tlsv10ScanCommand(),
        Tlsv11ScanCommand(),
        Tlsv12ScanCommand(),
        Tlsv13ScanCommand()
    ]
}

# sslyze config
SynchronousScanner.DEFAULT_NETWORK_RETRIES = 1
SynchronousScanner.DEFAULT_NETWORK_TIMEOUT = 3

ERROR_MSG_CONNECTION_TIMEOUT = 'TCP connection to {}:{} timed-out'.format
ERROR_MSG_UNKNOWN_CONNECTION = \
    'TCP connection to {}:{} encountered unknown error'.format


def scan(name, ip, port, view, suite):
    """ Five inputs: web site name, ip, port
Пример #26
0
def ssltlsscan(web):

    target = web.split('//')[1]
    print(R + '\n    ===============================')
    print(R + '     S S L   E N U M E R A T I O N')
    print(R + '    ===============================\n')
    print(GR + ' [*] Testing server SSL status...')
    try:
        req = requests.get('https://' + target)
        print(G + ' [+] SSL Working Properly...')
        time.sleep(0.6)
        print(O + " [!] Running SSL Enumeration...\n")
        try:
            server_tester = ServerConnectivityTester(hostname=target)
            server_info = server_tester.perform()
            scanner = SynchronousScanner()

            command = Tlsv10ScanCommand()
            scan_result = scanner.run_scan_command(server_info, command)
            print(G + " [+] Available TLS v1.0 Ciphers:")
            for cipher in scan_result.accepted_cipher_list:
                print(C + '    {}'.format(cipher.name))
            print('')

            command = Tlsv11ScanCommand()
            scan_result = scanner.run_scan_command(server_info, command)
            print(G + " [+] Available TLS v1.1 Ciphers:")
            for cipher in scan_result.accepted_cipher_list:
                print(C + '    {}'.format(cipher.name))
            print('')

            command = Tlsv12ScanCommand()
            scan_result = scanner.run_scan_command(server_info, command)
            print(G + " [+] Available TLS v1.2 Ciphers:")
            for cipher in scan_result.accepted_cipher_list:
                print(C + '    {}'.format(cipher.name))
            print('')

            command = CertificateInfoScanCommand()
            scan_result = scanner.run_scan_command(server_info, command)
            print(G + ' [+] Certificate Information:')
            for entry in scan_result.as_text():
                if entry != '':
                    if 'certificate information' in entry.lower():
                        pass
                    elif ':' in entry:
                        print(GR + '    [+] ' +
                              entry.strip().split(':', 1)[0].strip() + ' : ' +
                              C + entry.strip().split(':', 1)[1].strip())
                    else:
                        print(O + '\n  [+] ' + entry.strip())
            print('')

            command = HttpHeadersScanCommand()
            scan_result = scanner.run_scan_command(server_info, command)
            print(G + ' [+] HTTP Results:')
            for entry in scan_result.as_text():
                if 'http security' not in entry.strip().lower(
                ) and entry != '':
                    if '-' in entry:
                        print(GR + '    [+] ' +
                              entry.split('-', 1)[0].strip() + ' - ' + C +
                              entry.split('-', 1)[1].strip())
                    elif ':' in entry:
                        print(GR + '    [+] ' +
                              entry.strip().split(':', 1)[0].strip() + ' : ' +
                              C + entry.strip().split(':', 1)[1].strip())
                    else:
                        print(O + '\n  [+] ' + entry.strip())
            print('')

        except Exception as e:
            print(R + ' [-] Unhandled SSL Runtime Exception : ' + str(e))
            pass

    except requests.exceptions.SSLError as e:
        print(R + ' [-] Distant Server SSL not working : ' + str(e))

    print(G + ' [+] SSlScan Module Completed!')
Пример #27
0
def attack_host(results, host_name):
    print("Running forward_secrecy_attack.py host name: {}".format(host_name))
    expected_tls1_2_suites = ['TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256']

    try:
        server_tester = ServerConnectivityTester(
            hostname=host_name,
            port=443,
            tls_wrapped_protocol=TlsWrappedProtocolEnum.HTTPS)

        server_info = server_tester.perform()
    except ServerConnectivityError as e:
        results.append(AttackResult('10.13', host_name, False, e))
        return

    synchronous_scanner = SynchronousScanner()

    tls1_3_scan_result = synchronous_scanner.run_scan_command(server_info, Tlsv13ScanCommand())
    tls1_3_accepted_ciphers = tls1_3_scan_result.accepted_cipher_list

    tls1_2_scan_result = synchronous_scanner.run_scan_command(server_info, Tlsv12ScanCommand())
    tls1_2_accepted_ciphers = tls1_2_scan_result.accepted_cipher_list
    tls1_2_accepted_cipher_names = cipher_list_to_string_list(tls1_2_accepted_ciphers)

    tls1_1_scan_result = synchronous_scanner.run_scan_command(server_info, Tlsv11ScanCommand())
    tls1_1_accepted_ciphers = tls1_1_scan_result.accepted_cipher_list

    tls1_0_scan_result = synchronous_scanner.run_scan_command(server_info, Tlsv10ScanCommand())
    tls1_0_accepted_ciphers = tls1_0_scan_result.accepted_cipher_list

    ssl3_0_scan_result = synchronous_scanner.run_scan_command(server_info, Sslv30ScanCommand())
    ssl3_0_accepted_ciphers = ssl3_0_scan_result.accepted_cipher_list

    ssl2_0_scan_result = synchronous_scanner.run_scan_command(server_info, Sslv20ScanCommand())
    ssl2_0_accepted_ciphers = ssl2_0_scan_result.accepted_cipher_list

    # Determine result
    result = list_equal(tls1_2_accepted_cipher_names, expected_tls1_2_suites) and \
        len(tls1_3_accepted_ciphers) == 0 and \
        len(tls1_1_accepted_ciphers) == 0 and \
        len(tls1_0_accepted_ciphers) == 0 and \
        len(ssl3_0_accepted_ciphers) == 0 and \
        len(ssl3_0_accepted_ciphers) == 0

    # Build details
    details = ''
    if len(tls1_3_accepted_ciphers) != 0:
        details += 'TLS 1.3 should not be supported '

    if not list_equal(tls1_2_accepted_cipher_names, expected_tls1_2_suites):
        details += ' TLS 1.2 supporting ' + str(tls1_2_accepted_cipher_names) \
                   + ', should only be ' + str(expected_tls1_2_suites) + ' '

    if len(tls1_1_accepted_ciphers) != 0:
        details += 'TLS 1.1 should not be supported '

    if len(tls1_0_accepted_ciphers) != 0:
        details += 'TLS 1.0 should not be supported '

    if len(ssl3_0_accepted_ciphers) != 0:
        details += 'SSL 3.0 should not be supported '

    if len(ssl2_0_accepted_ciphers) != 0:
        details += 'SSL 2.0 should not be supported '

    if details == '':
        details = 'Cipher suites are correct'

    results.append(AttackResult('forward_secrecy', host_name, result, details))


# attack_host([], 'google.co.uk')
Пример #28
0
def get_supported_tls_cipher_suites(hostname):
    server_info = get_ssl_server_info(hostname)
    concurrent_scanner = ConcurrentScanner()
    concurrent_scanner.queue_scan_command(server_info, Sslv20ScanCommand())
    concurrent_scanner.queue_scan_command(server_info, Sslv30ScanCommand())
    concurrent_scanner.queue_scan_command(server_info, Tlsv10ScanCommand())
    concurrent_scanner.queue_scan_command(server_info, Tlsv11ScanCommand())
    concurrent_scanner.queue_scan_command(server_info, Tlsv12ScanCommand())
    concurrent_scanner.queue_scan_command(server_info, Tlsv13ScanCommand())
    concurrent_scanner.queue_scan_command(server_info,
                                          FallbackScsvScanCommand())

    for scan_result in concurrent_scanner.get_results():
        # A scan command can fail (as a bug); it is returned as a PluginRaisedExceptionResult
        if isinstance(scan_result, PluginRaisedExceptionScanResult):
            raise RuntimeError(
                f'Scan command failed: {scan_result.scan_command.get_title()}')

        if isinstance(scan_result.scan_command, Sslv20ScanCommand):
            accepted_ssl2 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_ssl2 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_ssl2 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, Sslv30ScanCommand):
            accepted_ssl3 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_ssl3 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_ssl3 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, Tlsv10ScanCommand):
            accepted_tls10 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_tls10 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_tls10 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, Tlsv11ScanCommand):
            accepted_tls11 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_tls11 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_tls11 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, Tlsv12ScanCommand):
            accepted_tls12 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_tls12 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_tls12 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, Tlsv13ScanCommand):
            accepted_tls13 = [
                cipher.name for cipher in scan_result.accepted_cipher_list
            ]
            denied_tls13 = [
                cipher.name for cipher in scan_result.rejected_cipher_list
            ]
            errored_tls13 = [
                cipher.name for cipher in scan_result.errored_cipher_list
            ]
        if isinstance(scan_result.scan_command, FallbackScsvScanCommand):
            supports_fallback_scsv = scan_result.supports_fallback_scsv

    return {
        'accepted_ssl2': accepted_ssl2,
        'denied_ssl2': denied_ssl2,
        'errored_ssl2': errored_ssl2,
        'accepted_ssl3': accepted_ssl3,
        'denied_ssl3': denied_ssl3,
        'errored_ssl3': errored_ssl3,
        'accepted_tls10': accepted_tls10,
        'denied_tls10': denied_tls10,
        'errored_tls10': errored_tls10,
        'accepted_tls11': accepted_tls11,
        'denied_tls11': denied_tls11,
        'errored_tls11': errored_tls11,
        'accepted_tls12': accepted_tls12,
        'denied_tls12': denied_tls12,
        'errored_tls12': errored_tls12,
        'accepted_tls13': accepted_tls13,
        'denied_tls13': denied_tls13,
        'errored_tls13': errored_tls13,
        'supports_fallback_scsv': supports_fallback_scsv
    }
Пример #29
0
            hostname, e.error_msg))

    # 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
Пример #30
0
def scan_parallel(scanner, server_info, data, options):
    logging.debug("\tRunning scans in parallel.")

    def queue(command):
        try:
            return scanner.queue_scan_command(server_info, command)
        except OSError as err:
            text = ("OSError - likely too many processes and open files.")
            data['errors'].append(text)
            logging.warn("%s\n%s" % (text, utils.format_last_exception()))
            return None, None, None, None, None, None, None
        except Exception as err:
            text = ("Unknown exception queueing sslyze command.\n%s" %
                    utils.format_last_exception())
            data['errors'].append(text)
            logging.warn(text)
            return None, None, None, None, None, None, None

    # Initialize commands and result containers
    sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2, tlsv1_3, certs = None, None, None, None, None, None

    # Queue them all up
    queue(Sslv20ScanCommand())
    queue(Sslv30ScanCommand())
    queue(Tlsv10ScanCommand())
    queue(Tlsv11ScanCommand())
    queue(Tlsv12ScanCommand())
    queue(Tlsv13ScanCommand())

    if options.get("sslyze-certs", True) is True:
        queue(CertificateInfoScanCommand())

    # Reassign them back to predictable places after they're all done
    was_error = False
    for result in scanner.get_results():
        try:
            if isinstance(result, PluginRaisedExceptionScanResult):
                error = ("Scan command failed: %s" % result.as_text())
                logging.warn(error)
                data['errors'].append(error)
                return None, None, None, None, None, None, None

            if type(result.scan_command) == Sslv20ScanCommand:
                sslv2 = result
            elif type(result.scan_command) == Sslv30ScanCommand:
                sslv3 = result
            elif type(result.scan_command) == Tlsv10ScanCommand:
                tlsv1 = result
            elif type(result.scan_command) == Tlsv11ScanCommand:
                tlsv1_1 = result
            elif type(result.scan_command) == Tlsv12ScanCommand:
                tlsv1_2 = result
            elif type(result.scan_command) == Tlsv13ScanCommand:
                tlsv1_3 = result
            elif type(result.scan_command) == CertificateInfoScanCommand:
                certs = result
            else:
                error = "Couldn't match scan result with command! %s" % result
                logging.warn("\t%s" % error)
                data['errors'].append(error)
                was_error = True

        except Exception as err:
            was_error = True
            text = ("Exception inside async scanner result processing.\n%s" %
                    utils.format_last_exception())
            data['errors'].append(text)
            logging.warn("\t%s" % text)

    # There was an error during async processing.
    if was_error:
        return None, None, None, None, None, None, None

    logging.debug("\tDone scanning.")

    return sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2, tlsv1_3, certs