-
Notifications
You must be signed in to change notification settings - Fork 457
Expand file tree
/
Copy pathanalyze_ttp_risk_objects.py
More file actions
74 lines (57 loc) · 2.28 KB
/
analyze_ttp_risk_objects.py
File metadata and controls
74 lines (57 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python3
"""
Analyze TTP detections with multiple risk_objects.
Finds all YAML files under detections/**/*.yml where:
- type == TTP
- rba.risk_objects has 2 or more entries
Aggregates results by the set of risk_object types and reports
files that do NOT follow the standard (1 user + 1 system) pattern.
Usage:
uv run --with pyyaml scripts/analyze_ttp_risk_objects.py
"""
import os
import yaml
from collections import defaultdict
DETECTIONS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "detections")
def main():
results = defaultdict(list)
total_ttp_with_multi_risk = 0
for root, dirs, files in os.walk(DETECTIONS_DIR):
for fname in files:
if not fname.endswith(".yml"):
continue
fpath = os.path.join(root, fname)
try:
with open(fpath) as f:
data = yaml.safe_load(f)
except Exception:
continue
if not isinstance(data, dict):
continue
if data.get("type") != "TTP":
continue
rba = data.get("rba")
if not isinstance(rba, dict):
continue
risk_objects = rba.get("risk_objects", [])
if not isinstance(risk_objects, list) or len(risk_objects) < 2:
continue
total_ttp_with_multi_risk += 1
types = tuple(sorted(ro.get("type", "unknown") for ro in risk_objects))
results[types].append(fpath)
print(f"Total TTP files with 2+ risk_objects: {total_ttp_with_multi_risk}\n")
print("Aggregated by risk_object_type set:")
for type_combo, files in sorted(results.items(), key=lambda x: -len(x[1])):
print(f" {list(type_combo)} — {len(files)} file(s)")
print("\nNon-(1 user + 1 system) combos:")
non_standard_total = 0
for type_combo, files in sorted(results.items(), key=lambda x: -len(x[1])):
if type_combo == ("system", "user"):
continue
non_standard_total += len(files)
print(f" {list(type_combo)} — {len(files)} file(s)")
for f in files:
print(f" {os.path.relpath(f, DETECTIONS_DIR)}")
print(f"\nTotal non-(1 user + 1 system): {non_standard_total}")
if __name__ == "__main__":
main()