1
1
import logging
2
2
import types
3
3
from abc import abstractmethod
4
+ import random
4
5
5
6
from nebula .addons .attacks .attacks import Attack
6
7
7
8
8
9
class CommunicationAttack (Attack ):
9
- def __init__ (self , engine , target_class , target_method , round_start_attack , round_stop_attack , decorator_args = None ):
10
+ def __init__ (self , engine ,
11
+ target_class ,
12
+ target_method ,
13
+ round_start_attack ,
14
+ round_stop_attack ,
15
+ attack_interval ,
16
+ decorator_args = None ,
17
+ selectivity_percentage : int = 100 ,
18
+ selection_interval : int = None
19
+ ):
10
20
super ().__init__ ()
11
21
self .engine = engine
12
22
self .target_class = target_class
13
23
self .target_method = target_method
14
24
self .decorator_args = decorator_args
15
25
self .round_start_attack = round_start_attack
16
26
self .round_stop_attack = round_stop_attack
27
+ self .attack_interval = attack_interval
17
28
self .original_method = getattr (target_class , target_method , None )
29
+ self .selectivity_percentage = selectivity_percentage
30
+ self .selection_interval = selection_interval
31
+ self .last_selection_round = 0
32
+ self .targets = set ()
18
33
19
34
if not self .original_method :
20
35
raise AttributeError (f"Method { target_method } not found in class { target_class } " )
@@ -24,10 +39,28 @@ def decorator(self, *args):
24
39
"""Decorator that adds malicious behavior to the execution of the original method."""
25
40
pass
26
41
42
+ async def select_targets (self ):
43
+ if self .selectivity_percentage != 100 :
44
+ if self .selection_interval :
45
+ if self .last_selection_round % self .selection_interval == 0 :
46
+ logging .info ("Recalculating targets..." )
47
+ all_nodes = await self .engine .cm .get_addrs_current_connections (only_direct = True )
48
+ num_targets = max (1 , int (len (all_nodes ) * (self .selectivity_percentage / 100 )))
49
+ self .targets = set (random .sample (list (all_nodes ), num_targets ))
50
+ elif not self .targets :
51
+ logging .info ("Calculating targets..." )
52
+ all_nodes = await self .engine .cm .get_addrs_current_connections (only_direct = True )
53
+ num_targets = max (1 , int (len (all_nodes ) * (self .selectivity_percentage / 100 )))
54
+ self .targets = set (random .sample (list (all_nodes ), num_targets ))
55
+ else :
56
+ logging .info ("All neighbors selected as targets" )
57
+ self .targets = await self .engine .cm .get_addrs_current_connections (only_direct = True )
58
+
59
+ logging .info (f"Selected { self .selectivity_percentage } % targets from neighbors: { self .targets } " )
60
+ self .last_selection_round += 1
61
+
27
62
async def _inject_malicious_behaviour (self ):
28
63
"""Inject malicious behavior into the target method."""
29
- logging .info ("Injecting malicious behavior" )
30
-
31
64
decorated_method = self .decorator (self .decorator_args )(self .original_method )
32
65
33
66
setattr (
@@ -38,14 +71,18 @@ async def _inject_malicious_behaviour(self):
38
71
39
72
async def _restore_original_behaviour (self ):
40
73
"""Restore the original behavior of the target method."""
41
- logging .info (f"Restoring original behavior of { self .target_class } .{ self .target_method } " )
42
74
setattr (self .target_class , self .target_method , self .original_method )
43
75
44
76
async def attack (self ):
45
77
"""Perform the attack logic based on the current round."""
46
- if self .engine .round == self .round_stop_attack :
47
- logging .info (f"[{ self .__class__ .__name__ } ] Restoring original behavior" )
78
+ if self .engine .round not in range (self .round_start_attack , self .round_stop_attack + 1 ):
79
+ pass
80
+ elif self .engine .round == self .round_stop_attack :
81
+ logging .info (f"[{ self .__class__ .__name__ } ] Stoping attack" )
48
82
await self ._restore_original_behaviour ()
49
- elif self .engine .round == self .round_start_attack :
50
- logging .info (f"[{ self .__class__ .__name__ } ] Injecting malicious behavior" )
83
+ elif (self .engine .round == self .round_start_attack ) or ((self .engine .round - self .round_start_attack ) % self .attack_interval == 0 ):
84
+ await self .select_targets ()
85
+ logging .info (f"[{ self .__class__ .__name__ } ] Performing attack" )
51
86
await self ._inject_malicious_behaviour ()
87
+ else :
88
+ await self ._restore_original_behaviour ()
0 commit comments