summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorW. Kosior <koszko@koszko.org>2024-12-18 07:20:35 +0100
committerW. Kosior <koszko@koszko.org>2024-12-18 07:32:27 +0100
commit8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3 (patch)
treeba8c4f0500e4ae091c6cfb66184ec12dc145044f
parentb94e315bc34bd5ce93d69d68b2837dc968a4a39a (diff)
downloadAGH-threat-intel-course-8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3.tar.gz
AGH-threat-intel-course-8e0d7716dd73a2e3f042c3c8d61d04dfec5adef3.zip
Generate a techniques table.
-rw-r--r--Makefile17
-rw-r--r--techniques_table.py80
-rw-r--r--techniques_table_doc.tex19
3 files changed, 113 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 7154069..48661d3 100644
--- a/Makefile
+++ b/Makefile
@@ -2,13 +2,15 @@
#
# Copyright (C) 2024 Wojtek Kosior <koszko@koszko.org>
-# Make sure you have Pandoc, Python as well as Python packages `BeautifulSoup4',
-# `pyyaml' (YAML parser library) and `requests' installed.
+# Make sure you have Pandoc, a LaTeX distribution, Python as well as Python
+# packages `BeautifulSoup4', `pyyaml' (YAML parser library) and `requests'
+# installed.
PYTHON=python3
PANDOC=pandoc
+LATEXMK=latexmk
-all: tables.pdf profiles_with_scraped_info.yaml
+all: tables.pdf techniques_table_doc.pdf profiles_with_scraped_info.yaml
.PHONY: all
.SUFFIXES: .pdf .md
@@ -28,8 +30,15 @@ tables.md: threats_by_sector_table.py profiles.yaml
profiles_with_scraped_info.yaml: scrape_groups_info.py profiles.yaml
$(PYTHON) $^ > $@
+techniques_table.tex: techniques_table.py profiles_with_scraped_info.yaml
+ $(PYTHON) $^ > $@
+
+techniques_table_doc.pdf: techniques_table_doc.tex techniques_table.tex
+ $(LATEXMK) -pdf $<
+
th-proj-archive.tar.gz: Makefile profiles.yaml scrape_groups_info.py \
profiles_with_scraped_info.yaml tables.md tables.pdf \
+ techniques_table_doc.pdf techniques_table.py \
threats_by_sector_table.py
tar --transform='s|^|th-proj-archive/|' \
--mtime=1970-01-01T00:00:00-00:00 --group=0 --owner=0 \
@@ -37,7 +46,9 @@ th-proj-archive.tar.gz: Makefile profiles.yaml scrape_groups_info.py \
clean:
rm -rf profiles_with_scraped_info.yaml tables.pdf tables.md \
+ techniques_table_doc.pdf techniques_table.tex \
th-proj-archive.tar.gz
+ $(LATEXMK) -C
.PHONY: clean
magisterclean: clean
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("}")
diff --git a/techniques_table_doc.tex b/techniques_table_doc.tex
new file mode 100644
index 0000000..0fbb023
--- /dev/null
+++ b/techniques_table_doc.tex
@@ -0,0 +1,19 @@
+%% SPDX-License-Identifier: CC0-1.0
+%%
+%% This LaTeX source is copyright (C) 2024 W. Kosior <koszko@koszko.org>
+
+\documentclass{article}
+
+\usepackage[a4paper, total={6in, 8in}, margin=1in]{geometry}
+\usepackage{longtable}
+\usepackage[table]{xcolor}
+
+\title{Statistics of groups using particular techniques}
+
+\author{Wojciech Kosior}
+
+\begin{document}
+
+\input{techniques_table.tex}
+
+\end{document}