Opening a SSL socket connection in Python

I’m trying to establish a secure socket connection in Python, and i’m having a hard time with the SSL bit of it. I’ve found some code examples of how to establish a connection with SSL, but they all involve key files. The server i’m trying to connect with doesn’t need to receive any keys or certificates. My question is how do I essentially wrap a python socket connection with SSL. I know for a fact that the cipher i’m suppose to use is ADH-AES256-SHA, and the protocol is TLSv1. This is what i’ve been trying:

import socket
import ssl

# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
HOST, PORT = 'XX.XX.XX.XX', 4434

# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)

# WRAP SOCKET ???
ssl.wrap_socket(sock, ssl_version="TLSv1", ciphers="ADH-AES256-SHA")

# CONNECT AND PRINT REPLY
sock.connect((HOST, PORT))
sock.send(packet)
print sock.recv(1280)

# CLOSE SOCKET CONNECTION
sock.close()

When I run this code, I don’t get any errors, but I get a blank response. When trying to debug this code in the command line, by typing in python in the terminal and pasting in code line by line, I get what i’m assuming is a status code when running sock.send(packet). The integer response I get is 26. If anyone knows what this means, or can help in anyway it would be greatly appreciated. Thanks in advance!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Ok, I figured out what was wrong. It was kind of foolish of me. I had two problems with my code. My first mistake was when specifying the ssl_version I put in TLSv1 when it should have been ssl.PROTOCOL_TLSv1. The second mistake was that I wasn’t referencing the wrapped socket, instead I was calling the original socket that I have created. The below code seemed to work for me.

import socket
import ssl

# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
HOST, PORT = 'XX.XX.XX.XX', 4434

# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)

# WRAP SOCKET
wrappedSocket = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, ciphers="ADH-AES256-SHA")

# CONNECT AND PRINT REPLY
wrappedSocket.connect((HOST, PORT))
wrappedSocket.send(packet)
print wrappedSocket.recv(1280)

# CLOSE SOCKET CONNECTION
wrappedSocket.close()

Hope this can help somebody!

Method 2

You shouldn’t be setting PROTOCOL_TLSv1 (or TLSv1). This restricts the connection to TLS v1.0 only. Instead you want PROTOCOL_TLS (or the deprecated PROTOCOL_SSLv23) that supports all versions supported by the library.

You’re using an anonymous cipher, because for some reason you think you don’t need a certificate or key. This means that there is no authentication of the server and that you’re vulnerable to a man in the middle attack. Unless you really know what you’re doing, I suggest you don’t use anonymous ciphers (like ADH-AES256-SHA).

Method 3

I was looking for a good working ssl socket that starts the connection with a https package. This helped me a lot but is a little outdated, so here is the code for python3:

import socket
import ssl

package = "GET /ws/LiveWebcastUpdate/22000557 HTTP/1.1rnHost: 
www.website_name.comrnUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; 
rv:80.0) Gecko/20100101 Firefox/80.0rnAccept: */*rnAccept-Language: nl,en- 
US;q=0.7,en;q=0.3rnSec-WebSocket-Version: 13rnOrigin: 
https://www.website_name.comrnSec-WebSocket-Key: 
NU/EsJMICjSociJ751l0Xw==rnConnection: keep-alive, UpgradernPragma: no- 
cachernCache-Control: no-cachernUpgrade: websocketrnrn"

hostname = 'www.website_name.com'
port = 443

context = ssl.create_default_context()

with socket.create_connection((hostname, port)) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())
        ssock.send(package.encode())
        while True:
            data = ssock.recv(2048)
            if ( len(data) < 1 ) :
                break
            print(data)

This is as simple as possible, for more information visit
https://docs.python.org/3/library/ssl.html

Method 4

There is a lot of fun to be had solving these problems but for me, I found that the underlying infrastructure for python ssl is openssl. Try validating your certificates with openssl and do this before you try to get python to use that same stack.

I needed to import a root certificate into openssl before I could validate the leaf certificate.

This was helpful.
http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl

Another interesting thing was that two different build of the same version of python on different hosts had different methods. One had ssl.get_default_verify_paths() and the other didn’t had any at all. The lesson here is that python ssl is built on openssl. Different underlying libraries give you a different python.

Python SSL is built on openssl so solve certificate issues in openssl first.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x