关于 analyzing-apt-group-with-mitre-navigator
面向安全分析师的 MITRE ATT&CK 分析技能,用于整理 APT 组织的技术与战术并在 Navigator 中可视化。涵盖多组织比较、检测覆盖差距分析和检测工程报告。
主要功能
- 01查询 ATT&CK 组织与技术数据
- 02生成 Navigator 图层 JSON
- 03比较多个 APT 组织
- 04叠加图层分析检测差距
- 05按战术汇总技术
适用场景
- 01梳理 APT 组织使用的技术
- 02对比组织 TTP 并找出共同点
- 03检查监控覆盖并确定检测优先级
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill analyzing-apt-group-with-mitre-navigator安装后在 Claude Code 中输入/analyzing-apt-group-with-mitre-navigator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
使用 MITRE ATT&CK Navigator 分析 APT 组织
概述
MITRE ATT&CK Navigator 是一款基于 Web 的工具,用于标注和探索 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 Enterprise 矩阵:14 个战术、200+ 个技术、子技术
- 可访问威胁情报报告或 MISP/OpenCTI 以获取威胁行为者数据
- 熟悉 STIX 2.1 Intrusion Set 和 Attack Pattern 对象
关键概念
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 编号标识(例如,APT29 为 G0016,APT28 为 G0007,Lazarus Group 为 G0032)。
多图层分析
Navigator 支持同时加载多个图层,使分析师能够将威胁行为者 TTP 与检测覆盖范围叠加以识别缺口、比较多个 APT 组织以找到值得优先处理的共同技术,并跟踪技术覆盖范围随时间的变化。
工作流
步骤 1:查询 APT 组织的 ATT&CK 数据
from attackcti import attack_client
import json
lift = attack_client()
# Get all threat groups
groups = lift.get_groups()
print(f"Total ATT&CK groups: {len(groups)}")
# Find APT29 (Cozy Bear / Midnight Blizzard)
apt29 = next((g for g in groups if g.get('name') == 'APT29'), None)
if apt29:
print(f"Group: {apt29['name']}")
print(f"Aliases: {apt29.get('aliases', [])}")
print(f"Description: {apt29.get('description', '')[:300]}")
# Get techniques used by APT29 (G0016)
techniques = lift.get_techniques_used_by_group("G0016")
print(f"APT29 uses {len(techniques)} 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 Coverage",
"versions": {"attack": "16.1", "navigator": "5.1.0", "layer": "4.5"},
"domain": "enterprise-attack",
"description": f"Techniques attributed to {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"Used by {group_name}", "color": color},
{"label": "Not observed", "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("[+] Layer saved: 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"Techniques common to all groups: {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"\nUnique to {gname}: {len(unique)} techniques")
步骤 4:使用图层叠加进行检测缺口分析
# Define your current detection capabilities
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"=== Detection Gap Analysis for APT29 ===")
print(f"Actor techniques: {len(actor_techniques)}")
print(f"Detected: {len(covered)} ({len(covered)/len(actor_techniques)*100:.0f}%)")
print(f"Gaps: {len(gaps)} ({len(gaps)/len(actor_techniques)*100:.0f}%)")
# Create gap layer (red = undetected, green = detected)
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"{'DETECTED' if tech_id in detected_techniques else 'GAP'}: {info.get('name', '')}",
"enabled": True,
"score": 100 if tech_id in detected_techniques else 0,
})
gap_layer = {
"name": "APT29 Detection Gap Analysis",
"versions": {"attack": "16.1", "navigator": "5.1.0", "layer": "4.5"},
"domain": "enterprise-attack",
"description": "Green = detected, Red = gap",
"techniques": gap_techniques,
"gradient": {"colors": ["#ff3333", "#66ff66"], "minValue": 0, "maxValue": 100},
"legendItems": [
{"label": "Detected", "color": "#66ff66"},
{"label": "Detection Gap", "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 Tactic Breakdown ===")
for tactic in tactic_order:
techs = tactic_breakdown.get(tactic, [])
if techs:
print(f"\n{tactic.upper()} ({len(techs)} techniques):")
for t in techs:
print(f" {t['id']}: {t['name']}")
验证标准
- 通过 TAXII 服务器成功查询 ATT&CK 数据
- APT 组织映射到所有已记录的技术,并附有过程示例
- Navigator 图层 JSON 可通过验证,并在 ATT&CK Navigator 中正确渲染
- 多图层叠加显示威胁行为者与检测覆盖范围的对比
- 检测缺口分析识别出未监控的技术,并给出数据源建议
- 跨组织比较揭示共有的和独有的 TTP
- 输出可操作,便于检测工程确定优先级