nabla-c0d3 / sslyze

Fast and powerful SSL/TLS scanning library.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple issues with pure SSLv2 server

extrwi opened this issue · comments

Describe the bug
sslyze seems to be unable to connect to pure SSLv2 servers.

To Reproduce
Steps to reproduce the behavior:

  1. Build a legacy version of OpenSSL 1.0.2e with options zlib enable-rc5 enable-md2 enable-gost enable-cast enable-idea enable-ripemd enable-mdc2
  2. Run a server with only SSLv2 enabled: /opt/openssl-1.0.2e/bin/openssl s_server -www -port 1234 -cert foo.crt -key foo.key -ssl2
  3. Run sslyze localhost:1234
  4. Observe first error: Probing failed: could not find a TLS version and cipher suite supported by the server; discarding scan.
  5. Apply patch (see below)
  6. Run sslyze localhost:1234
  7. Observe multiple errors (see replies)

Expected behavior
sslyze should complete all checks without errors.

Python environment (please complete the following information):

  • OS: Ubuntu 22.04
  • Python version: Python 3.10

Additional context
I was unsure whether to open multiple issues or not. I'm going to respond to this bug report, so you can split as needed.

Patch

diff --git a/sslyze/server_connectivity.py b/sslyze/server_connectivity.py
index 7a2c9ab..860d6ec 100644
--- a/sslyze/server_connectivity.py
+++ b/sslyze/server_connectivity.py
@@ -86,6 +86,7 @@ def check_connectivity_to_server(
             TlsVersionEnum.TLS_1_1,
             TlsVersionEnum.TLS_1_0,
             TlsVersionEnum.SSL_3_0,
+            TlsVersionEnum.SSL_2_0,
         ]:
             try:
                 tls_detection_result = _detect_support_for_tls_1_2_or_below(
@@ -275,7 +276,14 @@ def _detect_support_for_tls_1_2_or_below(
     # First try the default cipher list, and then all ciphers; this is to work around F5 network devices
     # that time out when the client hello is too long (ie. too many cipher suites enabled)
     # https://support.f5.com/csp/article/K14758
-    for cipher_list in ["DEFAULT", "ALL:COMPLEMENTOFALL:-PSK:-SRP"]:
+
+    # DEFAULT excludes SSLv2 ciphers in OpenSSL 1.0.2
+    if tls_version == TlsVersionEnum.SSL_2_0:
+        default_cipher_list = "SSLv2"
+    else:
+        default_cipher_list = "DEFAULT"
+
+    for cipher_list in [default_cipher_list, "ALL:COMPLEMENTOFALL:-PSK:-SRP"]:
         ssl_connection = SslConnection(
             server_location=server_location,
             network_configuration=network_config,
 * Error when running --certinfo:
       You can open an issue at https://github.com/nabla-c0d3/sslyze/issues with the following information:

       * SSLyze version: 5.0.5
       * Server: localhost:1234 - 127.0.0.1
       * Scan command: certificate_info

       Traceback (most recent call last):
         File "[...]sslyze/sslyze/scanner/_mass_scanner.py", line 267, in _generate_result_for_completed_server_scan
    scan_cmd_result = plugin_implementation_cls.result_for_completed_scan_jobs(
         File "[...]sslyze/sslyze/plugins/certificate_info/implementation.py", line 104, in result_for_completed_scan_jobs
    received_chain_as_pem, ocsp_response, custom_ca_file = completed_job.get_result()
         File "[...]sslyze/sslyze/plugins/plugin_base.py", line 61, in get_result
    raise self._exception
         File "[...]sslyze/sslyze/scanner/_jobs_worker_thread.py", line 50, in run
    return_value = job_to_complete.function_to_call(*job_to_complete.function_arguments)
         File "[...]sslyze/sslyze/plugins/certificate_info/_get_cert_chain.py", line 20, in get_certificate_chain
    ssl_connection.ssl_client.set_cipher_list(openssl_cipher_string)
         File "[...]sslyze/.venv/lib/python3.10/site-packages/nassl/ssl_client.py", line 306, in set_cipher_list
    self._ssl.set_cipher_list(cipher_list)
       nassl._nassl.OpenSSLError: error:1410F0B9:SSL routines:SSL_set_cipher_list:no cipher match
 * Error when running --openssl_ccs:
       You can open an issue at https://github.com/nabla-c0d3/sslyze/issues with the following information:

       * SSLyze version: 5.0.5
       * Server: localhost:1234 - 127.0.0.1
       * Scan command: openssl_ccs_injection

       Traceback (most recent call last):
         File "[...]sslyze/sslyze/scanner/_mass_scanner.py", line 267, in _generate_result_for_completed_server_scan
    scan_cmd_result = plugin_implementation_cls.result_for_completed_scan_jobs(
         File "[...]sslyze/sslyze/plugins/openssl_ccs_injection_plugin.py", line 87, in result_for_completed_scan_jobs
    return OpenSslCcsInjectionScanResult(is_vulnerable_to_ccs_injection=scan_job_results[0].get_result())
         File "[...]sslyze/sslyze/plugins/plugin_base.py", line 61, in get_result
    raise self._exception
         File "[...]sslyze/sslyze/scanner/_jobs_worker_thread.py", line 50, in run
    return_value = job_to_complete.function_to_call(*job_to_complete.function_arguments)
         File "[...]sslyze/sslyze/plugins/openssl_ccs_injection_plugin.py", line 108, in _test_for_ccs_injection
    ssl_connection.connect()
         File "[...]sslyze/sslyze/connection_helpers/tls_connection.py", line 294, in connect
    self.ssl_client.do_handshake()
         File "[...]sslyze/sslyze/plugins/openssl_ccs_injection_plugin.py", line 151, in _do_handshake_with_ccs_injection
    tls_record, len_consumed = TlsRecordParser.parse_bytes(remaining_bytes)
         File "[...]sslyze/.venv/lib/python3.10/site-packages/tls_parser/parser.py", line 11, in parse_bytes
    record_header, len_consumed = TlsRecordHeader.from_bytes(raw_bytes)
         File "[...]sslyze/.venv/lib/python3.10/site-packages/tls_parser/record_protocol.py", line 35, in from_bytes
    record_type = TlsRecordTypeByte(struct.unpack("B", raw_bytes[0:1])[0])
         File "/usr/lib/python3.10/enum.py", line 385, in __call__
    return cls.__new__(cls, value)
         File "/usr/lib/python3.10/enum.py", line 710, in __new__
    raise ve_exc
       ValueError: 130 is not a valid TlsRecordTypeByte
 * Error when running --heartbleed:
       You can open an issue at https://github.com/nabla-c0d3/sslyze/issues with the following information:

       * SSLyze version: 5.0.5
       * Server: localhost:1234 - 127.0.0.1
       * Scan command: heartbleed

       Traceback (most recent call last):
         File "[...]sslyze/sslyze/scanner/_mass_scanner.py", line 267, in _generate_result_for_completed_server_scan
    scan_cmd_result = plugin_implementation_cls.result_for_completed_scan_jobs(
         File "[...]sslyze/sslyze/plugins/heartbleed_plugin.py", line 86, in result_for_completed_scan_jobs
    return HeartbleedScanResult(is_vulnerable_to_heartbleed=scan_job_results[0].get_result())
         File "[...]sslyze/sslyze/plugins/plugin_base.py", line 61, in get_result
    raise self._exception
         File "[...]sslyze/sslyze/scanner/_jobs_worker_thread.py", line 50, in run
    return_value = job_to_complete.function_to_call(*job_to_complete.function_arguments)
         File "[...]sslyze/sslyze/plugins/heartbleed_plugin.py", line 107, in _test_heartbleed
    ssl_connection.connect()
         File "[...]sslyze/sslyze/connection_helpers/tls_connection.py", line 294, in connect
    self.ssl_client.do_handshake()
         File "[...]sslyze/sslyze/plugins/heartbleed_plugin.py", line 146, in _do_handshake_with_heartbleed
    tls_version=tls_parser.record_protocol.TlsVersionEnum[self._ssl_version.name], heartbeat_data=b"\x01" * 16381
         File "/usr/lib/python3.10/enum.py", line 440, in __getitem__
    return cls._member_map_[name]
       KeyError: 'SSLV2'
 * Error when running --robot:
       You can open an issue at https://github.com/nabla-c0d3/sslyze/issues with the following information:

       * SSLyze version: 5.0.5
       * Server: localhost:1234 - 127.0.0.1
       * Scan command: robot

       Traceback (most recent call last):
         File "[...]sslyze/sslyze/scanner/_mass_scanner.py", line 267, in _generate_result_for_completed_server_scan
    scan_cmd_result = plugin_implementation_cls.result_for_completed_scan_jobs(
         File "[...]sslyze/sslyze/plugins/robot/implementation.py", line 102, in result_for_completed_scan_jobs
    server_responses_per_robot_payloads = future.get_result()
         File "[...]sslyze/sslyze/plugins/plugin_base.py", line 61, in get_result
    raise self._exception
         File "[...]sslyze/sslyze/scanner/_jobs_worker_thread.py", line 50, in run
    return_value = job_to_complete.function_to_call(*job_to_complete.function_arguments)
         File "[...]sslyze/sslyze/plugins/robot/_robot_tester.py", line 176, in test_robot
    rsa_params = _get_rsa_parameters(server_info, tls_version_to_use, cipher_string)
         File "[...]sslyze/sslyze/plugins/robot/_robot_tester.py", line 244, in _get_rsa_parameters
    cert_as_pem = ssl_connection.ssl_client.get_received_chain()[0]
         File "[...]sslyze/.venv/lib/python3.10/site-packages/nassl/ssl_client.py", line 399, in get_received_chain
    return [x509.as_pem() for x509 in self._ssl.get_peer_cert_chain()]
       ValueError: Error getting the peer's certificate chain.

Hello,
Thanks for the bug report. I've pushed a fix so that SSLyze provides a better error for SSL2-only servers. Full scans still won't be supported tho.

Fixed in v5.2.0.