mal-toolbox 0.1.11__tar.gz → 0.2.0__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.
Files changed (41) hide show
  1. {mal_toolbox-0.1.11/mal_toolbox.egg-info → mal_toolbox-0.2.0}/PKG-INFO +2 -2
  2. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0/mal_toolbox.egg-info}/PKG-INFO +2 -2
  3. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/__init__.py +2 -2
  4. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/analyzers/apriori.py +61 -1
  5. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/attackgraph.py +294 -245
  6. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/node.py +23 -7
  7. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/file_utils.py +6 -2
  8. mal_toolbox-0.2.0/maltoolbox/language/__init__.py +8 -0
  9. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/language/classes_factory.py +86 -70
  10. mal_toolbox-0.2.0/maltoolbox/language/languagegraph.py +1731 -0
  11. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/model.py +44 -35
  12. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/pyproject.toml +1 -1
  13. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/tests/test_model.py +53 -45
  14. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/tests/test_wrappers.py +1 -1
  15. mal_toolbox-0.1.11/maltoolbox/language/__init__.py +0 -4
  16. mal_toolbox-0.1.11/maltoolbox/language/languagegraph.py +0 -1184
  17. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/AUTHORS +0 -0
  18. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/LICENSE +0 -0
  19. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/README.md +0 -0
  20. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/mal_toolbox.egg-info/SOURCES.txt +0 -0
  21. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/mal_toolbox.egg-info/dependency_links.txt +0 -0
  22. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/mal_toolbox.egg-info/requires.txt +0 -0
  23. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/mal_toolbox.egg-info/top_level.txt +0 -0
  24. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/__main__.py +0 -0
  25. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/__init__.py +0 -0
  26. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/analyzers/__init__.py +0 -0
  27. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/attacker.py +0 -0
  28. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/attackgraph/query.py +0 -0
  29. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/default.conf +0 -0
  30. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/exceptions.py +0 -0
  31. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/ingestors/__init__.py +0 -0
  32. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/ingestors/neo4j.py +0 -0
  33. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/language/compiler/__init__.py +0 -0
  34. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/language/compiler/mal_lexer.py +0 -0
  35. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/language/compiler/mal_parser.py +0 -0
  36. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/language/compiler/mal_visitor.py +0 -0
  37. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/translators/__init__.py +0 -0
  38. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/translators/securicad.py +0 -0
  39. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/translators/updater.py +0 -0
  40. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/maltoolbox/wrappers.py +0 -0
  41. {mal_toolbox-0.1.11 → mal_toolbox-0.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: mal-toolbox
3
- Version: 0.1.11
3
+ Version: 0.2.0
4
4
  Summary: A collection of tools used to create MAL models and attack graphs.
5
5
  Author-email: Andrei Buhaiu <buhaiu@kth.se>, Giuseppe Nebbione <nebbione@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Joakim Loxdal <loxdal@kth.se>
6
6
  License: Apache Software License
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: mal-toolbox
3
- Version: 0.1.11
3
+ Version: 0.2.0
4
4
  Summary: A collection of tools used to create MAL models and attack graphs.
5
5
  Author-email: Andrei Buhaiu <buhaiu@kth.se>, Giuseppe Nebbione <nebbione@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Joakim Loxdal <loxdal@kth.se>
6
6
  License: Apache Software License
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # MAL Toolbox v0.1.11
2
+ # MAL Toolbox v0.2.0
3
3
  # Copyright 2024, Andrei Buhaiu.
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,7 @@ MAL-Toolbox Framework
21
21
  """
22
22
 
23
23
  __title__ = 'maltoolbox'
24
- __version__ = '0.1.11'
24
+ __version__ = '0.2.0'
25
25
  __authors__ = ['Andrei Buhaiu',
26
26
  'Giuseppe Nebbione',
27
27
  'Nikolaos Kakouros',
@@ -12,6 +12,7 @@ Currently these are:
12
12
  """
13
13
 
14
14
  from __future__ import annotations
15
+ from typing import Optional
15
16
  import logging
16
17
 
17
18
  from ..attackgraph import AttackGraph
@@ -41,6 +42,7 @@ def propagate_viability_from_node(node: AttackGraphNode) -> None:
41
42
  if child.is_viable != original_value:
42
43
  propagate_viability_from_node(child)
43
44
 
45
+
44
46
  def propagate_necessity_from_node(node: AttackGraphNode) -> None:
45
47
  """
46
48
  Arguments:
@@ -53,11 +55,13 @@ def propagate_necessity_from_node(node: AttackGraphNode) -> None:
53
55
  )
54
56
 
55
57
  if node.ttc and 'name' in node.ttc:
56
- if node.ttc['name'] not in ['Enabled', 'Disabled']:
58
+ if node.ttc['name'] not in ['Enabled', 'Disabled', 'Instant']:
57
59
  # Do not propagate unnecessary state from nodes that have a TTC
58
60
  # probability distribution associated with them.
59
61
  # TODO: Evaluate this more carefully, how do we want to have TTCs
60
62
  # impact necessity and viability.
63
+ # TODO: Have this condition be any probability that has a
64
+ # Bernoulli component
61
65
  return
62
66
 
63
67
  for child in node.children:
@@ -108,6 +112,7 @@ def evaluate_viability(node: AttackGraphNode) -> None:
108
112
  logger.error(msg, node.full_name, node.id, node.type)
109
113
  raise ValueError(msg % (node.full_name, node.id, node.type))
110
114
 
115
+
111
116
  def evaluate_necessity(node: AttackGraphNode) -> None:
112
117
  """
113
118
  Arguments:
@@ -141,6 +146,7 @@ def evaluate_necessity(node: AttackGraphNode) -> None:
141
146
  logger.error(msg, node.full_name, node.id, node.type)
142
147
  raise ValueError(msg % (node.full_name, node.id, node.type))
143
148
 
149
+
144
150
  def evaluate_viability_and_necessity(node: AttackGraphNode) -> None:
145
151
  """
146
152
  Arguments:
@@ -149,6 +155,7 @@ def evaluate_viability_and_necessity(node: AttackGraphNode) -> None:
149
155
  evaluate_viability(node)
150
156
  evaluate_necessity(node)
151
157
 
158
+
152
159
  def calculate_viability_and_necessity(graph: AttackGraph) -> None:
153
160
  """
154
161
  Arguments:
@@ -163,13 +170,66 @@ def calculate_viability_and_necessity(graph: AttackGraph) -> None:
163
170
  if not node.is_necessary:
164
171
  propagate_necessity_from_node(node)
165
172
 
173
+
166
174
  def prune_unviable_and_unnecessary_nodes(graph: AttackGraph) -> None:
167
175
  """
168
176
  Arguments:
169
177
  graph - the attack graph for which we wish to remove the
170
178
  the nodes which are not viable or necessary.
171
179
  """
180
+ logger.debug('Prune unviable and unnecessary nodes from the attack graph.')
172
181
  for node in graph.nodes:
173
182
  if (node.type == 'or' or node.type == 'and') and \
174
183
  (not node.is_viable or not node.is_necessary):
175
184
  graph.remove_node(node)
185
+
186
+
187
+ def propagate_viability_from_unviable_node(
188
+ unviable_node: AttackGraphNode,
189
+ ) -> list[AttackGraphNode]:
190
+ """
191
+ Update viability of nodes affected by newly enabled defense
192
+ `unviable_node` in the graph and return any attack steps
193
+ that are no longer viable because of it.
194
+
195
+ Propagate recursively via children as long as changes occur.
196
+
197
+ Arguments:
198
+ unviable_node - the node to propagate viability from
199
+
200
+ Returns:
201
+ attack_steps_made_unviable - list of the attack steps that have been
202
+ made unviable by a defense enabled in the
203
+ current step. Builds up recursively.
204
+ """
205
+
206
+ attack_steps_made_unviable = []
207
+
208
+ logger.debug(
209
+ 'Update viability for node "%s"(%d)',
210
+ unviable_node.full_name,
211
+ unviable_node.id
212
+ )
213
+
214
+ assert not unviable_node.is_viable, (
215
+ "propagate_viability_from_unviable_node should not be called"
216
+ f" on viable node {unviable_node.full_name}"
217
+ )
218
+
219
+ if unviable_node.type in ('and', 'or'):
220
+ attack_steps_made_unviable.append(unviable_node)
221
+
222
+ for child in unviable_node.children:
223
+ original_value = child.is_viable
224
+ if child.type == 'or':
225
+ child.is_viable = False
226
+ for parent in child.parents:
227
+ child.is_viable = child.is_viable or parent.is_viable
228
+ if child.type == 'and':
229
+ child.is_viable = False
230
+
231
+ if child.is_viable != original_value:
232
+ attack_steps_made_unviable += \
233
+ propagate_viability_from_unviable_node(child)
234
+
235
+ return attack_steps_made_unviable