mitre-attack-framework について
実際に観測された攻撃者の行動を、戦術、テクニック、手順、緩和策、検知に整理するセキュリティのナレッジベース兼フレームワークです。セキュリティチームは検知範囲の対応付けや脅威グループの追跡、ギャップの把握に利用できます。
主な機能
- 01攻撃者の戦術とテクニック
- 02サブテクニックの分類
- 03実際の手順の例
- 04緩和策と検知の対応付け
- 05カバレッジとギャップの評価
活用シーン
- 01検知をATT&CKのテクニックに対応付ける
- 02ATT&CK Navigatorでカバレッジを可視化する
- 03脅威グループの戦術とテクニックを追跡する
- 04防御カバレッジのギャップを特定する
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ copyleftdev/ sk1llz --skill mitre-attack-frameworkインストール後、Claude Code で/mitre-attack-frameworkを入力して読み込まれたか確認します。
同梱ファイルreferences/techniques.mdscripts/coverage_analyzer.py
詳細
MITRE ATT&CK フレームワーク
概要
MITRE ATT&CK(敵対的戦術、技術、共通知識)は、実際の観測に基づく敵対者の行動に関する、世界中からアクセス可能なナレッジベースです。MITRE Corporation が作成したこのフレームワークは、敵対者の行動を説明するための共通言語となっています。
参考資料
- ウェブサイト: https://attack.mitre.org/
- ナビゲーター: https://mitre-attack.github.io/attack-navigator/
- GitHub: https://github.com/mitre-attack
基本理念
「敵を知る。」
「理解していないものから身を守ることはできません。」
ATT&CK は、IOC(攻撃者が使用するもの)から TTP(攻撃者の行動)へと焦点を移します。この行動に着目することで、より長期にわたって有効な検知戦略を立てられます。
ATT&CK マトリックスの構造
Enterprise ATT&CK Matrix
TACTICS (The "Why" - Adversary Goals)
├── Reconnaissance ← Gather information
├── Resource Development ← Build infrastructure
├── Initial Access ← Get into the network
├── Execution ← Run malicious code
├── Persistence ← Maintain foothold
├── Privilege Escalation ← Get higher privileges
├── Defense Evasion ← Avoid detection
├── Credential Access ← Steal credentials
├── Discovery ← Learn the environment
├── Lateral Movement ← Move through network
├── Collection ← Gather target data
├── Command and Control ← Communicate with implants
├── Exfiltration ← Steal data
└── Impact ← Damage or disrupt
TECHNIQUES (The "How" - Methods Used)
└── Each tactic contains multiple techniques
└── Techniques may have sub-techniques
└── Example: T1059.001 (PowerShell) under T1059 (Command and Scripting Interpreter)
主な構成要素
| 構成要素 | 説明 | 例 |
|---|---|---|
| 戦術 | 敵対者の目標 | 認証情報へのアクセス |
| テクニック | 目標の達成方法 | OS の認証情報ダンプ(T1003) |
| サブテクニック | 具体的な実装方法 | LSASS メモリ(T1003.001) |
| 手順 | 実際の事例 | APT28 は Mimikatz を使用 |
| 緩和策 | 防止方法 | Credential Guard |
| 検知 | 発見方法 | LSASS へのアクセスを監視 |
実装時の指針
必ず行うこと
- 検知を ATT&CK のテクニックに対応付けます
- すべての戦術にわたってカバレッジを評価します
- 可視化には ATT&CK Navigator を使用します
- アラートにテクニック ID を記載します
- 敵対者グループとその TTP を追跡します
- ATT&CK の進化に合わせてマッピングを更新します
決して行わないこと
- わずかな検知で全範囲を網羅できていると思い込まないでください
- 現在検知できていないテクニックを無視しないでください
- ATT&CK をコンプライアンスチェックリストとして扱わないでください
- カバレッジを水増しするために不正確なマッピングをしないでください
- 分析でサブテクニックを見落とさないでください
優先すること
- シグネチャ照合より行動ベースの検知を優先します
- 初期段階では深さよりカバレッジの広さを優先します
- テクニックベースのハンティング仮説を立てます
- ATT&CK に準拠した脅威インテリジェンスを活用します
- カバレッジを継続的に評価します
実装パターン
ATT&CK カバレッジ評価
# attack_coverage.py
# Assess and visualize ATT&CK coverage
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Set
from enum import Enum
import json
class CoverageLevel(Enum):
NONE = 0
MINIMAL = 1 # Basic detection exists
PARTIAL = 2 # Some variants covered
SUBSTANTIAL = 3 # Most variants covered
COMPREHENSIVE = 4 # Full coverage with validation
@dataclass
class Technique:
"""ATT&CK Technique representation"""
id: str # e.g., "T1003.001"
name: str # e.g., "LSASS Memory"
tactic: str # e.g., "Credential Access"
platforms: List[str] # e.g., ["Windows"]
data_sources: List[str] # Required telemetry
# Coverage tracking
detections: List[str] = field(default_factory=list)
coverage_level: CoverageLevel = CoverageLevel.NONE
last_validated: Optional[str] = None
@property
def is_sub_technique(self) -> bool:
return "." in self.id
@dataclass
class Detection:
"""A detection rule mapped to ATT&CK"""
name: str
techniques: List[str] # ATT&CK technique IDs
query: str
platform: str # SIEM/EDR platform
false_positive_rate: float
validated: bool = False
class ATTACKCoverageAnalyzer:
"""Analyze detection coverage against ATT&CK"""
def __init__(self):
self.techniques: Dict[str, Technique] = {}
self.detections: List[Detection] = []
self.tactics = [
"Reconnaissance", "Resource Development", "Initial Access",
"Execution", "Persistence", "Privilege Escalation",
"Defense Evasion", "Credential Access", "Discovery",
"Lateral Movement", "Collection", "Command and Control",
"Exfiltration", "Impact"
]
def load_attack_data(self, attack_json_path: str):
"""Load ATT&CK STIX data"""
# In practice, load from MITRE's STIX bundle
pass
def add_detection(self, detection: Detection):
"""Add detection and update coverage"""
self.detections.append(detection)
for tech_id in detection.techniques:
if tech_id in self.techniques:
self.techniques[tech_id].detections.append(detection.name)
self._update_coverage_level(tech_id)
def _update_coverage_level(self, tech_id: str):
"""Recalculate coverage level for technique"""
tech = self.techniques[tech_id]
detection_count = len(tech.detections)
if detection_count == 0:
tech.coverage_level = CoverageLevel.NONE
elif detection_count == 1:
tech.coverage_level = CoverageLevel.MINIMAL
elif detection_count < 3:
tech.coverage_level = CoverageLevel.PARTIAL
elif detection_count < 5:
tech.coverage_level = CoverageLevel.SUBSTANTIAL
else:
tech.coverage_level = CoverageLevel.COMPREHENSIVE
def coverage_by_tactic(self) -> Dict[str, dict]:
"""Get coverage statistics per tactic"""
results = {}
for tactic in self.tactics:
tactic_techs = [t for t in self.techniques.values()
if t.tactic == tactic]
if not tactic_techs:
continue
covered = sum(1 for t in tactic_techs
if t.coverage_level != CoverageLevel.NONE)
results[tactic] = {
'total_techniques': len(tactic_techs),
'covered': covered,
'coverage_percent': (covered / len(tactic_techs)) * 100,
'gaps': [t.id for t in tactic_techs
if t.coverage_level == CoverageLevel.NONE]
}
return results
def identify_gaps(self) -> List[Technique]:
"""Find techniques with no detection coverage"""
return [t for t in self.techniques.values()
if t.coverage_level == CoverageLevel.NONE]
def prioritize_gaps(self) -> List[Technique]:
"""Prioritize gaps by adversary usage"""
gaps = self.identify_gaps()
# Prioritize by:
# 1. Commonly used by threat groups
# 2. Data sources already available
# 3. Tactic importance
high_priority_tactics = [
"Initial Access", "Execution", "Persistence",
"Credential Access", "Lateral Movement"
]
prioritized = sorted(
gaps,
key=lambda t: (
t.tactic in high_priority_tactics, # Prioritize key tactics
len(t.data_sources) # Easier to detect
),
reverse=True
)
return prioritized
def generate_navigator_layer(self) -> dict:
"""Generate ATT&CK Navigator layer JSON"""
layer = {
"name": "Detection Coverage",
"version": "4.4",
"domain": "enterprise-attack",
"description": "Current detection coverage",
"techniques": []
}
color_map = {
CoverageLevel.NONE: "#ffffff",
CoverageLevel.MINIMAL: "#ffcccc",
CoverageLevel.PARTIAL: "#ffff99",
CoverageLevel.SUBSTANTIAL: "#99ff99",
CoverageLevel.COMPREHENSIVE: "#00ff00"
}
for tech in self.techniques.values():
layer["techniques"].append({
"techniqueID": tech.id,
"color": color_map[tech.coverage_level],
"comment": f"Detections: {len(tech.detections)}"
})
return layer
テクニックベースの検知
# technique_detection.py
# Build detections aligned to ATT&CK techniques
from dataclasses import dataclass
from typing import List, Dict
@dataclass
class ATTACKDetection:
"""Detection rule with full ATT&CK context"""
# ATT&CK mapping
technique_id: str
technique_name: str
tactic: str
# Detection details
name: str
description: str
query: str
platform: str
# Quality metrics
severity: str
confidence: str
false_positive_guidance: str
# Data requirements
data_sources: List[str]
# Response
recommended_response: List[str]
def to_sigma(self) -> str:
"""Export as Sigma rule"""
return f"""
title: {self.name}
id: {self.technique_id.lower().replace('.', '-')}-detection
status: experimental
description: {self.description}
references:
- https://attack.mitre.org/techniques/{self.technique_id}/
author: Security Team
date: 2024/01/01
tags:
- attack.{self.tactic.lower().replace(' ', '_')}
- attack.{self.technique_id.lower()}
logsource:
category: process_creation
product: windows
detection:
selection:
# Detection logic here
condition: selection
falsepositives:
- {self.false_positive_guidance}
level: {self.severity.lower()}
"""
# Example: T1003.001 - LSASS Memory
lsass_detection = ATTACKDetection(
technique_id="T1003.001",
technique_name="LSASS Memory",
tactic="Credential Access",
name="LSASS Memory Access via Suspicious Process",
description="Detects processes accessing LSASS memory, "
"commonly used for credential dumping",
query="""
event.code:10 AND
winlog.event_data.TargetImage:*lsass.exe AND
NOT winlog.event_data.SourceImage:(
*MsMpEng.exe OR *csrss.exe OR *wininit.exe
)
""",
platform="Elastic SIEM",
severity="High",
confidence="Medium",
false_positive_guidance="Security tools may legitimately access LSASS",
data_sources=["Process: Process Access (Sysmon EID 10)"],
recommended_response=[
"Isolate affected host",
"Capture memory dump for analysis",
"Reset potentially compromised credentials",
"Hunt for lateral movement"
]
)
脅威グループの追跡
# threat_groups.py
# Track adversary groups and their TTPs
from dataclasses import dataclass
from typing import List, Set, Dict
@dataclass
class ThreatGroup:
"""Known adversary group with TTPs"""
id: str # e.g., "G0007"
name: str # e.g., "APT28"
aliases: List[str] # e.g., ["Fancy Bear", "Sofacy"]
# Attribution
suspected_origin: str
target_sectors: List[str]
target_regions: List[str]
# TTPs
techniques: List[str] # ATT&CK technique IDs
# Intelligence
first_seen: str
last_seen: str
active: bool
def technique_overlap(self, other: 'ThreatGroup') -> Set[str]:
"""Find common techniques with another group"""
return set(self.techniques) & set(other.techniques)
def unique_techniques(self, all_groups: List['ThreatGroup']) -> Set[str]:
"""Find techniques unique to this group"""
other_techniques = set()
for group in all_groups:
if group.id != self.id:
other_techniques.update(group.techniques)
return set(self.techniques) - other_techniques
class ThreatIntelligence:
"""Manage threat group intelligence"""
def __init__(self):
self.groups: Dict[str, ThreatGroup] = {}
def relevant_groups(self, sector: str, region: str) -> List[ThreatGroup]:
"""Find groups targeting specific sector/region"""
return [
g for g in self.groups.values()
if (sector in g.target_sectors or "All" in g.target_sectors) and
(region in g.target_regions or "Global" in g.target_regions) and
g.active
]
def priority_techniques(self, sector: str, region: str) -> Dict[str, int]:
"""Rank techniques by threat relevance"""
relevant = self.relevant_groups(sector, region)
technique_counts = {}
for group in relevant:
for tech in group.techniques:
technique_counts[tech] = technique_counts.get(tech, 0) + 1
# Sort by frequency across relevant groups
return dict(sorted(
technique_counts.items(),
key=lambda x: x[1],
reverse=True
))
def detection_priorities(self,
sector: str,
region: str,
current_coverage: Set[str]) -> List[str]:
"""Prioritize detections based on threat landscape"""
priority_techs = self.priority_techniques(sector, region)
# Find high-priority techniques without coverage
gaps = [
tech for tech, count in priority_techs.items()
if tech not in current_coverage and count >= 2
]
return gaps[:10] # Top 10 priorities
ハンティング仮説の生成
# hypothesis_generator.py
# Generate hunt hypotheses from ATT&CK
from dataclasses import dataclass
from typing import List
@dataclass
class HuntHypothesis:
"""ATT&CK-based hunt hypothesis"""
technique_id: str
technique_name: str
tactic: str
hypothesis: str
rationale: str
data_requirements: List[str]
hunt_query: str
expected_findings: List[str]
success_criteria: str
def generate_hypotheses(technique_id: str,
technique_data: dict) -> List[HuntHypothesis]:
"""Generate hunt hypotheses for a technique"""
hypotheses = []
# Hypothesis 1: Direct technique detection
hypotheses.append(HuntHypothesis(
technique_id=technique_id,
technique_name=technique_data['name'],
tactic=technique_data['tactic'],
hypothesis=f"Adversaries are using {technique_data['name']} "
f"in our environment",
rationale=f"This technique is commonly used by threat groups "
f"targeting our sector",
data_requirements=technique_data['data_sources'],
hunt_query=technique_data.get('detection_query', ''),
expected_findings=[
"Legitimate use by IT/security tools",
"Developer/admin testing",
"Potential adversary activity"
],
success_criteria="Identify all instances, triage findings, "
"create detection for confirmed malicious patterns"
))
# Hypothesis 2: Technique chaining
if technique_data.get('related_techniques'):
hypotheses.append(HuntHypothesis(
technique_id=technique_id,
technique_name=technique_data['name'],
tactic=technique_data['tactic'],
hypothesis=f"Adversaries using {technique_data['name']} "
f"are also using related techniques",
rationale="Techniques are often used in combination",
data_requirements=technique_data['data_sources'],
hunt_query="Correlated query across related techniques",
expected_findings=["Attack chains", "Lateral movement paths"],
success_criteria="Map complete attack chain if present"
))
return hypotheses
メンタルモデル
MITRE ATT&CK の実践者は、次のように問いかけます。
- これはどの戦術か? 敵対者の目標を理解します
- どのテクニックか? 具体的な手法を特定します
- これを検知できているか? カバレッジを評価します
- 誰がこれを使っているか? 脅威グループを特定します
- ギャップは何か? 改善の優先順位を決めます
代表的な ATT&CK の取り組み
- すべての検知とアラートにテクニック ID を記載
- カバレッジの可視化に Navigator のレイヤーを活用
- 脅威グループの TTP を追跡
- 戦術ごとにギャップを分析
- テクニックから仮説を生成
- カバレッジを継続的に評価
コメント
Markdown 対応