merge: testing → main (reconcile 2-week divergence)
This commit is contained in:
108
decnet/clustering/ukc.py
Normal file
108
decnet/clustering/ukc.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
Unified Kill Chain phase vocabulary (Pols, 2017).
|
||||
|
||||
Used as the canonical phase enum for campaign clustering and (eventually)
|
||||
the MITRE ATT&CK / TTPs-tagging worker. UKC tactic names map cleanly onto
|
||||
ATT&CK tactics, so emitting these labels in synthetic data and runtime
|
||||
phase inference avoids a renaming pass when TTP-tagging lands.
|
||||
|
||||
A honeypot does not observe the entire chain. Pre-target phases (OSINT
|
||||
reconnaissance, resource development, weaponization, social engineering)
|
||||
happen before any decky is touched. The DSL allows the full enum so a
|
||||
campaign spec can describe an end-to-end story; the synthetic generator
|
||||
emits no events for unobservable phases.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class UKCPhase(str, Enum):
|
||||
# In — initial foothold
|
||||
RECONNAISSANCE = "reconnaissance"
|
||||
RESOURCE_DEVELOPMENT = "resource_development"
|
||||
WEAPONIZATION = "weaponization"
|
||||
DELIVERY = "delivery"
|
||||
SOCIAL_ENGINEERING = "social_engineering"
|
||||
EXPLOITATION = "exploitation"
|
||||
PERSISTENCE = "persistence"
|
||||
DEFENSE_EVASION = "defense_evasion"
|
||||
COMMAND_AND_CONTROL = "command_and_control"
|
||||
# Through — network propagation
|
||||
PIVOTING = "pivoting"
|
||||
DISCOVERY = "discovery"
|
||||
PRIVILEGE_ESCALATION = "privilege_escalation"
|
||||
EXECUTION = "execution"
|
||||
CREDENTIAL_ACCESS = "credential_access"
|
||||
LATERAL_MOVEMENT = "lateral_movement"
|
||||
# Out — action on objectives
|
||||
COLLECTION = "collection"
|
||||
EXFILTRATION = "exfiltration"
|
||||
IMPACT = "impact"
|
||||
OBJECTIVES = "objectives"
|
||||
|
||||
|
||||
# Phases a honeypot can plausibly observe. Pre-target phases are excluded:
|
||||
# OSINT recon, infrastructure-stand-up, payload authoring, and human-target
|
||||
# manipulation all happen before the attacker touches a decky. The synthetic
|
||||
# generator validates campaign specs against this set and warns (but does
|
||||
# not error) on unobservable phases — a campaign can describe them; we just
|
||||
# emit no events.
|
||||
OBSERVABLE_PHASES: frozenset[UKCPhase] = frozenset({
|
||||
UKCPhase.DELIVERY,
|
||||
UKCPhase.EXPLOITATION,
|
||||
UKCPhase.PERSISTENCE,
|
||||
UKCPhase.DEFENSE_EVASION,
|
||||
UKCPhase.COMMAND_AND_CONTROL,
|
||||
UKCPhase.PIVOTING,
|
||||
UKCPhase.DISCOVERY,
|
||||
UKCPhase.PRIVILEGE_ESCALATION,
|
||||
UKCPhase.EXECUTION,
|
||||
UKCPhase.CREDENTIAL_ACCESS,
|
||||
UKCPhase.LATERAL_MOVEMENT,
|
||||
UKCPhase.COLLECTION,
|
||||
UKCPhase.EXFILTRATION,
|
||||
UKCPhase.IMPACT,
|
||||
UKCPhase.OBJECTIVES,
|
||||
})
|
||||
|
||||
|
||||
# Stage groupings — useful for the multi_operator fixture (operators tend
|
||||
# to split along the In / Through / Out boundary) and for downstream
|
||||
# UI rendering of campaign timelines.
|
||||
STAGE_IN: frozenset[UKCPhase] = frozenset({
|
||||
UKCPhase.RECONNAISSANCE,
|
||||
UKCPhase.RESOURCE_DEVELOPMENT,
|
||||
UKCPhase.WEAPONIZATION,
|
||||
UKCPhase.DELIVERY,
|
||||
UKCPhase.SOCIAL_ENGINEERING,
|
||||
UKCPhase.EXPLOITATION,
|
||||
UKCPhase.PERSISTENCE,
|
||||
UKCPhase.DEFENSE_EVASION,
|
||||
UKCPhase.COMMAND_AND_CONTROL,
|
||||
})
|
||||
|
||||
STAGE_THROUGH: frozenset[UKCPhase] = frozenset({
|
||||
UKCPhase.PIVOTING,
|
||||
UKCPhase.DISCOVERY,
|
||||
UKCPhase.PRIVILEGE_ESCALATION,
|
||||
UKCPhase.EXECUTION,
|
||||
UKCPhase.CREDENTIAL_ACCESS,
|
||||
UKCPhase.LATERAL_MOVEMENT,
|
||||
})
|
||||
|
||||
STAGE_OUT: frozenset[UKCPhase] = frozenset({
|
||||
UKCPhase.COLLECTION,
|
||||
UKCPhase.EXFILTRATION,
|
||||
UKCPhase.IMPACT,
|
||||
UKCPhase.OBJECTIVES,
|
||||
})
|
||||
|
||||
|
||||
def stage_of(phase: UKCPhase) -> str:
|
||||
"""Return 'in' | 'through' | 'out' for a given phase."""
|
||||
if phase in STAGE_IN:
|
||||
return "in"
|
||||
if phase in STAGE_THROUGH:
|
||||
return "through"
|
||||
return "out"
|
||||
Reference in New Issue
Block a user