0x00 前言
恶意软件规避技术广泛用于规避检测机制、加大分析及理解难度。在规避技术中,由于目前沙箱正成为判断恶意威胁的一种最快速和最简单的方式,因此反沙箱检测是比较重要的一类技术。许多企业会使用这类系统来触发已发现的恶意文件及URL,提取更多攻击特征,拓展防御能力,阻止其他相关的恶意活动。现在我们都将安全理解成一个整体过程,沙箱系统是这个生态系统中的一部分,因此我们必须重点关注恶意软件所使用的技术,研究如何针对性防御这些技术。
从历史角度来看,沙箱可以帮助研究人员可视化呈现恶意软件在一段时间内的行为。在过去几年中,随着技术的不断发展,恶意软件开发者开始改进恶意代码,不断深入系统底层来检测沙箱环境。
由于沙箱变得越来越复杂,不断改进检测机制,我们观察到有多款恶意软件会动态修改规避策略,保持对防守方的技术优势。在下文中,我们将回顾恶意软件开发者在过去几年中最常用的一些规避策略,可以看到相关恶意软件家族代码在不断拓展,引入更为隐蔽的技术。
在本文中,我们将重点关注恶意软件最常用的一些规避技术,如下图所示。此外恶意软件还用过其他一些技术,这里没有全面覆盖。
0x01 规避技术
延迟执行
在早期阶段,研究人员观察到有多款恶意软件会使用基于时间的规避技术,利用已知的一些Windows API(如NtDelayExecution
、CreateWaitTableTImer
、SetTimer
等)来延迟执行恶意代码。在沙箱环境开始识别并防御之前,这些技术依然非常受攻击者欢迎。
GetTickCount
当沙箱检测到恶意软件,想通过加速代码执行的方式防御恶意软件时,攻击者也开始通过多种方法来识别环境中的加速执行机制。有多款恶意软件家族(包括Win32/Kovter
)会在代码中使用GetTickCount
这个Windows API来判断代码运行时间是否匹配预期时间,我们也在一些恶意软件家族中看到该方法的一些改进版。
沙箱厂商很容易就能绕过这种规避技术,只要简单创建超过20分钟的快照,让主机运行更长时间即可。
API Flooding
在Win32/Cutwail
恶意软件中,我们观察到后续不断被使用的一种方法,那就是在循环中调用无用的API来引入执行延迟,这也就是所谓的API Flooding(API洪泛)技术。使用该方法的恶意软件代码片段如下所示:
内联代码
前面的代码可能会导致DOS效果,因为沙箱无法有效处理这种逻辑。另一方面,随着时间的推移,这种行为也不难检测,沙箱开始能够处理基于API的停顿代码。此时攻击者开始通过另一种策略来实现同样效果,那就是引入内联汇编代码,在执行恶意代码之前等待5分钟。我们发现恶意软件使用过这种技术,如下所示:
沙箱的功能不断加强,配备代码检测技术以及完整的系统模拟功能,能够识别并报告停顿代码。事实证明,这种简单的方法可以规避大多数高级沙箱。根据观察分析,我们梳理了过去几年中恶意软件在基于时间的规避技术方面的演进流程,如下图所示:
硬件检测
识别硬件指纹是恶意软件所广泛采用的另一类规避策略,恶意软件会重点检查物理内存总量、可用硬盘大小及类型以及可用的CPU核心。
这些方法在某些恶意软件家族中非常流行,比如Win32/Phorpiex
、Win32/Comrerop
、Win32/Simda
等。根据我们对这些变种的跟踪,我们注意到恶意软件会将DeviceIoControl()
API与特定的控制代码一起使用,获取存储类型及存储大小的相关信息。
研究人员发现勒索软件及加密货币挖掘类恶意软件会使用GlobalMemoryStatusEx ()
技巧来检查主机上的可用物理内存总量,类似的检测方法如下所示。
检查存储空间大小:
沙箱会使用一些API拦截代码,用来操控函数所返回的存储空间大小,典型代码如下:
此后,恶意软件开始青睐基于WMI(Windows Management Instrumentation)的技术,因为当时已知的沙箱无法简单地拦截这些调用。
我们梳理了一些恶意软件家族在存储类型及大小检测上的演进过程,如下图所示:
CPU温度检测
恶意软件开发者始终在添加新的有趣方法来绕过沙箱系统。有一种检测思路非常有趣,就是在执行过程中检测处理器的温度。
我们观察到的典型代码如下所示:
代码用到了系统中的一个WMI调用,这种方法比较有趣,因为VM系统在调用语句后不会返回结果数据。
CPU计数
像Win32/Dyreza
之类的恶意软件家族会计算CPU核心数量作为检测策略。最早时研究人员观察到一些恶意软件家族会使用前文提到过的比较简单的API来计算CPU核心数,然而随着时间的推移,大多数恶意软件家族选择使用WMI以及更为隐蔽的基于PEB的方法。
如果恶意软件在规避代码中没有依赖于API,那么对沙箱环境的检测机制而言更具挑战,恶意软件开发者自然会更长使用这些方法。早期的恶意软件会使用如下检测方法:
还有其他方法能够获取CPU核心数,更为隐蔽的方法是访问PEB,可以引入如下内联汇编代码或者使用内部函数来实现:
另一篇文章中介绍了获取CPU核心数的一些较新技术。根据我们的观察,我们梳理了恶意软件在获取CPU核心数上的技术演进过程,如下图所示:
用户交互
恶意软件开发者还会使用其他技术来规避沙箱环境,比如用户交互过程,这是因为自动化分析系统永远不会与真实用户进行交互。传统的沙箱在设计上并没有去模拟用户行为,因此恶意软件在开发过程中加入了相关代码,用来检测自动化系统与真实系统之间的差异。最初有多款恶意软件家族会监控Windows事件,在这些事件生成之前保持挂起状态。
比如,Win32/Gataka
变种会使用GetForeGroundWindow
来检查是否有对这个API的其他调用操作,判断窗口句柄是否发生变化。研究人员也在Locky勒索软件变种中发现过这种技术。
Win32/Sazoora
恶意软件的部分代码片段如下所示,这款恶意软件会检查鼠标移动轨迹,这也是其他几款恶意软件家族广泛使用的一种技术。
此外,研究人员发现恶意软件还部署了一系列技术,用来检测用户与被感染系统的历史交互痕迹。比如负责投递Dridex
的恶意软件会广泛使用自动执行类宏,这些宏只有在文档关闭时才会触发,部分VB代码如下所示:
这款恶意软件还会检查注册表键值,判断MRU(Most Recently Used,最近使用)文件来分析用户与被感染系统的历史交互行为。恶意软件还会通过代码来改进这种检测方法。
检测注册表键值来分析MRU记录(\HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\User MRU
):
对应的代码片段如下所示:
我们观察到的演进过程如下图所示:
环境检测
恶意软件所使用的另一种技术就是提取目标环境的指纹信息,从而利用沙箱环境的错误配置。在早期阶段,恶意软件只需要使用Red Pill之类的技术就足以检测虚拟环境,随后沙箱开始在架构上进行加固,恶意软件开发者也开始使用新的技术,比如检查主机名是否匹配常见的沙箱名,或者检查注册表来分析已安装的程序,如果安装程序过少,则很有可能是虚假的主机。此外还有一些技术可以用来检测正在运行的进程,比如检测文件名,判断其中是否存在匹配的哈希值或者关键字(如malware
),以发现环境中是否存在监控工具,也可以检测网络地址,来判断地址是否位于黑名单列表中(如AV厂商所属地址)。
Locky及Dridex用到了网络地址检测技术。
演进过程如下所示:
0x02 总结
在过去几年中,我们观察到攻击者在恶意软件投递过程中不断改进沙箱检测及规避技术,使防御方更加难以检测及分析。攻击者逐步在感染向量上新增一个防护层,避免载荷失效。因此,我们经常会在恶意Word文档及其他攻击文档样本中看到一些规避技术的踪影。
传统的沙箱环境基于现有的一些虚拟化解决方案(如VMware、VirtualBox、KVM及Xen)来构建,这给恶意软件留下了非常大的发挥空间。
恶意软件开发者不断添加新的技术来绕过安全解决方案,利用规避技术作为检测沙箱环境的有力手段。随着防御技术的改进,恶意软件技术也在紧跟步伐,不断进步。
沙箱系统现在已经部署了一些高级的指令及模拟功能,可以成功检测本文提到的技术。然而,我们认为在未来研究中,沙箱技术可以往元数据分析环境方向上发展,这样即便存在一些常见的脆弱点,也肯定能成功防御任何形式的规避技术。