资讯详情

MITRE ATTCK文本标注:分层多标签分类模型实践

发布时间:2026/9/26 13:49:10

500+
企业客户服务经验
120+
行业领域内容覆盖
3000+
原创页面设计沉淀
98%
客户满意度

MITRE ATTCK文本标注:分层多标签分类模型实践

做安全运营或者威胁情报分析的朋友应该都熟悉这样的场景一篇APT报告、一条告警日志、一堆威胁情报摘要堆在你面前你需要判断它属于MITRE ATTCK的哪个战术阶段、哪个具体技术。这种“文本→ATTCK标签”的映射工作如果全靠人工完成不仅慢而且不同人标出来的结果往往对不上。所以我做了这个“MITRE ATTCK文本标注的多标签分层分类模型”让模型自动把一段安全文本打上多个战术和技术标签并且利用ATTCK自身的层次结构来组织分类过程。这篇文章把我从数据标注、模型选型到训练推理的完整过程记录下来适合正在做安全运营自动化、威胁情报解析和告警降噪的朋友参考。1. 为什么把“文本→ATTCK标签”做成一个分层多标签问题1.1 人工映射标签真的会把人逼疯我先说一个真实感受人肉把安全文本映射到ATTCK是一件看着简单、做起来极其痛苦的事。原因在于安全文本的表达方式和ATTCK标准的表达方式之间存在一条明显鸿沟。比如有段报告写“攻击者向受害者发送了带有宏的Word文档用户打开后运行了macro随后通过PowerShell下载了Cobalt Strike”。人眼扫一遍能很快形成判断这是钓鱼攻击有执行阶段还涉及脚本解释器。但要落到ATTCK标签上就要经过好几道换算钓鱼对应T1566宏对应T1566.001还是T1204.002PowerShell执行能不能只标T1059.001要不要把Command and Scripting Interpreter的父技术T1059也带上不同的人在这几个问题上的本能反应差别很大标出来的结果五花八门落到下游自动化里就会互相打架。我团队之前做过统计让三个分析师独立标同一批共500条告警文本战术层的一致性还能看技术层的一致率不到六成。这不是分析师水平不够而是ATTCK粒度太细、不同技术之间存在语义重叠人工标注的一致性天然难以保证。所以第一步要做的不是急着训练模型而是承认“人肉映射不可规模化、不可复现”然后把问题定义清楚这是一个文本多标签分类任务。1.2 一条文本对多个标签这是常态而非常态刚开始做这个项目时有人建议我简化成“一条文本只预测一个最相关的技术标签”。听起来省事实际跑不通。因为安全事件的真实形态就是多步骤、多战术阶段并存的。最典型的例子就是钓鱼邮件攻击邮件投递属于“初始访问”阶段用户点击执行宏或者链接属于“执行”阶段后续下载payload又可能落到“命令与控制”阶段。一条文本描述了这个完整链条如果模型只准输出一个标签等于逼它在一堆正确答案里只挑一个信息损失非常大。所以标签输出必须多标签化。每个样本的输出不是一个标签而是一个标签集合。在训练目标上就是对每个候选标签做独立的二分类判断用Binary Cross Entropy来学习。多标签设计看着只是把模型输出层改一下其实它直接决定了数据标注方式、评估指标和推理策略都应该提前想好。1.3 分层不是炫技而是为了对付那个“几百个标签”的分类难题既然是多标签那能不能直接把所有标签拉平做一个扁平的多标签分类器理论上可以实践中很难受。因为ATTCK企业主矩阵里目前有十几个战术、四百多个技术加上子技术数量更大。如果全部拉平作为输出空间模型要在一个几百类的空间里做判断而多数标签在训练语料里只出现几十次甚至几次数据极度稀疏模型很难学明白。这就引出分层分类的核心价值利用ATTCK本身的“战术—技术”层次关系把一个大而难的问题拆成两步。第一步只判断文本涉及哪几个战术类别空间只有十几类第二步再根据命中的战术把技术预测限制在该战术下的候选技术集合里类别空间一下子从几百缩小到几十。这样每一个二分类器要学的模式都更聚焦数据利用率也更高。我后来把这种方式称为“两段式约束分类”本质上不是两个模型独立跑而是让上层战术预测结果作为下层技术预测的条件和先验。这也是这个项目里“分层”两个字的关键所在。2. 数据和标签体系建模前最容易被低估的一步2.1 先把ATTCK的层次关系固化成一张约束表动手写模型前我先做了一张“约束表”。这张表长什么样很简单三列战术ID、战术名称、该战术下包含的所有技术ID和技术名称。tactic_id, tactic_name, technique_ids TA0001, Initial Access, T1091|T1190|T1199|T1566|T1133|... TA0002, Execution, T1059|T1204|T1203|T1106|T1047|...这张表不是从文档里复制粘贴就行而是要从ATTCK的技术关系数据里整理出来并且最好定期更新。因为ATTCK每年都会加新技术、调整归类如果约束表过期模型预测的技术可能根本不在当前版本里。整理这张表时要特别注意ATTCK的“战术—技术”关系并不是严格的树形结构一个技术可能出现在多个战术下。比如T1059Command and Scripting Interpreter既出现在执行战术也出现在“防御规避”甚至“渗透”相关战术里分别代表脚本执行和脚本绕过检测的不同场景。所以约束表不能做成“技术只能属于一个战术”的互斥结构而要保留“一对多”的关系。后续做技术层分类时候选集是多个战术候选并集的叠加而不是某个单一战术的子集。2.2 语料来源、清洗和标注闭环约束表做好后接下来是语料。这个模型的语料可以从三个方向收集公开威胁情报报告、企业内部的告警和安全事件工单、以及安全博客和技术文档中对攻击手法的描述。其中最容易踩坑的是“直接用现成标注数据”。网上很多公开数据集确实带ATTCK标签但它们的标注口径、技术和子技术粒度可能和你需要的完全不同。比如有的数据只标到战术层有的把子技术标得很细有的把“技术编号”和“攻击步骤”混在一起。我建议把公开数据只当预训练或者辅助训练资源核心训练集还是要按自己的标注规范重新做一遍。文本清洗这块我提三个优先级很高的操作。首先是去掉所有URL、IP、哈希值和域名因为这些IOC会对模型产生强干扰——模型可能学会“看到IP就是初始访问”从而忽略真正的语义特征。其次是过滤掉模板化内容比如漏洞报告里的“受影响版本”清单、厂商免责声明这些段落和攻击行为描述无关。第三是如果原始报告带有厂商自己的威胁分类名词比如“Ransomware”“恶意文档”这类词信息量大但也容易让模型偷懒只按厂商分类走不真正学习ATTCK结构所以清洗时可以根据情况做归一化或保留为辅助字段。标注流程也不能让一个人单干。我建议至少两个人独立标注然后对分歧样本做第三方仲裁或会诊。标注界面上把规则提前写清楚比如“子技术命中时是否同时标父技术”“同一战术内多个技术同时出现时是否全部标出”。这些规则看似琐碎实际上直接影响模型训练标签的噪声水平。2.3 标注一致性怎么控制控制标注一致性我用的是Cohen’s Kappa。这个指标好理解它把两人随机碰巧一致的概率也排除掉比单纯算“一致率”真实得多。实操中我对战术层的Kappa目标定在0.8以上技术层定在0.7以上。低于这个值时说明标注规范里还有歧义没解决例如“spearphishing attachment”和“spearphishing link”这两个子技术在样本里经常同时出现如果不定义清楚边界两个人一个标attachment一个标link模型学到的东西就是混乱的。一致性确认之后还要做一次标签分布分析。哪个技术出现次数多、哪个技术几乎没有样本心里要有数。如果某个技术样本数只有个位数那模型大概率学不出来宁可先把它从训练目标里降级或者用“相似技术合并”的思路暂时归并等后续补数据再拆开。3. 模型选型与结构设计最终采用的分层两段式方案3.1 扁平多标签、生成式和层次模型各有什么坑动手前我盘了三种方案分别是扁平多标签分类、生成式文本生成以及分层两段式分类。先说扁平多标签分类。用BERT这类模型编码文本后在输出层直接堆几百个二分类头每个头判断一个技术标签是否出现。这个方案代码最简单但问题明显几百个类别对应几百个二分类头每个头只有少部分样本是正例负例多正例少模型很容易把概率压得很低收敛很慢而且几百个头之间没有任何先验关系等于完全忽略ATTCK的层次结构。实际测试下来宏F1明显偏低特别是低频技术几乎全部漏报。再说生成式方案。当时也想过用T5之类模型做text-to-text把输入文本翻译成一组标签序列。但一个绕不开的问题是输出不稳定性——模型可能生成一个不存在的标签ID或者生成一个和输入的语义完全不符的组合这种非法输出在安全场景里是致命的因为你没法保证模型每次都能遵守ATTCK的约束关系。除非另加复杂的解码约束否则投入产出比不高。所以最终我采用了第三种也就是分层两段式。它不是最花哨的但最符合ATTCK的自带结构每一步都直观可解释也方便在工程上做人工介入。3.2 两段式架构战术分类器技术分类器整体架构分两部分共享一个文本编码器然后分叉出两组分类头。编码器我用的是预训练语言模型英文安全报告用bert-base-uncased中英混合语料我会考虑用XLM-R因为不少国内安全报告是中英混着写的XLM-R跨语言表现更稳。编码器之上第一个分叉是战术分类头。战术层类别只有十几个所以直接做多标签二分类每个战术一个sigmoid输出阈值可以单独调。这里输出的不是一个唯一战术而是一个“战术候选集”。比如文本描述钓鱼攻击链时输出可能是TA0001Initial Access、TA0002Execution、TA0011Command and Control三个战术同时命中。第二个分叉是技术分类头。它做预测的时候不是对四百多个技术都打分而是先取上一阶段预测出的战术集合根据约束表把所有相关技术合并成候选集再在这个候选集上给每个技术做二分类打分。这里要特别说明“候选集并集”的处理。因为ATTCK里一个技术可能归属多个战术比如T1059既在执行战术里也在防御规避战术里所以候选集是“预测战术对应技术列表的并集”。如果预测出TA0002和TA0001两个战术候选集就等于TA0002下所有技术加上TA0001下所有技术再删掉重复。这样既控制了搜索空间又避免漏掉跨战术技术。训练时我采用了真实战术标签约束技术头的方案也就是teacher forcing推理时则用预测战术来约束。这样做的好处是训练时技术头能更集中地学习本战术范围内的模式但代价是推理时会存在误差传递如果第一步战术预测错了第二步的候选集会跟着错。所以推理阶段要加防御机制后面会细说。3.3 联合训练时的细节战术头和技术头可以单独训练也可以联合训练。单独训练的好处是实现简单、每个模块的metric很清楚联合训练的好处是文本编码器能学到对战术和技术都有用的共享表示。我实际采用的是“先单独预热后联合微调”的两阶段式训练法。具体做法是先用战术层标注预训练一个战术分类器让它先具备基本的战术判断能力然后在这个基础上加上技术头用两个loss相加联合微调。这样编码器既不会在一开始被技术层的噪声带偏又能在微调阶段学会面向技术分类的语义细节。Loss设计上战术层和技术层都各自使用BCEWithLogitsLoss。要注意的地方是两个loss不能简单等权相加我习惯先让战术loss权重为1技术loss权重在0.5到1之间搜索看验证集的表现动态调整。原因在于技术层label更稀疏、更难学如果权重太大会把编码器拉成“只盯技术细节忽略整体语义”反而降低战术层的效果。4. 训练、评估和推理的关键参数与实操4.1 训练参数和损失函数的处理训练参数我直接给一组可以参考的默认值学习率2e-5batch size 8到16max token length 256到512warmup ratio 0.1epoch 5到10之间用早停判断收敛。这里有一个经常被忽略的问题多标签分类的模型输出层要处理好loss函数。HuggingFace的BertForSequenceClassification默认用的是交叉熵那是给单标签分类用的。多标签场景下必须把输出维度改成类别数然后自己用BCEWithLogitsLoss把logits和标签算损失或者在config里设置problem_typemulti_label_classification。如果你忘了改训练不会报错但loss和指标会一样离谱属于典型的“看起来能跑结果全错”。另一个细节是文本长度。威胁情报报告经常很长几百token是常事。如果直接截断很可能把“攻击者通过XX漏洞获取权限”这种关键句截丢了。我建议先做敏感的句级切分或者用简单规则把文本切成段落让模型先对每段做预测最后在段落预测上做聚合而不是粗暴地从头截断。这个操作对我的效果提升非常明显尤其是技术层F1。4.2 评估指标别只盯着F1多标签分类的评估不能只看一个笼统的F1就交差。我在项目里同时看四组指标micro F1、macro F1、hamming loss以及为了贴合层次关系专门设计的“层次有效F1”。micro F1把样本合并后计算容易被高频类别带跑偏反映的是整体“量大不大”macro F1对每个类别算出来再平均能反映低频技术有没有被照顾到hamming loss则直接看每个标签位上的预测错误比例多标签场景下比accuracy更直观。那个“层次有效F1”我要单独说一下。它是这样定义的一个技术标签只有在它对应的战术标签也预测正确时才计入技术层的正确预测。比如真实标签是战术TA0002技术T1059模型战术层预测正确、技术层也预测了T1059那么这个T1059才算有效命中如果模型战术层只预测了TA0001哪怕技术层也预测了T1059这个T1059也不计数。这个指标很关键因为普通F1不会惩罚“战术错但技术撞对”的情况。一个模型如果只学了一堆高频技术词不管上下文它tactic可能错一堆但technique F1看起来还不差。层次有效F1能把这种隐性问题暴露出来同时也能为后续选择推理阈值提供依据。我评估时还会单独输出每个标签的precision、recall和F1形成一张标签级报表。因为不同战术和技术的样本分布差异太大只用汇总指标会掩盖低频技术完全没学会的问题。4.3 推理流程阈值、约束和复核机制推理阶段模型输出的是一堆sigmoid概率怎么变成标签集合答案是取阈值。但阈值怎么定别靠感觉拍脑袋。我的做法是在验证集上做阈值扫描比如对0.3到0.8每隔0.05扫一遍选出使得层次有效F1最高的阈值。战术层和技术层的阈值可以不一样分开扫。推理流程按下面的伪代码走def predict(text): logits_tactic, logits_technique model.encode(text) probs_tactic sigmoid(logits_tactic) pred_tactics { tactic_id for tactic_id, p in zip(TACTIC_IDS, probs_tactic) if p threshold_tactic } # 由预测战术推导技术候选集 candidate_techniques set() for tactic_id in pred_tactics: candidate_techniques | TACTIC_TO_TECHNIQUES[tactic_id] # 只对候选集中的技术打分 probs_technique sigmoid(logits_technique) pred_techniques { technique_id for technique_id in candidate_techniques if probs_technique[technique_id] threshold_technique } # 防御如果战术为空但某个技术分数极高暂不输出转人工 if not pred_tactics and pred_techniques: return {tactics: [], techniques: [], review: True} return {tactics: sorted(pred_tactics), techniques: sorted(pred_techniques), review: False}我特别说一下候选集约束配合阈值时的一个坑当预测战术集合很小比如只预测了一个战术那么候选技术集合就小漏召回的概率会增大反过来如果预测战术集合过大候选技术集合太大又可能冒出很多低分误报。所以推理时需要为战术层设置一个“最小召回阈值”宁愿让战术多预测几个候选也不要漏掉可能的战术。后续技术层再通过更严格的阈值把噪声过滤掉。另外模型对某些输入可能会输出“空标签”也就是战术层和技术层都低于阈值什么也没预测。这时候不要硬塞一个标签更合理的是把它送到人工复核队列。安全场景里“宁缺毋滥”错误标签比没标签更容易误导下游。5. 踩坑实录与排查速查表5.1 几个让我记忆深刻的坑第一个坑是高危IOC把模型带偏。第一次跑通以后我单独检查模型权重发现它对“攻击者通过RDP对外开放的3389端口进入内网”这种文本预测出T1133External Remote Services的置信度异常高。后来查数据发现训练语料里大量样本包含了外网IP泄露的模板模型已经学会“看到外网IP就联想远程服务”。把IOC清洗掉以后这个问题明显缓解。第二个坑是低频率技术完全学不到。开篇我提到的几百个技术标签里像T1059、T1566这类高频技术flooding整个训练集而很多高价值B级技术只出现几次。结果就是模型在这些低频技术上recall几乎为0。后来我做了三件事缓解一是对低频技术做欠采样和过采样但幅度不过大避免模型死记硬背二是坚持先预测战术再预测技术的结构让低频技术在战术约束下仍然能获得候选机会三是利用父技术的训练信号辅助子技术把T1059.001和T1059当作“相关标签”一起建模至少共享一部分表示。第三个坑是告警文本和报告文本的差异。报告文本写得很完整主谓宾齐全模型学起来容易真实告警文本往往就是“powershell -enc ...”“cmd.exe /c whoami”这种零碎字符串语义信息密度低。模型在报告测试集上表现不错一上真实告警就歇菜。这个问题的解决思路不是调整模型而是把告警原始文本做结构化重建把命令行抽取出来、把动作动词归一化、把二进制路径映射成已知恶意软件家族名再喂给模型。说白了文本质量比模型结构更能决定天花板。5.2 高频问题排查速查表下面是我总结的高频问题速查表按“现象→排查思路→解决方向”的格式整理方便你上线后快速定位问题。现象可能原因排查顺序与解决方向预测全为空标签阈值设置过高IOC清洗过度导致文本信息太少语料里包含大量模板段落先看验证集阈值扫描曲线降低战术层阈值检查输入文本样例技术层几乎无输出战术层预测过少导致候选集太小技术层阈值过高低频技术样本太少调大战术层召回降低技术层阈值补充低频技术语料战术层预测过多战术层阈值过低文本本身多步骤描述过于碎片化提高战术层阈值对长文本做段落聚合而不是整文预测高频技术准确率高、低频技术准确率差标签不均衡严重分层约束没有真正影响编码器检查标签级F1报表考虑先按父技术聚合训练再在推理时拆分真实告警效果远差于测试集训练语料偏向报告长文本告警短文本语义不足对告警做结构化重建加入真实告警微调训练集子技术和父技术同时预测冲突基础标签规则定义不清数据标注时没有统一“是否同时标父技术”回查标注规范推理时加入既定规则补全父/子技术5.3 工程闭环上的一点建议模型上线后不要让它孤立运行。我最终做了一个小闭环模型输出标签和对应证据片段全部存到索引里安全分析师可以直接看到“为什么这条文本被标成T1059.001”因为证据片段是“使用PowerShell执行恶意脚本”。这个设计不仅提升信任度还能发现模型的隐性问题。然后每个季度做一次周期性评估。挑一批增量数据重新跑一遍标签级F1对比历史曲线。一旦某个技术的F1明显回落大概率是ATTCK版本更新导致标签语义漂移或者新增的攻防模式没有被模型见过。这时候再决定要不要补语料继续训练。对于团队没有足够标注人力的情况一个很实际的做法是先上规则基线。用关键词和正则召回候选标签再用本文的分层模型做排序。规则打底模型精排冷启动阶段能少踩很多坑也能尽早给分析人员提供辅助价值。我在实际做完这个项目后最深的一个感受是分层多标签分类的模型部分其实不难难的是把ATTCK的层次约束、数据标注的规范和推理阶段的工程闭环串起来。多标签是输出层的事分层是结构设计的事而真正决定模型能不能在生产环境里被信任的是数据质量和人工复核机制。如果你也想做类似系统我建议从约束表整理和标注规范入手先把这一步做扎实再谈模型结构。否则再好的模型也会被混乱的标签数据拉下水。
热门专题

继续阅读更多专题内容

围绕企业服务、数字化转型与官网运营的常青话题,持续输出深度内容

企业官网建设指南 企业托管服务模式 财税政策与解读 企业数字化转型 官网SEO与获客 网站安全与运维
配套服务

读完这篇文章,了解更多服务

从整站搭建到SEO布局,17项核心服务助您打造高转化的企业官网

01

企业托管整站搭建

从信息架构到栏目预留,搭建可生长的企业站点骨架,每个页面独立原创设计。...

了解详情
02

规整可信网页设计

雪地靴温暖风原创设计,金属铜线条贯穿全页,拒绝通用模板与AI流水线。...

了解详情
03

企业服务SEO布局

关键词体系与语义化结构,从建站源头为搜索排名而生。...

了解详情
04

业务预约咨询表单

多场景表单与线索收集体系,把访问流量转化为可追踪的销售线索。...

了解详情
05

企业服务站点运维

安全巡检、数据备份与内容更新支持,全年守护网站稳定运行。...

了解详情
06

全终端商务适配

电脑、平板、手机一致呈现,移动端体验与转化同样出色。...

了解详情
需要专业建议?

让专业顾问为您解读行业趋势

关于企业官网建设、SEO获客与数字化转型的任何疑问,欢迎一对一咨询我们的专业顾问。