How to send a HTTPS packet in python? - python

I want to send a HTTPS packed In python. For example I want to send something to Google server. I wrote the following program :
import socket
import ssl
# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
HOST, PORT = 'www.google.com', 443
# 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()
But when I run it, I receive the following error :
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "C:/Users/Desktop/PySSL.py", line 16, in <module>
wrappedSocket.connect((HOST, PORT))
File "C:\Python27\lib\ssl.py", line 297, in connect
self.do_handshake()
File "C:\Python27\lib\ssl.py", line 281, in do_handshake
self._sslobj.do_handshake()
SSLError: [Errno 1] _ssl.c:499: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
>>>
What shall I do to handle it?
Update:
I checked Google encryption protocol already and you can see the result in the following picture :
But I don't have any idea how and where I must set this parameters in the program.
Update:
Note that I want to extract the used public key in the communication. So please suggest me a way that it make extracting the public key possible. I also want to set or see the used communication and encryption protocols.
Update2:
Although I wanted to set the cipher and ssl_version manually, but based on the answers, I tried to remove this to parameters from my function call and retry to run the program. well, the error changed:
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "C:/Users/Desktop/PySSL2.py", line 17, in <module>
wrappedSocket.send(packet)
File "D:\Python34\lib\ssl.py", line 679, in send
v = self._sslobj.write(data)
TypeError: 'str' does not support the buffer interface
>>>

wrappedSocket = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, ciphers="ADH-AES256-SHA")
You are trying to use ADH, i.e. a cipher with anonymous authentication. This is a cipher which does not use certificates for authentication and is thus usually only supported by misconfigured servers.
Just omit setting ssl_version and ciphers from your function call. In this case it will offer the server the best protocol version it can and a number of ciphers and the server will pick from these offers what it supports.
This should then make the SSL handshake possible. But since it does not look like your are really trying to talk HTTP on the socket you will probably run into further problems after the connection got established.

Why not using requests?
import requests
requests.get('https://www.google.com', port=443)
That way you will be bound to HTTP

Since it looks like you're trying to make simple http requests, you could use the requests library instead, which handles a lot of the stuff for you.
If you don't have it: pip install requests.
import requests
resp = requests.get("http://www.google.com")
print resp.text

Related

SSL raises version error only on re-connect attempt?

We have a server and client both running python3.
The client connects to the server and authenticates upon initialisation of the client. This completes without issue.
However, if the connection drops, the client catches the error (the socket.recv returning 0) and attempts to re-run the code that connects to the server).
The server recieves the initial request whilst listening on its given recieving socket and then once making a connection the next recv call raises the following error:
File "/usr/lib64/python3.7/ssl.py", line 1056, in recv
return self.read(buflen)
File "/usr/lib64/python3.7/ssl.py", line 931, in read
return self._sslobj.read(len)
ssl.SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:2570)
Why would this succeed upon the first connection but then raise this error thereafter? If the client is closed and restarted the error is avoided upon the next connection. However, if the server is closed and the client tries to connect once the server restarts this error is encountered.
At the client end the following error is raised:
File "\Our_Code", line 100, in make_connection
data = self.ssl_sock.recv(1024)
File "C:\Users\Home\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1226, in recv226, in recv
return self.read(buflen) 101, in read
File "C:\Users\Home\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1101, in read
return self._sslobj.read(len)
ssl.SSLError: [SSL] internal error (_ssl.c:2633)
This exact formultation suggests to me that the issue is actually with the client and some data that it is saving between reconnects. But it overwrites the sockets for a new connection so I thought all data from the previous connection would be discarded?
The connection function is as:
import socket
import ssl
def make_connection(self, email, password):
try:
self.ssl_sock = []
HOST = "9:9:99:999" # The server's hostname or IP address (not our actual IP)
PORT = 5432 # The port used by the server (not our actual port)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
self.ssl_sock = self.context.wrap_socket(sock)
password = password.encode('utf-8').strip()
password = base64.b64encode(password).decode("utf-8")
tcp_string = (f"^{email}*{password}$")
tcp_string = tcp_string.encode('utf-8')
self.ssl_sock.sendall(tcp_string)
data = self.ssl_sock.recv(1024)
data = data.decode('utf-8')
if data == "^good_connect$":
return True
else:
return False
except Exception:
print(f"make_connection - {traceback.format_exc()}")
I'm still fairly new to python and particularly networking, so I suspect I have made a rookie error. But so far all my searches have returned the obvious, that the TLS version is wrong, but the fact that it authenticates fine on the initial connection suggests to me that that isn't the case.
I'm happy to answer any questions I can about the situation.

Why am I getting a ConnectionResetError for my basic python UDP client?

I'm on a 2020.4 Kali Linux VM on VMWare Workstation 16 Player and I'm working with the Black Hat Python book by Justin Seitz. Right in the beginning of Chapter 2 he introduces a basic UDP client but for some reason, I get thrown a ConnectionResetError every time because either the port I'm sending to or the port I'm receiving from is occupied. I then added a line to make it bind to the address I'm sending to and it worked. Is it not automatically binding when I sendto()? If I'm pentesting, I shouldn't need the password/admin to bind when I make a UDP client.
Here is my code:
import socket
address = ('127.0.0.1', 80)
# Create a socket object.
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# I commented this out just for testing reasons.
# client.bind(address)
# Send some data.
client.sendto(b'AAABBBCCC', address)
# Receive some data.
data, addr = client.recvfrom(4096)
print(data)
Here's the error:
Traceback (most recent call last):
File ".\udp_client.py", line 15, in <module>
data, addr = client.recvfrom(4096)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
I apologize in advance if this is some dumb mistake on my part.
EDIT:
I changed the code to use a different port (65536) yet now it just doesn't print anything or end the script, it just keeps running.
I'd suggest you try using a port other than port 80 (default for all HTTP traffic) which is likely being used constantly and isn't a good port to try and hold onto, try port numbers > 1023

User can't communicate with proxy

I'm implementing an IMAP proxy which securely communicates with a client.However, I have a problem when handshaking.
The code of my proxy is:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((host, port))
ssock, addr = self.sock.accept()
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
self.conn_client = context.wrap_socket(ssock)
And I receive the error:
ssl.SSLError: [SSL: UNEXPECTED_MESSAGE] unexpected message (_ssl.c:833)
The code of my tests is:
M = imaplib.IMAP4_SSL(IP_PROXY)
And I receive the error:
ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:777)
However, when the code of the proxy is:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((host, port))
ssock, addr = self.sock.accept()
self.conn_client = ssl.wrap_socket(ssock, certfile=CERT, server_side= True)
It correctly works but I don't want to use certificate.
Thank you
It correctly works but I don't want to use certificate.
SSL/TLS is almost everywhere used with a certificate to make sure that the client is talking to the expected server and not to some man in the middle. If you don't want to use a certificate you need to either use a different kind of authentication (like PSK) or use no authentication at all ("anonymous authentication" - very bad idea).
In any way you would need to set the relevant ciphers to enable this alternative authentication on both client and server. This can be done with the ciphers attribute to wrap_socket on the server side and in your client code it could probably be done by constructed a SSLContext with the necessary ciphers and using the ssl_context argument to specific the context to be used in IMAP4_SSL.
But this is only for your specific Python based IMAP client. Don't expect that you will be able to configure commonly used IMAP clients like Thunderbird or Outlook to be usable with a server without certificates. And like I said, it is a bad idea in the first place.

Thrift TTransportException in python

I'm getting a weird error while trying to execute an RPC using thrift on python. I have found similar issues online, but none of them really apply to my situation.
Here is the error I'm getting
No handlers could be found for logger "thrift.transport.TSocket"
Traceback (most recent call last):
File "experiment.py", line 71, in <module>
transport.open()
File "/usr/local/lib/python2.7/dist-packages/thrift/transport/TTransport.py", line 152, in open
return self.__trans.open()
File "/usr/local/lib/python2.7/dist-packages/thrift/transport/TSocket.py", line 113, in open
raise TTransportException(TTransportException.NOT_OPEN, msg)
thrift.transport.TTransport.TTransportException: Could not connect to any of [('192.168.178.44', 9000)]
The following is, I believe, the code which produces it.
TECS_SERVER_IP = "192.168.178.44"
TECS_SERVER_PORT = 9000
transport = TSocket.TSocket(TECS_SERVER_IP, TECS_SERVER_PORT)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = TTSService.Client(protocol)
transport.open()
This happens whenever I try to communicate to another machine, so I tried with the ip "127.0.0.1" and it works. However, using the IP of the localhost "192.168.178.44" which should refer to the same computer also produces the error.
To me it seems like it cannot resolve IP addresses for some reason...
Any ideas on what's causing this and how to fix it?
I'm using Python 2.7.12, thrift 0.9.3 and Ubuntu 16.04, but I also got the error on Windows 10.
This is how my thrift service starts
handler = TTSHandler()
handler.__init__()
transport = TSocket.TServerSocket(host='localhost', port=9000)
processor = TTSService.Processor(handler)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
server.serve()
your server should bind to that address before client could connect to:
TSocket.TServerSocket(host='192.168.178.44', port=9000)
or use host='0.0.0.0' which means bind on all IPv4 addresses on the machine.

Why does my python's socket.shutdown work on Windows but not Ubuntu?

Here is what my socket code looks like, this is for a UDP connection.
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(8)
sock.sendto(req, (host, port))
buf = sock.recv(2048)
sock.shutdown(socket.SHUT_RDWR)
sock.close()
Here is the relevant portion of my stack trace
Exception in thread Thread-6:
Traceback (most recent call last):
File "udp_test.py", line 110, in my_method
sock.shutdown(socket.SHUT_RDWR)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 107] Transport endpoint is not connected
I don't know what OS the host is running, I assume it is some flavor of Linux. I can wrap the socket.shutdown[docs] call in a try catch and everything seems to work fine.
Does this problem have something to do with a difference between the way Windows and Linux handle sockets? Is wrapping sock.shutdown in a try catch the solution here or will I run nasty problems down the rode?
You are calling sock.shutdown() on a UDP socket. UDP doesn't have a connection to shut down. On Windows the call doesn't do much other than prevent you from writing to and reading from the socket (packets are still received and queued), on Linux calling shutdown on a UDP connection throws an error.
In either case, you shouldn't really be using shutdown at all. Just close the socket instead, or just don't send on the socket and don't read data from it.

Categories