mal-toolbox 1.2.1__py3-none-any.whl → 2.1.0__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.
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/METADATA +8 -75
- mal_toolbox-2.1.0.dist-info/RECORD +51 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/WHEEL +1 -1
- maltoolbox/__init__.py +2 -2
- maltoolbox/attackgraph/__init__.py +2 -2
- maltoolbox/attackgraph/attackgraph.py +121 -549
- maltoolbox/attackgraph/factories.py +68 -0
- maltoolbox/attackgraph/file_utils.py +0 -0
- maltoolbox/attackgraph/generate.py +338 -0
- maltoolbox/attackgraph/node.py +1 -0
- maltoolbox/attackgraph/node_getters.py +36 -0
- maltoolbox/attackgraph/ttcs.py +28 -0
- maltoolbox/language/__init__.py +2 -2
- maltoolbox/language/compiler/__init__.py +4 -499
- maltoolbox/language/compiler/distributions.py +158 -0
- maltoolbox/language/compiler/exceptions.py +37 -0
- maltoolbox/language/compiler/lang.py +5 -0
- maltoolbox/language/compiler/mal_analyzer.py +920 -0
- maltoolbox/language/compiler/mal_compiler.py +1071 -0
- maltoolbox/language/detector.py +43 -0
- maltoolbox/language/expression_chain.py +218 -0
- maltoolbox/language/language_graph_asset.py +180 -0
- maltoolbox/language/language_graph_assoc.py +147 -0
- maltoolbox/language/language_graph_attack_step.py +129 -0
- maltoolbox/language/language_graph_builder.py +282 -0
- maltoolbox/language/language_graph_loaders.py +7 -0
- maltoolbox/language/language_graph_lookup.py +140 -0
- maltoolbox/language/language_graph_serialization.py +5 -0
- maltoolbox/language/languagegraph.py +244 -1536
- maltoolbox/language/step_expression_processor.py +491 -0
- mal_toolbox-1.2.1.dist-info/RECORD +0 -33
- maltoolbox/language/compiler/mal_lexer.py +0 -232
- maltoolbox/language/compiler/mal_parser.py +0 -3159
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/entry_points.txt +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/licenses/AUTHORS +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/licenses/LICENSE +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from maltoolbox.language.expression_chain import ExpressionsChain
|
|
7
|
+
from maltoolbox.language.language_graph_lookup import get_var_expr_for_asset
|
|
8
|
+
from maltoolbox.language.language_graph_asset import LanguageGraphAsset
|
|
9
|
+
from maltoolbox.exceptions import (
|
|
10
|
+
LanguageGraphException,
|
|
11
|
+
LanguageGraphAssociationError,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
def process_attack_step_expression(
|
|
17
|
+
target_asset: LanguageGraphAsset,
|
|
18
|
+
step_expression: dict[str, Any]
|
|
19
|
+
) -> tuple[
|
|
20
|
+
LanguageGraphAsset,
|
|
21
|
+
None,
|
|
22
|
+
str
|
|
23
|
+
]:
|
|
24
|
+
"""The attack step expression just adds the name of the attack
|
|
25
|
+
step. All other step expressions only modify the target
|
|
26
|
+
asset and parent associations chain.
|
|
27
|
+
"""
|
|
28
|
+
return (
|
|
29
|
+
target_asset,
|
|
30
|
+
None,
|
|
31
|
+
step_expression['name']
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def process_set_operation_step_expression(
|
|
35
|
+
assets: dict[str, LanguageGraphAsset],
|
|
36
|
+
target_asset: LanguageGraphAsset,
|
|
37
|
+
expr_chain: ExpressionsChain | None,
|
|
38
|
+
step_expression: dict[str, Any],
|
|
39
|
+
lang_spec
|
|
40
|
+
) -> tuple[
|
|
41
|
+
LanguageGraphAsset,
|
|
42
|
+
ExpressionsChain,
|
|
43
|
+
None
|
|
44
|
+
]:
|
|
45
|
+
"""The set operators are used to combine the left hand and right
|
|
46
|
+
hand targets accordingly.
|
|
47
|
+
"""
|
|
48
|
+
lh_target_asset, lh_expr_chain, _ = process_step_expression(
|
|
49
|
+
assets,
|
|
50
|
+
target_asset,
|
|
51
|
+
expr_chain,
|
|
52
|
+
step_expression['lhs'],
|
|
53
|
+
lang_spec
|
|
54
|
+
)
|
|
55
|
+
rh_target_asset, rh_expr_chain, _ = process_step_expression(
|
|
56
|
+
assets,
|
|
57
|
+
target_asset,
|
|
58
|
+
expr_chain,
|
|
59
|
+
step_expression['rhs'],
|
|
60
|
+
lang_spec
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
assert lh_target_asset, (
|
|
64
|
+
f"No lh target in step expression {step_expression}"
|
|
65
|
+
)
|
|
66
|
+
assert rh_target_asset, (
|
|
67
|
+
f"No rh target in step expression {step_expression}"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if not lh_target_asset.get_all_common_superassets(rh_target_asset):
|
|
71
|
+
raise ValueError(
|
|
72
|
+
"Set operation attempted between targets that do not share "
|
|
73
|
+
f"any common superassets: {lh_target_asset.name} "
|
|
74
|
+
f"and {rh_target_asset.name}!"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
new_expr_chain = ExpressionsChain(
|
|
78
|
+
type=step_expression['type'],
|
|
79
|
+
left_link=lh_expr_chain,
|
|
80
|
+
right_link=rh_expr_chain
|
|
81
|
+
)
|
|
82
|
+
return (
|
|
83
|
+
lh_target_asset,
|
|
84
|
+
new_expr_chain,
|
|
85
|
+
None
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def process_variable_step_expression(
|
|
89
|
+
assets: dict[str, LanguageGraphAsset],
|
|
90
|
+
target_asset: LanguageGraphAsset,
|
|
91
|
+
step_expression: dict[str, Any],
|
|
92
|
+
lang_spec
|
|
93
|
+
) -> tuple[
|
|
94
|
+
LanguageGraphAsset,
|
|
95
|
+
ExpressionsChain,
|
|
96
|
+
None
|
|
97
|
+
]:
|
|
98
|
+
|
|
99
|
+
var_name = step_expression['name']
|
|
100
|
+
var_target_asset, var_expr_chain = (
|
|
101
|
+
resolve_variable(assets, target_asset, var_name, lang_spec)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if var_expr_chain is None:
|
|
105
|
+
raise LookupError(
|
|
106
|
+
f'Failed to find variable "{step_expression["name"]}" '
|
|
107
|
+
f'for {target_asset.name}',
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
var_target_asset,
|
|
112
|
+
var_expr_chain,
|
|
113
|
+
None
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def process_field_step_expression(
|
|
117
|
+
target_asset: LanguageGraphAsset,
|
|
118
|
+
step_expression: dict[str, Any]
|
|
119
|
+
) -> tuple[
|
|
120
|
+
LanguageGraphAsset,
|
|
121
|
+
ExpressionsChain,
|
|
122
|
+
None
|
|
123
|
+
]:
|
|
124
|
+
"""Change the target asset from the current one to the associated
|
|
125
|
+
asset given the specified field name and add the parent
|
|
126
|
+
fieldname and association to the parent associations chain.
|
|
127
|
+
"""
|
|
128
|
+
fieldname = step_expression['name']
|
|
129
|
+
|
|
130
|
+
if target_asset is None:
|
|
131
|
+
raise ValueError(
|
|
132
|
+
f'Missing target asset for field "{fieldname}"!'
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
new_target_asset = None
|
|
136
|
+
for association in target_asset.associations.values():
|
|
137
|
+
if (association.left_field.fieldname == fieldname and
|
|
138
|
+
target_asset.is_subasset_of(
|
|
139
|
+
association.right_field.asset)):
|
|
140
|
+
new_target_asset = association.left_field.asset
|
|
141
|
+
|
|
142
|
+
if (association.right_field.fieldname == fieldname and
|
|
143
|
+
target_asset.is_subasset_of(
|
|
144
|
+
association.left_field.asset)):
|
|
145
|
+
new_target_asset = association.right_field.asset
|
|
146
|
+
|
|
147
|
+
if new_target_asset:
|
|
148
|
+
new_expr_chain = ExpressionsChain(
|
|
149
|
+
type='field',
|
|
150
|
+
fieldname=fieldname,
|
|
151
|
+
association=association
|
|
152
|
+
)
|
|
153
|
+
return (
|
|
154
|
+
new_target_asset,
|
|
155
|
+
new_expr_chain,
|
|
156
|
+
None
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
raise LookupError(
|
|
160
|
+
f'Failed to find field {fieldname} on asset {target_asset.name}!',
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
def process_transitive_step_expression(
|
|
164
|
+
assets: dict[str, LanguageGraphAsset],
|
|
165
|
+
target_asset: LanguageGraphAsset,
|
|
166
|
+
expr_chain: ExpressionsChain | None,
|
|
167
|
+
step_expression: dict[str, Any],
|
|
168
|
+
lang_spec
|
|
169
|
+
) -> tuple[
|
|
170
|
+
LanguageGraphAsset,
|
|
171
|
+
ExpressionsChain,
|
|
172
|
+
None
|
|
173
|
+
]:
|
|
174
|
+
"""Create a transitive tuple entry that applies to the next
|
|
175
|
+
component of the step expression.
|
|
176
|
+
"""
|
|
177
|
+
result_target_asset, result_expr_chain, _ = (
|
|
178
|
+
process_step_expression(
|
|
179
|
+
assets,
|
|
180
|
+
target_asset,
|
|
181
|
+
expr_chain,
|
|
182
|
+
step_expression['stepExpression'],
|
|
183
|
+
lang_spec
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
new_expr_chain = ExpressionsChain(
|
|
187
|
+
type='transitive',
|
|
188
|
+
sub_link=result_expr_chain
|
|
189
|
+
)
|
|
190
|
+
return (
|
|
191
|
+
result_target_asset,
|
|
192
|
+
new_expr_chain,
|
|
193
|
+
None
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
def process_subType_step_expression(
|
|
197
|
+
assets: dict[str, LanguageGraphAsset],
|
|
198
|
+
target_asset: LanguageGraphAsset,
|
|
199
|
+
expr_chain: ExpressionsChain | None,
|
|
200
|
+
step_expression: dict[str, Any],
|
|
201
|
+
lang_spec
|
|
202
|
+
) -> tuple[
|
|
203
|
+
LanguageGraphAsset,
|
|
204
|
+
ExpressionsChain,
|
|
205
|
+
None
|
|
206
|
+
]:
|
|
207
|
+
"""Create a subType tuple entry that applies to the next
|
|
208
|
+
component of the step expression and changes the target
|
|
209
|
+
asset to the subasset.
|
|
210
|
+
"""
|
|
211
|
+
subtype_name = step_expression['subType']
|
|
212
|
+
result_target_asset, result_expr_chain, _ = (
|
|
213
|
+
process_step_expression(
|
|
214
|
+
assets,
|
|
215
|
+
target_asset,
|
|
216
|
+
expr_chain,
|
|
217
|
+
step_expression['stepExpression'],
|
|
218
|
+
lang_spec
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if subtype_name not in assets:
|
|
223
|
+
raise LanguageGraphException(
|
|
224
|
+
f'Failed to find subtype {subtype_name}'
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
subtype_asset = assets[subtype_name]
|
|
228
|
+
|
|
229
|
+
if result_target_asset is None:
|
|
230
|
+
raise LookupError("Nonexisting asset for subtype")
|
|
231
|
+
|
|
232
|
+
if not subtype_asset.is_subasset_of(result_target_asset):
|
|
233
|
+
raise ValueError(
|
|
234
|
+
f'Found subtype {subtype_name} which does not extend '
|
|
235
|
+
f'{result_target_asset.name}, subtype cannot be resolved.'
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
new_expr_chain = ExpressionsChain(
|
|
239
|
+
type='subType',
|
|
240
|
+
sub_link=result_expr_chain,
|
|
241
|
+
subtype=subtype_asset
|
|
242
|
+
)
|
|
243
|
+
return (
|
|
244
|
+
subtype_asset,
|
|
245
|
+
new_expr_chain,
|
|
246
|
+
None
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
def process_collect_step_expression(
|
|
250
|
+
assets: dict[str, LanguageGraphAsset],
|
|
251
|
+
target_asset: LanguageGraphAsset,
|
|
252
|
+
expr_chain: ExpressionsChain | None,
|
|
253
|
+
step_expression: dict[str, Any],
|
|
254
|
+
lang_spec
|
|
255
|
+
) -> tuple[
|
|
256
|
+
LanguageGraphAsset,
|
|
257
|
+
ExpressionsChain | None,
|
|
258
|
+
str | None
|
|
259
|
+
]:
|
|
260
|
+
"""Apply the right hand step expression to left hand step
|
|
261
|
+
expression target asset and parent associations chain.
|
|
262
|
+
"""
|
|
263
|
+
lh_target_asset, lh_expr_chain, _ = process_step_expression(
|
|
264
|
+
assets, target_asset, expr_chain, step_expression['lhs'], lang_spec
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if lh_target_asset is None:
|
|
268
|
+
raise ValueError(
|
|
269
|
+
'No left hand asset in collect expression '
|
|
270
|
+
f'{step_expression["lhs"]}'
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
rh_target_asset, rh_expr_chain, rh_attack_step_name = (
|
|
274
|
+
process_step_expression(
|
|
275
|
+
assets, lh_target_asset, None, step_expression['rhs'], lang_spec
|
|
276
|
+
)
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
new_expr_chain = lh_expr_chain
|
|
280
|
+
if rh_expr_chain:
|
|
281
|
+
new_expr_chain = ExpressionsChain(
|
|
282
|
+
type='collect',
|
|
283
|
+
left_link=lh_expr_chain,
|
|
284
|
+
right_link=rh_expr_chain
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
rh_target_asset,
|
|
289
|
+
new_expr_chain,
|
|
290
|
+
rh_attack_step_name
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def process_step_expression(
|
|
294
|
+
assets: dict[str, LanguageGraphAsset],
|
|
295
|
+
target_asset: LanguageGraphAsset,
|
|
296
|
+
expr_chain: ExpressionsChain | None,
|
|
297
|
+
step_expression: dict,
|
|
298
|
+
lang_spec
|
|
299
|
+
) -> tuple[
|
|
300
|
+
LanguageGraphAsset,
|
|
301
|
+
ExpressionsChain | None,
|
|
302
|
+
str | None
|
|
303
|
+
]:
|
|
304
|
+
"""Recursively process an attack step expression.
|
|
305
|
+
|
|
306
|
+
Arguments:
|
|
307
|
+
---------
|
|
308
|
+
target_asset - The asset type that this step expression should
|
|
309
|
+
apply to. Initially it will contain the asset
|
|
310
|
+
type to which the attack step belongs.
|
|
311
|
+
expr_chain - A expressions chain of linked of associations
|
|
312
|
+
and set operations from the attack step to its
|
|
313
|
+
parent attack step.
|
|
314
|
+
Note: This was done for the parent attack step
|
|
315
|
+
because it was easier to construct recursively
|
|
316
|
+
given the left-hand first expansion of the
|
|
317
|
+
current MAL language specification.
|
|
318
|
+
step_expression - A dictionary containing the step expression.
|
|
319
|
+
|
|
320
|
+
Return:
|
|
321
|
+
------
|
|
322
|
+
A tuple triplet containing the target asset, the resulting parent
|
|
323
|
+
associations chain, and the name of the attack step.
|
|
324
|
+
|
|
325
|
+
"""
|
|
326
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
327
|
+
# Avoid running json.dumps when not in debug
|
|
328
|
+
logger.debug(
|
|
329
|
+
'Processing Step Expression:\n%s',
|
|
330
|
+
json.dumps(step_expression, indent=2)
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
result: tuple[
|
|
334
|
+
LanguageGraphAsset,
|
|
335
|
+
ExpressionsChain | None,
|
|
336
|
+
str | None
|
|
337
|
+
]
|
|
338
|
+
|
|
339
|
+
match (step_expression['type']):
|
|
340
|
+
case 'attackStep':
|
|
341
|
+
result = process_attack_step_expression(
|
|
342
|
+
target_asset, step_expression
|
|
343
|
+
)
|
|
344
|
+
case 'union' | 'intersection' | 'difference':
|
|
345
|
+
result = process_set_operation_step_expression(
|
|
346
|
+
assets, target_asset, expr_chain, step_expression, lang_spec
|
|
347
|
+
)
|
|
348
|
+
case 'variable':
|
|
349
|
+
result = process_variable_step_expression(
|
|
350
|
+
assets, target_asset, step_expression, lang_spec
|
|
351
|
+
)
|
|
352
|
+
case 'field':
|
|
353
|
+
result = process_field_step_expression(
|
|
354
|
+
target_asset, step_expression
|
|
355
|
+
)
|
|
356
|
+
case 'transitive':
|
|
357
|
+
result = process_transitive_step_expression(
|
|
358
|
+
assets, target_asset, expr_chain, step_expression, lang_spec
|
|
359
|
+
)
|
|
360
|
+
case 'subType':
|
|
361
|
+
result = process_subType_step_expression(
|
|
362
|
+
assets, target_asset, expr_chain, step_expression, lang_spec
|
|
363
|
+
)
|
|
364
|
+
case 'collect':
|
|
365
|
+
result = process_collect_step_expression(
|
|
366
|
+
assets, target_asset, expr_chain, step_expression, lang_spec
|
|
367
|
+
)
|
|
368
|
+
case _:
|
|
369
|
+
raise LookupError(
|
|
370
|
+
f'Unknown attack step type: "{step_expression["type"]}"'
|
|
371
|
+
)
|
|
372
|
+
return result
|
|
373
|
+
|
|
374
|
+
def reverse_expr_chain(
|
|
375
|
+
expr_chain: ExpressionsChain | None,
|
|
376
|
+
reverse_chain: ExpressionsChain | None
|
|
377
|
+
) -> ExpressionsChain | None:
|
|
378
|
+
"""Recursively reverse the associations chain. From parent to child or
|
|
379
|
+
vice versa.
|
|
380
|
+
|
|
381
|
+
Arguments:
|
|
382
|
+
---------
|
|
383
|
+
expr_chain - A chain of nested tuples that specify the
|
|
384
|
+
associations and set operations chain from an
|
|
385
|
+
attack step to its connected attack step.
|
|
386
|
+
reverse_chain - A chain of nested tuples that represents the
|
|
387
|
+
current reversed associations chain.
|
|
388
|
+
|
|
389
|
+
Return:
|
|
390
|
+
------
|
|
391
|
+
The resulting reversed associations chain.
|
|
392
|
+
|
|
393
|
+
"""
|
|
394
|
+
if not expr_chain:
|
|
395
|
+
return reverse_chain
|
|
396
|
+
match (expr_chain.type):
|
|
397
|
+
case 'union' | 'intersection' | 'difference' | 'collect':
|
|
398
|
+
left_reverse_chain = \
|
|
399
|
+
reverse_expr_chain(expr_chain.left_link, reverse_chain)
|
|
400
|
+
right_reverse_chain = \
|
|
401
|
+
reverse_expr_chain(expr_chain.right_link, reverse_chain)
|
|
402
|
+
if expr_chain.type == 'collect':
|
|
403
|
+
new_expr_chain = ExpressionsChain(
|
|
404
|
+
type=expr_chain.type,
|
|
405
|
+
left_link=right_reverse_chain,
|
|
406
|
+
right_link=left_reverse_chain
|
|
407
|
+
)
|
|
408
|
+
else:
|
|
409
|
+
new_expr_chain = ExpressionsChain(
|
|
410
|
+
type=expr_chain.type,
|
|
411
|
+
left_link=left_reverse_chain,
|
|
412
|
+
right_link=right_reverse_chain
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
return new_expr_chain
|
|
416
|
+
|
|
417
|
+
case 'transitive':
|
|
418
|
+
result_reverse_chain = reverse_expr_chain(
|
|
419
|
+
expr_chain.sub_link, reverse_chain)
|
|
420
|
+
new_expr_chain = ExpressionsChain(
|
|
421
|
+
type='transitive',
|
|
422
|
+
sub_link=result_reverse_chain
|
|
423
|
+
)
|
|
424
|
+
return new_expr_chain
|
|
425
|
+
|
|
426
|
+
case 'field':
|
|
427
|
+
association = expr_chain.association
|
|
428
|
+
|
|
429
|
+
if not association:
|
|
430
|
+
raise LanguageGraphException(
|
|
431
|
+
"Missing association for expressions chain"
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
if not expr_chain.fieldname:
|
|
435
|
+
raise LanguageGraphException(
|
|
436
|
+
"Missing field name for expressions chain"
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
opposite_fieldname = association.get_opposite_fieldname(
|
|
440
|
+
expr_chain.fieldname)
|
|
441
|
+
new_expr_chain = ExpressionsChain(
|
|
442
|
+
type='field',
|
|
443
|
+
association=association,
|
|
444
|
+
fieldname=opposite_fieldname
|
|
445
|
+
)
|
|
446
|
+
return new_expr_chain
|
|
447
|
+
|
|
448
|
+
case 'subType':
|
|
449
|
+
result_reverse_chain = reverse_expr_chain(
|
|
450
|
+
expr_chain.sub_link,
|
|
451
|
+
reverse_chain
|
|
452
|
+
)
|
|
453
|
+
new_expr_chain = ExpressionsChain(
|
|
454
|
+
type='subType',
|
|
455
|
+
sub_link=result_reverse_chain,
|
|
456
|
+
subtype=expr_chain.subtype
|
|
457
|
+
)
|
|
458
|
+
return new_expr_chain
|
|
459
|
+
|
|
460
|
+
case _:
|
|
461
|
+
msg = 'Unknown assoc chain element "%s"'
|
|
462
|
+
logger.error(msg, expr_chain.type)
|
|
463
|
+
raise LanguageGraphAssociationError(msg % expr_chain.type)
|
|
464
|
+
|
|
465
|
+
def resolve_variable(
|
|
466
|
+
assets: dict[str, LanguageGraphAsset],
|
|
467
|
+
asset: LanguageGraphAsset,
|
|
468
|
+
var_name: str,
|
|
469
|
+
lang_spec
|
|
470
|
+
) -> tuple:
|
|
471
|
+
"""Resolve a variable for a specific asset by variable name.
|
|
472
|
+
|
|
473
|
+
Arguments:
|
|
474
|
+
---------
|
|
475
|
+
asset - a language graph asset to which the variable belongs
|
|
476
|
+
var_name - a string representing the variable name
|
|
477
|
+
|
|
478
|
+
Return:
|
|
479
|
+
------
|
|
480
|
+
A tuple containing the target asset and expressions chain required to
|
|
481
|
+
reach it.
|
|
482
|
+
|
|
483
|
+
"""
|
|
484
|
+
if var_name not in asset.variables:
|
|
485
|
+
var_expr = get_var_expr_for_asset(asset.name, var_name, lang_spec)
|
|
486
|
+
target_asset, expr_chain, _ = process_step_expression(
|
|
487
|
+
assets, asset, None, var_expr, lang_spec
|
|
488
|
+
)
|
|
489
|
+
asset.own_variables[var_name] = (target_asset, expr_chain)
|
|
490
|
+
return (target_asset, expr_chain)
|
|
491
|
+
return asset.variables[var_name]
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
mal_toolbox-1.2.1.dist-info/licenses/AUTHORS,sha256=zxLrLe8EY39WtRKlAY4Oorx4Z2_LHV2ApRvDGZgY7xY,127
|
|
2
|
-
mal_toolbox-1.2.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
3
|
-
maltoolbox/__init__.py,sha256=649BOg_Bo4OazvePvnuF2tjM0q4VbyS2Fsz9em_KEtM,2132
|
|
4
|
-
maltoolbox/__main__.py,sha256=aAm6NcZ-HtPmY9hfFlGNnTs5rydoI6NAc88RgXt1G9U,3515
|
|
5
|
-
maltoolbox/exceptions.py,sha256=4rwqzu8Cgj0ShjUoCXP2yik-bJaqYqj6Y-0tqxHy4vs,1316
|
|
6
|
-
maltoolbox/file_utils.py,sha256=IXA0cvyopjRFGGKqRPkRQ0RJOtKzq_XF13aHgcz-TFc,1911
|
|
7
|
-
maltoolbox/model.py,sha256=bqYPYNW8MxuS2wUef51z6yjaA5F13YXbeicM2qaYUd4,18138
|
|
8
|
-
maltoolbox/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
maltoolbox/str_utils.py,sha256=zZXHOFfXguhpQQJ5nyGe1VGWchOkanQUc8viV7nhQho,639
|
|
10
|
-
maltoolbox/attackgraph/__init__.py,sha256=l7dJ7jOqpcj7PdsOKZt1NuXlPyjd6vZYvcXlj8Kq09w,297
|
|
11
|
-
maltoolbox/attackgraph/attackgraph.py,sha256=WBRwnVmQqwpjp3x_kSR8HH49MnlRIhF6tZ_r7nqTAJw,27162
|
|
12
|
-
maltoolbox/attackgraph/node.py,sha256=7NAdEl40w6KMt_gKK1mP4SRAmmyCQGSTMaD-GHMNXHk,4186
|
|
13
|
-
maltoolbox/attackgraph/analyzers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
maltoolbox/language/__init__.py,sha256=RTTfhnCYa5PRGJCgDAWLpLLAzNCvNMn91UHNiOXszbg,490
|
|
15
|
-
maltoolbox/language/languagegraph.py,sha256=Tjqk5zv_37ghmepx8KBHPTH8tRlboaYcW836MiUS1d8,65140
|
|
16
|
-
maltoolbox/language/compiler/__init__.py,sha256=Rbdeco6SWHyFw-VJfpxLRSZO3UMjJxPGenMR8OujVpA,15846
|
|
17
|
-
maltoolbox/language/compiler/mal_lexer.py,sha256=TQvzEW7yCN0iY6Js5O6wCDFxSAE0_LAX4JVy96TnLro,14808
|
|
18
|
-
maltoolbox/language/compiler/mal_parser.py,sha256=bVfYWRZyyhU-s2tJI-D_YwbVQkl3AHzdrD6LWM0BQbI,116108
|
|
19
|
-
maltoolbox/patternfinder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
maltoolbox/patternfinder/attackgraph_patterns.py,sha256=jw6BlQHXLmiWm9xajLHbUZUWVQGM2qAgMHOs0Yo2YsE,5168
|
|
21
|
-
maltoolbox/translators/__init__.py,sha256=7qbhjeu--s2A-O_031a7xzSq794iQlrrUxM8gE1LxH4,201
|
|
22
|
-
maltoolbox/translators/networkx.py,sha256=v1JQAqO7st6-ktx5P3oy93DsL2SEUPly_3zcALv08o8,1352
|
|
23
|
-
maltoolbox/translators/updater.py,sha256=mFmTT2GHCw6nsoHe_ChnvAHd5j6UxKnvAqLFDSziqC4,8566
|
|
24
|
-
maltoolbox/visualization/__init__.py,sha256=7rrGclkGdP6LrxpfSh1esYFG_MnvnVruuEdUJI-DX-g,350
|
|
25
|
-
maltoolbox/visualization/draw_io_utils.py,sha256=CgsD0HEFpxZ6ZIWtUZtMekdPB2Irtmvhz0TNEm7x1ig,14378
|
|
26
|
-
maltoolbox/visualization/graphviz_utils.py,sha256=87B2pxRMrlmm2RHu0JM7nQRHWZD0Yt3zCmEwl8xUXdU,4709
|
|
27
|
-
maltoolbox/visualization/neo4j_utils.py,sha256=R2Qm2gC5GDpfiPhhB3oymuBI2W580SRXGVtQuFRYiIA,3496
|
|
28
|
-
maltoolbox/visualization/utils.py,sha256=EZWsxukO5hbRwGFW9GM9ZemKT-nYg-VMCup-SsntaQM,1480
|
|
29
|
-
mal_toolbox-1.2.1.dist-info/METADATA,sha256=Nlsaw-sJu-Pqz6hWme_f6K-hryjFK8-QHYyMqfXBfWA,6696
|
|
30
|
-
mal_toolbox-1.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
31
|
-
mal_toolbox-1.2.1.dist-info/entry_points.txt,sha256=oqby5O6cUP_OHCm70k_iYPA6UlbTBf7se1i3XwdK3uU,56
|
|
32
|
-
mal_toolbox-1.2.1.dist-info/top_level.txt,sha256=phqRVLRKGdSUgRY03mcpi2cmbbDo5YGjkV4gkqHFFcM,11
|
|
33
|
-
mal_toolbox-1.2.1.dist-info/RECORD,,
|