Zion Boggan zionboggan.com ↗
37 lines · python
History for this file →
1
from __future__ import annotations
2
 
3
from cti import mitre
4
from cti.models import Indicator, Technique
5
 
6
 
7
def extract_techniques(indicators: list[Indicator]) -> list[Technique]:
8
    table: dict[str, Technique] = {}
9
    for indicator in indicators:
10
        sources = indicator.source.split(",")
11
        for technique_id in indicator.techniques:
12
            technique = table.get(technique_id)
13
            if technique is None:
14
                technique = Technique(
15
                    technique_id=technique_id,
16
                    name=mitre.name_for(technique_id),
17
                    tactic=mitre.tactic_for(technique_id),
18
                )
19
                table[technique_id] = technique
20
            technique.sources.update(sources)
21
            technique.indicator_count += 1
22
    return sorted(table.values(), key=lambda t: (-t.indicator_count, t.technique_id))
23
 
24
 
25
def coverage_report(techniques: list[Technique]) -> str:
26
    lines = [
27
        "# TTP coverage",
28
        "",
29
        "| Technique | Tactic | Name | Indicators | Sources |",
30
        "|---|---|---|---|---|",
31
    ]
32
    for technique in techniques:
33
        lines.append(
34
            f"| {technique.technique_id} | {technique.tactic} | {technique.name} "
35
            f"| {technique.indicator_count} | {', '.join(sorted(technique.sources))} |"
36
        )
37
    return "\n".join(lines) + "\n"