网络安全领域现在最热的词,除了ATT&CK,大概就是知识图谱。前段时间我把两者凑到一起,做了一个以ATT&CK为骨架的网络安全知识图谱,从框架梳理、数据抽取到图存储和查询,完整跑了一遍。这篇分享就把整个设计思路、踩过的坑和可直接复用的实现方案都写出来。适合正在做威胁情报、SIEM/SOAR、安全运营自动化的同学,也适合刚进安全行、想搞清楚ATT&CK怎么落地的朋友。
1. 为什么是ATT&CK?知识图谱为什么比表格好用
1.1 ATT&CK补齐了安全知识建模的哪块拼图
先回答一个基础问题:为什么选ATT&CK当骨架?因为安全领域的知识本来就很零碎。一份威胁报告说“某组织通过钓鱼邮件投放恶意文档”,另一份日志说“某个进程执行了powershell命令”,第三份扫描结果说“某个主机存在远程代码执行漏洞”。这些信息单独看都没头绪,串起来才发现是一条攻击链:钓鱼获取初始访问,PowerShell作为执行手段,漏洞被用来提权。ATT&CK的价值就在于,它用统一的语言把攻击行为拆成了战术(Tactic)、技术(Technique)、子技术(Sub-technique)和具体过程(Procedure)。
以ATT&CK为骨架,其实就是让所有安全实体都能挂到一套明确的坐标系上。攻击者是谁、用了什么武器、干了什么动作、处于攻击的哪个阶段、对应什么检测逻辑,全部可以被标注、被关联、被检索。没有这个坐标系,安全数据就是一盘散沙;有了它,知识图谱才能真正“长”出结构。
1.2 关系型表解决不了的问题,图能解决
很多人会问:我建几张表存攻击组织、攻击技术和样本信息不就完了,为什么非要搞知识图谱?我的回答是:凡是需要反复多跳查询、路径分析、相似性比较的场景,表格会让你的SQL越来越难看,而且性能越查越差。
举个例子,安全分析师收到一条告警“主机A执行了mimikatz”。他需要知道:
- 这个行为对应ATT&CK哪个技术?通常是T1005(OS Credential Dumping的旧编号)或者现在的T1003。
- 历史上哪些勒索软件组织用过这个技术?
- 这家企业有没有部署对应的检测规则?
- 如果主机A属于域控,那下一步攻击者大概率会做什么?
这种“行为 -> 技术 -> 组织 -> 攻击阶段 -> 影响资产”的链路,在关系型数据库里要做四五次join,在知识图谱里就是一条路径查询,几行Cypher就能跑完。更关键的是,图结构可以让你顺着边不断扩展,发现原来没注意到的关联。比如某两个看似不相干的恶意样本,可能共同使用了同一个C2基础设施、同一个UAC绕过技术、同一个诱饵文档模板,图模型下这种“二阶关联”很容易曝光。
1.3 知识图谱安全建设的整体目标
回到项目本身。我定的目标不是做一个放满数据的“展示大屏”,而是搭建一个可供内部使用和外部扩展的知识底座。具体需要满足三个能力:
- 查询检索:用自然语言或结构化查询,快速定位技术、组织、样本、漏洞。
- 关联分析:从任意一个实体出发,顺藤摸瓜找出相关对象和攻击路径。
- 推理支撑:把ATT&CK技术映射到检测规则、缓解措施和风险评分,给告警分析提供上下文。
这个项目选择从ATT&CK的公开框架入手,而不是从某个客户处采集一套私有数据库,是为了数据质量可控、可验证、可自动化更新。MITRE官方发布了结构化的STIX 2.1数据,直接解决了知识抽取中最头疼的“实体边界和关系类型”问题,让我们把精力集中在业务建模和应用开发上。
2. 知识图谱的核心设计思路与本体建模
2.1 确定实体类型和关系类型
图谱的第一步是定义“有什么节点”和“节点之间有什么边”。ATT&CK框架本身给出了很清晰的实体划分:
- 攻击组织(Group):被威胁情报社区跟踪的APT组织或攻击团伙。
- 恶意软件(Malware):样本、家族、加载器、远控等。
- 战术(Tactic):攻击者在攻击链中想要达到的目的,比如初始访问、执行、持久化等。
- 技术(Technique):达到某个战术目的的具体方式,例如T1059表示命令和脚本解释器。
- 子技术(Sub-technique):对技术的细粒度拆解,例如T1059.001是PowerShell。
- 缓解措施(Mitigation):降低攻击面或阻断攻击动作的安全配置、系统控制。
- 检测方案(Detection):用于发现该攻击行为的日志源、规则和信号。
- 漏洞(Vulnerability):被技术利用的安全弱点,例如CVE编号。
- 资产(Asset):组织内真实的主机、服务、域控、数据存储。
关系类型按是否来自ATT&CK官方数据来区分。官方数据源里天然存在“组织使用技术”“恶意软件使用技术”“技术属于战术”“技术可以被缓解/检测”这几类关系。业务扩展关系则包括“漏洞影响到资产”“资产运行了软件”“告警关联到技术”“报告提到组织”等。
我用表格整理了一份简化的关系清单,供参考:
| 起始节点 | 关系 | 目标节点 | 示例 |
|---|---|---|---|
| Group | USES | Technique | APT28 -> T1566 Phishing |
| Malware | USES | Technique | Emotet -> T1059.001 PowerShell |
| Technique | BELONGS_TO | Tactic | T1136 -> Persistence |
| Technique | CAN_BE_MITIGATED_BY | Mitigation | T1055 -> M1028 |
| Technique | CAN_BE_DETECTED_BY | Detection | T1003 -> Windows Event 4104 |
| Vulnerability | EXPLOITED_BY | Technique | CVE-2021-34527 -> T1210 |
| Asset | RUNS | Software | host-42 -> mimikatz |
| Software | IMPLEMENTS | Malware | powershell.exe -> Agent Tesla |
这里有个关键设计思路:不要过度设计。一开始我也想把CVSS、时间线、情报置信度、数据源置信度全部模型化,后来发现实体和关系过多会让图谱很快变成一团乱麻。建议先保留核心的ATT&CK链和质量分数属性,后续需要再逐步增加属性字段或边类型。
2.2 属性如何设计:节点属性和边属性
节点属性建议保留“稳定标识”和“展示信息”两类。稳定标识包括STIX ID、ATT&CK ID、指纹HASH、CVE编号;展示信息包括名称、描述、URL、发布时间等。
边属性必须保存证据和支持信息。这是知识图谱和普通关系型模型最大的区别。原始的“USES”关系没有任何额外信息,但在实际安全运营里,我们一定想问:“凭什么说这个组织用了这个技术?可信度多少?”
我的做法是给核心关系加上三个属性:
- source:来源情报报告、工具扫描结果、日志规则或官方参考。
- confidence:0到1之间的置信度,初始由抽取算法给出,人工审核后更新。
- timestamp:证据产生或引用的时间,便于做时间衰减分析。
比如一条从「北极熊小组」到「T1566」的USES关系,如果来源是某安全厂商2023年的公开报告,我会写成confidence: 0.9;如果只是从某个论坛帖子里的模糊表述抽出来的,初始只有0.5,后续需要运营人员确认。这样当安全分析师看到“某组织使用了某技术”时,他能一眼看到这条知识是硬证据还是软推断。
2.3 为什么把战术层单列出来
有人会问:Tactic不就是一个ATT&CK技术矩阵里的列吗?有必要单列成实体吗?非常有必要。战术描述的是“意图”,技术描述的是“动作”。单列Tactic节点能让我们快速查询“某个攻击者最常用的前置战术是什么”“某类技术集中在哪个攻击阶段”。而且攻击链分析天然关心流程:初始访问 -> 执行 -> 持久化 -> 提权 -> 防御规避 -> 横向移动。把Tactic单独建模,就可以用路径算法快速还原攻击链。
3. 数据采集与实体关系抽取
3.1 从ATT&CK官方源开始,而不是自己造数据
构建网络安全知识图谱,最大的难点不是图数据库操作,而是“数据从哪来、质量怎么保证”。我的策略是:
- 首选官方结构化数据。
- 其次用公开威胁情报报告做增量补充。
- 最后才考虑从日志和告警中自动抽取。
MITRE ATT&CK提供了STIX 2.1格式的数据包,涵盖Enterprise、Mobile、ICS三个领域。每个对象有明确的type、id、name、description,加上攻击组织/恶意软件与technique的relation。直接在脚本里下载,解析后批量写库,比手工录入要可靠得多。比如从官方源码库拿到enterprise-attack.json后,可以先过滤出object-type: technique、tactic、malware、intrusion-set等对象,再用STIX模式里的kill_chain_phases关系把tactic和technique串起来。
这里切记要保留STIX对象的external_references字段。里面包含ATT&CK ID,像T1059,以及对应的MITRE官网URL。这些是后续关联到检测规则、漏洞库和外网情报报告的关键锚点。
3.2 非结构化文本怎么抽取:基于规则和远程上下文
真正费功夫的是抽取公开威胁报告里的“组织使用某技术”。报告不会写成标准的STIX三元组,它往往是这样的句子:
“TA505在针对金融机构的攻击活动中,使用带有宏的Excel附件获取初始访问,随后通过HTA脚本下发NanoCore。”
要从中抽出「TA505 - USES - T1566」这条边,需要两步处理。
第一步,命名实体识别。识别TA505是攻击组织,Excel附件和宏属于钓鱼攻击形态,HTA脚本是脚本执行类攻击形态。如果已经用BERT之类模型做过微调,可以直接做实体抽取;没有算力条件的话,用远程词典匹配先跑起来也够用。注意实体词典要包含ATT&CK技术名、常见恶意软件家族、CVE编号、威胁组织别名。
第二步,关系抽取。这里不是所有句子都值得建边,需要识别“谁对谁做了什么”。我的经验是先用“动词-宾语”模式自动打标签,比如出现“投放”“发送”“下载”“执行”等动作词后,检查句子中是否包含安全实体;再结合技术名判断,按ATT&CK战术里的上下文关键词做一些修正。例如“PowerShell”“cmd.exe”大概率与T1059.001相关,“mimikatz”“LSASS”大概率与T1003相关。先把这些规则累积起来,就能覆盖相当一部分常见报告。
3.3 动态情报源:厂商宝石IOC和日志中的实时置信度
除了官方和报告,真实业务环境还需要接动态数据,比如威胁情报平台返回的IP、域名HASH,以及SIEM里已经告警的原始日志。对这些数据,我不会一上来就当成事实导入知识图谱,而是记录为“候选证据节点”。
具体做法是维护三类临时节点:Raw_Indicator、Alert、Evidence。它们和核心图谱实体通过临时关系连接。后续人工确认或多次重复出现后,再提升为正式实体关系。这种做法避免了一个误报就把整条知识链污染掉,也让图谱里的数据经过“可信度筛选”。
4. 图数据库选型与图谱实现细节
4.1 存储选型对比:Neo4j、JanusGraph还是HugeGraph
目前做知识图谱,图数据库的选项很多。我以单机和中小规模团队为例,分享几款主流存储的适用场景:
| 数据库 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| Neo4j | 生态成熟、Cypher查询简单、内置路径算法、可视化工具好 | 单机有数据规模上限,集群版收费 | 数据量在亿级以下的内部知识图谱首选 |
| JanusGraph | 分布式、与Hadoop/Spark生态集成好 | 运维复杂、查询表达不如Cypher直观 | 大规模数据、跨多个后端存储 |
| HugeGraph | 国产、API丰富、支持图和OLTP,插件相对好用 | 社区热度不如Neo4j,版本迭代较快 | 需要本地化部署和二次开发团队 |
| ArangoDB | 支持多模型,API灵活 | 图分析算法较少,生态偏小 | 同时需要文档和图的混合应用 |
我最终的方案是Neo4j Community版加单机部署。坏处是没有高可用,好处是快速验证业务逻辑、Cypher表达能力强,很多安全图谱的开源项目也都是用它做演示和原型。如果未来数据量上来,再迁移到分布式图数据库,核心本体设计是通用的,迁移成本并不高。
4.2 从表格数据到Cypher导入脚本
解析完ATT&CK官方JSON后,我写了三套导入流程:
- 节点导入:批量创建Technique、Tactic、Group、Malware节点。
- 关系导入:根据STIX关系对象创建USES、BELONGS_TO、MITIGATES、DETECTS等关系。
- 属性更新:将外部来源的别名字典、置信度、报告链接通过MERGE语句追加到节点或关系上。
用Cypher搭结构的话,大致如下:
MERGE (t:Tactic {id: 'TA0001', name: 'Initial Access'}); MERGE (tech:Technique {id: 'T1566', name: 'Phishing'}); MERGE (g:Group {id: 'G0047', name: 'APT28'}); MERGE (tech)-[:BELONGS_TO]->(t); MERGE (g)-[:USES {confidence: 0.85, source: 'MITRE CTI'}]->(tech);这里必须养成一个习惯:不要用CREATE直接插入节点,除非你能保证数据绝对没有重复。同一实体可能来自官方数据、外部报告和内部日志,反复导入会把图谱搞出一堆同名不同ID的节点。用MERGE等于给实体加了唯一性约束,没有则创建,有则跳过或更新属性。
4.3 图查询实战:如何快速还原一个攻击链
图谱建好之后,最核心的查询就是“给一个起点,找到完整的攻击路径”。比如已知一个恶意软件样本,我想看它、它背后的组织、它使用的技术和对应战术:
MATCH (m:Malware {name: '自家样本ID'})-[r:USES]->(tech:Technique)-[:BELONGS_TO]->(tactic:Tactic) RETURN m.name, r.confidence, tech.name, tactic.name ORDER BY tactic.layer再典型一点,查询“和某组织共用最多技术的其它组织”:
MATCH (g1:Group {name: 'APT28'})-[:USES]->(tech:Technique)<-[:USES]-(g2:Group) WHERE g1 <> g2 RETURN g2.name, count(distinct tech) AS overlap ORDER BY overlap DESC LIMIT 10;这一招在做威胁狩猎和团伙聚类时非常有用。很多组织是未知团伙,单独看它的IOC没法归因,但通过共用技术这条关系,很容易发现它和某个已知组织在行为模式上高度相似,从而给研判提供方向。
4.4 可视化:攻击矩阵导航栏不是终点
ATT&CK Navigator只是把二维矩阵关系可视化,真正的知识图谱可视化需要能表达多跳关系。我推荐用Neo4j Browser做开发期调试,用Gephi做导出分析,用ECharts关系图做内网Web展示。展示的时候注意控制节点数量,一次展示超过几百个节点就会变成“毛线团”。建议按战术或攻击组织做局部子图展示,并允许用户点击节点进行扩展。
5. 应用场景与扩展方向
5.1 告警上下文增强:从单一事件到攻击链
这是知识图谱在安全运营里最直接的价值。传统SIEM只告诉你“这台主机执行了可疑命令”,而图谱可以告诉你:
- 这条命令对应的是ATT&CK T1059.001。
- 这个技术又属于Execution战术。
- 当前资产是否域控服务器,是否有其他Related的技术高概率在后续出现。
- 历史上哪个攻击组织最依赖这个技术,应该按什么优先级去处置。
有了这些上下文,安全分析师不用每次从头翻外部Wiki。图查询一次就能把上下文拉全,处理告警的效率提升非常明显。
5.2 攻防演练与红队模拟:自动生成战术路径
在做攻防演练时,红队往往希望从某个入口出发,列出可以覆盖的战术路径,并从图谱里查找对应的检测措施和缓解方案。用Cypher路径查询可以这样写:
MATCH path = (start:Technique {id:'T1566'})-[:USE*1..4]-(end:Tactic {id:'TA0005'}) RETURN path LIMIT 20;这不是让你完全代替脑力,而是帮助红队快速盘点可能的动作空间,避免遗漏ATT&CK框架里的一些冷门但有效的路径。对蓝队来说,反过来可以针对图谱中的高频路径,优先部署检测点。
5.3 外部情报扩展:关联漏洞和资产
把CVE漏洞节点加入图谱后,可以形成一个闭环:攻击者使用技术 -> 技术利用漏洞 -> 漏洞版本范围 -> 企业资产版本。运维侧通过图谱查询“当前受影响资产有哪些”秒级返回,甚至可以直接接自动化工单系统,在漏洞披露一小时内生成待修复资产清单。这是知识图谱与CMDB结合时最实用的扩展。
6. 常见问题与避坑技巧实录
6.1 实体重复导致图谱膨胀
这是最高频的问题。ATT&CK官方数据里,一个技术可能出现在多种平台、多处描述里;外部报告里也经常把“T1059.001”写成“PowerShell命令执行”而不是标准ID。我的解决办法是:
- 所有核心实体都必须有全局唯一ID,优先使用STIX ID和ATT&CK ID。
- 每次导入数据前先做标准化:名称去空格、统一大写、替换全角字符。
- 使用别名表:把PowerShell、PS、pwsh统一映射到T1059.001。
6.2 置信度过于笼统,影响研判
如果所有关系都是0.9,那这个字段就毫无意义。我把置信度分为三档:基于官方参考0.95,基于厂商报告0.8,基于自动抽取0.5。低于0.5的关系不直接进入核心图谱,只进候选区。实际运营中,我把知识图谱接入SOAR,置信度低于0.7的关系只给参考提示,不做自动阻断决策。
6.3 图谱性能慢:尽量限制路径长度和结果数量
多跳查询确实容易写成“笛卡尔积风暴”。比如匹配所有Group和所有Technique,复杂度会随着节点数指数增长。建议在Cypher里默认加LIMIT 200,必要时使用WHERE限定数据范围。另外,关系属性里有confidence字段,查询时可以先过滤低置信度边,性能会好很多,返回结果也更可信。
6.4 数据更新:拿到增量就全量重建
ATT&CK每半年会更新一次,一些技术会被合并、拆分、改编号。这种元数据变化,增量更新处理起来很痛苦。我的做法是:每个月从MITRE官方拉全量STIX包,丢进一个临时图空间,再跑一次MERGE导入。因为图数据库的MERGE天然支持去重,全量导入次数多一点没关系,只要查询和分析应用层已经用ID做关联,就不会产生脏数据。外部报告和内部数据则采用增量更新,尽量不与官方全量更新混在一起。
7. 一点实操心得,供参考
我在实际做这个项目时,最深刻的体会是:知识图谱的价值不在于你存了多少节点,而在于你能不能把边的逻辑讲清楚。很多人花了一堆时间“搭平台”,最后发现数据没打通,查询还是只能展示静态关系。
我的建议是,先定一个最小的业务闭环,比如“告警 -> 技术 -> 应对措施”,在这个闭环里把数据质量打磨好,再扩展到组织情报、漏洞资产甚至SOAR自动化。图谱是典型的“越用越有价值”的系统,初始阶段数据少没关系,关键是别把边建错,因为后续所有推理和研判都依赖这些关系。
最后分享一个小习惯:每次导入一批新关系之前,我会先在空库里跑几个典型查询,把输出结果和外部专家已知结论比对一遍,比如“某个已知APT组织是否在库内被正确关联到它的标志性技术”。确认无误后再全量导入。这样能显著减少后期返工,也让图谱真正成为一个安全团队可信赖的知识底座。