Emotet恶意软件深入分析

 

Emotet是一种主要通过垃圾邮件进行传播的木马。传播至今,已进行过多次版本迭代。早期版本中,它通过恶意JavaScript文件被投递。在后来的版本,演变为使用启用宏的Office文档从C2服务器下载后进行传播。

自Emotet首次被发现之后,FortiGuard Labs一直在对其追踪。在本博客中,我将对5月初发现的新Emotet样本进行深入分析。本篇分析主要包括:如何释放持久性payload,Emotet恶意软件如何与其C2服务器进行通信,如何识别可执行文件中的硬编码C2服务器列表及RSA密钥,以及如何加密它收集的数据。

 

0x01 恶意Word文档

这个样本是一个Word文档。当你打开它并启用宏时,恶意软件将开始运行。

图1:执行PowerShell脚本

我们可以看到恶意Word文档文件中的VB脚本使用PowerShell创建了一个新进程。而’-e’参数表示可以执行经base64编码的字符串类型的命令。

解码后的PowerShell脚本如图2所示:

图2:解码后的PowerShell脚本

变量$ YBAAU_D是一个包含五个URL的列表。通过调用它来从远程服务器下载payload并执行。下表中列出了所有恶意URL,并给出了每个URL所对应的payload的名称,md5值及大小。

在我5月初开始跟踪此活动时,前两个URL已无法访问,而其余三个URL则处于活跃状态。(URL对应的payload均为PE文件)。

接下来,需要选择其中一个进行进一步分析。在此博文中分析的payload是p4xl0bbb85.exe(md5:a97cbbd774ca6e61cf9447d713f7cf5d)。

 

0x02 第一层Payload

p4xl0bbb85.exe由定制化的封包工具进行封装。执行后,它会创建三个新进程,如下图所示:

图3:执行有效负载p4xl0bbb85.exe后的进程树

首先,它会使用命令’—f02b3a38’启动进程(pid:2784)。然后将PE文件’itsportal.exe’写入路径C: Users [XXX] AppData Local itsportal 。接下来,执行itsportal.exe(无附加参数)。执行后,使用命令’—c6857361’启动进程(pid:1980)。最后,退出前三个创建的进程,将PE文件p4xl0bbb85.exe从硬盘中删除。留下的PE文件itsportal.exe即为持久性payload。

图4:持久性payload

 

0x03 持久性payload分析

在本节中,我们将继续分析持久性payload itsportal.exe。这个payload使用了定制化的封包工具。从入口点跟踪几个步骤后,程序进入函数sub_4012E0()。

图5:函数sub_4012E0()

下图是函数sub_4012E0()的C语言伪代码。

图6:函数sub_4012E0()的C语言伪代码

在此函数中,恶意软件调用了函数sub_401440()并使用VirtualAllocEx()分配了新的内存空间(0x1D0000),并将此内存的起始地址加上0x102f0设置为蹦床(trampoline)地址。

然后,在循环中,首先会将0xf080f8的前0x7B字节复制到这个新内存空间中,然后开始复制数据部分。当达到0x37字节时,将停止复制。最终,复制到内存空间数据大小为0x10600。

接下来,函数sub_401560()会对新内存空间中的数据进行解密,在此过程中,trampoline code(蹦床代码)也将完成解密。然后程序将跳转到蹦床代码。最后,程序跳转到0x00401260执行相应命令。

图7:跳转到0x00401260

如图8所示,程序将跳转到0x1E02F0以执行trampoline code(蹦床代码)。

图8.跳转到trampoline code

trampoline code(蹦床代码)主要功能如下:

1.分配大小为0x10000 的新内存空间(0x1F0000),并将其命名为内存空间A。
2.从0xfD0124复制0xf600字节大小的数据到内存空间A。
3.在步骤2中解密内存空间A的数据。解密算法如下图所示:

4.分配大小为0x14000 的新内存空间(0x200000),并将其命名为内存空间B。
5.将内存空间A的前0x400字节的数据复制到内存空间B的开头。
6.将内存空间A所有数据段复制到内存空间B.
7.调用UnmapViewofFile函数 (0x400000),通过调用进程的地址空间来取消文件映射。
8.调用VirtualAlloc函数(0x400000,0x14000,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE)来保证对内存空间的执行,读/写权限。
9.从内存空间B复制0x14000字节数据到0x400000。
10.从蹦床地址跳回到真实入口点(0x4CA90)以执行指令。此时,已完成解包工作。

内存映射如下图所示,红框内为三块已分配的内存空间及解包的程序。

图9:三块已分配的内存空间及解包的程序

最后,程序跳转到实际入口点0x4C9A0。(注意:此时可以在x64dbg中使用OllyDumpEx插件dump出解包的程序。获得解包的程序后,就可以使用IDA Pro对其进行静态分析了)

图10:跳转到真正的入口点

到目前为止,我已经演示了如何对Emotet恶意软件进行解包。在解包的程序中,C2服务器列表和公钥分别硬编码在0x40F7100x40FBF0处。

 

0x04 与C2服务器通信

为了研究它与C2服务器的通信,我们首先需要获取C2服务器列表。如第3节所说到的,C2服务器列表是硬编码在可执行文件中的。

解包后,可以看到在缓冲区中,从偏移量0x40F710开始,存储的即为C2服务器列表,如图11所示:

图11.硬编码的C2服务器列表

全局变量存储在0x004124A0。其结构如下:

struct g_ip_port_list

{

                  DWORD *c2_list;

                  DWORD *current_c2;

                  DWORD size;

                  DWORD current_c2_index;

}

变量c2_list指向缓冲区中硬编码的C2服务器列表。这个列表中的每一项都包含一对IP地址和端口。大小为8个字节,其中前4个字节代表IP地址,接下来2个字节代表端口;变量current_c2指向当前被选中的C2服务器;变量size是C2服务器列表的大小;变量current_c2_index是当前被选中的C2服务器的索引。

此样本包含61个C2服务器,如下所示:

200.58.171.51:80 (即:C8 3A AB 33 :00 50)
189.196.140.187:80
222.104.222.145:443
115.132.227.247:443
190.85.206.228:80
216.98.148.136:4143
111.67.12.221:8080
185.94.252.27:443
139.59.19.157:80
159.69.211.211:8080
107.159.94.183:8080
72.47.248.48:8080
24.150.44.53:80
176.58.93.123:8080
186.139.160.193:8080
217.199.175.216:8080
181.199.151.19:80
85.132.96.242:80
51.255.50.164:8080
103.213.212.42:443
192.155.90.90:7080
66.209.69.165:443
109.104.79.48:8080
181.142.29.90:80
77.82.85.35:8080
190.171.230.41:80
144.76.117.247:8080
187.188.166.192:80
201.203.99.129:8080
200.114.142.40:8080
43.229.62.186:8080
189.213.208.168:21
181.37.126.2:80
109.73.52.242:8080
181.29.101.13:80
190.180.52.146:20
82.226.163.9:80
200.28.131.215:443
213.172.88.13:80
185.86.148.222:8080
190.117.206.153:443
192.163.199.254:8080
103.201.150.209:80
181.30.126.66:80
200.107.105.16:465
165.227.213.173:8080
81.3.6.78:7080
5.9.128.163:8080
69.163.33.82:8080
196.6.112.70:443
37.59.1.74:8080
23.254.203.51:8080
190.147.116.32:21
200.45.57.96:143
91.205.215.57:7080
189.205.185.71:465
219.94.254.93:8080
186.71.54.77:20
175.107.200.27:443
66.228.45.129:8080
62.75.143.100:7080

接下来,我们来看看发送到C2服务器的流量。在样本中,它向C2服务器发送了HTTP POST请求。

图12:发送到C2服务器的流量

HTTP会话如下图所示。其中数据部分进行了URL编码。

图13:HTTP会话数据

进行URL解码后,发现数据还有一层Base64编码。再执行一次Base64解码,最终得到了真实数据。在下一节中,我们将深入研究HTTP正文数据所用的加密算法。

图14:经过URL解码及Base64解码HTTP数据

 

0x05 加密算法

Emotet恶意软件会收集如主机名、运行进程列表等系统信息。下图为收集的系统信息:

图15:收集的系统信息

接下来,会使用Deflate算法对收集的信息进行压缩。

图16:使用Deflate算法压缩收集的数据

接下来,恶意软件用会话密钥对压缩后的数据进行加密,并将由RSA公钥加密的会话密钥(AES)、哈希值以及加密数据打包在一起,存放在接下来的结构中。

图17:打包后的数据

其中RSA公钥加密的会话密钥大小为0x60字节,哈希值的大小为0x14字节。

将这三个部分数据打包后,还要依次进行Base64编码和URL编码,才形成最终将要发送到C2服务器的http正文数据。

图18. HTTP正文数据

至此,已经完成了Emotet恶意软件与C2服务器通信时所用的数据加密算法的深入分析。

至于通信的后半部分,则是相反的。Emotet恶意软件首先解密HTTP响应数据,然后使用Deflate算法对相应的数据进行解码,最终完成对来自C2服务器响应数的处理。

此外,RSA密钥位于解包程序中0x0040FBF0处,并采用ASN.1 DER编码规则进行硬编码。其大小为0x6A字节。

图19. RSA密钥使用DER规则进行硬编码

 

 

0x07 结论

Emotet是一种精心设计的恶意软件,它使用了定制的高级封包工具以及复杂的加密算法来完成与C2服务器的通信及其他高级功能,并会从C2服务器下载攻击payload或其他恶意软件payload,来窃取受害者的敏感数据。

我们会继续追踪Emotet与其C2服务器之间的活动。

在下一篇博客中,我将介绍一些更有趣的研究成果,包括如何以编程方式解封Emotet可执行文件,并从可执行文件中提取硬编码的C2服务器列表和RSA密钥。我的目标是帮助研究人员节省更多的逆向分析时间,做到快速识别与Emotet相关的恶意流量,欢迎您继续关注!

 

参考

md5哈希

e86dc2921df8755d77acff8708119664(Word文件)
fd20aa063f3aca1be3ad3d7bf479173e(1n592ynn2ys9gg0.exe)
6312e50af74e027602835fbfbd0f36f1(s9cbyx.exe)
a97cbbd774ca6e61cf9447d713f7cf5d(p4xl0bbb85.exe)
a97cbbd774ca6e61cf9447d713f7cf5d(itsportal.exe)

URLs

hxxp://webaphobia[.]com/images/72Ca/ 
hxxps://montalegrense[.]graficosassociados.com/keywords/FOYo/
hxxp://purimaro[.]com/1/ww/
hxxp://jpmtech[.]com/css/GOOvqd/
hxxp://118.89.215.166/wp-includes/l5/
(完)