IcedID恶意软件原理分析(二)

lucywang 恶意软件 2019年10月31日发布
Favorite收藏

导语:上文,我们已经就如何解压缩IcedID恶意软件,IcedID使用的挂钩和进程注入技术,以及如何执行IcedID有效载荷进行了研究,在这部分,我们会继续来研究关于IcedID有效载荷分析(父进程)的问题。

上文,我们已经就如何解压缩IcedID恶意软件,IcedID使用的挂钩和进程注入技术,以及如何执行IcedID有效载荷进行了研究,在这部分,我们会继续来研究关于IcedID有效载荷分析(父进程)的问题。

有效载荷分

以下是有效载荷的入口函数,它首先解钩函数RtlExitUserProcess。核心函数在函数sub_0x27FE()中实现。成功执行核心模块后,程序将进入无限循环,以确保svchost.exe进程不会退出。

1.png

有效载荷的入口函数

接下来,让我们看一下函数sub_0x27FE()。

2.png

函数sub_0x27FE()

接下来,我将向你展示该函数的作用。

两个注入的内存区域

正如你在第一部分的图15中所看到的,svchost.exe进程中有两个注入的内存区域。第一个是大小为8KB的数据段。此部分在开头存储了几个系统API的地址,加密的C2服务器列表以及其他有用的信息。

以下是系统API的地址。程序可以通过“call [base_addr + offset]’之类的指令间接调用它们,间接调用系统API的方式对于静态分析非常棘手。

3.png

存储在注入的内存区域中的系统API地址

以下是上述地址的相应API名称:

4.png

这些系统API的名称

此外,它将加密的C2服务器列表存储在偏移量0x350处。

5.png

加密的C2服务器列表

第二存储区域具有三个段(一个代码段和两个数据段),有效载荷的核心函数在代码段中实现。

与C2服务器通

首先让我们看一下如何获取C2服务器列表。如上图所示,加密数据为256字节,解密后的数据如下图所示。

6.png

C2服务器列表

我们可以获得初始的C2服务器列表。

albarthurst[.]pro
mozambiquest[.]pw
ransmittend[.]club
summerch[.]xyz

IcedID使用WinHTTP API与C2服务器通信,它通过HTTPS发送请求并接收响应。我们可以通过Fiddler拦截HTTPS流量。但是在使用它之前,我们必须设置WinHTTP的代理。在Windows Vista和更高版本上,我们需要使用提升的(admin)命令提示符来调用netsh,如下所示。有关详细说明,请参阅https://www.telerik.com/blogs/using-fiddler-with-winhttp

7.png

设置WinHTTP的代理

以下是Fiddler中发送的解密HTTPS流量IcedID:

8.png

初始阶段发送的解密的HTTPS流量IcedID

在初始阶段,IcedID可以通过SSL向C2服务器发送HTTP请求。然后,它解析响应,并继续通过SSL发送7个HTTP请求,以下载7个.DAT配置文件。接下来,让我们深入研究HTTP POST请求的URL参数。

9.png

HTTP POST请求的URL参数,我突出显示了一些关键参数:

第一个是Bot ID,它也用作RC4密钥来加密原始.DAT配置文件。参数‘r’表示IcedID的版本。在此示例中,其版本号为108。关于RC4密钥生成算法,我将在下一部分中详细介绍。

RC4密钥生成算法

函数sub_0x29E2用于生成大小为4字节的RC4密钥。

10.png

RC4密钥生成算法

RC4密钥存储在距第二个注入的存储区域的起始地址偏移量0x74A8处。然后,RC4密钥也被复制到偏移量为0x74B8的缓冲区。

多线程协作工作

IcedID可以创建多个线程来执行不同的任务,根据我的分析,通过调用函数CreateThread创建了五个子线程。一些线程始终在运行,而其他线程在完成任务后将退出,具体取决于收到的C2命令。我在下面列出了本示例的线程函数。

线程1:线程函数0x2601

该线程函数主要负责与C2服务器的初始通信,处理HTTP响应以及根据HTTP响应下载,.DAT配置文件或其他类型的文件并将其存储到相应的文件夹中。以下是此线程函数的伪代码。

11.png

线程函数0x2601

在此无限循环中,它将一直等待,直到指定的对象处于发信号状态或超时间隔(此处为5分钟)过去为止。然后,它生成URL参数和HTTP请求正文。接下来,它可以通过HTTPS与C2服务器通信。最后,它处理HTTP响应,并根据HTTP响应的解析结果继续下载.DAT配置文件或其他文件。该线程不会退出,并且始终在运行以与C2服务器通信。

第一次执行IcedID时,初始通信流量如下所示:

12.png

与C2服务器的初始通信

如图12所示,响应是多行消息。每行是一个C2命令,由三部分组成,两部分之间用分号分隔。恶意软件可以调用相应的处理程序函数,以基于C2命令号完成特定任务。第一部分表示事件ID,第二部分表示处理程序函数的索引,第三部分表示传递给处理程序函数的参数。以下是对处理函数的调用。

13.png

对处理程序函数的调用以及所有处理程序的地址

在此IcedID示例中,它支持18种不同类型的C2命令。

线程2:线程函数0x5599

该线程函数负责从C2服务器下载.DAT配置文件和其他类型的文件(例如可执行文件),并将这些数据保存到本地文件中。对于.DAT配置文件,HTTP响应正文由RC4算法使用两个不同的密钥加密两次。让我们仔细看看加密进程。以下是来自C2服务器的HTTP响应。

14.png

HTTP响应主体上的两个RC4加密进程

如图14所示,HTTP响应正文中的前8个字节是第一层的RC4密钥。第二个RC4密钥的长度为4个字节。其生成算法参考“RC4密钥生成算法”部分。

线程3:线程函数0x2E59

这个线程函数负责将IcedID PE文件复制到“C:\ProgramData\{0CD48D26-D226-4D28-9E39-3D2840658FD3}\{8CD48D26-D226-4D28-9E3A-3D2844658FD3}\qgbjaykqtsu”中。并在登录时调度任务。子目录的名称在不同的受影响的计算机上可能不同。预定的任务如下所示:

15.png

在登录时的预定任务

线程4:线程函数0x1F9B

该线程函数负责与C2服务器通信,这个线程是在处理图13中C2命令17的处理程序函数中创建的。

线程5:线程函数0x52FC

该线程函数负责创建三个新的svchost.exe子进程,并将代码注入这些进程的空间。

16.png

线程函数0x52fc

如图16所示,IcedID使用参数CREATE_SUSPENDED创建svchost.exe子进程。新进程的主线程将处于挂起状态,并且新创建的进程在调用ResumeThread函数之前不会运行。在恢复主线程之前,IcedID将代码注入到新的进程空间中。之后,它将调用ResumeThread函数,注入代码的伪代码如图17所示。

17.png

将代码注入svchost.ext子进程

在注入函数中,它首先将三个内存区域分配到远程进程空间。然后,它将解密的DAT配置文件中注入的代码。接下来,它将代码注入到先前分配的三个内存区域中。最后,它在远程进程空间中的RtlExitUserProcess API上设置了一个挂钩。接下来,让我们继续分析哪个DAT配置文件会被注入到相应的子进程中。

1. yxuvgoshgc.dat(748961aabd75b85ee602e5f6d70322b281930349fbc98ad5c638104a759eba0b)

如下所示,此DAT配置文件被注入到子进程1中。有三个内存区域要注入到子进程1中,其中第一个是注入的代码段,第二个是一个数据段,包括几个系统API的地址和更新的C2服务器列表。第三个是PE文件。

18.png

注入的svchost.exe子进程1

子进程1中挂钩的RtlExitUserProcess如下所示,调用RtlExitUserProcess函数时,它将跳转到0x210DF(offset:0x10DF)以执行有效载荷。

19.png

svchost.exe子进程1中的挂钩RtlExitUserProcess

2.uvgbwwwjcc.dat(b1d9d9bb617463a1cef665322949b29ad23ebfee2892908385b30cd739c163ce)

如下所示,此DAT配置文件被注入到子进程2中。有三个内存区域要注入到子进程2中。第一个是注入的代码段,第二个是一个数据段,包括几个系统API的地址和更新的C2服务器列表,第三个是数据段。

20.png

注入的svchost.exe子进程2

子进程2中挂钩的RtlExitUserProcess如下所示,当调用RtlExitUserProcess函数时,它将跳转到0x21E0A(offset:0x1E0A)以执行有效载荷。

21.png

svchost.exe子进程2中的挂钩RtlExitUserProcess

3.encziczibc.dat(672440151cd67a20bccc5c9f9f66f7d091098b0bd2a087eeac79af1f11bf3403)

如下所示,此DAT配置文件被注入到子进程3中。有三个内存区域要注入到子进程3中。第一个是注入的代码段。第二个是一个数据段,包括几个系统API的地址和更新的C2服务器列表。第三个是数据段。

22.png

注入的svchost.exe子进程3

子进程3中挂钩的RtlExitUserProcess如下所示,调用RtlExitUserProcess函数时,它将跳转到0x11168E(offset:0x168E)以执行有效载荷。

23.png

svchost.exe子进程3中的挂钩RtlExitUserProcess

关于这三个子进程在内部如何工作,我将在后面介绍。

持久的有效载荷和文件写入操作

以上,我们观察到了一些文件写入操作,如下所示。它将持久性有效载荷放入特定的文件夹中。并且还将七个.DAT配置文件放入“C:\ProgramData\cmrreaykdkq”文件夹中。在不同的系统中,子目录名称可能有所不同。

24.png

持久有效载荷和DAT配置文件的文件写入操作

下表列出了这些DAT配置文件的详细说明。

25.png

DAT配置文件的详细描述

签名验证

IcedID可以对有效载荷进行签名验证,它首先使用RC4密钥解密C2服务器配置文件(alofykqgeb.dat)(请参阅‘RC4密钥生成算法’部分)。解密后的数据缓冲区如下所示。该缓冲区分为三个部分。前8个字节是原始RC4密钥。随后的0x80字节数据是要验证的签名数据,第三部分是更新后的C2服务器列表。

26.png

解密alofykqgeb.dat中的数据

接下来,使用XOR操作对硬编码RSA公钥的缓冲区进行解密。

27.png

加密的硬编码RSA公钥和RSA公钥

然后,它调用CryptVerifySignatureW函数以验证签名。

28.png

调用CryptVerifySignatureW函数来验证签名

至此,我们已经完成了对svchost.exe父进程的分析,它包括IcedID如何与C2服务器通信,RC4密钥生成算法,代码注入进程,多个线程的详细操作,签名验证等。

接下来,我们将对这三个svchost.exe子进程进行深入分析。

子进程A(入口偏移量:0x168E)

第一个子进程主要负责在浏览器中执行web注入,并充当检查和操作流量的代理,它还可以挂钩浏览器中的关键函数。

以下是入口函数的伪代码。

1.png

蹦床代码中入口函数的伪代码

在此函数中,该进程首先解钩RtlExitUserProcess API,然后加载许多动态库,其中函数sub_0x1A9F()是核心函数。

2.png

核心函数sub_0x1A9F()

以下是此函数的主要函数列表:

1. 建立一个C2服务器列表;

2. 使用文件映射技术创建一个线程来设置IPC;

3. 创建一个线程,然后调用QueueUserAPC函数,将用户模式异步过程调用对象添加到指定线程的APC队列中。在APC中,它可以读取DAT配置文件,使用RC4密钥对其解密,然后按如下方式解压数据。

3.png

解密的Web注入DAT配置文件

此DAT配置文件用于执行Web注入,它使用一个魔术数字‘zeus’。然后IcedID使用自定义算法对内容进行解码,以下是解压缩后的数据。

4.png

Web注入的解压缩数据

4. 将自签名证书添加到证书存储中,然后创建一个在TCP端口61420上绑定到127.0.0.1的代理服务器。接下来,它调用RegisterWaitForSingleObject函数来注册WSA(Windows Socket API)事件处理程序,然后使用初始化的代理服务器的套接字,用于处理所有连接,发送和接收网络请求。

5.png

代理服务器处理网络请求

此外,为了对SSL连接执行MiTM攻击,代理服务器必须生成一个证书并将其添加到证书存储中。以下是实现过程:

6.png

将一个自签名证书添加到证书存储中

我们还可以看到此svchost.exe子进程正在侦听TCP端口61420。

7.png

5. 创建一个线程以将代码注入浏览器,以下是浏览器代码注入的线程函数。

8.png

浏览器注入函数

它使用ZwQuerySystemInformation函数来收集所有当前正在运行的进程的列表,如果找到了浏览器进程,它将执行代码注入浏览器进程并在ZwWaitForSingleObject函数上设置一个挂钩。以下是检查正在运行的进程是否为浏览器进程的函数。它首先使用指定的算法生成带有进程名称的哈希。然后,它将哈希与四个浏览器(Firefox,Edge,IE和Chrome)的给定哈希进行比较。

9.png

检查进程名称的哈希

在执行代码注入之前,它首先通过调用IsWow64Process函数检查该进程是否在64位上运行。然后,它将代码注入浏览器进程,并根据进程位的版本,调用相应的挂钩函数以在ZwWaitForSingleObject函数上设置挂钩。

10.png

处理注入并在浏览器中设置挂钩

下面,我们将使用Firefox演示如何执行进程注入并设置挂钩。

11.png

注入Firefox的进程

它在Firefox进程中的ZwWaitForSingleObject API上设置了一个挂钩,如下所示:

12.png

挂钩的ZwWaitForSingleObject函数

当Firefox调用ZwWaitForSingleObject函数时,它将跳转到蹦床代码,蹦床代码的入口函数位于注入内存区域的偏移0x1856处,让我们仔细看看蹦床代码(偏移量:0x1856)。

在这个蹦床代码中,它首先解钩ZwWaitForSingleObject API。然后,它在SSL_AuthCertificateHook API(在Firefox的nss3.dll中)上建立一个挂钩。nss3.SSL_AuthCertificateHook函数会指定一个证书身份验证回调函数,调用该函数对传入的证书进行身份验证。

以下是已挂钩的nss3.SSL_AuthCertificateHook函数。

13.png

挂钩的nss3.SSL_AuthCertificateHook函数

它将nss3.SSL_AuthCertificateHook函数配置为始终返回SECSuccess。

请注意,它可以为浏览器特定的函数设置一个挂钩,这具体取决于浏览器的类型。但是,我们不会在此文中提供其他任何浏览器的详细信息。

接下来,它将继续在ws2_32.dll中的connect API上设置挂钩。以下是挂钩的连接API。

14.png

ws2_32.dll中的挂钩连接API

以下是挂钩的连接API的蹦床代码的伪代码:

15.png

用于连接API的蹦床代码的伪代码

一旦connect函数返回0,就代表连接成功,它将向该svchost.exe子进程中创建的代理服务器127.0.0.1:61420发送12个字节的数据,捕获的流量如图15所示:

16.png

浏览器将12个字节的数据发送到代理服务器

这12个字节的结构包括以下四个部分,如下所示:

0x00:未知

0x04:目标网站的IP地址

0x08:端口

0x0A:浏览器类型

子进程B(入口偏移量:0x1E0A)

第二个子进程用于与C2服务器通信,它将尝试通过WebSocket向C2服务器发送一个HTTP请求,如下所示:

17.png

通过WebSocket从C2请求数据

它还使用映射文件技术与父svchost.exe进程进行通信,并且,根据共享信息的不同,它可能会尝试通过SSL向C2服务器发出网络请求,然后创建一个新进程,执行代码注入并在RtlExitUserProcess函数上设置一个挂钩。

子进程C(入口偏移量:0x10DF)

此进程通过使用映射文件技术与父svchost.exe进程进行通信,它还能够执行一些注册表操作。

至此,我们已经对新的IcedID恶意软件样本进行了详细分析。IcedID是一种复杂的复杂银行木马,它在浏览器中执行Web注入,并充当检查和操纵流量的代理。它旨在从受害者那里窃取信息(例如凭据),然后将所窃取的信息发送给攻击者控制的服务器。为此,IcedID使用了大量的挂钩和进程注入技术,并且还将自己伪装成几个svchost.exe进程。

本文翻译自:https://www.fortinet.com/blog/threat-research/icedid-malware-analysis-part-two.html https://www.fortinet.com/blog/threat-research/deep-dive-icedid-malware-analysis-of-child-processes.html如若转载,请注明原文地址: https://www.4hou.com/malware/21231.html
点赞 5
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论