tintinweb / scapy-ssl_tls

SSL/TLS layers for scapy the interactive packet manipulation tool
GNU General Public License v2.0
419 stars 156 forks source link

Trying to Encrypt and Decrypt the communication between Client and Server using Modbus/TCP protocol. #149

Open PraveenKumarSoni opened 6 years ago

PraveenKumarSoni commented 6 years ago

I'm trying to encrypt the Modbus/TCP communication by using Machine_A and Machine_B between the Client and Server(PLC).

Scada System(PLC) <---> Machine_B <---> Machine_A <---> Client(Scada Host)

Client sends the data to the Machine_A. And Machine_A sniff the data and extract the load from Raw and Padding layer from the Modbus packet then encrypt the load with AES and write it on the SSL socket. Machine_B receive the should receive the data but it's not receiving :( and then Machine_B decrypt the load and should send it to the SCADA System(PLC). But this code work properly because in this communication 3-way handshaking is not happening.

Please Help me...!!

Client Side Code

``import socket import sys import hashlib from Crypto.Cipher import AES import ssl

KEY = hashlib.sha256("some random password").digest() IV = "abcdefghijklmnop" obj = AES.new(KEY, AES.MODE_CFB, IV)

def EncryptData(data): global obj print ("Start Encrypting....") data = obj.encrypt(data) print ("Data Encrypted" + data); return data

def DecryptData(data): global obj print ('Start Decrypting') data = obj.decrypt(data) print ('Data Decrypted') return data

def main(Packet): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_add = ('192.168.100.24', 5003)

print >> sys.stderr, 'connect to %s port %s',%server_add

sock.connect(server_add) #For normal Socket Connection

keyFile = 'priv.pem' certFile = 'cert.crt' context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)

context.load_verify_locations(keyFile)

context.load_verify_locations(certFile) ssock = context.wrap_socket(sock, server_hostname = server_add[0]) ssock.connect(server_add) print (dir(ssock)) for pkt in Packet: if (pkt.haslayer(TCP)): TCP_Option = pkt[TCP].options print "Option field of TCP Protocol is: " + TCP_Option elif (pkt.haslayer(Raw)): n=0 print("Detected Raw layer in Packet: " +str(pkt[n][TCP].load)) Payload = pkt.getlayer(Raw).load print("Payload of Raw layer is: " + Payload) ssock.sendall(EncryptData(Payload)) elif (pkt.haslyer(Padding)): n=0 print("Detected Padding layer in Packet: " +str(pkt[n][TCP].load)) Payload = pkt.getlayer(Padding.load) print("Payload of Padding layer is: " + Payload) ssock.sendall(EncryptData(Payload)) else: pass
sock.close()

if name == "main": sniff(iface="eth0", filter="tcp and host 192.168.100.12 and port 502", prn=main) `

Server Side Code

`import socket import sys import hashlib from Crypto.Cipher import AES import ssl

KEY = hashlib.sha256("some random password").digest() IV = "abcdefghijklmnop" #Initialization vector should always be 16 bit obj = AES.new(KEY, AES.MODE_CFB, IV) #creating an object to encrypt our data with

def EncryptData(data): global obj print ("Start Encrypting") data = obj.encrypt(data) print ("Data Encrypted") return data

def DecryptData(data): global obj print ("Start Decrypting....") data = obj.decrypt(data) return data

def each_client_normal(client_conn): data = None while data != 'q': data = str(client_conn.recv(1024)) print ("Encrypted data is here which is received from client: " + data) Decrypted_data = DecryptData(data) try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print "<<..Sucessfully socket created for send data to SCADA Machine..>>" port = 502 server_address = ('192.168.100.40', 502) s.connect(server_address) print "Socket Connected sucessfully to SCADA Machine" s.sendall(Decrypted_data) except socket.error as err: print "Socket creation failed with error %s" %(err) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('192.168.100.24', 5003) sock.bind(server_address) sock.listen(1) keyFile = 'priv.pem' certFile = 'cert.crt' context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.load_cert_chain(certFile, keyFile) # Put the certificate, private key ssock = context.wrap_socket(sock, server_side=True)

while True: try: print >> sys.stderr, 'Waiting for a connection'

conn, client = sock.accept()

conn, client = ssock.accept() print ("Connected to: " + str(client)) each_client_normal(conn)

except socket.error as e: print ("Error: {0}".format(e)) conn.close() ssock.close() sock.close() `