Zion Boggan zionboggan.com ↗
76 lines · python
History for this file →
1
from __future__ import annotations
2
 
3
from dataclasses import asdict, dataclass, field
4
from datetime import datetime, timezone
5
from typing import Optional
6
 
7
IndicatorType = str
8
 
9
 
10
@dataclass
11
class Indicator:
12
    type: IndicatorType
13
    value: str
14
    source: str
15
    threat_type: str
16
    confidence: int = 50
17
    malware: Optional[str] = None
18
    techniques: list[str] = field(default_factory=list)
19
    tags: list[str] = field(default_factory=list)
20
    reference: Optional[str] = None
21
    first_seen: Optional[str] = None
22
 
23
    def key(self) -> tuple[str, str]:
24
        return (self.type, self.value.lower())
25
 
26
    def to_dict(self) -> dict:
27
        return asdict(self)
28
 
29
 
30
@dataclass
31
class Technique:
32
    technique_id: str
33
    name: str
34
    tactic: str
35
    sources: set[str] = field(default_factory=set)
36
    indicator_count: int = 0
37
 
38
    def to_dict(self) -> dict:
39
        return {
40
            "technique_id": self.technique_id,
41
            "name": self.name,
42
            "tactic": self.tactic,
43
            "sources": sorted(self.sources),
44
            "indicator_count": self.indicator_count,
45
        }
46
 
47
 
48
@dataclass
49
class RuleBundle:
50
    bundle_id: str
51
    generated_at: str
52
    indicators: list[Indicator]
53
    techniques: list[Technique]
54
    cdb_lists: dict[str, str]
55
    rules_xml: str
56
 
57
    @staticmethod
58
    def now_iso() -> str:
59
        return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
60
 
61
    def counts_by_type(self) -> dict[str, int]:
62
        counts: dict[str, int] = {}
63
        for indicator in self.indicators:
64
            counts[indicator.type] = counts.get(indicator.type, 0) + 1
65
        return counts
66
 
67
    def manifest(self) -> dict:
68
        return {
69
            "bundle_id": self.bundle_id,
70
            "generated_at": self.generated_at,
71
            "indicator_count": len(self.indicators),
72
            "counts_by_type": self.counts_by_type(),
73
            "technique_count": len(self.techniques),
74
            "techniques": [t.technique_id for t in self.techniques],
75
            "cdb_lists": {name: content.count("\n") for name, content in self.cdb_lists.items()},
76
        }