分析样本出处
链接:https://www.malware-traffic-analysis.net/2022/04/20/index.html
样本表现
Emotet,是一种计算机恶意软件程序,最初是作为一种银行木马病毒开发的。其目的是访问外部设备并监视敏感的私有数据。Emotet 会骗过基本的防病毒程序并保持隐匿。一旦被感染,该恶意软件会像计算机蠕虫病毒一样传播,并试图渗透到网络中的其他计算机。
其中本样本在虚拟环境当中,不能直接运行,因为存在多种反逆向工程、反调试、反虚拟机技术,因此我们借助强大的第三方网站来帮助我们分析这个样本,以便于我们去验证该样本的行为特征。
分析环境
虚拟机VMware,虚拟机环境是Windows 7 64位,物理机Win 10 Pro。
分析工具
- IDA Pro 7.5
- Procmon.exe
- LordPE.exe
- Resource Hacker
- 火绒剑
分析过程
VirusTotal分析
放到VirusTotal中进行分析,可以看到结果在线分析结果。
在分析报告中,这里面可以看到是有很多引擎说它是病毒,这个病毒很多引擎都认识。
可以看到还是很多红色的。我们点开“DETAILS”里面,可以看到更多的分析报告。
从这个表格信息里面,我们可以看到,这个是一个64位程序,编译时间是2022-04-19。然后代码段、数据段什么的都是正常的,但是有一个值得注意的地方,就是.rsrc资源段的存在,这里面可能存在样本会释放的文件。
LorePE.exe和Resource Hacker分析
首先我们用LordPE这个程序来检查程序, 看到里面的程序入口点是0x470c0,镜像大小是0x10000000,总的来说还是比较大的,毕竟是64位程序。
我们再点击PE Editor当中的Sections。
查看这里面的段表看看有什么异样,根据前文在VirusTotal里面的表现,我们在再仔细看看这个表,总的来说,这个段表结构里面大小都是正常的,代码段、只读数据段、可变数据段都能过都是正常的,值得我们关注的,也还是.rsrc资源段,我们可以看到:资源段的大小在所有段表结构中是仅次于代码段的存在。而最后一个重定位代表段.reloc,根据经验我们可以知道,可能会调用GetProcAddress这个函数对这个重定位段里面的数据进行延迟绑定。在后面的分析里面可以看一下这个段里面有什么函数,值得我们注意。
接着我们放到Resource Hacker当中进行分析。
我们可以放到resource hacker当中进行分析,然后依次点击左边菜单栏出现的这些条目。我们发现在这个exe文件的资源段中含有丰富的光标资源,位图资源,还有一些窗口图形界面设计的一些预设配置在里面。从图中我们可以知道。他的这个感染效果可能是会影响受害主机的光标以及某些操作系统的图标会发生变化,以及会在某些地方的窗口进行替换。
我们根据网上的提示,猜测这些光标资源和窗口预配制的这些设置,是会影响用户主机上的office文件。在这里我们先留一个坑,在后面来填。
行为特征分析
在前文我们主要是通过静态分析的角度,从文件结构以及特殊段表的角度,去分析这个文件是否加壳,已经是否含有一些可疑的带留意的信息。我们在前面的分析知道这个样本的魔数,也就是magic number是MZ。那么对应的它是exe文件或者dll文件。那么接下来我们尝试运行样本,先改成exe文件,然后通过Process Monitor这个程序来监控他在注册表、网络行为、文件行为这些上面会有什么动作以下是我们的运行截图。
很不巧,我们看到这个是不能运行的,那我们在尝试换成dll文件运行一下。然后尝试运行rundll32 emotet.dll,然后在火绒剑里面进行分析。
运行火绒剑。
但是不论是虚拟机还是物理机这么运行这个程序,却也还是运行不了,没有确切的结果供我们参考。
这时候我们就没有什么思路继续展开。因为这个程序都已经运行不了了,我们只能借助第三方平台尝试去分析这个文件。我们找到的这个网站是JOE Sandbox Cloud,这个是国外一个比较有名的在线分析平台。他可以借助他的虚拟环境帮助我们进行分析,这个样本给出比较详尽的分析报告,帮助我们去进行分析学习。
我们在JOE SandBox Cloud当中进行分析,在这个雷达图中,我们可以看到隐匿者Evader被标注是恶意的。那图中一表示这个样本有可能会Bypass操作系统的安全防护,例如关闭一些安全选项,然后利用一些反逆向工程的技巧。比如反调试这些技巧来掩盖他们的行为。比如可以使用一些非正常的工具和数据。同时网站上也给出了相关恶意行为的分析。
从图中我们可以看到在这个样本当中有恶意分析软件的规避行为和反调试行为,当我们在虚拟机运行这个样本的时候,有可能是有些硬件信息被样本检测到导致样本判断环境异常,然后导致自动退出的这种行为。
在恶意分析系统规避的这条行为当中,网站给出了一些特征来帮助我们去分析这个样本。第一,样本可能使用了睡眠模式去规避动态检测;第二个,当样本在睡眠的时候它将会停止执行;第三个,是使用系统或者本地时间去决定是否执行,也就是说样本将会在特定时间执行,而这种行为是将其作为恶意样本的重要依据;第四个,它会查询硬盘信息,而这种行为通常被用来检测是否是虚拟机环境;第五个,在样本当中也找到了非常多的没有执行的API。而上述的五个行为可以认为样本在一定程度上是反虚拟机的、反动态分析的反逆向工程的技术存在。其余的还有枚举正在运行的进程、检查硬盘的剩余空间这些一些并不是特别敏感的操作,但这些行为同样可以收集部分信息来判断是否是虚拟机环境。
在对抗调试这一块,样本当中包含一些函数去检查是否有调试器正在运行,就比如IsDebuggerPresent这个函数;第2点是样本当中包含一些函数是为了动态绑定一些API调用;第3点,样本包括一些函数将会被用来探测是否有调试器的存在,比如GetProcessHeap这个函数;第4点,样本会检查当前进程是否处于被调试的状态;第五点,也是可疑的一点,就是样本包含一些函数会去注册他们自己的异常处理结构。
在这个样本分析网站上面。除了恶意分析系统规避和反调试这两个板块,当中他也给出了其他的一些恶意行为分析,但是我们分析该样本最主要的是分析其反逆向工程、反虚拟机和反调式的技术。因此我们的其他分析工作将会简短的、略过大部分、主要借助分析网站提供的方向,然后采取验证性操作。
IDA 7.5 分析
根据恶意样本分析这堂课上老师跟我们讲的,放到IDA里面,我们可以先行分析其输入表包含哪些函数,有些敏感的API可以帮助我们迅速分析这个样本的威胁行为。
为了快速判断样本引进了哪些Dll文件,我们先用010 editor这个二进制编辑工具,借助它exe可执行文件的分析脚本去解析样本引用了哪些dll文件。从图中我们可以看到除了常规的kernel32.dll、user32.dll,还有一些不太常见的dll文件。
其中GDI32.dll是windows下图形用户界面的应用拓展;comdlg32.dll是Windows应用程序公用对话框模块,用于例如打开文件对话框;WINSPOOL.DRV是系统打印管理库所需要的一个文件,如果缺少这个文件则系统无法正常进行打印工作,关联的文件有Winspool.drv和winspool.exe;ADVAPI32.DLL是一个高级API应用程序接口服务库的一部分,包含的函数与对象的安全性,注册表的操控以及事件日志有关;SHELL32.DLL是微软视窗外壳要求生效的命令代码集合,用于打开网页和文件,建立文件时的默认文件名的设置等大量功能;SHLWAPI.DLL用于注册键值和色彩设置;ole32.dll是链接和嵌入在应用程序中的对象的过程文件。它是用于编写和整合来自不同应用程序的数据在Windows作业系统的骨干部分;OLEAUT32.dll是对象链接与嵌入OLE相关文件。
上述的这些文件可以非常容易的帮助我们去分析这个样本的功能集合,那么我们放到ida里面进行分析,发现主函数非常多行,其中含有大量的变量在里面被赋值,从图中可以看到,单单主函数DllMain入口就将近两千多行的伪代码。
在主函数当中的最前面,有一段让人匪夷所思的代码。就是他首先会malloc申请一个大小为size的堆块,然后依次在这个堆块中按顺序赋值。赋值完之后它将会释放这个堆块。如果最后赋值的这个次数i,不等于这个Size的大小,那么它将退出程序。
在程序中,我们可以看到是0x5F5E100,也就是1亿字节。在这里我们猜测他申请这么多字节的堆块,然后尝试依次赋值,可能是为了检查宿主机有没有可用的内存进行使用。我们在接着往下分析,是可以看到这里面。检查完有可用内存之后就会对六个全局变量进行赋值,以及对site这个全局变量的低16位进行赋值。
然后我们在主函数当中可以发现一个连续的char数组,如图所示。图中我们可以看到他是被标记为v9,v10以及最后到v25都是char类型。那在这里面他其实我们可以认作是一个非常大的数组,只不过在负值有一些不同。然后我们进行计算一下,v9~v25一共是2904个字节,即0xB58。我们从main函数当中第一个被赋值的代码行数开始算起,从那一行到最后一个被赋值的数组元素,一共是2805行。检查之后发现v25没有被赋值。
在上文含有VirtualAlloc这个代码的截图中,我们可以看到,VirtualAlloc的功能是在调用进程的虚地址空间,预定或者提交一部分页。我们继续深入sub_10002518去看,更多是一种数据的重新计算初始化。
前面我们尝试说运行这个文件,然后分析他的行为,其实对于d11文件来说是不成立的。我们在前面的分析报告当中提及了一个点,就是这个样本当中有大量的函数没有被使用。这说明了一点,就是他是被作为一个动态扩展库被装载的。如果说要让里面的函数运行起来,肯定是要有一个主要的控制流程序来对它里面的程序函数进行调用,而对于它自身而言是没有什么办法去让自己执行起来。
所以接下来的分析,我们主要通过对特定的API函数进行静态分析。
反调试分析
我们分析这个文件头,然后看到他的程序入口地址是DllEntryPoint。我们按照这个地点进行一步一步的分析,然后根据前面的提示看到有很多反虚拟机行为的系列函数存在,我们推断在dll文件刚运行开始,它会检查环境是否是虚拟机环境,因此我们结合IDA这个程序进行调试分析。
首先,我们先用IDA查看DllEntryPoint看看代码,里面有一个_security_init_cookie()函数,双击进去我们看到里面是会检查系统里面的具体环境。
在检查这个security cookie这个函数里面,他首先会判断一个全局变量是否等于一个十分大的值,然后进入不同的看你条件,如果他等于这个值的话,全局变量本身等于这个值的话,它就会获取Windows高精度时间戳,然后还有或许主窗口句柄获取现成ID,从操作系统其中到现在所经历的毫秒数以及最后返回高精度性能计数器的一个值,他们把这些值进行异或xor等操作,然后将其跟一个值进行比较,如果还等于这个值的话,那么他们将在两个全局变量上,进行重新复制。我们在效果上看,也就是说第一个这个7c零的全局变量他将会递增加一然后7c8他将会是这个7c0全局变量的取反。
因此,根据上文分析,我们将7c0命名为cookie_1,将7c8命名为cookie_not_1。根据网上资料可以知道,这其实是在程序运行当中保证堆栈完整性的一个初始化操作,因为cookie的作用是在对每一个程序调用完之后,检查自己的堆栈cookie是否被改写,如果被改写了,说明可能存在栈溢出,将会触发异常保护机制。那么我们对这个函数按一下x来查看它的交叉引用发现在众多函数当中都被引用说明这个函数是贯彻始终的。
紧接着,我们尝试分析_DllMainCRTStartup函数,这个函数不论_security_init_cookie是否执行,其都会执行。
根据Win64平台的传参规则:使用寄存器传参递前四个参数,分别使用RCX、RDX、R8与R9传递,其他多余的参数使用堆栈传递,我们可以大体分析一下:
这个函数它首先会判断是启用了,Security的Cookie的初始化,如果他没有启用初始化,而且一个全局变量是等于零的话,那么他将会直接返回退出,因此我们判断这个曲全局变量应该是Ct是否被调用的一个值,因为我们双击进来的时候,发现他只在这个行当中被调用。因此我们可以继续往下分析。如果是正常运行的话,fdwReason和这个全局变量必定有一个是非零的,如果都不正常,说明系统可能的工作流程被篡改。正常情况下,在第九行的前两个判断条件是零,然后在crt这个函数当中我们双击进来看。他首先会检查第二个参数,那根据上下文我们可以知道,这个a2它就是fdwReason,然后a1是一个提示的dll名称。然后这第三个是一个fpvReserve,根据名称判断可能是处于调试环境下吧。正常情况下这里并没有写,刚进到crt这个函数当中,它会检查fdwReason的值,如果等于二的话。
以上就是初始化的主要分析工作。
我们根据具体函数IsDebuggerPresent来跟踪,看看在哪些地方会被跟踪,我们按下X按键来尝试跟踪。
我们看到有三个函数调用了这个IsDebuggerPresent这个函数。我们依次点进去看,发现他是贯通在非常多的函数里面。因此我们可以判断它是一个通用型的安全机制。也就是说他的反调是是在很多情况下都会触发,在我们发现除了第二个unknown_libname_147这个函数用不了不是在部分函数的退出前运行之外,__report_gsfailure所属的父函数_security_init_cookie和_invalid_parameter基本上都是在函数ret运行前运行的,说白了就是每次函数退出的时候都会检查是否处于被调试状态。
我们自己分析,函数发现,基本上的反调试在__report_gsfailure和_invalid_parameter之中的函数调用都是RtlCaptureContext、IsDebuggerPresent、SetUnhandledExceptionFilter、UnhandledExceptionFilter、GetCurrentProcess、TerminateProcess的流程。
这个函数它会调用RtlCaptureContext函数,获取当前进程的上下文,然后返回上下文记录给这个指针。这个指针它可以包含一些寄存器等上下文信息。接着把这个目前的一些异常返还给这个结构体然后进程会调用IsDebuggerPresent函数,检查进程是否处于被调试的状态。调试的话那就会返回1,没有调试的话就返回0。然后进程会通过SetUnhandledExceptionFilter函数注册一个空异常处理结构,然后调用UnhandledExceptionFilter函数来尝试解决这个异常,如果有这个异常的话,有调试器的话,这把异常交给调试器来进行处理。如没有调试器的话,那么将会跳过这个异常处理。然后将会调用GetCurrentProcess函数获取当前进程的ID,返回一个句柄。然后最后调用TerminateProcess函数将这个进程进行终止。
因此可见,进程中确实到处存在反调试的检查工作。
这一部分是关于从堆结构的flags上去判断是否处于被调试的状态。根据网友的分享,如下图所示。
我们知道可能在在获取堆结构之后,PEB.ProcessHeap+0xC的Flags和偏移0x10的ForceFlags上在调试的时候会被改变,因此,在反反调试上,只需要将其改成HEAP.Flags=0x2,HEAP.ForceFlags=0即可。
我们跟踪GetProcessHeap这个函数的交叉引用,我们可以判断这个样本当中是否有反调试的存在。
图中我们看到了全部都是在_CRT_INIT这个函数当中,我们综合分析了一下,然后结合下图来分析可以知道这个样本其实是一个初始化系统信息的,是检查系统版本的。
图示的两个HeapFree,都表明了最后堆块是会被释放的,且检查完结构后,并没有所谓的flags,更多的它是一个名为OSVERSIONINFOEX的结构体。与前面分析的不一样,所以在这里我们分析并没有反调试存在。
关于这条信息,因为我们没办法动态执行查找到相关的信息,只能借助在线平台来进行分析,因此这条我们无从考证。
分析结果
样本的自我保护:存在一些高危敏感行为,有反虚拟机行为、反检测技术和反逆向工程的技术在样本里面体现比如在动态调试的过程中,我们在缓冲区中发现了一个PE文件,在系统环境探测当中,它会检查注册表中的CPU名称以及检查硬盘相关的信息,通过检查常见的固件信息、查询系统硬盘大小、检查适配器地址等收集操作系统硬件相关的指纹信息来尝试判定样本是否处于虚拟环境中,而这种多方检查的手段让样本处于相对独立的运行环境,是反虚拟机行为、反检测技术和反逆向工程的技术体现。同时,二进制文件当中也存在被加密和压缩的数据,这是应对静态分析的反逆向工程技术的体现。自身也会检查系统的时间,而这个操作常常用于躲避恶意软件分析系统。
网络相关:样本当中存在可疑的HTTP流量,而这种可以流量在Emotet家族中具有可识别的特点。Emotet通常通过恶意垃圾邮件(malspam)电子邮件进行分发。
系统相关:轮询操作系统敏感路径下的文件,枚举进程模块,在枚举过程中,如果发现了特定的进程或者线程,将会对其进行相关检查、注入操作。样本会搜索并加载模块资源,枚举文件和目录,在临时目录中创建文件。Emotet感染链中的关键步骤是Microsoft Word文档,其中包含旨在感染易受攻击的Windows主机的宏。
总的来说,这个样本技术复杂度比较高的,威胁性高。特别是样本当中存储了一般虚拟环境的指纹信息,然后通过广泛收集各种操作系统的硬件信息来不断比较来判定样本是否处在虚拟环境中、调试环境中等。
在反调试、反虚拟机这一块,其编程手段值得我们学习。
学习网址
- https://www.kaspersky.com.cn/resource-center/threats/emotet
- https://www.malwarebytes.com/emotet
- https://www.xctf.org.cn/library/details/85162f1d6357c787b3cecc13302219e152f28904/
- https://analyze.intezer.com/files/978f702136527b15555bf7ebe208c464117219acaae692380ede3f96cafbdff4/sub/1de9d7d8-2de1-43ea-bf3d-bfb51fd4819e/genetic-summary
- https://www.joesandbox.com/analysis/612929/0/html#deviceScreen