FortiGuard Labs Threat Research

A Deep Dive Into IcedID Malware: Part III - Analysis of Child Processes

By Kai Lu | July 22, 2019

FortiGuard Labs Threat Analysis Report Series


In Part II of this blog series, we identified three child processes that were created by the IcedID malware. In Part III below, we’ll provide a deep analysis of those child processes.

Let’s get started!

0x01 Child process A (entry offset: 0x168E)

This first child process is primarily responsible for performing web injection in browsers and acting as a proxy to inspect and manipulate traffic. It can also hook key functions in browsers.

The following is the pseudo code of the entry point.

Figure 1. The pseudo code of the entry point in the trampoline code

In this function, the process first unhooks the RtlExitUserProcess API and then loads a number of dynamic libraries. The function sub_0x1A9F() is the core function. 

Figure 2. The core function sub_0x1A9F()

Here’s a list of the key functionalities of this function. 

1.     Build a C2 server list 

2.     Create a thread to set IPC with file mapping technique 

3.     Create a thread and then call the QueueUserAPC function to add a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread. In APC, it can read the DAT config file, decrypt it with an RC4 key, and then decompress the data as follows.

Figure 3. The decrypted web injection DAT config file

This DAT config file is used for performing web injections. It uses a Magic number, “zeus”. IcedID then uses a customized algorithm to decode the content. The following is the decompressed data.

Figure 4. The decompressed data of web injection

4. Add self-signed certificate into the certificate store and then create a proxy server which is bound to on TCP port 61420. Next, it calls the RegisterWaitForSingleObject function to register a WSA (Windows Socket API) event handler, then uses the socket of the initialized proxy server to handle all connect, send, and receive network requests.

Figure 5. Proxy server handles network requests

Additionally, in order to perform a MiTM attack on SSL connections, the proxy server has to generate a certificate and add it into the cert store. The following is that implementation.

Figure 6. Adding a self-signed cert into the cert store

We can also see that this svchost.exe child process is listening on TCP port 61420.    

5. Create a thread to perform code injection into the browser. The following is the thread function of the browser code injection.

Figure 7. The browser injection function

It uses the ZwQuerySystemInformation function to gather a list of all current running processes. If a browser process is found, it performs code injection into the browser process and sets up a hook on the ZwWaitForSingleObject function. The following is the function that checks to see if a running process is a browser process. It first generates a hash with the process name using a specified algorithm. Then, it compares the hash with the given hash of four browsers: Firefox, Edge, IE, and Chrome.

Figure 8. Checking the hash of the process name

Before performing its code injection, it first checks to see if this process is running on 64 bits by calling the IsWow64Process function. It then performs a code injection into the browser process, and depending on the process bits version, it calls the corresponding hook function to set up a hook on the ZwWaitForSingleObject function. 

Figure 9. Process injection and setting up a hook in a browser

Here we will use Firefox to demonstrate how it performs its process injection and sets up a hook.

Figure 10. Process injection into Firefox

It sets up a hook on the ZwWaitForSingleObject API in the Firefox process as follows.

Figure 11. Hooked ZwWaitForSingleObject function

When Firefox calls the ZwWaitForSingleObject function, it jumps to the trampoline code. The entry point of trampoline code is at offset 0x1856 from the injected memory region.

Let’s take a closer look at the trampoline code (offset:0x1856).

In this trampoline code, it first unhooks the ZwWaitForSingleObject API. Then it sets up a hook on the SSL_AuthCertificateHook API (in nss3.dll for Firefox.) The nss3.SSL_AuthCertificateHook function specifies a certificate authentication callback function that is called to authenticate an incoming certificate.

The following is the hooked nss3.SSL_AuthCertificateHook function.    

Figure 12. The hooked nss3.SSL_AuthCertificateHook function

It configures the nss3.SSL_AuthCertificateHook function to always return SECSuccess. 

Note that it can set up a hook for browser-specific functions depending on the type of browser. However, we won’t be providing details for any other browsers in this blog.

Next, it continues to set up a hook on the connect API in ws2_32.dll. The following is the hooked connect API.

Figure 13. The hooked connect API in ws2_32.dll

The following is the pseudo code of the trampoline code for the hooked connect API.    

Figure 14. The pseudo code of the trampoline code for the hooked connect API

Once the connect function returns 0 (the connection has succeeded), it sends 12 bytes of data to proxy server, which was created in this svchost.exe child process. The captured traffic is shown in Figure 15.

Figure 15. Brower sends 12 bytes of data to proxy server

The structure of these 12 bytes consists of four parts, as follows:

0x00: Unknown

0x04: Target website’s IP address

0x08: Port

0x0A: Browser type

0x02 Child Process B (entry offset: 0x1E0A)


This second child process is used to communicate with the C2 server. It will attempt to send an HTTP request to the C2 server via WebSocket, as follows.

Figure 16. Requesting data from the C2 via WebSocket

It also communicates with the parent svchost.exe process using a mapping file technique. And, depending on the shared info, it may attempt to make network requests to a C2 server over SSL, and then create a new process, perform code injections, and set up a hook on the RtlExitUserProcess function.

0x03 Child Process C (entry offset: 0x10DF)

This process communicates with the parent svchost.exe process by using a mapping file technique. It is also able to perform some registry operations.

0x04 Solution

This malicious PE file has been detected as “W32/Kryptik.GTSU!tr” by the FortiGuard AntiVirus service.

The C2 server list has been rated as “Malicious Websites” by the FortiGuard WebFilter service.


0x05 Conclusion

In this series of posts, I have provided a detailed analysis of a new IcedID malware sample. The entire detailed analysis is divided into three parts. The first two part are available here: Part I: Unpacking, Hooking, and Process Injection and Part II: Analysis of the Core IcedID Payload (Parent Process).

IcedID is a sophisticated and complicated banking trojan that performs web injection in browsers and acts as proxy to inspect and manipulate traffic. It is designed to steal information – such as credentials – from victims and then send that stolen information to attacker-controlled servers. To accomplish this, IcedID uses a large number of hooking and process injection techniques, and it also disguises itself as several svchost.exe processes, which we examined in this deep dive analysis series.


Learn more about FortiGuard Labs and the FortiGuard Security Services portfolioSign up for our weekly FortiGuard Threat Brief. 

Read about the FortiGuard Security Rating Service, which provides security audits and best practices.