本公众号发布的文章均转载自互联网或经作者投稿授权的原创,文末已注明出处,其内容和图片版权归原网站或作者本人所有,并不代表安世加的观点,若有无意侵权或转载不当之处请联系我们处理,谢谢合作!
欢迎各位添加微信号:asj-jacky
加入安世加 交流群 和大佬们一起交流安全技术
主要讲述恶意软件利用计时攻击绕过沙箱检测的技术手段。做HIDS的人看完这篇应该明白字节跳动HIDS需要对
sleep
挂钩。陈越大佬真是牛逼!最后防线:字节跳动HIDS分析的nanosleep钩子译自:https://www.lastline.com/labsblog/not-so-fast-my-friend-using-inverted-timing-attacks-to-bypass-dynamic-analysis/
动态恶意软件分析或者沙箱技术,已经变成每种主要安全方案的核心块,同样绕过它的代码也变成恶意软件的核心块。实际上,当前威胁的所有变体都包含某种沙箱检测逻辑。
绕过代码的一种非常简单的形式是将任何可疑功能的执行延迟一段时间,基本想法是基于这样事实:动态分析系统只会在有限时间内监控执行,在没有检测到恶意行为会把程序归类为无害的。另一方面,在受害者机器上,几分钟的延迟行为并没有实质影响,使得攻击者更容易在分析环境和实际目标机器上实现不同的行为。
最容易且最流行的延迟行为是使得程序休眠一定时间。由于这是一种普遍行为,很多分析沙箱都能够检测这种绕过,并且在大多数情况,直接跳过休眠。由于这个看上去一个简单的解决方案,它有很大范围的意外效果。
延迟的威力
在白皮书《延迟执行恶意代码的自动检测与消除》( Automated Detection and Mitigation of Execution-Stalling Malicious Code)里面描述应对沙箱的代码背后的原则:
延迟代码通常在任何恶意行为之前执行。攻击者的目标是将恶意活动的执行延迟到足够长的时间,以便自动动态分析系统无法提取有趣的恶意行为。
代码延迟可以通过多种方式实现:等待用户的特定操作,浪费CPU周期计算无用的数据,或者简单地使用调用sleep()
函数来延迟执行。
根据MSDN:
VOID WINAPI Sleep( _In_ DWORD dwMilliseconds);
//Suspends the execution of the current thread until the time-out interval elapses.
调用sleep()
将使当前线程的执行延迟作为参数传递的时间
大多数沙箱监视正在分析的程序的系统或API调用,都会看到这种绕过尝试。因此,沙箱能够检测到这种情况,并且在大多数情况下甚至可以对此作出反应,要么修改传递给操作系统的延迟参数,或者使用自定义实现替换被调用的函数,或者只需立即返回调用代码(完全跳过休眠)。
检查休眠补丁
最近,我们遇到了一个有趣的恶意软件家族,它使用沙箱使用的反规避技巧来检测分析环境的存在(可以称之为反规避技巧…)。
该恶意软件结合使用rdtsc
指令和sleep()
来检测休眠补丁,以检查执行的加速,如下面的代码摘录所示:
总而言之,此代码如下:
-
执行读取CPU的时间戳计数器的rdtsc,并将时间戳存储在临时值中, -
调用睡眠()以延迟执行, -
重新执行rdtsc -
比较这两个时间戳。
使用高精度动态分析进行休眠补丁
与传统的沙盒不同,Lastline
的高精度分析引擎监控的不仅仅是程序与操作系统(或API函数)之间的交互。Lastline
引擎可以监控并可以影响恶意程序执行的每条指令,而不仅仅是API函数调用。它还可以操作rdtsc
指令返回的值,因此即使对休眠接口打补丁时,也可以保持一致的执行状态,例如,在每次sleep
跳过或加速时把CPU
返回给程序的时间戳快进。
因此,程序无法再区分sleep
是否被完全执行,还是分析系统把沙箱的时间快进了。
Sleep
补丁的副作用:用户模拟
一些由Sleep
补丁引入的有趣副作用,虽然可能没有直接和专门的沙箱检测关联,如下面代码所示
这里,恶意样本通过每30秒检查鼠标位置来检测用户活动。
大多数沙箱有机制触发用户活动:重复改变鼠标位置,打开新窗口,点击对话框按钮。
在上面代码,恶意样本使用sleep
方法不是用来延迟恶意活动,仅仅用一种简单方法检查用户活动(在这里,主要是鼠标移动)在短时间被观察到。很明显,如果沙箱通过给sleep
打补丁加速这段代码执行,恶意样本在休眠时的预期行为就不会出现,这样就导致分析环境的存在被检测,从而躲避分析。
因此,一个执行延迟的简单方法就可以让攻击者识别沙箱的存在或者说,一个实际用户的缺席,从而躲避分析。
sleep
补丁的副作用:竞争条件
另外一个sleep
补丁相关的有趣问题是竞争条件。竞争条件不是一个细碎编程错误,多线程代码需要按照指定顺序执行才能够正常工作。
一个丑陋的避免竞争条件的方法是在另一个任务完成后延迟该任务代码一定时间。
在sleep
补丁的情况下,这种方法会失败,因为沙箱会影响休眠的时间。这样的例子可以见下面这段从另外一族恶意样本摘取出来的代码
在这段代码,恶意软件解密一个释放出来的文件,并执行它里面的代码,当代码执行完就删除该文件。在触发和删除该释放文件时,恶意样本使用了sleep
来确保它在被删除前执行。如果给sleep
打上不当补丁,沙箱会打破这个逻辑,使得恶意文件会在负载执行前被删除。
一个更复杂的例子如下
恶意软件从磁盘文件读取加密代码,然后在同一进程另一个线程执行它。一旦负载启动,主线程在结束进程会进入无尽休眠。
如果这个sleep
补丁比恶意负载的执行时间要短,这个进程会在完成活动之前结束,从而没有机会展现它的恶意行为。
总结
计时攻击在当今大多数恶意软件家族中很常见。虽然其中一些定时攻击很容易被发现,但克服这些逃避尝试的幼稚方法往往弊大于利,为基于反逃避系统的逃避攻击打开了大门。
本文始发于微信公众号(安世加):技术干货 | 利用计时攻击绕过沙箱的动态分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论