[阅读笔记]《AVPASS: Automatically Bypassing Android Malware Detection System》

Black Hat 2017 AVPASS系统的研究报告
——一个自动化逃逸android恶意软件检测的系统

  最近各界对AI模型的安全性和鲁棒性进行了深入的探讨,如何生成和检测对抗样本也慢慢进入大众视野。恶意软件的对抗其实是经久不衰的话题,从PC端的免杀到移动端的逃逸,一直在发展。为此笔者分析了在BlackHat 2017上开源的一个关于android恶意软件检测自动化逃逸的工具AVPASS,本文是结合该工具的演讲PPT演讲视频开源代码的研究报告。

简介:

  该议题是发表于BlackHat2017会议的一篇关于android对抗性样本自动生成的议题,主要使用了混淆的方法来逃逸静态方法的检测。目标是 1)自动化推断反病毒引擎检测移动恶意软件的特征,2)最小程度的混淆恶意样本的这些特征以逃过检测。议题中首先讲解了什么混淆,并且混淆是如何阻止逆向人员分析的。接着讲述了4个学术界检测apk的知名方法:基于API、基于数据流、基于组件、基于签名,并且讲述如何逃逸这些检测引擎。最后议题将工具运用到现实中,以VirusTotal上的检测引擎作为目标,自动推断出反病毒厂家常用的检测特征,并且逃逸这些引擎。

开场:

  开场举了Defcon 24的一个例子:拿一个使用了CVE-2012-4681漏洞的公开的恶意样本,分别在2014年和2016年使用VT对其进行检测,2次都大约有50%的厂家报毒,但是当样本被修改了一点点的信息,就可以绕过这些反病毒厂家的引擎。

混淆:

  整个AVPASS主要使用混淆的手动来达到逃逸的效果。混淆时需要确保2点:

  1. 保证原始apk的功能
  2. 混淆后的代码很难被反混淆和逆向:
    • 增加混淆的复杂度
    • 使用Java反射手段隐藏所有的API
    • 使用不同的key加密所有的字符串
    • 多次混淆

  一个混淆防止逆向人员分析的例子:

混淆前 混淆后

已知检测方法及逃逸(学术界):

  一个简单的短信拦截木马的实例代码:

  上图示例说明,在中了短信拦截木马的手机上,木马拦截一条短信的大概过程。首先系统收到短信后,会广播一条收到短信的消息,而注册了相关广播接收器(BroadcastReceiver)的应用都能够收到这条消息,木马也不例外。当木马的InterceptSMS组件收到消息的时候,会读取短息的内容和手机号,并将结果发送到后台运行的SendToNetwork组件(Service服务),该组件将收到的内容发送到远程服务器。当黑客收到短信时,整一个短信泄露的过程就完成了。

  接着,作者简要介绍了4种检测android恶意软件的方法,并针对性的进行恶意样本逃逸,最给出了逃逸的效果。(本文在4种检测方法的内容上进行了一定程度的扩充)

基于API

  基于API其实就是提取APK中使用到的API或者API序列作为特征,然后使用机器学习的算法进行分类,最后生成一个可用的模型。例如DroidMat(提取权限和API作为特征,使用knn算法分类)、Drebin(提取权限、API、字符串等文本特征,使用SVM算法分类)和MaMaDroid(使用隐马可夫模型对API包名的调用关系进行建模,然后分类)等模型都是属于这一类。对抗方式也很简单,左边是针对API序列(N-gram)的,在API序列中插入良性的API,右边是针对MaMaDroid的,修改部分API的类型。

针对N-gram算法 针对MaMaDroid模型

  经过前面的对抗方法的生成后,检测效果如下图。对于大量无用API的插入,逃逸率大约是80%(针对API的N-gram),混淆family/package名字的逃逸率是95%(针对MaMaDroid的特征)。

基于数据流

  模型如DroidMiner(提取应用程序组件之间和API之间的调用流图作为特征进行分类)、DroidSIFT(提取API调用关系,及其上下文关系作为特征进行分类)和FlowDroid(一个静态污点跟踪框架,对android应用程序的整个生命周期进行了模拟)等都属于基于数据流算法的模型,其中FlowDroid更加精确的提取API之间的数据流。一个数据流分析的例子:

  Source是指数据来源的可疑API(读),sink是指数据被传输的可疑API(写),当检测到source和sink有一条数据连通,就认为这是个敏感的数据流操作,并提示警告。例如上图的例子就是读取了短信(source),接着短信被http协议传输(sink)。针对数据流的攻击也是有2种,如下图:

方法1 方法2

  第一种是增加对抗数据流分析的代码,让数据流分析的模型分析失败,不过这个块比较难对抗,从后面的测试结果也可以看得出。第二种是使用反射的机制调用敏感的API(反射是Java的一个属性,可以通过字符串调用类和函数,而字符串又可以加密),这种方法能够有效的逃逸数据流的跟踪。从下图的实验结果可以看出,输入对抗数据流分析的代码的逃逸率仅有34%,通过反射机制隐藏API名字的逃逸方法能够100%逃逸掉基于数据流的检测模型。

基于组件

  ASTROID是一个基于组件检测android恶意软件的的系统,其通过自动提取app组件之间的调用流图,然后提取同一家族最大相似子图作为该家族的签名特征,进而识别到该家族的其他样本。AVPASS针对该模型的逃逸也是很简单,在2个组件的调用流中插入其他无关组件,混淆恶意样本的组件调用流图。如一开始短信拦截木马的例子,在一次短信拦截的过程中,Revicer组件会调用Servie组件。而逃逸的过程只需要在组件调用流中,插入一个新的组件,就可以达到100%的逃逸。如下图:

混淆前 混淆后

基于签名

  基于签名其实比较简单,比如恶意软件的类名、函数名、访问的url、恶意字符串等等信息都可以拿来作为签名特征,前面提到的混淆手段都能够适用于基于签名的检测引擎的逃逸。

VT上AVs的逃逸(工业界):

  上面提到的4种分类的测试用例都是拿学术界中开源模型进行测试的,接着作者对VirusTotal上面的反病毒引擎(AVs)进行了测试,在实验前提出了4个问题:

  1. 哪些特征是重要的?
  2. 混淆哪些特征能影响检测结果?
  3. AV引擎都使用了哪些分类器?
  4. 它们对变种的样本是否具有足够的鲁棒性?

  AVPASS的测试步骤也分成4步:

  1. 每个特征单独混淆然后查询,用来推断每个特征的影响程度
  2. 生成所有可能的变种然后查询,用来推断AVs检测样本特征的规则
  3. 将相似或者相关的特征混淆分组,用于降低查询的次数
  4. 为了安全的查询(不让AVs厂家获得完整的样本,但是又要体现混淆是否有效),使用假冒的恶意样本

  从推断测试的结果中可以发现,其中5个特征是敏感的(strong),3个特征是普通的(normal),2个是弱的(weak),还有2个特征混淆对于检测结果没有影响。

  (看到这里,我们可能会有一个疑问,为什么要推断出反病毒厂家使用的特征规则?而不是将所有能够使用的混淆技术都用上呢?原因有2个:1)为了最小化混淆特征能够通过检测。首先混淆程度太深,有可能会造成apk运行失败;其次,混淆程度有可能被拿来作为检测特征使用。2)对主要的特征进行混淆来生成伪装的恶意样本。意思就是对恶意特征进行混淆,留下良性的特征,而不是一股脑的全部混淆。)

  为了更简洁的测试,作者将混淆的特征分成7组,对100个样本不同组合的特征进行混淆,并提交到VT上进行检测(共进行了25,600次的查询):

  最后得出结论:

  1. 大多数AVs厂商使用7种组合的规则来检测恶意样本
  2. 推断出来的组合特征大约占所有组合的30%
  3. 越好的AVs厂商使用越多的组合规则

  查询过程还有一个问题需要解决:查询时如果使用全文件上传的话,这些样本都会被AVs厂商拿到,也就意味着这批样本很快就会失效,那么如何不让AVs厂商获得完整的样本,又能体现出混淆结果是否有效呢?作者提出了模仿模型(Imitation Mode):将混淆后的恶意代码插入到良性样本中进行查询,如果该样本被查杀了,也就是混淆不成功,否则反之。

  评估的结果如下,在不使用AVPASS工具下,2000个样本的检出率大约是65%,使用AVPASS后检出率是5.8%,基本上成功逃逸了各AV厂家的检测引擎。

  对于全混淆和推断规则后再混淆2种情况,发现检出率差异不大,推断规则的效果稍差,原因是只混淆了30%的特征,但是同时兼容性和运行性能都更好。而模仿模式下的混淆会比全混淆要好。

  对于为什么逃逸率不是100%,作者也做了2点的描述:

  1. 混淆不能修改所有的内容,比如权限(硬件请求和应用权限等)和Intent-filter(action、data)等
  2. AVPASS有可能遗漏了厂商使用的其他特征

  最后做了小结:

  1. 在VT上面的AVs都是基于静态分析的引擎,没有使用动态分析相关技术(VT本身有限制每个引擎的检查时间不能超过太长)。
  2. AVs主要是还是使用模式匹配的方法,缺少一些更先进的技术,比如数据流、组件流等(但是这些技术也更加耗时)
  3. 50%的AVs只使用样本的hash作为检查特征。(修改样本1个字节就检测不了)

讨论:

  首先,作者讨论了哪一类AVs更难被逃逸。第一,检查了更多特征和更多规则组合的引擎,能更好的发现恶意样本;其次是使用了数据流和组件流的引擎更难被逃逸,虽然AVPASS目前能够逃逸这2种方法实现的模型,但是使用的方法太明显了,很容易被针对,并且经过AVPASS混淆后的样本很难再重新开发,从而逃逸数据流和组件流的检测方法。

  接着,作者讨论了市面上反混淆的工具能否还原AVPASS生成的对抗样本。市面上反混淆的技术有2种,基于动态分析和基于概率分析。作者用一款商业上主流的反混淆工具DeGuard进行了测试,发现它能恢复70%的类名,其他的混淆就无能为力了。(只是恢复了类名混淆方法的70%,其他混淆方法都不能恢复)

  然后,作者讨论了防御的措施。首先,作者认为VT中的引擎应该增加其他标签,对于一些无效的样本应该返回无效,而不是良性或者恶意,因为混淆以后的恶意样本可能无法运行,如果返回恶意,那么就证明恶意代码被检查出来并且混淆方法没有用,进而推断出AVs使用的检测规则。其次,作者认为增加检测特征的数量也是有效的,可以防止模型被推测。最后,VT可以通过用户行为来识别推测行为,并对其进行一定的惩罚,比如在同一时间大量提交相似的样本,就需要对用户做一些限制了。

  最后,作者还讨论了AVPASS的局限性。1)如果恶意软件使用了payload的形式,比如apk被加固、恶意代码放到so文件中等情况,AVPASS是无法处理的。 2)AVPASS在开源后,部分特征可能被AVs用来作为检查恶意样本的恶意特征。 3)一些混淆手段对动态分析是无效的。

文末附上一张AVPASS的使用流程图

总结:

  AVPASS的分析结束,从文中可以看出,AVPASS主要针对的是反病毒引擎的静态分析,并且使用的是有针对性的混淆攻击方法,与神经网络的对抗性攻击关系不大,不过这也是可以理解的,因为目前深度学习运用在安全领域的还是比较少,大家主要采用的还是传统的机器学习(重点就是如何进行特征提取),那么自然而且对抗的方法也就在如何混淆特征这一问题上。

  AVPASS逃逸了4种主流的机器学习检测恶意软件的方法,并且自动化推断出了业界反病毒引擎所使用的特征规则,使用AVPASS后的恶意软件的检测率从65%降低到5.8%。

  AVPASS的有效性告诫我们不仅仅需要关注模型的识别率,还更需要关注模型的鲁棒性和安全性。未来,恶意软件的攻与防还会一直持续下去,作为安全研究员任重而道远。

坚持原创技术分享,您的支持将鼓励我继续创作!