Packer-based malware is malware which is modified in the runtime memory using different and sophisticated compression techniques. Such malware is hard to detect by known malware scanners and anti-virus solutions. In addition, it is a cheap way for hackers to recreate new signatures for the same malware on the fly simply by changing the encryption/packing method. Packers themselves are not malware; attackers use this tactic to obfuscate the code’s real intention.
For security solutions to be effective, they will need to augment their solutions with in-memory capabilities in order to monitor/hook the behavior of the malware after unpacking is completed.
This document describes a sophisticated Andromeda/Gamarue Custom Packer. Andromeda first appeared in 2011 and still remains popular. As the Andromeda attack chain has been described previously, this analysis focuses on the packer and deobfuscation, which happens before the malware downloads or executes its next stage malicious payload. The recent version of the custom packer we obtained (originating June 2016), has noteworthy and innovative functionality.
Does Morphisec stop this attack? Of course, even these new tricks can’t get past Morphisec, which prevents this attack before it can drop its load.
Andromeda/Gamarue Custom Packer
Nowadays most malware employs anti-analysis techniques to make their code harder to analyze by security researchers. Just like legitimate software developers protect their proprietary work, hackers use obfuscation techniques to protect their code from being reverse-engineered or debugged.
The malware sample in our analysis is packed by a custom packer. To be able to get to the actual code, we first need to unpack it.
How can you recognize a packed malware?
- The sample usually comes with a resource section (in this example RC data contains some encrypted content).
- Typically, the compressed file is very large.
- By looking at the import table – It might have only a few imports and many times these include LoadLibrary and/or GetModuleHandleW as those functions are used for the initial unpacking procedure.
- No readable static strings as the strings are encrypted.
- High entropy in sections for higher efficiency of information storage.
- A large portion of the code is inside the .data section (although there are newer versions with code inside text).
- The program has abnormal section sizes, such as .data and .rsrc sections. The RawDataSize is lower than VirtualSize and usually also the section names themselves may indicate a particular packer.
How to unpack?
In forensic analysis, there are different ways to handle the unpacking process. While there are automatic tools for different popular packers, it is more difficult to handle custom packers, which require some manual work and a deeper knowledge of the different anti-debugging obstacles. Moreover, custom packers usually also involve stripping off multiple packing layers.
The Packer - Detailed
Looking at Andromeda’s top-layer packer, we start by noticing an interesting, relatively high entropy in one of the sections (e.g. entropy of .rsrc is 7.376) which gives us the first indication that it is a packer.
Determining a point in time for which we know the malicious code was already unpacked, we identify the use of ws2_32.dll (responsible for communication API). This means we can assume that the malicious code will start communication after it is unpacked. This is of high probability for downloaders or C&C based malware.
As shown in the image below, there are two unnamed modules with RWE (read write execute) access rights – those are indicators for the unpacked executable shellcode (the code will write and execute from the same location).
Additionally, we can see now strings which are typical to Andromeda.
It is noticeable that those modules are still not a PE file (do not start with PE header) – those are executable shellcodes.
We also notice that the code starting from the entry point of the executable was modified, which reminds us of Process Hollowing/ RunPE techniques.
RunPE techniques are designed to evade AV mitigation methods.
Here are RunPE characteristics, as described in an Andromeda Bot Analysis by Infosec Institute:
- Unpack or decrypt the original EXE file in memory.
- Call CreateProcess on a target EXE using the CREATE_SUSPENDED flag. This maps the executable into memory and it’s ready to execute, but the entry point hasn’t executed yet.
- Next, Call GetThreadContext on the main thread of the newly created process. The returned thread context will have the state of all general-purpose registers. The EBX register holds a pointer to the Process Environment Block (PEB), and the EAX register holds a pointer to the entry point of the innocent application. In the PEB structure, at an offset of eight bytes, is the base address of the process image.
- Call NtUnmapViewOfSection to unmap and free up the virtual address space used by the new process.
- Call VirtualAllocEx to re-allocate the memory in the process’ address space to the correct size (the size of the new EXE).
- Call WriteProcessMemory to write the PE headers and each section of the new EXE (unpacked in Step 1) to the virtual address location they expect to be (calling VirtualProtextEx to set the protection flags that each section needs).
- The loader writes the new base address into the PEB and calls SetThreadContext to point EAX to the new entry point.
- Finally, the loader resumes the main thread of the target process with ResumeThread and the windows PE loader will do its magic. The executable is now mapped into memory without ever touching the disk.
Also in our case, the packer decrypts the executable memory space and replaces previously encrypted memory with the functional code. The packer also updates the entry point to the new functional code start.
Forensic analysts will usually stop at this stage and dump the first layer decrypted code for further static analysis using different tools like IDA.
Based on the resemblance to RunPE methodology, we will execute the malware again, although now we set a breakpoint on VirtualAlloc functions (used to allocate memory). Other similar functions are VirtualAlloc, VirtualAllocEx, or ZwAllocateVirtualMemory – also part of the Process Hollowing/RunPE method) called to reserve some RWX memory.
We get the VirtualAlloc function from PEB->Kernel32.EAT
After identifying the RWE buffer address, we set a memory breakpoint on write to this buffer -> the written code is actually the unpacker/decode function.
After the unpacking function finishes execution, its execution is redirected to the first shellcode:
EAX address shellcode start = 0x003D0000
From inside the shellcode, VirtualAlloc is called again. We set a memory breakpoint on write to the new buffer one more time, get a new PE and are redirected to a second shellcode, the unpacked PE.
From this stage on, we get the regular Andromeda Loader which is described in detail by the Avast Threat Intelligence Team.
This article describes a single custom packer for Andromeda, one of the most popular malware delivery frameworks.
Packers are a major concern for current security solutions. Packers allow attackers to penetrate network solutions, file scanning solutions and, in many cases, behavior or AI based solutions.
The use of custom packers will only increase, as will the need for in-memory solutions that can block these types of attacks.
A number of popular sandbox dynamic scanning services have some basic in-memory defenses, however these impose severe performance penalties. Moreover, they frequently are not even effective as many packers, such as in our case, include techniques to identify sandbox environments. Morphisec’s Moving Target Defense based technology wins the malware packer battle without monitoring, hooking or using any other methods that affect endpoint performance.