Thomas G
Thomas G

Reputation: 968

Identifying packet exchange type for an ssl/tls python socket server

Currently I am trying to reverse engineer how the key exchange and encryption works for a program. I mainly used wire shark to figure out how the packets where being encrypted. Of what I have found they are using ECDHE-RSA-AES128-GCM-SHA256 with TLS1.2

This is currently what I have.

import socket, ssl

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.bind(('', 443))
tcpSocket.listen(1)

while True:
    newsocket, fromaddr = tcpSocket.accept()
    newsocket = ssl.wrap_socket(newsocket,
                            server_side=True,
                            do_handshake_on_connect=True,
                            certfile="cert.pem",
                            ssl_version=ssl.PROTOCOL_TLSv1_2,
                            ciphers="ECDHE-RSA-AES128-GCM-SHA256")
    try:
        #Later add stuff
        pass
    finally:
        newsocket.shutdown(socket.SHUT_RDWR)
        newsocket.close()

I have tried to visualize how this works using a simple picture here. I made this using the wireshark packets that I saw here

Currently with this code, the server never replies with a client key exchange and instead just crashes leading to https://hastebin.com/wiqojapule.sql

So the main question im trying to ask is why does the python program never aw acknowledge the client and then send a server hello. Currently it just sends a Client Hello back.

Also, here is the wire shark for my python socket and the program: here

Upvotes: 0

Views: 290

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123639

Comparing the two pcap files (with real server and with test server) two things stand out:

  • In the working case (real server) the client is sending a server_name extension (SNI) with the target hostname and the server sends a certificate back which is signed by a public CA.
  • In the failing case (test server) the client is sending no server_name extension and the server is sending only a self-signed certificate back. The connection is then closed by the client, i.e. the handshake is not completed.

The missing SNI extension against the test server is probably due to given the destination as IP address and not a hostname. And this is probably also not the problem.

Very likely instead is that the client simply does not like the self-signed certificate send by the server and is therefore closing the connection. A nicer behaving client would probably send first a TLS alert unknown CA before the close but it is not uncommon that TLS stacks don't send these alerts and instead just close the connection.

... I am trying to reverse engineer how the key exchange and encryption works for a program

There does not seem anything special to reverse engineer here. The client seems to use TLS as specified in the standard, likely by using some of the many available TLS stacks and not by implementing its own. And contrary to the assumption of the OP that only a specific cipher is used the client is actually offering several ciphers (19 ciphers offered inside ClientHello) and the server can choose any of these.

The behavior one is seeing regarding self-signed certificates is actually expected: a proper client should not accept connections to a server with an untrusted certificate.

Upvotes: 2

Related Questions