使用 MITRE ATT&CK Navigator 分析 APT 組織 是做什麼的?
概述
MITRE ATT&CK Navigator 是一個基於網頁的工具,用於標註與探索 ATT&CK 矩陣,讓分析人員能夠視覺化威脅行為者的技術覆蓋範圍、比較多個 APT 組織、識別檢測缺口,並建立威脅驅動的防禦策略。本技能涵蓋如何以程式方式查詢 ATT&CK 數據、將 APT 組織的 TTP 映射至 Navigator 圖層、建立多層疊加以進行缺口分析,以及為檢測工程團隊產出可執行的情資報告。
使用時機
- 調查需要透過 mitre navigator 分析 apt 組織的安全事件時
- 為此領域建立檢測規則或威脅獵殺查詢時
- SOC 分析人員需要此分析類型的結構化程序時
- 驗證相關攻擊技術的安全性監控覆蓋率時
先決條件
- Python 3.9+,需安裝
attackcti、mitreattack-python、stix2、requests函式庫 - ATT&CK Navigator(https://mitre-attack.github.io/attack-navigator/)或本機部署
- 了解 ATT&CK 企業矩陣:14 項戰術、200+ 項技術與子技術
- 可存取威脅情資報告或 MISP/OpenCTI 以取得威脅行為者數據
- 熟悉 STIX 2.1 入侵集合與攻擊模式物件
關鍵概念
ATT&CK Navigator 圖層
Navigator 圖層是以 JSON 格式標註 ATT&CK 技術的檔案,包含分數、顏色、註解與元數據。每個圖層可代表單一 APT 組織的技術使用情況、檢測能力地圖或組合疊加圖層。圖層版本 4.5 支援 enterprise-attack、mobile-attack 與 ics-attack 領域,並可依平台(Windows、Linux、macOS、Cloud、Azure AD、Office 365、SaaS)進行篩選。
ATT&CK 中的 APT 組織資料
ATT&CK 目錄記錄了超過 140 個威脅組織及其記錄在案的技術使用情況。每個組織資料包含別名、目標產業、相關攻擊活動、使用的軟體以及附有程序層級細節的技術映射。組織以 G-code 識別(例如 G0016 為 APT29、G0007 為 APT28、G0032 為 Lazarus Group)。
多圖層分析
Navigator 支援同時載入多個圖層,讓分析人員能夠疊加威脅行為者的 TTP 與檢測覆蓋範圍以識別缺口、比較多個 APT 組織以找出值得優先處理的常見技術,以及追蹤技術覆蓋範圍隨時間的變化。
工作流程
步驟 1:查詢 APT 組織的 ATT&CK 數據
from attackcti import attack_client
import json
lift = attack_client()
# 取得所有威脅組織
groups = lift.get_groups()
print(f"ATT&CK 組織總數: {len(groups)}")
# 尋找 APT29(Cozy Bear / Midnight Blizzard)
apt29 = next((g for g in groups if g.get('name') == 'APT29'), None)
if apt29:
print(f"組織: {apt29['name']}")
print(f"別名: {apt29.get('aliases', [])}")
print(f"描述: {apt29.get('description', '')[:300]}")
# 取得 APT29(G0016)使用的技術
techniques = lift.get_techniques_used_by_group("G0016")
print(f"APT29 使用了 {len(techniques)} 項技術")
technique_map = {}
for tech in techniques:
tech_id = ""
for ref in tech.get("external_references", []):
if ref.get("source_name") == "mitre-attack":
tech_id = ref.get("external_id", "")
break
if tech_id:
tactics = [p.get("phase_name", "") for p in tech.get("kill_chain_phases", [])]
technique_map[tech_id] = {
"name": tech.get("name", ""),
"tactics": tactics,
"description": tech.get("description", "")[:500],
"platforms": tech.get("x_mitre_platforms", []),
"data_sources": tech.get("x_mitre_data_sources", []),
}
步驟 2:產生 Navigator 圖層 JSON
def create_navigator_layer(group_name, technique_map, color="#ff6666"):
techniques_list = []
for tech_id, info in technique_map.items():
for tactic in info["tactics"]:
techniques_list.append({
"techniqueID": tech_id,
"tactic": tactic,
"color": color,
"comment": info["name"],
"enabled": True,
"score": 100,
"metadata": [
{"name": "group", "value": group_name},
{"name": "platforms", "value": ", ".join(info["platforms"])},
],
})
layer = {
"name": f"{group_name} TTP 覆蓋率",
"versions": {"attack": "16.1", "navigator": "5.1.0", "layer": "4.5"},
"domain": "enterprise-attack",
"description": f"歸因於 {group_name} 的技術",
"filters": {
"platforms": ["Linux", "macOS", "Windows", "Cloud",
"Azure AD", "Office 365", "SaaS", "Google Workspace"]
},
"sorting": 0,
"layout": {
"layout": "side", "aggregateFunction": "average",
"showID": True, "showName": True,
"showAggregateScores": False, "countUnscored": False,
},
"hideDisabled": False,
"techniques": techniques_list,
"gradient": {"colors": ["#ffffff", color], "minValue": 0, "maxValue": 100},
"legendItems": [
{"label": f"由 {group_name} 使用", "color": color},
{"label": "未觀察到", "color": "#ffffff"},
],
"showTacticRowBackground": True,
"tacticRowBackground": "#dddddd",
"selectTechniquesAcrossTactics": True,
"selectSubtechniquesWithParent": False,
"selectVisibleTechniques": False,
}
return layer
layer = create_navigator_layer("APT29", technique_map)
with open("apt29_layer.json", "w") as f:
json.dump(layer, f, indent=2)
print("[+] 圖層已儲存: apt29_layer.json")
步驟 3:比較多個 APT 組織
groups_to_compare = {"G0016": "APT29", "G0007": "APT28", "G0032": "Lazarus Group"}
group_techniques = {}
for gid, gname in groups_to_compare.items():
techs = lift.get_techniques_used_by_group(gid)
tech_ids = set()
for t in techs:
for ref in t.get("external_references", []):
if ref.get("source_name") == "mitre-attack":
tech_ids.add(ref.get("external_id", ""))
group_techniques[gname] = tech_ids
common_to_all = set.intersection(*group_techniques.values())
print(f"所有組織共有的技術數: {len(common_to_all)}")
for tid in sorted(common_to_all):
print(f" {tid}")
for gname, techs in group_techniques.items():
others = set.union(*[t for n, t in group_techniques.items() if n != gname])
unique = techs - others
print(f"\n{gname} 獨有的技術數: {len(unique)} 項")
步驟 4:使用圖層疊加進行檢測缺口分析
# 定義您當前的檢測能力
detected_techniques = {
"T1059", "T1059.001", "T1071", "T1071.001", "T1566", "T1566.001",
"T1547", "T1547.001", "T1053", "T1053.005", "T1078", "T1027",
}
actor_techniques = set(technique_map.keys())
covered = actor_techniques.intersection(detected_techniques)
gaps = actor_techniques - detected_techniques
print(f"=== APT29 檢測缺口分析 ===")
print(f"攻擊者技術數: {len(actor_techniques)}")
print(f"已檢測: {len(covered)} ({len(covered)/len(actor_techniques)*100:.0f}%)")
print(f"缺口: {len(gaps)} ({len(gaps)/len(actor_techniques)*100:.0f}%)")
# 建立缺口圖層(紅色 = 未檢測,綠色 = 已檢測)
gap_techniques = []
for tech_id in actor_techniques:
info = technique_map.get(tech_id, {})
for tactic in info.get("tactics", [""]):
color = "#66ff66" if tech_id in detected_techniques else "#ff3333"
gap_techniques.append({
"techniqueID": tech_id,
"tactic": tactic,
"color": color,
"comment": f"{'已檢測' if tech_id in detected_techniques else '缺口'}: {info.get('name', '')}",
"enabled": True,
"score": 100 if tech_id in detected_techniques else 0,
})
gap_layer = {
"name": "APT29 檢測缺口分析",
"versions": {"attack": "16.1", "navigator": "5.1.0", "layer": "4.5"},
"domain": "enterprise-attack",
"description": "綠色 = 已檢測,紅色 = 缺口",
"techniques": gap_techniques,
"gradient": {"colors": ["#ff3333", "#66ff66"], "minValue": 0, "maxValue": 100},
"legendItems": [
{"label": "已檢測", "color": "#66ff66"},
{"label": "檢測缺口", "color": "#ff3333"},
],
}
with open("apt29_gap_layer.json", "w") as f:
json.dump(gap_layer, f, indent=2)
步驟 5:戰術分解分析
from collections import defaultdict
tactic_breakdown = defaultdict(list)
for tech_id, info in technique_map.items():
for tactic in info["tactics"]:
tactic_breakdown[tactic].append({"id": tech_id, "name": info["name"]})
tactic_order = [
"reconnaissance", "resource-development", "initial-access",
"execution", "persistence", "privilege-escalation",
"defense-evasion", "credential-access", "discovery",
"lateral-movement", "collection", "command-and-control",
"exfiltration", "impact",
]
print("\n=== APT29 戰術分解 ===")
for tactic in tactic_order:
techs = tactic_breakdown.get(tactic, [])
if techs:
print(f"\n{tactic.upper()}({len(techs)} 項技術):")
for t in techs:
print(f" {t['id']}: {t['name']}")
驗證標準
- 透過 TAXII 伺服器成功查詢 ATT&CK 數據
- APT 組織已對應至所有記錄在案的技術,並附有程序範例
- Navigator 圖層 JSON 在 ATT&CK Navigator 中驗證並正確渲染
- 多圖層疊加顯示威脅行為者與檢測覆蓋範圍的對比
- 檢測缺口分析識別出未監控的技術,並提供資料來源建議
- 跨組織比較揭露了共同與獨有的 TTP
- 輸出結果對檢測工程排程優先順序具有可行動性