Unpacking Emotet

In this post I take a look at unpacking Emotet to discover hard coded command and control servers.  The MD5 for the sample I’m looking at is 8db38c7f70214ee08e166cde8b9163c6.

This sample of Emotet uses a customized packer.  Instead of trying to reverse the algorithm to unpack the next stage, we can use dynamic analysis.  I’ll let the malware do the unpacking for me and grab the next stage out of memory.  The process will need to allocate memory for the next stage, so it’s a good assumption that we will see a call to VirtualAlloc.  Open up the sample in x32dbg and set a breakpoint on VirtualAlloc.  When the breakpoint is hit, we can note the parameters that were passed to the function.

LPVOID VirtualAlloc(
  LPVOID lpAddress, 0x0
  SIZE_T dwSize,  // 0xc000
  DWORD  flAllocationType, // 0x3000 i.e. MEM_COMMIT | MEM_RESERVE
  DWORD  flProtect // 0x4 i.e. PAGE_READWRITE

As you can see, the sample is letting the system determine where to allocate the memory with read write permissions.  After the call to VirtualAlloc, the eax register will contain the base address of the allocated region.  I dumped the memory at that address to keep an eye on it.  After letting the code run to the next breakpoint, I can see the memory has been populated.  Next, I jump to the memory map and dump the memory to a file.  

Opening the dump in a hex editor displays the following.

The file clearly contains a PE file but there is some extra code at the beginning of the file.  I’m unclear as to what this extra code is at this time, I may come back to look at it later. To move things along, I just looked for the magic number and trimmed the rest of the contents to the beginning of the file.  

Opening the file in IDA just to take a peek I noticed that there were zero imports.  Jumping to sub_403530 I noticed some signs of dynamically creating an import table.  Looking at some of the instructions I can see that it is grabbing a pointer to the process environment block.  From there it appears to be walking the structure to locate function pointers for its own import table. There is certainly more to research here, but I’ll save that for another post.

After unpacking, we can see the list of C2 servers is hard coded in the binary.  This information gets written to a buffer in the .data section of the code.  If we are looking to grab the IOCs from the sample, we want to let the malware run and write the C2 servers to the buffer and examine the memory.  In the following screenshot we can see the first IP address and port.

The list will contain a series of IP addresses.  The highlighted IP address and port will corollate to  The first four bytes is the IP address followed by two bytes for the port.  The next two bytes can be ignored.  I extracted the following C2 servers from the sample.