This blog post will walk you through on how to unpack emotet malware. It's not uncommon for malware authors to make analysis difficult by packing the malware. The sample used in this writeup can be obtained from the open source repository app.any[.]run.
Tools used:
pestudio (static analysis)
DIE (static analysis)
hxd (static analysis)
x32/x64dbg (dissasembler)
Disclaimer
You are dealing with a real malware sample. Run and Analyze it in a controlled environment (sandbox) with no connections to the internal network or internet. I am not responsible for any consequences or damages.
Hash:
MD5 - 8db38c7f70214ee08e166cde8b9163c6.
Analysis:
Method 1:
This Emotet sample uses a custom packer. Malware that uses customized pakers will not return any hits on tools such as DIE (detect it easy or PEID which only detect customized packers such as UPX. While this sample is unpacking, we can assume that it’s likely allocating new memory and passing execution. With this in mind, we will probably utilize the API/Function VirtualAlloc to allocate new memory and VirtualProtect to enable execution on the new region. This is only one of the methods of unpacking malware and no guarantees as it takes trial and error to locate what we need. If this is unsucessful, we can begin stepping over functions, paying attention to resolved API calls, noting interesting activity such as passing execution to a newly allocated memory region(s). For this we use dynamic analysis and let the malware do the unpacking for us to enable grabbing the next stage out of memory. Once the process allocates memory for the next stage, we shall then observe a call to VirtualAlloc.
Open the malware using x32/64dbg and set a breakpoint on VirtualAlloc and on the return of the VirtualAlloc in order to see the calls to this function. Run the malware (F9), it will hit the entry point breakpoint first then runt(F9) the malware again to hit the VirtualAlloc breakpoint. When execution stops, we observe that we’re sitting inside kernel32.dll.
The "ret" (return) of VirtualAlloc returns a value to the EAX register and this is interesting value that the unpacked Emotet is stored in the address base of all the unpacked data and to see where VirtualAlloc was called. We get to the return to VirtualAlloc by placing a breakpoint on the return (ret8) at the end of virtualAlloc, then using ctrl + f9 (or debug > ctrl + f9).
Once we get to the return to VirtualAlloc, place a breakpoint (F2) on it, and remove the first breakpoint that was set to VirtualAlloc. Run (F9) the malware and when we hit the breakpoint, we should see EIP pointing to it.
Next hit F8 (step over) or F7 step into and the module changes back to the executable code and if you scroll up, you will see a call to EDI. On the EDI register to the right, you will see that VirtuaAlloc is stored in EDI. Scrolling down below the breakpoint, you will see arguments such as [esp + 28] which will be used by the function. We look within them by right click them, chose follow in dump then pick the address where they reside. On the bottom left (Dump register) check to see if you can find a MZ header or words "This program is run in DOS mode" which would indicate presence of a PE. If none of the arguments have a PE in the dump section, repeat the process as there could be numerous calls to VirutalAlloc. Hit F9 to run the malware again and you will hit the breakpoint for return to VirtualAlloc. Hit F8 to step over. Scroll up and you'll see a call to EBP and VirtualAlloc is stored in the EBP register. Scroll down and pick available arguments used by the function [edi +54], right click to follow in dump to the address where they reside and luckily, the first argument contains a MZ header on the dump section.
We can now see the MZ header of the unpacked Emotet. We will then dump this memory to file. To do this, we can right-click the memory region in the dump, and select “Follow in memory map“. When we follow to the Memory Map, the protection page has ERW protection rights (Execute, Read, Write. From here, right-click the memory region, and select “Dump Memory to File“.
Opening the dump in a hex editor displays the following.
The file clearly contains a PE file (MZ header) but there is some extra code at the beginning of the file. Trim or delete the rest of the contents to the beginning of the file and save the new file that starts with hex- MZ and you will get your unpacked emotet PE.
FYI: Since we dumped the unpacked sample from memory, it’s possible that the file is mapped and sections offsets need to be aligned. If you attempt to run this file in a debugger and quickly run into “memory access violation” errors, this confirms that this is the case and you'll need reallignemnt of the RAW and VIRTUAL addresses using PE Bear to Change the “Raw Address” of the section headers to match the “Virtual Address“. Check the IcedID/Bokbot Malware Write-up for this type of situation (1.change raw address and size on section headers to match the virtual address and size. 2.In the optional header section, Change the “Image Base” to the memory address that we dumped the file from eg(0x41F0000)3.In HxD, remove unnecessary bytes so the .text section starts at the appropriate offset (eg 0x4000 to match .text of the Raw address under section header)). Luckily for us, we dont have this issue here.
Opening the file in PE studio confirms the same that it is an emotet Trojan.
Method 2:
Hash:
MD5: 90c2c10001134ab2a1cc87ec4382b197
Load and run the malware using x32/64 DBG. If the malware deletes itself after loading onto debugger and running it (F9), load the malware from it's new location ie the temp folder
Set a breakpoint using the API call/function CreateProcessW or CreateProcessInternalW and run the malware.
Once you hit the breakpoint, go to the Memory Map section, right click to find the pattern in HEX "This program" and click ok.
You will find different patterns and pick one at a time and follow click "Follow in Dump".
We will then dump this memory to file. To do this, we can right-click the memory region in the dump with the MZ header, and select “Follow in memory map“. When we follow to the Memory Map, chose the protection page that has ERW protection rights (Execute, Read, Write. From here, right-click the memory region, and select “Dump Memory to File“.
Open the dump in a hex editor, find hex value MZ and trim the rest of the contents before MZ to the beginning of the file to save a unpacked PE. PE studio should confirm that the unpacked PE is Emotet.
Config Extraction
The malware config that contains the IP addresses and port numbers of the attacker infrastructure is stored in the rsrc, data or text sections. Dump this individually from the memory map section where you dump the unpacked PE. The dumped sections can extract C2’s using the following python script written by CyberCDH:
https://github.com/cybercdh/hacks/tree/master/emotet
python3 xxx.bin emotet_config.py
xxx.bin (dumped text,data or rsrc section)
Shout out to @cybercdh, MalwareAnalysisForHedgehogs and OA labs
Comments
Post a Comment