Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language oblivious error handling leads to wrong exception being thrown #434

Closed
weddige opened this issue Apr 29, 2020 · 6 comments
Closed

Comments

@weddige
Copy link

weddige commented Apr 29, 2020

Describe the bug
This is a follow up to #430. I did some investigation into the issue and was able to locate a plausible cause for the crash.

To Reproduce

The issue is platform and language dependent.

The following code produces an exception on

  • Win 10
  • German Language
  • Python 3.8
  • sslyze 3.0.3

but does not produce an exception on

  • Linux
  • Python 3.8
  • sslyze 3.0.3
import sslyze
import nassl
import socket

server_location = sslyze.ServerNetworkLocationViaDirectConnection.with_ip_address_lookup("asml.com", 443)
server_info = sslyze.ServerConnectivityTester().perform(server_location)

The relevant part of the stack trace is:

c:\path\.env38\lib\site-packages\nassl\ssl_client.py in do_handshake(self)
    190                 # Recover the peer's encrypted response
--> 191                 handshake_data_in = self._sock.recv(self._DEFAULT_BUFFER_SIZE)
    192                 if len(handshake_data_in) == 0:

ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen

This exception can be reproduced with the following code:

with socket.create_connection(('asml.com', 443)) as sock:
    ssl_client = nassl.ssl_client.SslClient(
        ssl_version=nassl.ssl_client.OpenSslVersionEnum.TLSV1_2,
        ssl_verify=nassl.ssl_client.OpenSslVerifyEnum.NONE
    )
    ssl_client.set_cipher_list('ECDHE-ECDSA-CHACHA20-POLY1305')
    ssl_client.set_tlsext_host_name('asml.com')
    ssl_client.set_underlying_socket(sock)
    try:
        ssl_client.do_handshake()
        print('Success', ssl_client.get_current_cipher_name())
    except Exception as e:
        print(type(e), e)

This raises an ConnectionResetError on both aforementioned platforms:

  • [Errno 104] Connection reset by peer (Linux)
  • [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen (Win 10; german)

Expected behavior
The expected behavior is identical behavior on all platforms.

Additional context
This leads to the following lines in sslyze as the likely cause of #430:

ServerRejectedTlsHandshake is only raised if the error message matches one entry of _HANDSHAKE_REJECTED_SOCKET_ERRORS, but this does not work with localized error messages.

        except OSError as e:
            for error_msg in _HANDSHAKE_REJECTED_SOCKET_ERRORS.keys():
                if error_msg in str(e.args):
                    raise ServerRejectedTlsHandshake(
                        server_location=self._server_location,
                        network_configuration=self._network_configuration,
                        error_message=_HANDSHAKE_REJECTED_SOCKET_ERRORS[error_msg],
                    )

            # Unknown socket error
            raise
@dquitmann-op
Copy link

Just to confirm the report of weddige:

performing sslyze --tlsv1_2 --json_out test.json asml.com on a Win10 VM with english language, Python3.8 and SSLyze 3.0.3 runs without error and the json contains entries like

{
    "cipher_suite": {
        "is_anonymous": false,
        "key_size": 128,
        "name": "TLS_RSA_WITH_RC4_128_SHA",
        "openssl_name": "RC4-SHA"
    },
    "error_message": "Server closed the connection: received TCP FIN"
},

So the WinError 10054 got correctly mapped to this error message (as defined in https://github.com/nabla-c0d3/sslyze/blob/3.0.3/sslyze/connection_helpers/tls_connection.py#L105).

@nabla-c0d3
Copy link
Owner

Thanks for figuring this out 👍 . I just pushed a fix - can you try it? Thanks!

@dquitmann-op
Copy link

This looks good for me and it works in general.

Nevertheless, I recognized one issue. When performing sslyze --regular asml.com I get:

 * Error when running --reneg:
       You can open an issue at https://github.com/nabla-c0d3/sslyze/issues with the following information:

       * Server: asml.com:443 - 51.144.7.192
       * Scan command: session_renegotiation

       Traceback (most recent call last):
         File "c:\python-envs\test-sslyze\lib\site-packages\sslyze\scanner.py", line 229, in get_results
    result = implementation_cls.result_for_completed_scan_jobs(
         File "c:\python-envs\test-sslyze\lib\site-packages\sslyze\plugins\session_renegotiation_plugin.py", line 100, in result_for_completed_scan_jobs
    result_enum, value = job.result()
         File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.752.0_x64__qbz5n2kfra8p0\lib\concurrent\futures\_base.py", line 432, in result
    return self.__get_result()
         File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.752.0_x64__qbz5n2kfra8p0\lib\concurrent\futures\_base.py", line 388, in __get_result
    raise self._exception
         File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.752.0_x64__qbz5n2kfra8p0\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
         File "c:\python-envs\test-sslyze\lib\site-packages\sslyze\plugins\session_renegotiation_plugin.py", line 148, in _test_client_renegotiation
    ssl_connection.ssl_client.do_renegotiate()
         File "c:\python-envs\test-sslyze\lib\site-packages\nassl\legacy_ssl_client.py", line 81, in do_renegotiate
    self.do_handshake()
         File "c:\python-envs\test-sslyze\lib\site-packages\nassl\ssl_client.py", line 191, in do_handshake
    handshake_data_in = self._sock.recv(self._DEFAULT_BUFFER_SIZE)
       ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen

This is due to https://github.com/nabla-c0d3/sslyze/blob/3.0.3/sslyze/plugins/session_renegotiation_plugin.py#L155-L163, where the same issue should be fixed in a similar way to de8c1da. A quick search for the appropriate keywords revealed no further code locations with the same issue.

Thanks for the quick response and fix. Looking forward to Release 3.0.4!

@nabla-c0d3
Copy link
Owner

Thanks :). Just pushed the change for renegotiation - can you try it? Thanks!

@dquitmann-op
Copy link

It works for me with multiple servers where I had problems before. No problems, no errors. 👍

Thanks for the help and the fixes!

@nabla-c0d3
Copy link
Owner

Released in v3.0.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants