diff options
author | W. Kosior <koszko@koszko.org> | 2024-12-18 07:20:35 +0100 |
---|---|---|
committer | W. Kosior <koszko@koszko.org> | 2024-12-18 07:32:27 +0100 |
commit | 8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3 (patch) | |
tree | ba8c4f0500e4ae091c6cfb66184ec12dc145044f /techniques_table.py | |
parent | b94e315bc34bd5ce93d69d68b2837dc968a4a39a (diff) | |
download | AGH-threat-intel-course-8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3.tar.gz AGH-threat-intel-course-8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3.zip |
Generate a techniques table.
Diffstat (limited to 'techniques_table.py')
-rw-r--r-- | techniques_table.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/techniques_table.py b/techniques_table.py new file mode 100644 index 0000000..bee4027 --- /dev/null +++ b/techniques_table.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +# SPDX-License-Identifier: CC0-1.0 +# +# Copyright (C) 2024 Wojtek Kosior <koszko@koszko.org> + +import yaml +import sys + +def read_APT_data(yaml_path): + if yaml_path: + with open(yaml_path) as inp: + return yaml.safe_load(inp) + else: + return yaml.safe_load(sys.stdin) + +profiles_data = read_APT_data(None if len(sys.argv) < 2 else sys.argv[1]) + +groups_by_origin = {} +groups_by_techniques_by_origin = {} + +for group in profiles_data["groups"]: + origin = group["origin"] + groups_by_origin[origin] = groups_by_origin.get(origin, []) + [group] + + groups_by_technique = groups_by_techniques_by_origin.get(origin, {}) + for tid in group["technique_ids"]: + groups_by_technique[tid] = groups_by_technique.get(tid, []) + [group] + groups_by_techniques_by_origin[origin] = groups_by_technique + +def group_name_list(origin, tid): + return ", ".join(sorted( + g["name"] + for g in groups_by_techniques_by_origin[origin].get(tid, []) + )) + +def technique_use_percent(tid, origin): + return (100 * len(groups_by_techniques_by_origin[origin].get(tid, [])) / + len(groups_by_origin[origin])) + +def technique_popularity_score(tid): + return sum(technique_use_percent(tid, origin) + for origin in groups_by_origin) + +all_tids = sorted(set().union(*groups_by_techniques_by_origin.values()), + key=technique_popularity_score, + reverse=True) + +all_origins = sorted(groups_by_origin) + +technique_names = dict((t["mitre_id"], t["name"]) + for t in profiles_data["techniques"]) + +print("{") +print("\\footnotesize") +print("\\rowcolors{3}{gray!20}{white!100}") +print("\\renewcommand*{\\arraystretch}{1.3}") +print("""\ +\\begin{longtable}{\ +p{0.3\\textwidth} \ +p{0.65in} p{0.65in} p{0.65in} p{0.65in} \ +>{\\centering\\arraybackslash} p{0.85in} \ +}""") +print(f"technique & {' & '.join(all_origins)} & total APT count \\\\") +print("\\hline\\hline \\endhead") + +for tid in all_tids: + name = technique_names[tid] + group_count = sum([len(groups_by_techniques_by_origin[origin].get(tid, [])) + for origin in all_origins]) + + group_precents_markup = ' & '.join( + f"{round(technique_use_percent(tid, origin))}\\% groups" + for origin in all_origins + ) + + print(f"{name} & {group_precents_markup} & {group_count} \\\\") + +print("\\end{longtable}") +print("}") |