Попытка зашифровать текстовое объединение протокола Modbus/Tcp. Но соединение не работает должным образом
Я пытаюсь зашифровать связь по протоколу Modbus/Tcp, поместив две машины Машина A и Машина B между клиентом и сервером (ПЛК). Так что я могу защитить связь.
Вот код машины А.
Клиент отправляет данные в Machine_A, и сначала в Machine_A я вынюхиваю эти данные, которые отправляет клиент, а затем извлекаю из пакета полезную нагрузку из уровня Raw и Padding (поскольку тогда это пакет Modbus, если я извлечу его в scapy, то Пакет Modbus будет отображаться в слое Padding уровня Raw после уровня TCP), и я зашифровал его с помощью AES, а затем установил соединение SSL Socket с Machine_B. И отправьте зашифрованные данные, используя SSL, как вы можете видеть в коде.
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 = ('172.16.248.24', 5003)
#server_add = ('127.0.0.1', 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.40 and port 502", prn=main)
Код машины B
Здесь я получил зашифрованную полезную нагрузку, которую отправляет Machine_A, и расшифровал ее на основе ключа AES. Затем я отправил дешифрованную полезную нагрузку в ПЛК, работающий по протоколу Modbus/Tcp.
**Here is the Code of Machine B**
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 = ('172.16.248.40', 502) #This is IP of PLC
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 = ('172.16.248.24', 5003)
sock.bind(server_address)
sock.listen(1)
# SSL Code
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()
Невозможно выполнить сеанс (TCP 3 Way handshaking) между этим маршрутом (клиент - компьютер A -> компьютер B -> сервер (ПЛК)).