mal-toolbox 0.3.8__tar.gz → 0.3.10__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.
- {mal_toolbox-0.3.8/mal_toolbox.egg-info → mal_toolbox-0.3.10}/PKG-INFO +1 -1
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10/mal_toolbox.egg-info}/PKG-INFO +1 -1
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/__init__.py +2 -2
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/attacker.py +4 -35
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/attackgraph.py +9 -15
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/model.py +0 -1
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/pyproject.toml +1 -1
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/tests/test_model.py +0 -3
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/AUTHORS +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/LICENSE +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/README.md +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/mal_toolbox.egg-info/SOURCES.txt +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/mal_toolbox.egg-info/dependency_links.txt +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/mal_toolbox.egg-info/entry_points.txt +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/mal_toolbox.egg-info/requires.txt +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/mal_toolbox.egg-info/top_level.txt +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/__main__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/analyzers/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/analyzers/apriori.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/node.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/attackgraph/query.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/exceptions.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/file_utils.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/ingestors/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/ingestors/neo4j.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/language/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/language/compiler/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/language/compiler/mal_lexer.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/language/compiler/mal_parser.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/language/languagegraph.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/translators/__init__.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/translators/securicad.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/maltoolbox/translators/updater.py +0 -0
- {mal_toolbox-0.3.8 → mal_toolbox-0.3.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mal-toolbox
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.10
|
|
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.
|
|
3
|
+
Version: 0.3.10
|
|
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,5 +1,5 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# MAL Toolbox v0.3.
|
|
2
|
+
# MAL Toolbox v0.3.10
|
|
3
3
|
# Copyright 2025, 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.3.
|
|
24
|
+
__version__ = "0.3.10"
|
|
25
25
|
__authors__ = [
|
|
26
26
|
"Andrei Buhaiu",
|
|
27
27
|
"Giuseppe Nebbione",
|
|
@@ -3,7 +3,6 @@ MAL-Toolbox Attack Graph Attacker Class
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
|
-
import copy
|
|
7
6
|
import logging
|
|
8
7
|
|
|
9
8
|
from typing import Optional
|
|
@@ -18,15 +17,15 @@ class Attacker:
|
|
|
18
17
|
def __init__(
|
|
19
18
|
self,
|
|
20
19
|
name: str,
|
|
21
|
-
entry_points: set[AttackGraphNode],
|
|
22
|
-
reached_attack_steps: set[AttackGraphNode],
|
|
20
|
+
entry_points: Optional[set[AttackGraphNode]] = None,
|
|
21
|
+
reached_attack_steps: Optional[set[AttackGraphNode]] = None,
|
|
23
22
|
attacker_id: Optional[int] = None
|
|
24
23
|
):
|
|
25
24
|
self.name = name
|
|
26
25
|
self.id = attacker_id
|
|
27
|
-
self.entry_points = entry_points
|
|
26
|
+
self.entry_points = entry_points or set()
|
|
28
27
|
self.reached_attack_steps: set[AttackGraphNode] = set()
|
|
29
|
-
for node in reached_attack_steps:
|
|
28
|
+
for node in reached_attack_steps or {}:
|
|
30
29
|
self.compromise(node)
|
|
31
30
|
|
|
32
31
|
def to_dict(self) -> dict:
|
|
@@ -49,36 +48,6 @@ class Attacker:
|
|
|
49
48
|
def __repr__(self) -> str:
|
|
50
49
|
return f'Attacker(name: "{self.name}", id: {self.id})'
|
|
51
50
|
|
|
52
|
-
def __deepcopy__(self, memo) -> Attacker:
|
|
53
|
-
"""Deep copy an Attacker
|
|
54
|
-
The deepcopy will copy over attacker specific information, name and
|
|
55
|
-
id, but it will not copy relations to attack graph nodes, reached
|
|
56
|
-
attack steps or entry points. These references should be recreated
|
|
57
|
-
when deepcopying the attack graph itself.
|
|
58
|
-
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
# Check if the object is already in the memo dictionary
|
|
62
|
-
if id(self) in memo:
|
|
63
|
-
return memo[id(self)]
|
|
64
|
-
|
|
65
|
-
copied_attacker = Attacker(
|
|
66
|
-
name = self.name,
|
|
67
|
-
attacker_id = self.id,
|
|
68
|
-
entry_points = set(),
|
|
69
|
-
reached_attack_steps = set()
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
# Remember that self was already copied
|
|
73
|
-
memo[id(self)] = copied_attacker
|
|
74
|
-
|
|
75
|
-
copied_attacker.entry_points = copy.deepcopy(
|
|
76
|
-
self.entry_points, memo = memo)
|
|
77
|
-
copied_attacker.reached_attack_steps = copy.deepcopy(
|
|
78
|
-
self.reached_attack_steps, memo = memo)
|
|
79
|
-
|
|
80
|
-
return copied_attacker
|
|
81
|
-
|
|
82
51
|
def compromise(self, node: AttackGraphNode) -> None:
|
|
83
52
|
"""
|
|
84
53
|
Have the attacker compromise the node given as a parameter.
|
|
@@ -249,11 +249,7 @@ class AttackGraph():
|
|
|
249
249
|
_ag_node.parents.add(parent)
|
|
250
250
|
|
|
251
251
|
for attacker in serialized_attackers.values():
|
|
252
|
-
ag_attacker = Attacker(
|
|
253
|
-
name = attacker['name'],
|
|
254
|
-
entry_points = set(),
|
|
255
|
-
reached_attack_steps = set()
|
|
256
|
-
)
|
|
252
|
+
ag_attacker = Attacker(name = attacker['name'])
|
|
257
253
|
attack_graph.add_attacker(
|
|
258
254
|
attacker = ag_attacker,
|
|
259
255
|
attacker_id = int(attacker['id']),
|
|
@@ -330,11 +326,7 @@ class AttackGraph():
|
|
|
330
326
|
logger.error(msg)
|
|
331
327
|
raise AttackGraphException(msg)
|
|
332
328
|
|
|
333
|
-
attacker = Attacker(
|
|
334
|
-
name = attacker_info.name,
|
|
335
|
-
entry_points = set(),
|
|
336
|
-
reached_attack_steps = set()
|
|
337
|
-
)
|
|
329
|
+
attacker = Attacker(name = attacker_info.name)
|
|
338
330
|
self.add_attacker(attacker)
|
|
339
331
|
|
|
340
332
|
for (asset, attack_steps) in attacker_info.entry_points:
|
|
@@ -497,11 +489,13 @@ class AttackGraph():
|
|
|
497
489
|
target_assets,
|
|
498
490
|
expr_chain.left_link
|
|
499
491
|
)
|
|
500
|
-
rh_targets =
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
492
|
+
rh_targets = set()
|
|
493
|
+
for lh_target in lh_targets:
|
|
494
|
+
rh_targets |= self._follow_expr_chain(
|
|
495
|
+
model,
|
|
496
|
+
{lh_target},
|
|
497
|
+
expr_chain.right_link
|
|
498
|
+
)
|
|
505
499
|
return rh_targets
|
|
506
500
|
|
|
507
501
|
case _:
|
|
@@ -464,7 +464,6 @@ class Model():
|
|
|
464
464
|
attackers_info = serialized_object['attackers']
|
|
465
465
|
for attacker_id in attackers_info:
|
|
466
466
|
attacker = AttackerAttachment(name = attackers_info[attacker_id]['name'])
|
|
467
|
-
attacker.entry_points = []
|
|
468
467
|
for asset_name, entry_points_dict in \
|
|
469
468
|
attackers_info[attacker_id]['entry_points'].items():
|
|
470
469
|
target_asset = model.get_asset_by_id(
|
|
@@ -455,14 +455,12 @@ def test_model_add_attacker(model: Model):
|
|
|
455
455
|
|
|
456
456
|
# Add attacker 1
|
|
457
457
|
attacker1 = AttackerAttachment()
|
|
458
|
-
attacker1.entry_points = []
|
|
459
458
|
model.add_attacker(attacker1)
|
|
460
459
|
assert attacker1.name == f'Attacker:{attacker1.id}'
|
|
461
460
|
|
|
462
461
|
# Add attacker 2 with explicit id set (can be duplicate id)
|
|
463
462
|
attacker2_id = attacker1.id
|
|
464
463
|
attacker2 = AttackerAttachment()
|
|
465
|
-
attacker2.entry_points = []
|
|
466
464
|
model.add_attacker(attacker2, attacker_id=attacker2_id)
|
|
467
465
|
|
|
468
466
|
# Add attacker 2 with explicit id set (can be duplicate id)
|
|
@@ -515,7 +513,6 @@ def test_model_get_attacker_by_id(model: Model):
|
|
|
515
513
|
|
|
516
514
|
# Add attacker 1
|
|
517
515
|
attacker1 = AttackerAttachment()
|
|
518
|
-
attacker1.entry_points = []
|
|
519
516
|
model.add_attacker(attacker1)
|
|
520
517
|
|
|
521
518
|
assert attacker1.id is not None
|
|
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
|
|
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
|
|
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
|