利用MITRE ATT&CK分析威胁行为者TTP 是做什么的?
概述
MITRE ATT&CK是一个基于真实世界观测的、全球可访问的对手战术、技术和程序(TTP)知识库。本技能涵盖如何系统地将威胁行为者行为映射到ATT&CK框架、使用ATT&CK Navigator构建技术覆盖热力图、识别检测漏洞,并生成将观测到的IOC与企业、移动和ICS矩阵中特定对手技术关联的可行情报报告。
适用场景
- 调查涉及利用MITRE ATT&CK分析威胁行为者TTP的安全事件时
- 构建该领域的检测规则或威胁狩猎查询时
- SOC分析师需要此类分析类型的结构化流程时
- 验证针对相关攻击技术的安全监控覆盖范围时
前提条件
- Python 3.9+ 并安装
mitreattack-python、attackcti、stix2库 - MITRE ATT&CK Navigator(基于网页或本地部署)
- 理解ATT&CK矩阵结构:策略、技术、子技术
- 可访问威胁情报报告或MISP/OpenCTI以获取威胁行为者数据
- 熟悉STIX 2.1攻击模式对象
关键概念
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()
# 构建数据源覆盖图
data_source_coverage = {}
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)
# 比较威胁行为者技术与现有检测能力
detected_techniques = {"T1059", "T1071", "T1566"} # 示例:你能检测的技术
actor_techniques = set(technique_map.keys())
covered = actor_techniques.intersection(detected_techniques)
gaps = actor_techniques - detected_techniques
print(f"\n=== 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}%)")
print(f"\n未检测到的技术:")
for tech_id in sorted(gaps):
if tech_id in technique_map:
print(f" {tech_id}: {technique_map[tech_id]['name']}")
步骤5:跨团体技术比较
from attackcti import attack_client
lift = attack_client()
# 比较多个团体的技术
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:
tid = t.get("external_references", [{}])[0].get("external_id", "")
if tid:
tech_ids.add(tid)
group_techniques[gname] = tech_ids
# 找出共同和独特的技术
all_groups = list(group_techniques.keys())
common_to_all = set.intersection(*group_techniques.values())
print(f"\n所有{len(all_groups)}个团体共用的技术数: {len(common_to_all)}")
for tid in sorted(common_to_all):
print(f" {tid}")
for gname, techs in group_techniques.items():
unique = techs - set.union(*[t for n, t in group_techniques.items() if n != gname])
print(f"\n{gname}独有的技术: {len(unique)}种")
验证标准
- 通过TAXII服务器或本地副本成功查询到ATT&CK数据
- 威胁行为者已映射到特定技术并附有程序示例
- ATT&CK Navigator层JSON有效且能正确渲染
- 检测漏洞分析能识别出未监控的技术
- 跨团体比较揭示了共享和独特的TTP
- 输出对检测工程优先级排序具有可操作性