csle-attack-profiler 0.5.3__py3-none-any.whl → 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of csle-attack-profiler might be problematic. Click here for more details.

@@ -1 +1 @@
1
- __version__ = '0.5.3'
1
+ __version__ = '0.6.1'
@@ -1,12 +1,12 @@
1
+ from typing import List, Union, Tuple, Any
2
+ import numpy as np
3
+ import sys
1
4
  from csle_common.dao.system_identification.emulation_statistics import EmulationStatistics
2
5
  from csle_common.dao.emulation_action.attacker.emulation_attacker_action_id import EmulationAttackerActionId
3
6
  from csle_common.dao.emulation_action.attacker.emulation_attacker_action_type import EmulationAttackerActionType
4
7
  from csle_common.dao.emulation_action.attacker.emulation_attacker_action_outcome import EmulationAttackerActionOutcome
5
8
  from csle_common.dao.emulation_action.attacker.emulation_attacker_action import EmulationAttackerAction
6
9
  from csle_attack_profiler.attack_profiler import AttackProfiler
7
- from typing import List, Union, Tuple, Any
8
- import numpy as np
9
- import sys
10
10
 
11
11
 
12
12
  class HMMProfiler:
@@ -20,6 +20,7 @@ class HMMProfiler:
20
20
 
21
21
  :param statistics: The list of EmulationStatistics objects
22
22
  :param model_name: The name of the model
23
+ :return: None
23
24
  """
24
25
  self.statistics = statistics
25
26
  self.transition_matrix: List[List[float]] = []
@@ -38,11 +39,12 @@ class HMMProfiler:
38
39
 
39
40
  :param transition_matrix: The transition matrix
40
41
  :param states: The list of states of the HMM (format: 'A:attack_name' or
41
- 'no_intrusion' based on emulation statistics file)
42
+ 'no_intrusion' based on emulation statistics file)
42
43
  :param metrics: The list of metrics to profile
43
44
  :param save: Whether to save the matrices to a file
44
45
  :param location: The location to save the matrices, if save = True, e.g "./resources",
45
- default is current directory
46
+ default is current directory
47
+ :return: None
46
48
  """
47
49
  emission_matrix, emission_matrix_observations = self.get_matrices_of_observation(self.statistics,
48
50
  metric, hidden_states)
@@ -63,7 +65,7 @@ class HMMProfiler:
63
65
  Loads the HMM model from the given location.
64
66
 
65
67
  :param location: The location of the model files, default is current directory
66
- :param metric: The data metric to use
68
+ :return: None
67
69
  """
68
70
  self.transition_matrix = np.load(f'{location}/transition_matrix.npy')
69
71
  self.hidden_states = np.load(f'{location}/hidden_states.npy')
@@ -78,14 +80,14 @@ class HMMProfiler:
78
80
  :param sequence: The sequence of observations
79
81
  :return: The most likely sequence of states
80
82
  """
81
-
83
+
82
84
  path = HMMProfiler.viterbi(self.hidden_states, self.start_state_probs,
83
85
  self.transition_matrix, self.emission_matrix,
84
86
  sequence, self.emission_matrix_observations)
85
87
  profiled_sequence = []
86
88
  for i in range(len(path)):
87
89
  profiled_sequence.append(self.hidden_states[int(path[i])])
88
-
90
+
89
91
  return profiled_sequence
90
92
 
91
93
  def get_matrices_of_observation(self, statistics: List[EmulationStatistics],
@@ -95,13 +97,14 @@ class HMMProfiler:
95
97
 
96
98
  :param statistics: The list of EmulationStatistics objects
97
99
  :param metric: The metric to get the emission matrix for
100
+ :param states: The list of states
98
101
  :return: The emission matrix, the list of observations, the list of states
99
102
  """
100
103
  emission_matrix = []
101
104
  attack_observations = {}
102
105
  attack_observations_total_counts = {}
103
106
  all_keys = set()
104
-
107
+
105
108
  for stats in statistics:
106
109
  for condition, metric_distribution in stats.conditionals_counts.items():
107
110
  action = condition.split('_')
@@ -115,7 +118,7 @@ class HMMProfiler:
115
118
  # Add the observations of the attack to the dictionary
116
119
  if metric in metric_distribution:
117
120
  attack_observations[action[0]] = metric_distribution[metric]
118
- # Sum the total counts of the observations
121
+ # Sum the total counts of the observations
119
122
  attack_observations_total_counts[action[0]] = sum(attack_observations[action[0]].values())
120
123
  # Aggregate the counts from the metric distribution
121
124
  else:
@@ -132,7 +135,7 @@ class HMMProfiler:
132
135
  # Store all possible values for the observation
133
136
  if action[0] in attack_observations:
134
137
  all_keys.update(attack_observations[action[0]])
135
-
138
+
136
139
  # Normalize the counts
137
140
  for attack, _ in attack_observations.items():
138
141
  attack_observations_total_counts[attack] = sum(attack_observations[attack].values())
@@ -186,34 +189,33 @@ class HMMProfiler:
186
189
  for state in states:
187
190
  if state == 'A:Continue':
188
191
  action = EmulationAttackerAction(id=EmulationAttackerActionId.CONTINUE, name="Continue", cmds=[],
189
- type=EmulationAttackerActionType.CONTINUE, descr="CONTINUE", ips=[],
190
- index=0, action_outcome=EmulationAttackerActionOutcome.CONTINUE)
192
+ type=None, descr="CONTINUE", ips=[], index=0, action_outcome='')
191
193
  p = AttackProfiler.get_attack_profile(action)
192
194
  new_states.append(p)
193
195
  elif state == 'A:CVE-2015-1427 exploit':
194
196
  action = EmulationAttackerAction(
195
- id=EmulationAttackerActionId.CVE_2015_1427_EXPLOIT, name="CVE-2015-1427 exploit", cmds=[],
197
+ id=EmulationAttackerActionId.CVE_2015_1427_EXPLOIT, name="CVE-2015-1427 exploit", cmds=None,
196
198
  type=EmulationAttackerActionType.EXPLOIT,
197
199
  descr="Uses the CVE-2015-1427 vulnerability to "
198
- "get remote code execution and then sets up a SSH backdoor"
199
- "to upgrade the channel", index=-1, ips=[],
200
+ "get remote code execution and then sets up a SSH backdoor"
201
+ "to upgrade the channel", index=None, ips=[],
200
202
  action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
201
203
  p = AttackProfiler.get_attack_profile(action)
202
204
  new_states.append(p)
203
205
  elif state == 'A:DVWA SQL Injection Exploit':
204
206
  action = EmulationAttackerAction(
205
207
  id=EmulationAttackerActionId.DVWA_SQL_INJECTION, name="DVWA SQL Injection Exploit",
206
- cmds=[], type=EmulationAttackerActionType.EXPLOIT,
208
+ cmds=None, type=EmulationAttackerActionType.EXPLOIT,
207
209
  descr="Uses the DVWA SQL Injection exploit to extract secret passwords",
208
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
210
+ index=None, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
209
211
  p = AttackProfiler.get_attack_profile(action)
210
212
  new_states.append(p)
211
213
  elif state == 'A:Install tools':
212
214
  action = EmulationAttackerAction(
213
- id=EmulationAttackerActionId.INSTALL_TOOLS, name="Install tools", cmds=[],
215
+ id=EmulationAttackerActionId.INSTALL_TOOLS, name="Install tools", cmds=None,
214
216
  type=EmulationAttackerActionType.POST_EXPLOIT,
215
217
  descr="If taken root on remote machine, installs pentest tools, e.g. nmap",
216
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.PIVOTING)
218
+ index=None, ips=[], action_outcome=EmulationAttackerActionOutcome.PIVOTING)
217
219
  p = AttackProfiler.get_attack_profile(action)
218
220
  new_states.append(p)
219
221
  elif state == 'A:Network service login':
@@ -221,85 +223,86 @@ class HMMProfiler:
221
223
  id=EmulationAttackerActionId.NETWORK_SERVICE_LOGIN, name="Network service login",
222
224
  cmds=[], type=EmulationAttackerActionType.POST_EXPLOIT,
223
225
  descr="Uses known credentials to login to network services on a server",
224
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.LOGIN)
226
+ index=None, ips=None, action_outcome=EmulationAttackerActionOutcome.LOGIN)
225
227
  p = AttackProfiler.get_attack_profile(action)
226
228
  new_states.append(p)
227
229
  elif state == 'A:Ping Scan':
228
230
  action = EmulationAttackerAction(
229
231
  id=EmulationAttackerActionId.PING_SCAN_HOST, name="Ping Scan",
230
- cmds=[], type=EmulationAttackerActionType.RECON,
232
+ cmds=None, type=EmulationAttackerActionType.RECON,
231
233
  descr="A host discovery scan, it is quick because it only checks of hosts "
232
- "are up with Ping, without scanning the ports.", ips=[], index=-1,
234
+ "are up with Ping, without scanning the ports.", ips=None, index=None,
233
235
  action_outcome=EmulationAttackerActionOutcome.INFORMATION_GATHERING, backdoor=False)
234
236
  p = AttackProfiler.get_attack_profile(action)
235
237
  new_states.append(p)
236
238
  elif state == 'A:Sambacry Explolit':
237
239
  action = EmulationAttackerAction(
238
- id=EmulationAttackerActionId.SAMBACRY_EXPLOIT, name="Sambacry Explolit", cmds=[],
240
+ id=EmulationAttackerActionId.SAMBACRY_EXPLOIT, name="Sambacry Explolit", cmds=None,
239
241
  type=EmulationAttackerActionType.EXPLOIT,
240
242
  descr="Uses the sambacry shell to get remote code execution and then"
241
- "sets up a SSH backdoor to upgrade the channel",
242
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
243
+ "sets up a SSH backdoor to upgrade the channel",
244
+ index=None, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
243
245
  p = AttackProfiler.get_attack_profile(action)
244
246
  new_states.append(p)
245
247
  elif state == 'A:ShellShock Explolit':
246
248
  action = EmulationAttackerAction(
247
- id=EmulationAttackerActionId.SHELLSHOCK_EXPLOIT, name="ShellShock Exploit",
248
- cmds=[], type=EmulationAttackerActionType.EXPLOIT,
249
+ id=EmulationAttackerActionId.SHELLSHOCK_EXPLOIT, name="ShellShock Explolit",
250
+ cmds=None, type=EmulationAttackerActionType.EXPLOIT,
249
251
  descr="Uses the Shellshock exploit and curl to do remote code execution and create a backdoor",
250
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
252
+ index=None, ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
251
253
  p = AttackProfiler.get_attack_profile(action)
252
254
  new_states.append(p)
253
255
  elif state == 'A:SSH dictionary attack for username=pw':
254
256
  action = EmulationAttackerAction(
255
257
  id=EmulationAttackerActionId.SSH_SAME_USER_PASS_DICTIONARY_HOST,
256
- name="SSH dictionary attack for username=pw", cmds=[],
257
- type=EmulationAttackerActionType.EXPLOIT, index=-1,
258
+ name="SSH dictionary attack for username=pw", cmds=None,
259
+ type=EmulationAttackerActionType.EXPLOIT, index=None,
258
260
  descr="A dictionary attack that tries common passwords and usernames for SSH"
259
- "where username=password", ips=[], action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
261
+ "where username=password", ips=None,
262
+ action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
260
263
  p = AttackProfiler.get_attack_profile(action)
261
264
  new_states.append(p)
262
265
  elif state == 'A:FTP dictionary attack for username=pw':
263
266
  action = EmulationAttackerAction(
264
267
  id=EmulationAttackerActionId.FTP_SAME_USER_PASS_DICTIONARY_HOST,
265
- name="FTP dictionary attack for username=pw", cmds=[], type=EmulationAttackerActionType.EXPLOIT,
266
- index=-1, descr="A dictionary attack that tries common passwords and"
267
- "usernames for FTP where username=password", ips=[],
268
+ name="FTP dictionary attack for username=pw", cmds=None, type=EmulationAttackerActionType.EXPLOIT,
269
+ index=None, descr="A dictionary attack that tries common passwords and"
270
+ "usernames for FTP where username=password", ips=None,
268
271
  action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
269
272
  p = AttackProfiler.get_attack_profile(action)
270
273
  new_states.append(p)
271
274
  elif state == 'A:Telnet dictionary attack for username=pw':
272
275
  action = EmulationAttackerAction(
273
276
  id=EmulationAttackerActionId.TELNET_SAME_USER_PASS_DICTIONARY_HOST,
274
- name="Telnet dictionary attack for username=pw", cmds=[],
275
- type=EmulationAttackerActionType.EXPLOIT, index=-1,
277
+ name="Telnet dictionary attack for username=pw", cmds=None,
278
+ type=EmulationAttackerActionType.EXPLOIT, index=None,
276
279
  descr="A dictionary attack that tries common passwords and usernames for"
277
- "Telnet where username=password", ips=[],
280
+ "Telnet where username=password", ips=None,
278
281
  action_outcome=EmulationAttackerActionOutcome.SHELL_ACCESS)
279
282
  p = AttackProfiler.get_attack_profile(action)
280
283
  new_states.append(p)
281
284
  elif state == 'A:CVE-2010-0426 exploit':
282
285
  action = EmulationAttackerAction(
283
286
  id=EmulationAttackerActionId.CVE_2010_0426_PRIV_ESC,
284
- name="CVE-2010-0426 exploit", cmds=[], type=EmulationAttackerActionType.PRIVILEGE_ESCALATION,
287
+ name="CVE-2010-0426 exploit", cmds=None, type=EmulationAttackerActionType.PRIVILEGE_ESCALATION,
285
288
  descr="Uses the CVE-2010-0426 vulnerability to perform privilege escalation to get root access",
286
- index=-1, ips=[], action_outcome=EmulationAttackerActionOutcome.PRIVILEGE_ESCALATION_ROOT)
289
+ index=None, ips=[], action_outcome=EmulationAttackerActionOutcome.PRIVILEGE_ESCALATION_ROOT)
287
290
  p = AttackProfiler.get_attack_profile(action)
288
291
  new_states.append(p)
289
292
  elif state == 'A:TCP SYN (Stealth) Scan':
290
293
  action = EmulationAttackerAction(
291
294
  id=EmulationAttackerActionId.TCP_SYN_STEALTH_SCAN_HOST, name="TCP SYN (Stealth) Scan",
292
- cmds=[], type=EmulationAttackerActionType.RECON,
293
- descr="A stealthy and fast TCP SYN scan to detect open TCP ports on the subnet", ips=[],
294
- index=-1, action_outcome=EmulationAttackerActionOutcome.INFORMATION_GATHERING, backdoor=False)
295
+ cmds=None, type=EmulationAttackerActionType.RECON,
296
+ descr="A stealthy and fast TCP SYN scan to detect open TCP ports on the subnet", ips=None,
297
+ index=None, action_outcome=EmulationAttackerActionOutcome.INFORMATION_GATHERING, backdoor=False)
295
298
  p = AttackProfiler.get_attack_profile(action)
296
299
  new_states.append(p)
297
300
  elif state == 'ssh backdoor':
298
301
  action = EmulationAttackerAction(
299
302
  id=EmulationAttackerActionId.SSH_BACKDOOR, name="Install SSH backdoor",
300
- cmds=[], type=EmulationAttackerActionType.POST_EXPLOIT,
303
+ cmds=None, type=EmulationAttackerActionType.POST_EXPLOIT,
301
304
  descr="If taken root on remote machine, installs a ssh backdoor useful for"
302
- "upgrading telnetor weaker channels", index=-1, ips=[],
305
+ "upgrading telnetor weaker channels", index=None, ips=[],
303
306
  action_outcome=EmulationAttackerActionOutcome.PIVOTING, alt_cmds=None, backdoor=True)
304
307
  p = AttackProfiler.get_attack_profile(action)
305
308
  new_states.append(p)
@@ -307,7 +310,7 @@ class HMMProfiler:
307
310
  new_states.append(state)
308
311
 
309
312
  return new_states
310
-
313
+
311
314
  def calculate_initial_states(self, transition_matrix: List[List[float]]) -> List[float]:
312
315
  """
313
316
  Calculates the initial states probabilities based on the transition matrix.
@@ -315,7 +318,6 @@ class HMMProfiler:
315
318
  1 / (# of states)
316
319
 
317
320
  :param transition_matrix: The transition matrix
318
-
319
321
  :return: The start states probabilities
320
322
  """
321
323
  start_states = []
@@ -338,7 +340,6 @@ class HMMProfiler:
338
340
  :param emission_matrix: The emission matrix
339
341
  :param obs: The observation sequence
340
342
  :param emissions_list: The list of possible observations
341
-
342
343
  :return: The most likely sequence of hidden states
343
344
  """
344
345
  # Convert the emissions list to a numpy array, to use the where function
@@ -401,23 +402,21 @@ class HMMProfiler:
401
402
  generated based on emission matrix and transition matrix. The length of this intrusion
402
403
  sequence is given by the intrusion_length parameter.
403
404
 
404
- :param P_obs: The emission matrix
405
- :param P_states: The transition matrix
406
- :param states: The list of states
407
- :param observations: The list of observations
408
405
  :param intrusion_length: The length of the intrusion
409
- :param initial_state: The initial state
406
+ :param initial_state_index: The index of the initial state
407
+ :param seed: The seed for the random number generator
410
408
  return: The sequence of states and observations
411
409
  """
410
+
412
411
  P_obs = self.emission_matrix
413
412
  P_states = self.transition_matrix
414
413
  states = self.hidden_states
415
414
  observations = self.emission_matrix_observations
415
+
416
416
  if seed:
417
417
  np.random.seed(seed)
418
418
  obs_len = len(observations)
419
419
  states_len = len(states)
420
-
421
420
  # Return the geometric distribution of the initial state
422
421
  dist = np.random.geometric(p=P_states[initial_state_index][0], size=1000)
423
422
  T_i = round(sum(dist) / len(dist))
@@ -425,25 +424,25 @@ class HMMProfiler:
425
424
  state_seq = [states[initial_state_index]] * T_i
426
425
  obs_seq = []
427
426
  for i in range(T_i):
428
-
429
427
  o_i = np.random.choice(obs_len, p=P_obs[initial_state_index])
430
428
  obs_seq.append(observations[o_i])
431
429
 
432
430
  recon_states_sum = np.sum(P_states[initial_state_index][1:])
433
431
  recon_states = P_states[initial_state_index][1:] / recon_states_sum
434
432
 
435
- intrusion_start_state = np.random.choice(states_len - 1, p=recon_states)
433
+ intrusion_start_state = np.random.choice(states_len - 1, p=recon_states) + 1
436
434
  intrusion_start_observation = np.random.choice(obs_len, p=P_obs[intrusion_start_state])
437
435
  state_seq.append(states[intrusion_start_state])
438
436
  obs_seq.append(observations[intrusion_start_observation])
439
437
 
440
438
  s_i = intrusion_start_state
441
- for i in range(intrusion_length):
439
+ if intrusion_length == 1:
440
+ return state_seq, obs_seq
441
+ for i in range(intrusion_length - 1):
442
442
  # si ~ Ps(si | si-1)
443
443
  s_i = np.random.choice(states_len, p=P_states[s_i])
444
444
  # oi ~ Po(oi | si)
445
445
  o_i = np.random.choice(obs_len, p=P_obs[s_i])
446
446
  state_seq.append(states[s_i])
447
447
  obs_seq.append(observations[o_i])
448
-
449
448
  return state_seq, obs_seq
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csle-attack-profiler
3
- Version: 0.5.3
3
+ Version: 0.6.1
4
4
  Summary: Library with MITRE attack profiler for CSLE
5
5
  Author: Bength Pappila
6
6
  Author-email: brpa@kth.se
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Intended Audience :: Science/Research
16
16
  Requires-Python: >=3.8
17
17
  Requires-Dist: mitreattack-python ==2.0.14
18
- Requires-Dist: csle-base ==0.5.3
19
- Requires-Dist: csle-common ==0.5.3
18
+ Requires-Dist: csle-base ==0.6.1
19
+ Requires-Dist: csle-common ==0.6.1
20
20
  Provides-Extra: testing
21
21
  Requires-Dist: pytest >=6.0 ; extra == 'testing'
22
22
  Requires-Dist: pytest-cov >=2.0 ; extra == 'testing'
@@ -0,0 +1,8 @@
1
+ csle_attack_profiler/__init__.py,sha256=C7_gE0lIQJ8Wh2jgU8C8P_xyvq76bKTf0gm8bGYhMBk,37
2
+ csle_attack_profiler/__version__.py,sha256=gd3s3RotD0_KL90Tua-YkOr60Jm2C2_wvlEhAT08068,22
3
+ csle_attack_profiler/attack_profiler.py,sha256=bYqSeItJkhswronvIRFPyvf1rtvUKEWPPF4K2t1JVqE,10535
4
+ csle_attack_profiler/hmm_profiling.py,sha256=cHE2wImgBJ3xwW33S0JcTwsiccstijR9uRMeBPXIT18,24167
5
+ csle_attack_profiler-0.6.1.dist-info/METADATA,sha256=qcoiNvO6GxPrQRxB9P9IiaIxwR46ZKAIRu2nDd0_svA,2006
6
+ csle_attack_profiler-0.6.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
7
+ csle_attack_profiler-0.6.1.dist-info/top_level.txt,sha256=OuI4zvPo3MQYLQ7Dqm32oM0V8rNdwHe9tjtngx2KVtA,21
8
+ csle_attack_profiler-0.6.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- csle_attack_profiler/__init__.py,sha256=C7_gE0lIQJ8Wh2jgU8C8P_xyvq76bKTf0gm8bGYhMBk,37
2
- csle_attack_profiler/__version__.py,sha256=TFkACo7SKbVpSQl32OCSCNmy1zVX-jsQX6dAXMbWmkU,22
3
- csle_attack_profiler/attack_profiler.py,sha256=bYqSeItJkhswronvIRFPyvf1rtvUKEWPPF4K2t1JVqE,10535
4
- csle_attack_profiler/hmm_profiling.py,sha256=6xlvv3Q84E47AYEwH1c89-oAaJb89XJXcNnmS-aO9qg,24128
5
- csle_attack_profiler-0.5.3.dist-info/METADATA,sha256=KebzwlqGaKxWGL2WM3jG_wBXEu5lx7Pvi2EPd_A1PaM,2006
6
- csle_attack_profiler-0.5.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
7
- csle_attack_profiler-0.5.3.dist-info/top_level.txt,sha256=OuI4zvPo3MQYLQ7Dqm32oM0V8rNdwHe9tjtngx2KVtA,21
8
- csle_attack_profiler-0.5.3.dist-info/RECORD,,