mal-toolbox 0.3.4__tar.gz → 0.3.6__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 (35) hide show
  1. {mal_toolbox-0.3.4/mal_toolbox.egg-info → mal_toolbox-0.3.6}/PKG-INFO +1 -1
  2. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6/mal_toolbox.egg-info}/PKG-INFO +1 -1
  3. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/__init__.py +3 -3
  4. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/attacker.py +4 -2
  5. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/model.py +14 -17
  6. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/pyproject.toml +1 -1
  7. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/tests/test_model.py +9 -1
  8. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/AUTHORS +0 -0
  9. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/LICENSE +0 -0
  10. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/README.md +0 -0
  11. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/mal_toolbox.egg-info/SOURCES.txt +0 -0
  12. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/mal_toolbox.egg-info/dependency_links.txt +0 -0
  13. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/mal_toolbox.egg-info/entry_points.txt +0 -0
  14. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/mal_toolbox.egg-info/requires.txt +0 -0
  15. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/mal_toolbox.egg-info/top_level.txt +0 -0
  16. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/__main__.py +0 -0
  17. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/__init__.py +0 -0
  18. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/analyzers/__init__.py +0 -0
  19. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/analyzers/apriori.py +0 -0
  20. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/attackgraph.py +0 -0
  21. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/node.py +0 -0
  22. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/attackgraph/query.py +0 -0
  23. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/exceptions.py +0 -0
  24. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/file_utils.py +0 -0
  25. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/ingestors/__init__.py +0 -0
  26. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/ingestors/neo4j.py +0 -0
  27. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/language/__init__.py +0 -0
  28. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/language/compiler/__init__.py +0 -0
  29. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/language/compiler/mal_lexer.py +0 -0
  30. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/language/compiler/mal_parser.py +0 -0
  31. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/language/languagegraph.py +0 -0
  32. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/translators/__init__.py +0 -0
  33. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/translators/securicad.py +0 -0
  34. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/maltoolbox/translators/updater.py +0 -0
  35. {mal_toolbox-0.3.4 → mal_toolbox-0.3.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mal-toolbox
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: A collection of tools used to create MAL models and attack graphs.
5
5
  Author-email: Andrei Buhaiu <buhaiu@kth.se>, Joakim Loxdal <loxdal@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Giuseppe Nebbione <nebbione@kth.se>
6
6
  License: Apache Software License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mal-toolbox
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: A collection of tools used to create MAL models and attack graphs.
5
5
  Author-email: Andrei Buhaiu <buhaiu@kth.se>, Joakim Loxdal <loxdal@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Giuseppe Nebbione <nebbione@kth.se>
6
6
  License: Apache Software License
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # MAL Toolbox v0.3.4
3
- # Copyright 2024, Andrei Buhaiu.
2
+ # MAL Toolbox v0.3.6
3
+ # Copyright 2025, Andrei Buhaiu.
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ MAL-Toolbox Framework
21
21
  """
22
22
 
23
23
  __title__ = "maltoolbox"
24
- __version__ = "0.3.4"
24
+ __version__ = "0.3.6"
25
25
  __authors__ = [
26
26
  "Andrei Buhaiu",
27
27
  "Giuseppe Nebbione",
@@ -23,9 +23,11 @@ class Attacker:
23
23
  attacker_id: Optional[int] = None
24
24
  ):
25
25
  self.name = name
26
- self.entry_points = entry_points
27
- self.reached_attack_steps = reached_attack_steps
28
26
  self.id = attacker_id
27
+ self.entry_points = entry_points
28
+ self.reached_attack_steps: set[AttackGraphNode] = set()
29
+ for node in reached_attack_steps:
30
+ self.compromise(node)
29
31
 
30
32
  def to_dict(self) -> dict:
31
33
  attacker_dict: dict = {
@@ -152,11 +152,6 @@ class Model():
152
152
  self.lang_graph = lang_graph
153
153
  self.maltoolbox_version: str = mt_version
154
154
 
155
- # Below sets used to check for duplicate names or ids,
156
- # better for optimization than iterating over all assets
157
- self.asset_ids: set[int] = set()
158
- self.asset_names: set[str] = set()
159
-
160
155
 
161
156
  def add_asset(
162
157
  self,
@@ -192,16 +187,15 @@ class Model():
192
187
 
193
188
  # Set asset ID and check for duplicates
194
189
  asset_id = asset_id or self.next_id
195
- if asset_id in self.asset_ids:
190
+ if asset_id in self.assets:
196
191
  raise ValueError(f'Asset index {asset_id} already in use.')
197
- self.asset_ids.add(asset_id)
198
192
 
199
193
  self.next_id = max(asset_id + 1, self.next_id)
200
194
 
201
195
  if not name:
202
196
  name = asset_type + ':' + str(asset_id)
203
197
  else:
204
- if name in self.asset_names:
198
+ if name in self._name_to_asset:
205
199
  if allow_duplicate_names:
206
200
  name = name + ':' + str(asset_id)
207
201
  else:
@@ -209,7 +203,6 @@ class Model():
209
203
  f'Asset name {name} is a duplicate'
210
204
  ' and we do not allow duplicates.'
211
205
  )
212
- self.asset_names.add(name)
213
206
 
214
207
  lg_asset = self.lang_graph.assets[asset_type]
215
208
 
@@ -252,7 +245,10 @@ class Model():
252
245
  )
253
246
 
254
247
  # First remove all of the associated assets
255
- for fieldname, assoc_assets in asset.associated_assets.items():
248
+ # We can not remove from the dict while iterating over it
249
+ # so we first have to copy the keys and then remove those assets
250
+ associated_fieldnames = dict(asset.associated_assets)
251
+ for fieldname, assoc_assets in associated_fieldnames.items():
256
252
  asset.remove_associated_assets(fieldname, assoc_assets)
257
253
 
258
254
  # Also remove all of the entry points
@@ -656,17 +652,13 @@ class ModelAsset:
656
652
  other_fieldname, set()
657
653
  ).add(self)
658
654
 
659
- def remove_associated_assets(self, fieldname: str,
660
- assets: set[ModelAsset]):
655
+ def remove_associated_assets(
656
+ self, fieldname: str, assets: set[ModelAsset]):
661
657
  """ Remove the assets provided as a parameter from the set of
662
658
  associated assets dictionary entry corresponding to the fieldname
663
659
  parameter.
664
660
  """
665
- self._associated_assets[fieldname] -= set(assets)
666
- if len(self._associated_assets[fieldname]) == 0:
667
- del self._associated_assets[fieldname]
668
-
669
- # Also remove this asset to the associated assets' dictionaries
661
+ # Remove this asset from its associated assets' dictionaries
670
662
  lg_assoc = self.lg_asset.associations[fieldname]
671
663
  other_fieldname = lg_assoc.get_opposite_fieldname(fieldname)
672
664
  for asset in assets:
@@ -674,6 +666,11 @@ class ModelAsset:
674
666
  if len(asset._associated_assets[other_fieldname]) == 0:
675
667
  del asset._associated_assets[other_fieldname]
676
668
 
669
+ # Remove associated assets from this asset
670
+ self._associated_assets[fieldname] -= set(assets)
671
+ if len(self._associated_assets[fieldname]) == 0:
672
+ del self._associated_assets[fieldname]
673
+
677
674
 
678
675
  @property
679
676
  def associated_assets(self):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mal-toolbox"
3
- version = "0.3.4"
3
+ version = "0.3.6"
4
4
  authors = [
5
5
  { name="Andrei Buhaiu", email="buhaiu@kth.se" },
6
6
  { name="Joakim Loxdal", email="loxdal@kth.se" },
@@ -230,16 +230,23 @@ def test_model_add_asset_duplicate_name(model: Model):
230
230
  assert len(model.assets) == 2
231
231
 
232
232
 
233
- def test_model_remove_asset(model: Model):
233
+ def test_model_remove_asset_with_association(model: Model):
234
234
  """Remove assets from a model"""
235
235
 
236
236
  # Add two program assets to the model
237
237
  asset1 = model.add_asset(asset_type = 'Application')
238
238
  asset2 = model.add_asset(asset_type = 'Application')
239
+ asset1.add_associated_assets('hostApp', {asset2})
239
240
 
241
+ assert asset1.associated_assets == {'hostApp': {asset2}}
242
+ assert asset2.associated_assets == {'appExecutedApps': {asset1}}
240
243
  num_assets_before = len(model.assets)
244
+
241
245
  model.remove_asset(asset1)
242
246
 
247
+ assert asset1.associated_assets == {}
248
+ assert asset2.associated_assets == {}
249
+
243
250
  # Make sure asset asset1 was deleted, but asset2 still exists
244
251
  assert asset1 not in model.assets.values()
245
252
  assert asset2 in model.assets.values()
@@ -362,6 +369,7 @@ def test_model_remove_associated_asset(model: Model):
362
369
  # removed from assets and model
363
370
  asset1.remove_associated_assets(
364
371
  fieldname = 'appExecutedApps', assets = {asset2})
372
+
365
373
  assert 'appExecutedApps' not in asset1.associated_assets
366
374
  assert 'hostApp' not in asset2.associated_assets
367
375
 
File without changes
File without changes
File without changes
File without changes