I'm developing a server-client service on the socket level. My Server gets spammed with random packets. I need a way to differenciate between good and bad IPs, but I don't know all of the good IPs, so a whitelist/blacklist doesn't work.
The server manages a list of all clients and informs all clients about the current queue of clients. When the first client has acted, it sends a positive reply to the server and the server advances the queue. A filter, which scans the data of the incomming packet could work, but I'm not sure if it is possible, to catch all attacks just with that (normal letters, ',', '.' and numbers have to be bypassed since that could be a valid client).
Today I got this console output (sorry for the formatting, and cut exceptions, this very nice website thinks the following is code and wants me to use some arbitrary indentation, which I can't resolve, so I just deleted things until it didn't think it's code anymore)
listening on: 4444
Connection address ('198.108.67.48', 53556)
I am: \r\n
listening on: 4444
Connection address:('198.108.67.48', 62346)
I am: GET / HTTP/1.1\r\nHost
listening on 4444
activeDisps[['198.108.67.48', '\r\n'], ['198.108.67.48', 'GET / HTTP/1.1\r\nHost']]
ValueError: invalid literal for int() with base 10: 'z\xc2\x00\x00 \xc0/\xc00\xc0+\xc0'
Connection address('198.108.67.48', 7204)
I am \x16\x03\x01\x00\x89\x01\x00\x00\x85\x03\x03\xcf\xef\x1f\xea\xe5\x11\x88\xba\x86
listening on 4444
activeDisps[['198.108.67.48', '\r\n'], ['198.108.67.48', 'GET / HTTP/1.1\r\nHost'], ['198.108.67.48', '\x16\x03\x01\x00\x89\x01\x00\x00\x85\x03\x03\xcf\xef\x1f\xea\xe5\x11\x88\xba\x86']]
I have found a working solution for me: Since the malicious packets all seem to contain non alphanumeric characters, I can run a pattern matching over the received data to determine, whether it is a valid client or not:
import re
pattern = re.compile("^([0-9]\*\w+[0-9]\*)+$")
while True:
clientName=''
conn, addr = myPorts[0].accept()
try:
data = conn.recv(BUFFER_SIZE)
dataStr=str(data)
nameStr=dataStr.split("'")[1]
clientName=nameStr.split(",")[0] #This is my own protocoll, might be different for you
except:
print("Connection failed")
if pattern.match(clientName):
listeningThread = threading.Thread(target=myListener, args=(conn, [addr[0], clientName]))
listeningThread.daemon = True
listeningThread.start()
else:
conn.close()