无C2的投票式恶意软件:四个AI内部决策如何颠覆传统威胁检测
1. 一个没有C2指令的样本恶意软件内部的老哥们先投了个票上周复盘一次授权攻防演练的数据时我盯着终端日志里一个时间戳看了很久。恶意软件在凌晨3:17发起了一次横向移动但全流量回溯显示没有任何外部主机给它下发指令——没有传统意义上的心跳信标没有远程控制器没有账号联动。一开始我以为只是样本静默潜伏后的定时触发直到把它丢进隔离环境反复观察才发现问题远不简单它的决策链路里坐着四个AI攻击动作是这四个模型内部投票之后才拍板的。恶意软件、AI、投票这三个词组合在一起意味着一种完全不同的攻击范式。过去我们分析恶意软件核心问题永远是谁下的令。一个进程做坏事背后总有一条指令链远程攻击者通过C2通道下发命令或至少有一个预编译的硬编码逻辑在按时间、按条件触发。分析师的思路就是顺着这条链往上摸摸到人威胁就闭环了。而这套四AI投票机制把这条链彻底剪断了——样本落地之后所有决策都在主机内部完成一个个上游模型给出各自判断凑够阈值才动手。就算你把样本完整拖进沙箱看到的也只是几个进程在频繁读写共享内存根本找不到谁下的令。1.1 我为什么第一次看到投票会有后背发凉的感觉先说一个背景我平时做红队和恶意代码分析见过大量使用机器学习的恶意样本。绝大多数所谓AI恶意软件其实很粗糙无非是在C2通信里塞了ML分类器做流量伪装或者在免杀环节套一层生成式模型把载荷重写一遍。这类样本的AI部分再花哨也只是工具决策权仍然在远端的人手里模型顶多算个翻译官。但这回的样本不一样。它内部那四个AI各自拥有独立的输入和判断标准最后通过一个投票协议汇总意见。没有人在它们之间传话攻击触发也不需要任何人点头。我把它称为群体决策型恶意软件——攻击意图不再是外部注入的而是模型在特定上下文里涌现出来的。谁写的规则谁设的阈值原始作者只是定了一个框架具体什么时候攻击、以什么方式攻击全是模型自己碰出来的。这种样本对防御体系的冲击不是单点上的而是方法论层面的。传统的检测思路是找异常→关联到人→封堵链路而投票式恶意软件把攻击决策变成了一个黑盒民主过程你看到的是结果横向移动、数据外渗看不到产生结果的辩论过程。更麻烦的是如果把样本放进沙箱它不会复制在真实环境里的行为——因为沙箱里观察到的上下文不同四个AI投出来的票也就不一样。1.2 传统恶意软件的下令链是怎么被剪断的把旧范式和这个新样本放在一起对比会看得更清楚。经典的恶意软件生命周期是投放载体→执行载荷→回连C2→等待指令→执行指令。哪怕是最先进的定向攻击也离不开一个远程控制端因为攻击者需要在关键时刻调整策略。C2信标就是这条链上最粗的一根线防御方只要盯住外部控制端到内部主机的通信就能抓住它的小辫子。投票式恶意软件把这根线拆了。四个AI全部在本地运行样本自带模型文件、自带本地推理库回连动作只在极特殊情况下发生。它不需要C2下发指令因为攻击什么、怎么攻击这些事已经被分解成四个模型各自的评分任务。攻击者真正需要做的是在投放前把所有知识封装进模型权重里剩下的交给投票。这是一种预谋前置执行自动化的架构远程的那个人在打包样本的那一刻就已经把意图写在模型里了后面机器只是按自己的判断去执行。在这个上下文里没人下令不是说没有攻击意图而是攻击意图被移到了人的视野之外。这就像你把一套房贷审批制度写好了审批员换成了四个有主见的AI它们各自评估信用、房产、收入、政策风险最后投票决定放不放款——你不需要亲自打电话催审批。恶意软件也一样它不需要你每天发命令它自己开会、自己拍板。2. 四个AI的分工和那份投票协议既然叫投票就不能只有一张票。这套机制的核心在于分工四个AI对应四种不同的判断维度互相之间不读对方的决策只读对方产出的评分。我后面在仿真环境里复现过一次把四个Agent的黑盒壳子拆开看到的内部结构非常清晰。2.1 四个席位各管一段投票的前提是每个投票人看问题的角度不同否则投出来的票没有信息量。样本里的四个席位可以这样理解Agent席位主要输入输出评分A1侦察席目标存活状态、端口开放情况、服务指纹、补丁信息目标价值分A2策略席内置漏洞库、路径可达性、当前权限状态攻击方案可行分A3规避席主机上安全软件进程、网络出口策略、沙箱特征、用户习惯暴露风险分A4执行席前三者的评分、系统资源余量、运行时间预算综合置信度侦察席的逻辑不复杂类似一个轻量级资产识别器但它输出的不是扫到了什么而是这个目标值不值得我冒风险。它会看目标的开放服务数量、版本指纹和网络拓扑位置给目标打一个0到1之间的分。策略席更像一个规划器输入漏洞库和当前权限后在有限动作空间里选一条它认为胜率最高的攻击路径同样输出一个0到1的可行分。规避席是最有意思的一个席位。它不关心攻击成不成功只关心我做这个动作被发现的概率有多大。它会检查当前主机上有没有EDR进程、防火墙策略有没有异常、系统是不是跑在虚拟机里、网络里有没有蜜罐特征。如果它嗅到沙箱的味道就会给出极低的规避分。执行席则像最终拍板的项目经理它不看重某个具体环节而是把前三项评分加权汇总加上对当前资源状态的判断输出一个最终置信度。这套装修思路的好处是任何一个单一Agent被干扰或欺骗都不至于让整个决策崩盘。你可以在沙箱里伪造环境变量骗过侦察席但规避席可能仍然觉得不对劲把整票拉低。2.2 投票不是举手是带权重的软投票如果用少数服从多数来理解这套投票机制会把它想简单了。它在实现上用的是带权重的软投票每个Agent不只投进攻/放弃这种二元票还附带一个置信度最终决策值是加权和。我复现时采用的协议参数是这样的权重分配侦察席0.25、策略席0.30、规避席0.20、执行席0.25四项权重和为1。决策值S Σ(权重 × 置信度)取值范围0到1。进攻阈值S ≥ 0.62。最低票数至少3个Agent的置信度不低于0.4防止单一高权重Agent独走。一票否决执行席若输出置信度低于0.15无论总分如何直接进入休眠不攻击。投票窗口200到800毫秒之间超时未交票的席位按弃权处理弃权不改变分母只让权重重新归一化。为什么阈值定在0.62而不是0.5因为0.5只反映多数支持而0.62意味着连权重最低的规避席都得给出中等以上的置信度否则光靠侦察和策略两个高权席位很难凑够。换句话说即使其他三个席位都赞成只要规避席觉得暴露风险高S大概率被压在0.6以下。这个阈值在数学上天然给了被发现概率这一项极高的隐性话语权。至于200到800毫秒的投票窗口这是我最欣赏的一个细节。它防止了某席位因为推理太慢而“赖着不走”拖垮整个决策过程。对应的风险是如果某Agent执行环境异常导致推理超时系统会自动弃权按剩余席位重新归一化。这是一种容错设计代价是决策质量下降——在后面的实测里这个设计直接引出了一个意外见4.4。2.3 为什么攻击者要设计成投票而不是弄一个总控AI这是我在分析时反复问自己的问题。样本作者完全可以把四个小模型合成一个大模型让一个总控AI直接决定攻不攻何必多此一举搞投票答案从两个角度都能站住。从生存性看投票架构天然抗斩首。安全软件杀进程是单点打击如果你把决策集中在一个大模型进程里杀它就等于废了整个样本。但投票架构不一样——四个Agent分布在四个独立进程里杀掉一个剩下三个还能靠归一化权重继续投票系统只是降级而非瘫痪。我实测过杀掉规避席进程后剩余三席重新归一化权重S照样能过0.62只是对暴露风险的敏感度下降。这种断一指不断整臂的特性明显是冲着EDR的终结能力设计的。从决策质量看投票本身就是对抗过拟合的手段。一个统一大模型面对复杂环境时容易在某些特定输入组合上犯系统性错误比如在VMware特征明显的蜜罐里照样攻击。而四个分工模型各有各的盲区投票机制相当于把这些盲区互相抵消了一部分。就算策略席对某个漏洞过于乐观规避席只要嗅到蜜罐气息就能把总分拉下来。这是一种工程上的集成学习思维——不追求单个模型的高分而是通过多模型冗余减少整体误判。对恶意软件来说误判的代价是暴露对防御方来说这四个模型互相制衡形成的复杂依赖恰好是最难看懂、最难模拟的部分。3. 投票式恶意软件凭什么绕过现有防御很多熟悉的防御手段在四AI投票机制面前失效这不是玄学而是每一件都能在技术原理上讲清楚。3.1 静态检测模型文件成为新的特征面杀软做静态检测的核心是特征匹配恶意代码里特有的字符串、PE文件的导入表、加壳指纹、固定的文件哈希。传统的恶意软件无论怎么变形总有稳定的特征可以提取。但四AI投票的样本本身就带着一堆模型文件——GGUF、ONNX、SAFETENSORS这些是神经网络权重不是代码。你没法从一个权重张量里提取恶意意图特征因为权重本身只是一堆浮点数。更要命的是攻击者完全可以从开源社区拿现成的通用模型微调后塞进样本。这些模型的原身可能是合法的翻译模型、文本分类模型或视觉模型在杀软的模型识别库里可能被标记为AI工具而不是恶意代码。四个模型又是异构的——不同架构、不同量化方式、不同来源——它们的组合特征空间几乎是无穷的传统特征库根本拼接不出来。我试过把复现样本丢给市面主流查杀引擎结果是三个模型文件全部判定正常只有负责调度的壳层被报可疑。只要攻击者把壳层换成合法白签名程序整个样本就是一套看起来很正常的AI全家桶。3.2 流量侧没有C2就失去了主战场防守方在流量侧最擅长找的是周期性外联和指令下发模式。传统恶意软件总归要回连不管走HTTP隧道还是DNS隧道总有一个可辨识的通信模型。而投票式恶意软件的默认状态是无外联——模型在本地推理决策在本地完成只有攻击成功后才可能产生少量数据回传。这意味着你在流量侧等不到那个熟悉的上报-响应节奏。就算样本在某些环节需要外联比如从远程拉取最新的模型权重更新这种流量也可以做得非常干净——走HTTPS、挂正规CDN、请求间隔随机化。因为模型更新本来就不是高频行为一个月更新一次都算勤快了流量侧那套固定周期探测模型根本没法覆盖这个尺度。我自己的经验是流量侧的AI检测模型在高频短周期通信上效果不错但对低频长周期的大型二进制下载几乎无能为力这正好被投票式恶意软件利用了个正着。3.3 行为分析的最大麻烦行为不可复现沙箱和行为分析引擎的核心假设是同一个恶意软件在真实环境里做什么在沙箱里也会做什么。只要这个假设成立沙箱观察到的行为序列就能用来训练检测模型。投票式恶意软件直接击碎了这个假设。它的攻击动作依赖四个AI在特定上下文里的投票结果而沙箱本身就是一种特殊的上下文。侦察席在沙箱里可能观察到没有域环境没有历史文件流量被代理规避席可能看到存在虚拟机特征“桌面无用户活动”这些输入会把S压到阈值以下。于是沙箱里看到的样本是安静的、无害的而真实环境的用户机器上同样一份样本却能投出进攻票。这是沙箱检测的经典困境——环境感知型恶意软件只不过过去靠硬编码的环境检测条件现在靠模型动态判断让沙箱作者连伪造什么字段才能骗过它都难以确定。我观察到的更麻烦的现象是投票决策是概率性的即使同一环境轻微改动某个输入值比如打开一个文件、改变一下网络延迟就可能让投票结果翻转。行为分析引擎面对的是一只在同样条件下会给出不同行为的恶意软件模型训练起来会极其痛苦——你以为抓到了规律换个输入分布又全变了。3.4 对威胁情报的冲击IoC叙事的终结威胁情报圈子里已经形成了一套固定的工作流拿到样本→提取哈希、域名、IP、文件路径→发布IoC→其他防守方拉黑。投票式恶意软件对这种工作流是全面嘲讽哈希是唯一的但下次攻击者重新微调一下模型权重哪怕只改一个量化参数整个文件的哈希就全变了恶意域名它根本没有C2攻击路径由策略席在运行时决定每次可能不同。你发布的IoC还没配完人家的模型又进化了一轮。真正要做的是把情报粒度从静态指示物升级到行为模式。比如在一台主机上发现四个独立进程、各自加载了深度学习推理库、通过共享内存交换结构化JSON、随后出现命令执行——这类行为组合特征才是对抗投票式恶意软件的可行情报形态。4. 在仿真环境里复现四票攻击我观测到的全过程说再多原理不如拉出来跑一遍。下面是我们在授权靶场里做的复现实验完整链路包括环境搭建、Agent部署、投票过程观测以及三个谁都没预料到的意外。4.1 实验环境与放行策略靶场划分了三个网段攻击网段跑样本和攻击工具内网段放了一台模拟业务服务器Windows Server 一个老旧Web服务管理网段挂日志收集器和网络探针。三网段之间通过防火墙控制互通业务服务器上只开80端口和445端口模拟一个缺乏补丁的中小型企业内网。放行策略上我特意做了两个设置一是沙箱探针只做被动监听不做主动拦截否则观察不到完整的投票过程二是在业务服务器上放了一个低交互蜜罐监听445端口并返回伪造的SMB banner。这么做的目的是想让规避席在投票时能真实看见蜜罐特征观察它对总决策值的影响。模型侧选型遵循能耗最小化原则两个静态分类器用ONNX格式分别做端口服务识别和漏洞匹配一个端侧小模型用GGUF量化承担策略推理的角色但只开了三层网络本质上是一个文本规则映射器规避席则用了一个规则轻量逻辑回归的混合模型。没有引入任何需要联网的大模型接口——这也是这套架构最让人头疼的地方完全离线。4.2 四个Agent的落地形态与共享内存机制Agent进程之间不通过TCP通信避免流量侧被一个简单的网络检测就能盯上。它们用的是操作系统级的共享内存和命名管道——Linux靶机上就是POSIX共享内存和消息队列Windows靶机上换成了命名管道和内存映射文件。每次投票时四个Agent各自向共享内存的投票箱写入一个JSON结构包含席位ID、置信度、决策建议和时间戳。投票箱是一个有界环形队列容量12条记录写满后最早的消息被覆盖。为什么要设计成环形队列因为作者不希望投票历史永久留存——一旦攻击完成清除投票痕迹比遍历删除文件简单得多直接把共享内存对象释放掉就行。这对取证来说是个大麻烦你分析样本的时候投票的历史记录可能已经被覆盖了只能靠日志侧碰运气。调度器在每次发起动作前会做一次轻量模型加载。四个模型的体积控制得很小总大小不到40MB加载完成后常驻内存。这意味着一台2GB内存的旧终端也能跑得动完全符合中小型企业内网里大量老旧机器的实际配置。对防守方来说跑不动AI这个最后的防线也没有了。4.3 投票过程的完整观测记录实验里我抓到了一轮非常完整的投票过程时间线如下时间事件T0s样本执行初始化共享内存四个Agent相继加载完毕T2s侦察席扫描内网段发现业务服务器80端口和445端口开放T3s侦察席写入投票目标价值0.82T4s策略席查询内置漏洞库命中445端口MS17-010类指纹写入可行分0.91T5s规避席检查主机与目标机未发现EDR进程但探测到445端口响应banner与真实服务器不一致蜜罐特征写入暴露分0.21T6s执行席汇总S 0.25×0.82 0.30×0.91 0.20×0.21 0.25×0.85 0.705超过0.62阈值但执行席注意到规避分异常低给出置信度0.60未触发一票否决T7s样本发起445端口漏洞利用蜜罐记录到攻击流量T8s利用失败蜜罐不包含真实漏洞逻辑样本进入下一轮投票T10s第二轮投票中策略席改用80端口Web服务漏洞方案规避席蜜罐特征消失因为目标换了端口暴露分回升到0.58S再次超过阈值T12sWeb漏洞利用成功样本在业务服务器上建立立足点这轮记录完美展示了投票→失败→重新投票→换策略→再进攻的闭环。它不像传统恶意软件那样一条路走到黑而是像红队分析师一样打完一套方案发现不行开个短会换个方案继续。这种自适应性是四AI投票机制最让防御方难受的地方。4.4 实测中谁都没料到的三个意外第一个意外杀掉规避席进程后系统确实降级运行了但降级得比预想更狠。剩余三席权重重新归一化后策略席权重从0.30涨到0.42侦察席从0.25涨到0.35整个系统变得比完整状态更激进。原本需要犹豫半天的攻击杀掉规避席后几乎秒批。这说明防御方如果只做单点清除反而可能触发去抑制效应把恶意软件逼成更莽撞的版本。第二个意外投票窗口的超时机制在低配机器上会反向坑自己。在模拟终端上加了一倍CPU负载后某个Agent推理时间超过800毫秒被自动弃权系统按剩余三席重新归一化结果又是去抑制S值反而更容易过线。这个设计的容错初衷是好的但在实际低配环境里它等于主动放宽了决策标准——防御方在资源受限的IoT或老旧终端上可能会看到投票机制自我降智后产生更多攻击尝试。第三个意外和蜜罐有关。低交互蜜罐的SMB banner确实被规避席识别出来了暴露分一度压到0.21但执行席并没有因为这个低分直接否决而是把攻击切换到另一个端口继续。也就是说蜜罐只能阻止某一条具体路径的攻击却不能阻止整体攻击意图。真要骗过这套系统光在banner层做文章远远不够得让多个维度的输入同时出现这不是真实业务系统的特征才可能把总分压到阈值以下。5. 防御侧的破局思路不拦指令断共识分析了这么多总要落到怎么防。既然投票式恶意软件的设计是绕开指令链防守方就不能再顺着找指令的思路走而是要正视这个事实你拦不住它的动作但你可以影响它的投票结果。5.1 思路一让侦察席投出反对票上下文污染投票机制依赖输入而输入的很大一部分是环境信息。防守方完全可以主动污染环境上下文让某个关键席位的置信度系统性走低。最有效的目标不是规避席而是侦察席——因为侦察席是投票链路的源头它给出的目标价值分低后面策略席再想拿高分也撑不起总分。具体做法是制造低价值目标的假象在关键业务服务器上配置伪造的软件版本信息、关闭非必要服务、伪造假的补丁提示让侦察席扫到一个看似陈旧但实际无价值的系统。同时配合蜜罐在多个入口返回明显不真实的响应。重点是要让多个维度的输入协同指向同一个结论单点伪造会被其他Agent拉回来。5.2 思路二识别模型存在性而不是识别攻击行为投票式恶意软件的硬特征是它必须携带AI模型和本地推理能力。对安全产品来说与其等它攻击不如先盯住模型文件落地推理库加载这两个前置动作。GGUF、ONNX、SAFETENSORS这些格式有非常固定的文件头在终端侧做一个轻量扫描就能发现。如果一台普通业务机器上突然出现几个模型文件伴随进程加载了onnxruntime或ggml等推理库这个组合就足够触发告警了。我建议在EDR里追加下面这类检测逻辑同一进程或父进程关联的进程组内出现不低于3个独立模型文件的释放或映射这些模型文件的元数据里包含quantizationonnxgguf等关键字段且文件大小分布在几十MB量级随后出现跨进程共享内存的写入行为共享内存名或管道名包含vote、verdict、decide等语义字段以上条件同时满足时无论当前是否有恶意行为直接标记为“AI决策集群嫌疑”进入人工排查队列。这套规则的误报率可控因为普通业务程序几乎不会同时创建多个模型文件并通过共享内存做结构化通信。真正常见的AI应用往往会走本地的推理进程加单一模型文件结构上就差了几个数量级。5.3 思路三审计投票过程把民主变成把柄进攻方指望共享内存环形队列销毁证据防御方反制的办法是在系统层面留一个投票审计员。在Windows上可以利用ETW在Linux上利用auditd或eBPF重点记录带特定语义的共享内存读写事件。不用管具体内容是什么只要发现某个进程周期性向共享内存写入结构化的JSON消息并且这个周期和后续的横向移动或者文件操作在时间上强相关这条链就可以作为关联分析的基础。更进一步可以把这个审计日志接入SIEM做投票时序分析某主机上出现结构化内存通信→随后出现横向移动流量中间间隔只有几百毫秒这种模式在正常业务里几乎不会出现。一次两次可能是巧合连续出现三四次基本可以判定主机上有群体决策型恶意软件在工作。5.4 落地的优先级排序结合我自己的使用感受给资源有限的团队排一个落地优先级优先级措施投入成本收益P0终端侧模型文件扫描推理库加载检测低只需扩展EDR检测规则高直接命中架构硬特征P1共享内存通信审计并接入SIEM中需要部署审计组件中高能提供取证和关联分析P2蜜罐多维环境伪造让侦察席投反对票高需要长期维护中仅影响特定攻击路径P3流量侧低频大文件下载检测中低只覆盖模型更新的窗口P0一定要先做因为它完全不需要理解AI的任何原理只要认文件格式就够。P1会对取证有帮助但需要先有P0的告警做驱动。P2和P3属于进阶优化资源充足再考虑。6. 实验之外的体会威胁在变防守的手艺也得跟着变做完这轮分析我最深的感受不是AI多可怕而是威胁设计思路已经从规则执行升级到了决策自主。过去的安全对抗本质是双方规则的博弈——攻击者写规则防守者找规则漏洞。而现在恶意软件内部已经不再用规则表达攻击意图而是用模型参数和投票协议封装意图。你没法通过分析代码逻辑找到它在什么条件下会攻击因为条件本身是四个模型在运行时动态判断出来的。我个人在实际操作中的体会是面对这种样本最重要的不是学更多AI算法而是建立一个新习惯看到任何程序行为先问一句这个行为的决策来自哪里。如果一个进程的行为模式不是线性的、不在固定条件集合里、仿佛带着某种判断力那它背后大概率坐着模型而模型的权重文件、推理库、共享内存就是它藏不住的马脚。把检测视角从行为是什么切到决策从哪来你就能在它还没做出危险动作之前先抓到它。最后再分享一个小技巧如果你手头没有复杂工具只靠任务管理器级别的粒度就盯模块加载列表。凡是出现onnxruntime、tensorflow-lite、ggml、openvino这类推理库模块同时进程又不在正常Audio/Video/Ocr处理场景里一律按可能携带本地模型上报。这个动作几乎能覆盖所有本地推理型恶意软件而且从Windows到Linux都通用。以后的恶意软件只会越来越像会独立思考的东西防守方也该学会用它怎么思考而不是它做了什么去还原真相了。