csle-attack-profiler 0.5.3__tar.gz → 0.6.1__tar.gz
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.
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/PKG-INFO +1 -1
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/setup.cfg +2 -2
- csle_attack_profiler-0.6.1/src/csle_attack_profiler/__version__.py +1 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler/hmm_profiling.py +57 -58
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/PKG-INFO +1 -1
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/requires.txt +2 -2
- csle_attack_profiler-0.5.3/src/csle_attack_profiler/__version__.py +0 -1
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/README.md +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/pyproject.toml +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/setup.py +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler/__init__.py +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler/attack_profiler.py +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/SOURCES.txt +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/dependency_links.txt +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/not-zip-safe +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler.egg-info/top_level.txt +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/tests/test_attack_profiler.py +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/tests/test_hmm_profiler.py +0 -0
- {csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/tests/test_kullback.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.6.1'
|
{csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler/hmm_profiling.py
RENAMED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
:
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
199
|
-
|
|
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=
|
|
208
|
+
cmds=None, type=EmulationAttackerActionType.EXPLOIT,
|
|
207
209
|
descr="Uses the DVWA SQL Injection exploit to extract secret passwords",
|
|
208
|
-
index
|
|
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
|
|
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
|
|
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=
|
|
232
|
+
cmds=None, type=EmulationAttackerActionType.RECON,
|
|
231
233
|
descr="A host discovery scan, it is quick because it only checks of hosts "
|
|
232
|
-
|
|
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
|
-
|
|
242
|
-
index
|
|
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
|
|
248
|
-
cmds=
|
|
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
|
|
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
|
|
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
|
-
|
|
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=
|
|
266
|
-
index
|
|
267
|
-
|
|
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
|
|
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
|
-
|
|
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=
|
|
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
|
|
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=
|
|
293
|
-
descr="A stealthy and fast TCP SYN scan to detect open TCP ports on the subnet", ips=
|
|
294
|
-
index
|
|
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=
|
|
303
|
+
cmds=None, type=EmulationAttackerActionType.POST_EXPLOIT,
|
|
301
304
|
descr="If taken root on remote machine, installs a ssh backdoor useful for"
|
|
302
|
-
|
|
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
|
|
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
|
-
|
|
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 +0,0 @@
|
|
|
1
|
-
__version__ = '0.5.3'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{csle_attack_profiler-0.5.3 → csle_attack_profiler-0.6.1}/src/csle_attack_profiler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|