本帖最后由 B100D1E55 于 2019-12-4 00:06 编辑
在今年的DEFCON AI Village上,Endgame联合MRG-Effitas以及VM-Ray共同举办了一届机器学习样本静态免杀竞赛。随着机器学习引擎逐步在各路安全厂商中开始普及(特别是客户端点上),针对静态机器学习引擎的免杀研究也越来越多。今年7月VICE就曾经报道过一个字符串免杀CylanceProtect的“惨案”,而这个竞赛正是切中这个要害,吸引各路人马免杀机器学习模型并分享自己的免杀方法。
就目前而言,在学术圈里对抗机器学习还大多将焦点集中在计算机视觉上。在这些研究中,研究人员大多对像素进行人肉眼难以识别的篡改,从而使得一张图在人眼视觉上仍旧大致保留原来的模样,但会被算法进行误分拣
对Stop标识进行特殊处理后就能让机器学习识别为“避让”标识从而可能引发车祸
但是由于PE文件有结构要求,而线性运行的机器码并不能在任意修改后仍能轻易保持原来的功能,对病毒的静态免杀势必和计算机视觉的“免杀”有极大不同。因此如何在保持程序原始功能的基础上进行免杀便是一个很有意思的课题。
在这场竞赛中,Endgame以白盒(完全公开源代码和模型权重)的形式给参赛者提供了3个分拣模型:MalConv、非负MalConv、以及EMBER。MalConv是一个端对端的深度学习模型;非负MalConv网络结构同MalConv一致,但模型的权重被约束为非负数,使得模型的打分变为单调递增,也就是说黑特征能让恶意分数提高而白特征理论上则无法降低恶意分数,这样有效对抗掺杂白特征的免杀;最后则是Endgame自家的一个名为EMBER的分拣模型,基于集成的提升决策树对文件静态信息进行评估。
需要注意的是前两个模型是处理整个PE的数据特征,并没有PE结构上的理解,而EMBER则是提取了如下这些PE结构特征:
字节直方图 字节熵 区段信息(名称、大小、熵、属性) 导入表库及入口信息 导出函数 文件基础信息(各类体积和数量信息) 文件头信息(机器码、结构、链接器、版本号) 字符串信息(文件中字符串的各种统计信息) 数据目录(名字、大小、虚拟内存地址)
所有模型都使用Endgame公开的EMBER数据集训练。比赛提供50个病毒样本,成功让一个样本同时逃过三个模型的检测计3分,总分150分。
ESET的首席产品官(后文使用他的名字简称JD指代他,其实他在官方论坛上用户名也是JD哈哈哈)以个人身份参加了这个竞赛并写下了详细的解题过程(也就是没使用任何ESET的内部工具),在参赛初期他的成绩远超其他选手,但最终并未获得冠军,这里大致概述一下他的免杀过程,个人觉得挺有意思,值得借鉴来调戏NGAV引擎:
首先JD用自己电脑里的ProgramFiles评估了一下三个模型的检出率和误报率,发现EMBER的成绩还不错,误报率大概在5%(这样的误报率仍旧无法在业界实用,顶多是学术研究用一下),而另外两个MalConv的模型误报率则高达70%,单个基本没有实用价值。
JD提到竞赛中的规则:除了文件体积限制外,不能使用自解压,不能使用下载器。这两点对于静态免杀竞赛而言很重要,因为静态引擎对于这类手段基本没有防范能力——静态引擎仅在单个“点”进行特征提取,如果这个“点”上无法提取出恶意特征,那么待测样本则会被判白。很多下载器仅在被执行后才能获取恶意特征,因此静态引擎就较难判定这类情况。而不能使用自解压原因也很简单,因为其类似于一个“壳”,但这个壳也经常被用于白文件。如果静态引擎被训练来识别自解压的“壳特征”,则有可能产生大量的误报。在静态引擎看来,自解压程序的内容本质上就是一片噪声而无法分拣(注:这里没考虑到一些边边角角的特征,比如自解压本身包含的执行脚本,QVM经常就凭借这个爱杀带有后台执行能力的sfx,管你是黑是白)
JD认为相较于现实生活中的情况,这个竞赛更偏向于学术研究,因为其规定参赛者只能在给定的50个PE文件基础上进行修改,而现实生活中黑客往往能从源码入手进行免杀。此外给定的50个文件全是exe而没有dll,使动态加载变得困难。
JD的解题思路主要分为几个阶段,在第一个阶段里他试图使用模糊测试寻找模型使用的PE解析器的漏洞,但他马上意识到其实这么做有可能被判成0分,因为如果是DoS漏洞顶多会让程序崩溃但仍旧没有达到“判白”的效果,同时还可能使得主办方的判定系统崩溃从而影响其他参赛者的进度。在第二个阶段里JD尝试使用Process Hollowing等手段制作PE,将样本存在资源段内,运行时提取并执行,但他马上也放弃了这个思路,一方面对现成PE文件“造壳”在有限时间内成本偏高,另一方面造壳和使用自解压原理一致,有可能被参赛方认为是犯规(注:这里解释了静态判定的本质局限,没法看到壳内的东西,只能是通过壳特征辅助一些额外信息来“猜”壳内究竟是什么)。
由于修改样本——>沙盒内执行(注:因为比赛规则要求免杀样本跑出来的IOC/行为要和免杀前完全一致)——>再修改样本这个循环实在过于耗时,JD决定换个思路:先选取一个被误报的白文件,通过对白文件修改后实机测试即可更快地找出免杀方法。JD使用UPX、PECompact、ASPack分别对误报文件加壳,发现PECompact和ASPack加壳样本始终被判定为毒,但UPX并不总是被判定为毒。这意味着UPX壳打包的文件很可能落在模型分拣边界上,稍加修改就能将其移动到分拣边界的“白区”。UPX之所以有这样的特性很可能是因为白文件也大量使用UPX壳,因此简单判定壳特征会产生过多误报。
JD在实验过程中发现7zip命令行程序作为样本非常有用——用UPX加壳后的7z样本在三个模型上都被报毒。JD自己修改了UPX加壳代码,因为原始UPX壳在加壳过程中仍旧保留了原始PE的一些导入函数信息,而这个特征对于静态引擎来说是非常重要的强特征,通过动态加载等手段可以混淆此类检测。
因此在第三阶段中,JD写了一个脚本对UPX加壳过的7z样本程序头进行了模糊测试。模糊测试中先确保PE解析器可以正常解析程序,然后检测修改后的样本是否使得检测模型的恶意打分降低,如果降低了则执行程序。使用这样的手段他马上发现EMBER分拣器的漏洞:90%的情况下NT Optional 头内如果包含了DIRECTORY_ENTRY_SECURITY则会被EMBER判白。
第三阶段已经搞定了EMBER模型,现在则要对付MalConv模型。JD看了一下模型的源码马上意识到这个模型只是将PE使用卷积滑窗的模式进行了处理,因此马上就知道解决方法了。打个比方,如果有一个模型专门用来对图片进行识别,包含恶意的是“大灰狼”,而白文件则是“小绵羊”图案,那么对于一张大灰狼图片,将图片的“画布”拓展之后在空白画布上画上羊的图案,那么这时候机器学习识别出来的是羊还是狼?只要“小绵羊”图案加得足够多足够明显,那么就很容易诱骗对图结构毫无理解的机器学习引擎认定是一张羊的图而不是狼的图。
第四阶段中JD使用三个模型对他电脑上ProgramFiles的文件进行打分并筛选出“小绵羊”属性最强的文件,他将这些小绵羊文件添附在恶意程序文件末尾立刻使得机器学习对其判白。(注:PE文件的特性之一在于文件末尾可以添附任意数据,这些数据虽然存在于文件中,但实际执行的时候并不会被加载入内存,这种PE末尾添附数据的做法又被称作overlay)
额外的问题:
JD将改好的样本传入鉴定系统却意外地发现50个样本中只有一个样本判定为免杀成功,在简单分析后他才发现让“有效程序”过三引擎鉴定并不难,难的是如何让系统提取出来的IOC也一模一样。于是他重新写了一个自动化脚本,先提取原始样本的行为特征,然后再使用自动化的手段用沙盒逐个测试修改后的样本。然而上传样本后却发现鉴定系统卡住了。主办方表示鉴定系统的确出了问题,几天后才能修复。由于JD本人还有其他事情无法继续跟进比赛提高成绩,因此等到最终结果出来时他只拿了141分,而第一名获得了满分150分。主办方后来承认打分出了问题,因此比赛被再次延长,而他之前提交的一些样本并没被系统接受……
JD赛后重新审查被拒样本时发现熵值也是判定的重要依据之一,因此他对overlay的内容稍加修改轻松得到了150分,但是比赛再度出了问题第二天所有选手的比分再次被全部清零(注:我觉得真是太惨了),因为JD后来公司还有事+休假因此不再继续跟进比赛……
------------------------------分割线---------------------------------
最终得到冠军的是来自美国军方的William Fleshman(后文简称WF),和JD这种典型系统工程思路入手的解体流程相比,他的解题思路的形成直接扎根于三个模型的算法本身,这里概括一下他分享的一些有意思的额外信息:
MalConv这类模型直接忽视PE的结构,对整个文件进行直接处理(类似图片)。文件输入到MalConv之后输出一连串0~255范围内的数值,其中一个嵌入层将这些数值映射为特征向量,而这个向量则被神经网络处理,最后输出一个“无害分”和一个“有害分”。和JD的论述一样,只要在文件末尾添附足够多的白特征就可让无害判定盖过有害判定从而实现免杀。而按理来说非负MalConv模型由于使打分单调递增,通过简单的白内容添附无法实现在MalConv上同样的免杀手段,但比赛中的这个模型却有一个致命疏忽:模型仍旧输出了“无害”和“有害”两个打分,因此就算神经网络权重为非负数,无害分仍旧可能盖过有害分,因为这两个分最后使用softmax函数进行综合。softmax处理中,如果无害分更高,则这个函数会降低有害分的权重,即使检测到的有害成分丝毫没有变少。基于这个漏洞,overlay仍旧可以欺骗这个模型
除了上文多次提及的overlay,WF还使用了“slack space”,即由于PE区段2^n的对齐要求,有一些区段会有额外的空间,通过填充这些空间同样可以添附内容。不仅如此,通过对PE添加新的无用的节,可以混淆EMBER提取的字节直方图和字节熵特征;通过修改段名可以将决策树导向其他分支,对新增节进行字符串填充可以进一步影响字符串特征从而混淆机器学习的判断。使用这些手段辅以一些自动化搜索脚本,他马上发现填充0xA9最能降低恶意打分……后来他又通过对PE文件填充微软程序中的用户许可协议进一步提升了免杀效果,显然模型在学习微软白文件特征的时候将EULA纳入了强白特征……
------------------------------分割线---------------------------------
总结
机器学习并非坚不可摧,特别是新兴的那些静态机器学习算法,其虽然开发成本相对较低且分拣精度高,但与黑客的对抗能力和误报控制相比于传统手段仍旧是个未知数。对于这类新兴的高检出产品,我个人认为至少要从两个方面来客观评估:1.其误报水平如何?2.其对抗水平如何。很多新产品刚出时都曾经是大杀器,但随着产品普及度慢慢变高,当其成为黑客们的众矢之的后检测率往往就泯然众人矣。毕竟藏在暗处的东西/小众的东西/误报高的东西倘若不是搞APT的黑客根本懒得管,他们只针对众数,就算难缠的产品(误报高普及率高)使用社工也能轻松绕过。
从上文也能看出这些攻击手段都需要一个反馈机制,例如模糊测试通过对文件进行随机修改并获取引擎打分来判断是否改对了,因此切断这个反馈机制也是安全厂商和黑客拉锯战的要点之一,我猜测这也是为什么当今不少产品开始弱化本地端加强云端的原因之一(当然是不是为了隐藏自己后台是多引擎而本地端没什么像样引擎我就不知道了)。这点其实就算在大厂产品中也能体现出来,本地客户端检出由于是免杀的重灾区往往是伤痕累累,但其云端的鉴定引擎因为时间差不将鉴定结果直接反馈给黑客免杀测试,且模型细节藏于云端,因此检测率基本上都显著高于客户端。总而言之,客户端的高检测率需要结合其误报情况和受针对程度来综合衡量一个产品的技术水平。
最后的题外话:我个人觉得MalConv这种提取模式太naive,直觉上只能算这个领域研究初期的产物,想必现在各路厂商已经针对其overlay弱点进行了改进。不过其实你拿着一个VT NGAV厂商都报的样本弄一点overlay,还是会有很多NGAV引擎被骗,这里我就不点名了。
参考资料:
|