Ejemplo n.º 1
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        sslClient = SslClient(sock=sock, sslVerify=SSL_VERIFY_NONE)
        sslClient.do_handshake()
        self.x509ext = sslClient.get_peer_certificate()._x509.get_extensions()[0];
Ejemplo n.º 2
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        sslClient = SslClient(sslVersion=SSLV23, sock=sock, sslVerify=SSL_VERIFY_NONE)
        sslClient.do_handshake()
        self.sslClient = sslClient
Ejemplo n.º 3
0
    def process_task(self, target, command, args):

        MAX_THREADS = 30
        sslVersionDict = {'sslv2': SSLV2, 
                       'sslv3': SSLV3, 
                       'tlsv1': TLSV1, 
                       'tlsv1_1': TLSV1_1, 
                       'tlsv1_2': TLSV1_2}
        try:
            sslVersion = sslVersionDict[command]
        except KeyError:
            raise Exception("PluginOpenSSLCipherSuites: Unknown command.")

        # Get the list of available cipher suites for the given ssl version
        sslClient = SslClient(sslVersion=sslVersion)
        sslClient.set_cipher_list('ALL:COMPLEMENTOFALL')
        cipher_list = sslClient.get_cipher_list()

        # Create a thread pool
        NB_THREADS = min(len(cipher_list), MAX_THREADS) # One thread per cipher
        thread_pool = ThreadPool()

        # Scan for every available cipher suite
        for cipher in cipher_list:
            thread_pool.add_job((self._test_ciphersuite,
                                 (target, sslVersion, cipher)))

        # Scan for the preferred cipher suite
        thread_pool.add_job((self._pref_ciphersuite,
                             (target, sslVersion)))

        # Start processing the jobs
        thread_pool.start(NB_THREADS)

        result_dicts = {'preferredCipherSuite':{}, 'acceptedCipherSuites':{},
                        'rejectedCipherSuites':{}, 'errors':{}}
        
        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, result) = completed_job
            if result is not None:
                (result_type, ssl_cipher, keysize, msg) = result
                (result_dicts[result_type])[ssl_cipher] = (msg, keysize)
                    
        # Store thread pool errors
        for failed_job in thread_pool.get_error():
            (job, exception) = failed_job
            ssl_cipher = str(job[1][2])
            error_msg = str(exception.__class__.__module__) + '.' \
                        + str(exception.__class__.__name__) + ' - ' + str(exception)
            result_dicts['errors'][ssl_cipher] = (error_msg, None)        
            
        thread_pool.join()
        
        # Generate results
        return PluginBase.PluginResult(self._generate_text_output(result_dicts, command),
                                       self._generate_xml_output(result_dicts, command))
Ejemplo n.º 4
0
    def setUp(self):
        # Requires being online :(
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.fr", 443))

        sslClient = SslClient(sslVersion=SSLV23, sock=sock, sslVerify=SSL_VERIFY_NONE)
        sslClient.do_handshake()
        self.sslClient = sslClient
        self.cert = sslClient.get_peer_certificate()
Ejemplo n.º 5
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("www.google.com", 443))

        sslClient = SslClient(sslVersion=SSLV23,
                              sock=sock,
                              sslVerify=SSL_VERIFY_NONE)
        sslClient.do_handshake()
        self.sslClient = sslClient
Ejemplo n.º 6
0
    def setUp(self):
        self.sslClient = SslClient(sslVersion=SSLV23,
                                   sslVerify=SSL_VERIFY_NONE)

        testFile = tempfile.NamedTemporaryFile(delete=False)
        testFile.write("""-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,7D15D836EE9E1B77

fzTe/7+BUBBpW7rFqfffSMeNTNwjVT8uT6+aQFkv1sazU295heEWcvnqYPQ2suDS
dqud4pxLizkSRZpAIoKZV/E0z3iM1zsrGiyNXZ3mouRjSZdESEBnPEbtIdsyHLkL
9arhA/kvuMqXMjgun+tPD0+ETlaFf5GCKgfFQzbF2W4WpeEXii43ZLZ9UmObUUql
5Y65K/07+ga/dj3E+l1dLtA7VhVV5CK+8TTmVdqOr85pEZ/BC3U09vnwovDWJ+l0
sV7GhzsDFSpwxeArZy7wSMkSOTe71O1gvjOxWlupznFcZvirhRtI+5k1/btcn7hx
8b7dp36pTb/GfwaeUVsAvJBqwdSun3NOWX7zJxIDGU6LxA80eiV4z3SxAykS52gl
rlb2e+F6dV+tRuREfaDaeS1DSlDMp1mQjPSD2ix6nSypv19FHdh01OoCd0OFxM6D
xs5RQnUeu4J9g45Wdp6lmXM62EhUqYLKRbjXnZbFMlVMq81UwpMazwAruTEOCxl4
iQk3rNzfREONa9HeshiMlkeRAQpyB1qLZwhoTwTl6xKaMkt6nFEE6qX1KrrACHkH
CFJVbuWVJCyoRFv+0Gypi7zn1ZZGkE4inDHxqIzUa0sSmbShEWooTxCyGUSoosaY
u2ozh8ESQCy03JFR9DY6mo3YekbIcCEjgdmE35nK4lJQFbo3A8YlHunEdVK0tb8Z
Wxf7cJ6J55bG5/Kft65kJnXAHrV9LnM1tPiRkB8umZkj/ou5NpDKiuLjR+WBfwi0
tqXk90NdSqJtMMGgrtVM84TYFPXP58QCBnE9oAI7XYM1rusuVBOXZw==
-----END RSA PRIVATE KEY-----
""")
        testFile.close()
        self.testFile = testFile
        testFile2 = tempfile.NamedTemporaryFile(delete=False)
        testFile2.write("""-----BEGIN CERTIFICATE-----
MIIDCjCCAnOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBgDELMAkGA1UEBhMCRlIx
DjAMBgNVBAgMBVBhcmlzMQ4wDAYDVQQHDAVQYXJpczEWMBQGA1UECgwNRGFzdGFy
ZGx5IEluYzEMMAoGA1UECwwDMTIzMQ8wDQYDVQQDDAZBbCBCYW4xGjAYBgkqhkiG
9w0BCQEWC2xvbEBsb2wuY29tMB4XDTEzMDEyNzAwMDM1OFoXDTE0MDEyNzAwMDM1
OFowgZcxCzAJBgNVBAYTAkZSMQwwCgYDVQQIDAMxMjMxDTALBgNVBAcMBFRlc3Qx
IjAgBgNVBAoMGUludHJvc3B5IFRlc3QgQ2xpZW50IENlcnQxCzAJBgNVBAsMAjEy
MRUwEwYDVQQDDAxBbGJhbiBEaXF1ZXQxIzAhBgkqhkiG9w0BCQEWFG5hYmxhLWMw
ZDNAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlnvP1ltVO
8JDNT3AA99QqtiqCi/7BeEcFDm2al46mv7looz6CmB84osrusNVFsS5ICLbrCmeo
w5sxW7VVveGueBQyWynngl2PmmufA5Mhwq0ZY8CvwV+O7m0hEXxzwbyGa23ai16O
zIiaNlBAb0mC2vwJbsc3MTMovE6dHUgmzQIDAQABo3sweTAJBgNVHRMEAjAAMCwG
CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
HQ4EFgQUYR45okpFsqTYB1wlQQblLH9cRdgwHwYDVR0jBBgwFoAUP0X2HQlaca7D
NBzVbsjsdhzOqUQwDQYJKoZIhvcNAQEFBQADgYEAWEOxpRjvKvTurDXK/sEUw2KY
gmbbGP3tF+fQ/6JS1VdCdtLxxJAHHTW62ugVTlmJZtpsEGlg49BXAEMblLY/K7nm
dWN8oZL+754GaBlJ+wK6/Nz4YcuByJAnN8OeTY4Acxjhks8PrAbZgcf0FdpJaAlk
Pd2eQ9+DkopOz3UGU7c=
-----END CERTIFICATE-----
""")
        testFile2.close()
        self.testFile2 = testFile2
Ejemplo n.º 7
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("login.live.com", 443))

        sslClient = SslClient(sock=sock, sslVerify=SSL_VERIFY_NONE)
        sslClient.set_tlsext_status_ocsp()
        sslClient.do_handshake()
        self.ocspResp = sslClient.get_tlsext_status_ocsp_resp()._ocspResp
Ejemplo n.º 8
0
def test_cipher_list_for_differences():
    from nassl.SslClient import SslClient
    from nassl import SSLV2, SSLV3, TLSV1, TLSV1_1, TLSV1_2

    set2 = set(MAPPING2)
    set3 = set(MAPPING3)

    for sslVersion in (SSLV2, SSLV3, TLSV1, TLSV1_1, TLSV1_2):
        logging.info("Starting test for SSLV2")
        ssl_client = SslClient(sslVersion=sslVersion)
        ssl_client.set_cipher_list('ALL:COMPLEMENTOFALL')
        current = set(ssl_client.get_cipher_list())

        if sslVersion == SSLV2:
            statset = set2
        else:
            statset = set3

        logging.info("SSLv/TLSv (%d)" % sslVersion)
        logging.info("Only in currentVersion   %s" % (current - statset))
        logging.info("Only in statisticVersion %s" % (statset - current))
        logging.info("In both versions %s" % (current & statset))
        logging.info("-----")
Ejemplo n.º 9
0
    def setUp(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect(("login.live.com", 443))

        sslClient = SslClient(sock=sock, sslVerify=SSL_VERIFY_NONE)
        sslClient.set_tlsext_status_ocsp()
        sslClient.do_handshake()
        self.ocspResp = sslClient.get_tlsext_status_ocsp_resp()._ocspResp;
Ejemplo n.º 10
0
    def setUp(self):
        self.sslClient = SslClient(sslVersion=SSLV23, sslVerify=SSL_VERIFY_NONE)

        testFile = tempfile.NamedTemporaryFile(delete=False)
        testFile.write("""-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,7D15D836EE9E1B77

fzTe/7+BUBBpW7rFqfffSMeNTNwjVT8uT6+aQFkv1sazU295heEWcvnqYPQ2suDS
dqud4pxLizkSRZpAIoKZV/E0z3iM1zsrGiyNXZ3mouRjSZdESEBnPEbtIdsyHLkL
9arhA/kvuMqXMjgun+tPD0+ETlaFf5GCKgfFQzbF2W4WpeEXii43ZLZ9UmObUUql
5Y65K/07+ga/dj3E+l1dLtA7VhVV5CK+8TTmVdqOr85pEZ/BC3U09vnwovDWJ+l0
sV7GhzsDFSpwxeArZy7wSMkSOTe71O1gvjOxWlupznFcZvirhRtI+5k1/btcn7hx
8b7dp36pTb/GfwaeUVsAvJBqwdSun3NOWX7zJxIDGU6LxA80eiV4z3SxAykS52gl
rlb2e+F6dV+tRuREfaDaeS1DSlDMp1mQjPSD2ix6nSypv19FHdh01OoCd0OFxM6D
xs5RQnUeu4J9g45Wdp6lmXM62EhUqYLKRbjXnZbFMlVMq81UwpMazwAruTEOCxl4
iQk3rNzfREONa9HeshiMlkeRAQpyB1qLZwhoTwTl6xKaMkt6nFEE6qX1KrrACHkH
CFJVbuWVJCyoRFv+0Gypi7zn1ZZGkE4inDHxqIzUa0sSmbShEWooTxCyGUSoosaY
u2ozh8ESQCy03JFR9DY6mo3YekbIcCEjgdmE35nK4lJQFbo3A8YlHunEdVK0tb8Z
Wxf7cJ6J55bG5/Kft65kJnXAHrV9LnM1tPiRkB8umZkj/ou5NpDKiuLjR+WBfwi0
tqXk90NdSqJtMMGgrtVM84TYFPXP58QCBnE9oAI7XYM1rusuVBOXZw==
-----END RSA PRIVATE KEY-----
""")
        testFile.close()
        self.testFile = testFile
        testFile2 = tempfile.NamedTemporaryFile(delete=False)
        testFile2.write("""-----BEGIN CERTIFICATE-----
MIIDCjCCAnOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBgDELMAkGA1UEBhMCRlIx
DjAMBgNVBAgMBVBhcmlzMQ4wDAYDVQQHDAVQYXJpczEWMBQGA1UECgwNRGFzdGFy
ZGx5IEluYzEMMAoGA1UECwwDMTIzMQ8wDQYDVQQDDAZBbCBCYW4xGjAYBgkqhkiG
9w0BCQEWC2xvbEBsb2wuY29tMB4XDTEzMDEyNzAwMDM1OFoXDTE0MDEyNzAwMDM1
OFowgZcxCzAJBgNVBAYTAkZSMQwwCgYDVQQIDAMxMjMxDTALBgNVBAcMBFRlc3Qx
IjAgBgNVBAoMGUludHJvc3B5IFRlc3QgQ2xpZW50IENlcnQxCzAJBgNVBAsMAjEy
MRUwEwYDVQQDDAxBbGJhbiBEaXF1ZXQxIzAhBgkqhkiG9w0BCQEWFG5hYmxhLWMw
ZDNAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlnvP1ltVO
8JDNT3AA99QqtiqCi/7BeEcFDm2al46mv7looz6CmB84osrusNVFsS5ICLbrCmeo
w5sxW7VVveGueBQyWynngl2PmmufA5Mhwq0ZY8CvwV+O7m0hEXxzwbyGa23ai16O
zIiaNlBAb0mC2vwJbsc3MTMovE6dHUgmzQIDAQABo3sweTAJBgNVHRMEAjAAMCwG
CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
HQ4EFgQUYR45okpFsqTYB1wlQQblLH9cRdgwHwYDVR0jBBgwFoAUP0X2HQlaca7D
NBzVbsjsdhzOqUQwDQYJKoZIhvcNAQEFBQADgYEAWEOxpRjvKvTurDXK/sEUw2KY
gmbbGP3tF+fQ/6JS1VdCdtLxxJAHHTW62ugVTlmJZtpsEGlg49BXAEMblLY/K7nm
dWN8oZL+754GaBlJ+wK6/Nz4YcuByJAnN8OeTY4Acxjhks8PrAbZgcf0FdpJaAlk
Pd2eQ9+DkopOz3UGU7c=
-----END CERTIFICATE-----
""")
        testFile2.close()
        self.testFile2 = testFile2
Ejemplo n.º 11
0
    def process_task(self, target, command, args):

        MAX_THREADS = 15
        sslVersionDict = {
            'sslv2': SSLV2,
            'sslv3': SSLV3,
            'tlsv1': TLSV1,
            'tlsv1_1': TLSV1_1,
            'tlsv1_2': TLSV1_2
        }
        try:
            sslVersion = sslVersionDict[command]
        except KeyError:
            raise Exception("PluginOpenSSLCipherSuites: Unknown command.")

        # Get the list of available cipher suites for the given ssl version
        sslClient = SslClient(sslVersion=sslVersion)
        sslClient.set_cipher_list('ALL:COMPLEMENTOFALL')
        cipher_list = sslClient.get_cipher_list()

        # Create a thread pool
        NB_THREADS = min(len(cipher_list),
                         MAX_THREADS)  # One thread per cipher
        thread_pool = ThreadPool()

        # Scan for every available cipher suite
        for cipher in cipher_list:
            thread_pool.add_job(
                (self._test_ciphersuite, (target, sslVersion, cipher)))

        # Scan for the preferred cipher suite
        thread_pool.add_job((self._pref_ciphersuite, (target, sslVersion)))

        # Start processing the jobs
        thread_pool.start(NB_THREADS)

        result_dicts = {
            'preferredCipherSuite': {},
            'acceptedCipherSuites': {},
            'rejectedCipherSuites': {},
            'errors': {}
        }

        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, result) = completed_job
            if result is not None:
                (result_type, ssl_cipher, keysize, dh_infos, msg) = result
                (result_dicts[result_type])[ssl_cipher] = (msg, keysize,
                                                           dh_infos)

        # Store thread pool errors
        for failed_job in thread_pool.get_error():
            (job, exception) = failed_job
            ssl_cipher = str(job[1][2])
            error_msg = str(
                exception.__class__.__name__) + ' - ' + str(exception)
            result_dicts['errors'][ssl_cipher] = (error_msg, None, None)

        thread_pool.join()

        # Generate results
        return PluginBase.PluginResult(
            self._generate_text_output(result_dicts, command),
            self._generate_xml_output(result_dicts, command))
Ejemplo n.º 12
0
    def _process_parsing_results(self, args_command_list):
        """
        Performs various sanity checks on the command line that was used to
        launch SSLyze.
        Returns the shared_settings object to be fed to plugins.
        """

        shared_settings = {}
        # Sanity checks on the client cert options
        if bool(args_command_list.cert) ^ bool(args_command_list.key):
            raise CommandLineParsingError('No private key or certificate file were given. See --cert and --key.')

        # Private key and cert formats
        if args_command_list.certform == 'DER':
            args_command_list.certform = SSL_FILETYPE_ASN1
        elif args_command_list.certform == 'PEM':
            args_command_list.certform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--certform should be DER or PEM.')

        if args_command_list.keyform == 'DER':
            args_command_list.keyform = SSL_FILETYPE_ASN1
        elif args_command_list.keyform == 'PEM':
            args_command_list.keyform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--keyform should be DER or PEM.')

        # Let's try to open the cert and key files
        if args_command_list.cert:
            try:
                open(args_command_list.cert,"r")
            except:
                raise CommandLineParsingError('Could not open the client certificate file "' + str(args_command_list.cert) + '".')

        if args_command_list.key:
            try:
                open(args_command_list.key,"r")
            except:
                raise CommandLineParsingError('Could not open the client private key file "' + str(args_command_list.key) + '"')

            # Try to load the cert and key in OpenSSL
            try:
                sslClient = SslClient()
                sslClient.use_private_key(args_command_list.cert,
                                        args_command_list.certform,
                                        args_command_list.key,
                                        args_command_list.keyform,
                                        args_command_list.keypass)
            except _nassl.OpenSSLError as e:
                if 'bad decrypt' in str(e.args):
                    raise CommandLineParsingError('Could not decrypt the private key. Wrong passphrase ?')
                raise CommandLineParsingError('Could not load the certificate or the private key. Passphrase needed ?')



        # HTTP CONNECT proxy
        shared_settings['https_tunnel_host'] = None
        if args_command_list.https_tunnel:

            # Parse the proxy URL
            parsedUrl = urlparse(args_command_list.https_tunnel)

            if not parsedUrl.netloc:
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.')

            if parsedUrl.scheme in 'http':
               defaultPort = 80
            elif parsedUrl.scheme in 'https':
               defaultPort = 443
            else:
                raise CommandLineParsingError(
                    'Invalid URL scheme for --https_tunnel, discarding all tasks.')

            if not parsedUrl.hostname:
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.')

            try :
                shared_settings['https_tunnel_port'] = parsedUrl.port if parsedUrl.port else defaultPort
            except ValueError: # The supplied port was not a number
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.')

            shared_settings['https_tunnel_host'] = parsedUrl.hostname
            shared_settings['https_tunnel_user'] = parsedUrl.username
            shared_settings['https_tunnel_password'] = parsedUrl.password


        # STARTTLS
        if args_command_list.starttls:
            if args_command_list.starttls not in self.START_TLS_PROTS:
                raise CommandLineParsingError(self.START_TLS_USAGE)

        if args_command_list.starttls and args_command_list.https_tunnel:
            raise CommandLineParsingError(
                'Cannot have --https_tunnel and --starttls at the same time.')

        # Number of connection retries
        if args_command_list.nb_retries < 1:
            raise CommandLineParsingError(
                'Cannot have a number smaller than 1 for --nb_retries.')

        # All good, let's save the data
        for key, value in args_command_list.__dict__.iteritems():
            shared_settings[key] = value

        return shared_settings
Ejemplo n.º 13
0
    def _process_parsing_results(self, args_command_list):
        """
        Performs various sanity checks on the command line that was used to 
        launch SSLyze.
        Returns the shared_settings object to be fed to plugins.
        """

        shared_settings = {}
        # Sanity checks on the client cert options
        if bool(args_command_list.cert) ^ bool(args_command_list.key):
            raise CommandLineParsingError(
                'No private key or certificate file were given. See --cert and --key.'
            )

        # Private key and cert formats
        if args_command_list.certform is 'DER':
            args_command_list.certform = SSL_FILETYPE_ASN1
        elif args_command_list.certform is 'PEM':
            args_command_list.certform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--certform should be DER or PEM.')

        if args_command_list.keyform is 'DER':
            args_command_list.keyform = SSL_FILETYPE_ASN1
        elif args_command_list.keyform is 'PEM':
            args_command_list.keyform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--keyform should be DER or PEM.')

        # Let's try to open the cert and key files
        if args_command_list.cert:
            try:
                open(args_command_list.cert, "r")
            except:
                raise CommandLineParsingError(
                    'Could not open the client certificate file "' +
                    str(args_command_list.cert) + '".')

        if args_command_list.key:
            try:
                open(args_command_list.key, "r")
            except:
                raise CommandLineParsingError(
                    'Could not open the client private key file "' +
                    str(args_command_list.key) + '"')

            # Try to load the cert and key in OpenSSL
            try:
                sslClient = SslClient()
                sslClient.use_certificate_file(args_command_list.cert,
                                               args_command_list.certform)
                sslClient.use_privateKey_file(args_command_list.key,
                                              args_command_list.keyform,
                                              args_command_list.keypass)
                sslClient.check_private_key()
            except _nassl.OpenSSLError as e:
                if 'bad decrypt' in str(e.args):
                    raise CommandLineParsingError(
                        'Could not decrypt the private key. Wrong passphrase ?'
                    )
                raise CommandLineParsingError(
                    'Could not load the certificate or the private key. Passphrase needed ?'
                )

        # HTTP CONNECT proxy
        if args_command_list.https_tunnel:
            if '2.7.' not in platform.python_version():  # Python 2.7 only
                raise CommandLineParsingError(
                    '--https_tunnel requires Python 2.7.X. '
                    'Current version is ' + platform.python_version() + '.')

            try:  # Need to parse the proxy host:port string now
                (host, port) = TargetStringParser.parse_target_str(
                    args_command_list.https_tunnel, 443)
                shared_settings['https_tunnel_host'] = host
                shared_settings['https_tunnel_port'] = port
            except InvalidTargetError:
                raise CommandLineParsingError(
                    'Not a valid host/port for --https_tunnel'
                    ', discarding all tasks.')

        else:
            shared_settings['https_tunnel_host'] = None
            shared_settings['https_tunnel_port'] = None

        # STARTTLS
        if args_command_list.starttls:
            if args_command_list.starttls not in self.START_TLS_PROTS:
                raise CommandLineParsingError(self.START_TLS_USAGE)

        if args_command_list.starttls and args_command_list.https_tunnel:
            raise CommandLineParsingError(
                'Cannot have --https_tunnel and --starttls at the same time.')

        # Number of processes
        if args_command_list.nb_processes < 1:
            raise CommandLineParsingError(
                'Cannot have a number smaller than 1 for --processes.')

        # All good, let's save the data
        for key, value in args_command_list.__dict__.iteritems():
            shared_settings[key] = value

        return shared_settings
    def process_task(self, target, command, args):

        if 'algorithm' in self._shared_settings and self._shared_settings[
                'algorithm']:
            algorithm = self._shared_settings['algorithm']
        else:
            algorithm = 'naive'

        logging.info("SUBSTART\t%s\t%s\t%s\t%s\t%s" %
                     (datetime.utcnow(), self._shared_settings['targets_in'],
                      target[0], command, algorithm))

        MAX_THREADS = 15
        sslVersionDict = {
            'sslv2': SSLV2,
            'sslv3': SSLV3,
            'tlsv1': TLSV1,
            'tlsv1_1': TLSV1_1,
            'tlsv1_2': TLSV1_2
        }

        result_dicts = {
            'preferredCipherSuite': {},
            'acceptedCipherSuites': {},
            'rejectedCipherSuites': {},
            'errors': {}
        }

        try:
            sslVersion = sslVersionDict[command]
        except KeyError:
            raise Exception("PluginOpenSSLCipherSuites: Unknown command.")

        # Get the list of available cipher suites for the given ssl version
        sslClient = SslClient(sslVersion=sslVersion)
        sslClient.set_cipher_list('ALL:COMPLEMENTOFALL')
        cipher_list = sslClient.get_cipher_list()

        NB_THREADS = min(len(cipher_list),
                         MAX_THREADS)  # One thread per cipher

        # Create a thread pool
        thread_pool = ThreadPool()
        # First add the "pref" job to only execute it once
        # Scan for the preferred cipher suite
        if algorithm != 'connopt':
            thread_pool.add_job((self._pref_ciphersuite, (target, sslVersion)))

        log_round_counter = 0

        while (len(result_dicts['acceptedCipherSuites']) +
               len(result_dicts['rejectedCipherSuites']) +
               len(result_dicts['errors']) < len(cipher_list)):

            log_round_counter += 1

            new_jobs = self._calculate_jobs(sslVersion, cipher_list,
                                            result_dicts, algorithm, target[2])
            for job in new_jobs:
                thread_pool.add_job(
                    (self._test_ciphersuite, (target, sslVersion, job)))

            # logging.debug("Adding following jobs:\n%s" % pprint.pformat(new_jobs))
            # logging.debug("%s: round=%d, new_jobs=%d, algorithm=%s" % (sslVersion,
            #                                                           log_round_counter,
            #                                                           len(new_jobs),
            #                                                           algorithm))

            # Start processing the jobs
            thread_pool.start(NB_THREADS)

            # Store the results as they come
            for completed_job in thread_pool.get_result():
                (job, results) = completed_job
                for result in results:
                    (result_type, ssl_cipher, keysize, dh_infos, msg) = result
                    (result_dicts[result_type])[ssl_cipher] = (msg, keysize,
                                                               dh_infos)

            # Store thread pool errors
            for failed_job in thread_pool.get_error():
                (job, exception) = failed_job
                # job[1][2] is a list of cipher suites now
                ssl_ciphers = job[1][2]
                error_msg = str(
                    exception.__class__.__name__) + ' - ' + str(exception)
                for ssl_cipher in ssl_ciphers:
                    result_dicts['errors'][ssl_cipher] = (error_msg, None,
                                                          None)

            thread_pool.join()
            # Reset thread pool
            thread_pool = ThreadPool()

            # logging.debug("ciphers total %d results a: %d, r: %d, e: %d after %d connections" % (
            #    len(cipher_list),
            #    len(result_dicts['acceptedCipherSuites']),
            #    len(result_dicts['rejectedCipherSuites']),
            #    len(result_dicts['errors']),
            #    self.log_connection_counter))

        timedelta = datetime.now() - self.log_starttime
        logging.info("RESULT\t%s\t%s\t%s" % (target[0], command, ",".join(
            stats.get_pattern_for_result_dict(sslVersion, result_dicts))))
        logging.info("SUBEND\t%s\t%s\t%s\t%s\t%s\t%s\t%s" %
                     (datetime.utcnow(), self._shared_settings['targets_in'],
                      target[0], command, algorithm, timedelta.total_seconds(),
                      self.log_connection_counter))

        increment(self.log_connection_counter)

        # Generate results
        return PluginBase.PluginResult(
            self._generate_text_output(result_dicts, command),
            self._generate_xml_output(result_dicts, command))
    def process_task(self, target, command, args):

        MAX_THREADS = 15
        sslVersionDict = {"sslv2": SSLV2, "sslv3": SSLV3, "tlsv1": TLSV1, "tlsv1_1": TLSV1_1, "tlsv1_2": TLSV1_2}
        try:
            sslVersion = sslVersionDict[command]
        except KeyError:
            raise Exception("PluginOpenSSLCipherSuites: Unknown command.")

        # Get the list of available cipher suites for the given ssl version
        sslClient = SslClient(sslVersion=sslVersion)
        sslClient.set_cipher_list("ALL:COMPLEMENTOFALL")
        cipher_list = sslClient.get_cipher_list()

        # Create a thread pool
        NB_THREADS = min(len(cipher_list), MAX_THREADS)  # One thread per cipher
        thread_pool = ThreadPool()

        cipher_whitelist = [
            "ECDHE-RSA-AES128-GCM-SHA256",
            "ECDHE-ECDSA-AES128-GCM-SHA256",
            "ECDHE-RSA-AES256-GCM-SHA384",
            "ECDHE-ECDSA-AES256-GCM-SHA384",
            "DHE-RSA-AES128-GCM-SHA256",
            "DHE-DSS-AES128-GCM-SHA256",
            "kEDH+AESGCM",
            "ECDHE-RSA-AES128-SHA256",
            "ECDHE-ECDSA-AES128-SHA256",
            "ECDHE-RSA-AES128-SHA",
            "ECDHE-ECDSA-AES128-SHA",
            "ECDHE-RSA-AES256-SHA384",
            "ECDHE-ECDSA-AES256-SHA384",
            "ECDHE-RSA-AES256-SHA",
            "ECDHE-ECDSA-AES256-SHA",
            "DHE-RSA-AES128-SHA256",
            "DHE-RSA-AES128-SHA",
            "DHE-DSS-AES128-SHA256",
            "DHE-RSA-AES256-SHA256",
            "DHE-DSS-AES256-SHA",
            "DHE-RSA-AES256-SHA",
        ]

        cipher_blacklist = ["RC4", "EXPORT", "DES", "aNULL", "eNULL", "MD5"]
        version_whitelist = ["TLSV1_1", "TLSV1_2"]
        version_blacklist = ["SSLV2", "SSLV3"]
        cdict = {"whitelist": cipher_whitelist, "blacklist": cipher_blacklist}
        verdict = {"whitelist": version_whitelist, "blacklist": version_blacklist}

        # Scan for every available cipher suite
        for cipher in cipher_list:
            thread_pool.add_job((self._test_ciphersuite, (target, sslVersion, cipher, cdict)))

        # Scan for the preferred cipher suite
        thread_pool.add_job((self._pref_ciphersuite, (target, sslVersion, cdict)))

        # Start processing the jobs
        thread_pool.start(NB_THREADS)

        result_dicts = {
            "preferredCipherSuite": {},
            "acceptedCipherSuites": {},
            "rejectedCipherSuites": {},
            "errors": {},
        }

        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, result) = completed_job
            if result is not None:
                (result_type, ssl_cipher, keysize, dh_infos, msg) = result
                (result_dicts[result_type])[ssl_cipher] = (msg, keysize, dh_infos)

        # Store thread pool errors
        for failed_job in thread_pool.get_error():
            (job, exception) = failed_job
            ssl_cipher = str(job[1][2])
            error_msg = str(exception.__class__.__name__) + " - " + str(exception)
            result_dicts["errors"][ssl_cipher] = (error_msg, None, None)

        thread_pool.join()

        # Generate results
        return PluginBase.PluginResult(
            self._generate_text_output(result_dicts, command, verdict),
            self._generate_xml_output(result_dicts, command, verdict),
        )
Ejemplo n.º 16
0
    def _process_parsing_results(self, args_command_list):
        """
        Performs various sanity checks on the command line that was used to
        launch SSLyze.
        Returns the shared_settings object to be fed to plugins.
        """

        shared_settings = {}
        # Sanity checks on the client cert options
        if bool(args_command_list.cert) ^ bool(args_command_list.key):
            raise CommandLineParsingError(
                'No private key or certificate file were given. See --cert and --key.'
            )

        # Private key and cert formats
        if args_command_list.certform == 'DER':
            args_command_list.certform = SSL_FILETYPE_ASN1
        elif args_command_list.certform == 'PEM':
            args_command_list.certform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--certform should be DER or PEM.')

        if args_command_list.keyform == 'DER':
            args_command_list.keyform = SSL_FILETYPE_ASN1
        elif args_command_list.keyform == 'PEM':
            args_command_list.keyform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--keyform should be DER or PEM.')

        # Let's try to open the cert and key files
        if args_command_list.cert:
            try:
                open(args_command_list.cert, "r")
            except:
                raise CommandLineParsingError(
                    'Could not open the client certificate file "' +
                    str(args_command_list.cert) + '".')

        if args_command_list.key:
            try:
                open(args_command_list.key, "r")
            except:
                raise CommandLineParsingError(
                    'Could not open the client private key file "' +
                    str(args_command_list.key) + '"')

            # Try to load the cert and key in OpenSSL
            try:
                sslClient = SslClient()
                sslClient.use_private_key(args_command_list.cert,
                                          args_command_list.certform,
                                          args_command_list.key,
                                          args_command_list.keyform,
                                          args_command_list.keypass)
            except _nassl.OpenSSLError as e:
                if 'bad decrypt' in str(e.args):
                    raise CommandLineParsingError(
                        'Could not decrypt the private key. Wrong passphrase ?'
                    )
                raise CommandLineParsingError(
                    'Could not load the certificate or the private key. Passphrase needed ?'
                )

        # HTTP CONNECT proxy
        shared_settings['https_tunnel_host'] = None
        if args_command_list.https_tunnel:

            # Parse the proxy URL
            parsedUrl = urlparse(args_command_list.https_tunnel)

            if not parsedUrl.netloc:
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.'
                )

            if parsedUrl.scheme in 'http':
                defaultPort = 80
            elif parsedUrl.scheme in 'https':
                defaultPort = 443
            else:
                raise CommandLineParsingError(
                    'Invalid URL scheme for --https_tunnel, discarding all tasks.'
                )

            if not parsedUrl.hostname:
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.'
                )

            try:
                shared_settings[
                    'https_tunnel_port'] = parsedUrl.port if parsedUrl.port else defaultPort
            except ValueError:  # The supplied port was not a number
                raise CommandLineParsingError(
                    'Invalid Proxy URL for --https_tunnel, discarding all tasks.'
                )

            shared_settings['https_tunnel_host'] = parsedUrl.hostname
            shared_settings['https_tunnel_user'] = parsedUrl.username
            shared_settings['https_tunnel_password'] = parsedUrl.password

        # STARTTLS
        if args_command_list.starttls:
            if args_command_list.starttls not in self.START_TLS_PROTS:
                raise CommandLineParsingError(self.START_TLS_USAGE)

        if args_command_list.starttls and args_command_list.https_tunnel:
            raise CommandLineParsingError(
                'Cannot have --https_tunnel and --starttls at the same time.')

        # Number of connection retries
        if args_command_list.nb_retries < 1:
            raise CommandLineParsingError(
                'Cannot have a number smaller than 1 for --nb_retries.')

        # All good, let's save the data
        for key, value in args_command_list.__dict__.iteritems():
            shared_settings[key] = value

        return shared_settings
Ejemplo n.º 17
0
    def _process_parsing_results(self, args_command_list):
        """
        Performs various sanity checks on the command line that was used to
        launch SSLyze.
        Returns the shared_settings object to be fed to plugins.
        """

        shared_settings = {}
        # Sanity checks on the client cert options
        if bool(args_command_list.cert) ^ bool(args_command_list.key):
            raise CommandLineParsingError('No private key or certificate file were given. See --cert and --key.')

        # Private key and cert formats
        if args_command_list.certform is'DER':
            args_command_list.certform = SSL_FILETYPE_ASN1
        elif args_command_list.certform is 'PEM':
            args_command_list.certform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--certform should be DER or PEM.')

        if args_command_list.keyform is'DER':
            args_command_list.keyform = SSL_FILETYPE_ASN1
        elif args_command_list.keyform is 'PEM':
            args_command_list.keyform = SSL_FILETYPE_PEM
        else:
            raise CommandLineParsingError('--keyform should be DER or PEM.')

        # Let's try to open the cert and key files
        if args_command_list.cert:
            try:
                open(args_command_list.cert,"r")
            except:
                raise CommandLineParsingError('Could not open the client certificate file "' + str(args_command_list.cert) + '".')

        if args_command_list.key:
            try:
                open(args_command_list.key,"r")
            except:
                raise CommandLineParsingError('Could not open the client private key file "' + str(args_command_list.key) + '"')

            # Try to load the cert and key in OpenSSL
            try:
                sslClient = SslClient()
                sslClient.use_private_key(args_command_list.cert,
                                        args_command_list.certform,
                                        args_command_list.key,
                                        args_command_list.keyform,
                                        args_command_list.keypass)
            except _nassl.OpenSSLError as e:
                if 'bad decrypt' in str(e.args):
                    raise CommandLineParsingError('Could not decrypt the private key. Wrong passphrase ?')
                raise CommandLineParsingError('Could not load the certificate or the private key. Passphrase needed ?')



        # HTTP CONNECT proxy
        if args_command_list.https_tunnel:
            if '2.7.' not in platform.python_version(): # Python 2.7 only
                raise CommandLineParsingError(
                    '--https_tunnel requires Python 2.7.X. '
                    'Current version is ' + platform.python_version() + '.')

            try: # Need to parse the proxy host:port string now
                (user,password),(host, port) = TargetStringParser.parse_proxy_target_str(args_command_list.https_tunnel)
                shared_settings['https_tunnel_host'] = host
                shared_settings['https_tunnel_port'] = port
                shared_settings['https_tunnel_user'] = user
                shared_settings['https_tunnel_password'] = password
            except InvalidTargetError:
                raise CommandLineParsingError(
                    'Not a valid host/port for --https_tunnel'
                    ', discarding all tasks.')

        else:
            shared_settings['https_tunnel_host'] = None
            shared_settings['https_tunnel_port'] = None

        # STARTTLS
        if args_command_list.starttls:
            if args_command_list.starttls not in self.START_TLS_PROTS:
                raise CommandLineParsingError(self.START_TLS_USAGE)

        if args_command_list.starttls and args_command_list.https_tunnel:
            raise CommandLineParsingError(
                'Cannot have --https_tunnel and --starttls at the same time.')

        # Number of connection retries
        if args_command_list.nb_retries < 1:
            raise CommandLineParsingError(
                'Cannot have a number smaller than 1 for --nb_retries.')

        # All good, let's save the data
        for key, value in args_command_list.__dict__.iteritems():
            shared_settings[key] = value

        return shared_settings