Files
splunk-security_content/scripts/analyze_ttp_risk_objects.py

75 lines
2.3 KiB
Python

#!/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()