使用MITRE ATT&CK分析威脅行為者TTPs
概述
MITRE ATT&CK是一個基於真實世界觀察,全球可存取的敵對戰術、技術及程序(TTPs)知識庫。此技能涵蓋如何系統性地將威脅行為者行為映射到ATT&CK框架、使用ATT&CK Navigator建立技術覆蓋熱力圖、識別檢測缺口,並產出可操作的情資報告,將觀察到的IOCs與企業、行動裝置及ICS矩陣中的特定敵對技術連結起來。
使用時機
- 調查安全事件,需要分析威脅行為者的TTPs時
- 為此領域建立檢測規則或威脅狩獵查詢時
- SOC分析師需要此類分析的結構化流程時
- 驗證針對相關攻擊技術的安全監控覆蓋率時
先決條件
- Python 3.9+,並安裝
mitreattack-python、attackcti、stix2程式庫 - MITRE ATT&CK Navigator(網頁版或本地部署)
- 了解ATT&CK矩陣結構:戰術、技術、子技術
- 可存取威脅情資報告或MISP/OpenCTI以取得威脅行為者資料
- 熟悉STIX 2.1 Attack Pattern物件
關鍵概念
ATT&CK矩陣結構
ATT&CK企業矩陣將敵對行為組織成14個戰術(「為什麼」),包含技術(「如何做」)與子技術(具體實作)。每項技術都有相關的資料來源、檢測方式、緩解措施,以及來自觀察到威脅群組的真實世界程序範例。
威脅群組概況
ATT&CK收錄了超過140個威脅群組(例如APT28、APT29、Lazarus Group、FIN7),並記錄了它們使用的技術。每個群組概況包括別名、目標產業、相關活動、使用的軟體,以及帶有程序層級細節的技術映射。
ATT&CK Navigator
ATT&CK Navigator是一個基於網頁的工具,用於建立自訂的ATT&CK矩陣視覺化。分析師建立圖層(JSON檔案),為技術加上分數、顏色、註解與中繼資料,以視覺化威脅行為者覆蓋率、檢測能力或風險評估。
工作流程
步驟1:程式化查詢ATT&CK資料
from attackcti import attack_client
import json
# 初始化ATT&CK客戶端(查詢MITRE TAXII伺服器)
lift = attack_client()
# 取得所有企業技術
enterprise_techniques = lift.get_enterprise_techniques()
print(f"企業技術總數:{len(enterprise_techniques)}")
# 取得所有威脅群組
groups = lift.get_groups()
print(f"威脅群組總數:{len(groups)}")
# 依名稱取得特定群組
apt29 = [g for g in groups if 'APT29' in g.get('name', '')]
if apt29:
group = apt29[0]
print(f"群組:{group['name']}")
print(f"別名:{group.get('aliases', [])}")
print(f"描述:{group.get('description', '')[:200]}")
步驟2:將威脅行為者映射到ATT&CK技術
from attackcti import attack_client
lift = attack_client()
# 取得APT29使用的技術
apt29_techniques = lift.get_techniques_used_by_group("G0016") # APT29群組ID
technique_map = {}
for entry in apt29_techniques:
tech_id = entry.get("external_references", [{}])[0].get("external_id", "")
tech_name = entry.get("name", "")
description = entry.get("description", "")
tactic_refs = [
phase.get("phase_name", "")
for phase in entry.get("kill_chain_phases", [])
]
technique_map[tech_id] = {
"name": tech_name,
"tactics": tactic_refs,
"description": description[:300],
}
print(f"\nAPT29使用了{len(technique_map)}項技術:")
for tid, info in sorted(technique_map.items()):
print(f" {tid}: {info['name']} [{', '.join(info['tactics'])}]")
步驟3:產生ATT&CK Navigator圖層
import json
def create_navigator_layer(group_name, technique_map, description=""):
"""為威脅群組產生ATT&CK Navigator圖層JSON。"""
techniques_list = []
for tech_id, info in technique_map.items():
techniques_list.append({
"techniqueID": tech_id,
"tactic": info["tactics"][0] if info["tactics"] else "",
"color": "#ff6666", # 紅色表示已觀察到的技術
"comment": info["description"][:200],
"enabled": True,
"score": 100,
"metadata": [
{"name": "group", "value": group_name},
],
})
layer = {
"name": f"{group_name} TTP覆蓋",
"versions": {
"attack": "16.1",
"navigator": "5.1.0",
"layer": "4.5",
},
"domain": "enterprise-attack",
"description": description or f"歸屬於{group_name}的技術",
"filters": {"platforms": ["Windows", "Linux", "macOS", "Cloud"]},
"sorting": 0,
"layout": {
"layout": "side",
"aggregateFunction": "average",
"showID": True,
"showName": True,
"showAggregateScores": False,
"countUnscored": False,
},
"hideDisabled": False,
"techniques": techniques_list,
"gradient": {
"colors": ["#ffffff", "#ff6666"],
"minValue": 0,
"maxValue": 100,
},
"legendItems": [
{"label": "已觀察到的技術", "color": "#ff6666"},
{"label": "未觀察到", "color": "#ffffff"},
],
"showTacticRowBackground": True,
"tacticRowBackground": "#dddddd",
"selectTechniquesAcrossTactics": True,
"selectSubtechniquesWithParent": False,
"selectVisibleTechniques": False,
}
return layer
# 產生並儲存圖層
layer = create_navigator_layer("APT29", technique_map, "APT29 (Cozy Bear) TTP分析")
with open("apt29_navigator_layer.json", "w") as f:
json.dump(layer, f, indent=2)
print("[+] Navigator圖層已儲存至 apt29_navigator_layer.json")
步驟4:識別檢測缺口
from attackcti import attack_client
lift = attack_client()
# 取得所有技術及其資料來源
all_techniques = lift.get_enterprise_techniques()
# 建立資料來源覆蓋對應
資料來源覆蓋 = {}
for tech in all_techniques:
tech_id = tech.get("external_references", [{}])[0].get("external_id", "")
data_sources = tech.get("x_mitre_data_sources", [])
for ds in data_sources:
if ds not in data_source_coverage:
data_source_coverage[ds] = []
data_source_coverage[ds].append(tech_id)
# 比較威脅行為者技術與可用檢測
已檢測到的技術 = {"T1059", "T1071", "T1566"} # 範例:你可以檢測到的技術
行為者技術集 = set(technique_map.keys())
已涵蓋 = 行為者技術集.intersection(已檢測到的技術)
缺口 = 行為者技術集 - 已檢測到的技術
print(f"\n=== APT29的檢測缺口分析 ===")
print(f"行為者技術總數:{len(行為者技術集)}")
print(f"已檢測到:{len(已涵蓋)} ({len(已涵蓋)/len(行為者技術集)*100:.0f}%)")
print(f"缺口:{len(缺口)} ({len(缺口)/len(行為者技術集)*100:.0f}%)")
print(f"\n未檢測到的技術:")
for tech_id in sorted(缺口):
if tech_id in technique_map:
print(f" {tech_id}: {technique_map[tech_id]['name']}")
步驟5:跨群組技術比較
from attackcti import attack_client
lift = attack_client()
# 比較多個群組使用的技術
欲比較的群組 = {
"G0016": "APT29",
"G0007": "APT28",
"G0032": "Lazarus Group",
}
群組技術集 = {}
for gid, gname in 欲比較的群組.items():
techs = lift.get_techniques_used_by_group(gid)
tech_ids = set()
for t in techs:
tid = t.get("external_references", [{}])[0].get("external_id", "")
if tid:
tech_ids.add(tid)
群組技術集[gname] = tech_ids
# 找出共同與獨有的技術
所有群組 = list(群組技術集.keys())
全部共同 = set.intersection(*群組技術集.values())
print(f"\n所有{len(所有群組)}個群組共用的技術:{len(全部共同)}")
for tid in sorted(全部共同):
print(f" {tid}")
for gname, techs in 群組技術集.items():
獨有 = techs - set.union(*[t for n, t in 群組技術集.items() if n != gname])
print(f"\n{gname}獨有的技術:{len(獨有)}項")
驗證標準
- 成功透過TAXII伺服器或本地副本查詢ATT&CK資料
- 威脅行為者已映射到特定技術,並附有程序範例
- ATT&CK Navigator圖層JSON有效且正確呈現
- 檢測缺口分析找出未受監控的技術
- 跨群組比較揭示共享與獨有的TTPs
- 輸出可用於檢測工程優先排序