Month: January 2021

Hunting BlackEnergy3 in Memory

Hunting BlackEnergy3 in Memory

I recently was investigating a memory dump from a host infected with BlackEnergy3. BlackEnergy3, which is a modified version of the original BlackEnergy malware families, was used in the attacks on the Ukrainian power grid in 2015. BlackEnergy3 is similar to its version 2 counterpart, but has been modified with additional modules that serve multiple purposes such as extraction of credentials, keystroke logging, and destruction capabilities.

This post is a sort of a step-by-step methodology for investigating BlackEnergy3 infections, and more generally, rootkit behavior in memory. I will be using Volatility as my primary tool for this investigation.

Edit: One reader asked which sample I used for this investigation. This write-up is from a memory image provided by SANS and was included with the Advanced Memory Forensics and Threat Detection course. (This course is highly recommended if you are interested in memory forensics and hunting advanced malware!). I don’t know exactly which sample was used on the infected system, but I found a possible similar sample on VirusTotal here.

Investigating Userland

I always start a memory forensics investigation by inspecting the processes that were running on the system before the memory was extracted. The Volatility “Pstree” command provides an output of processes in a nice tree-based form:

vol.py -f memdump.img --profile=Win7SP1x64 pstree

What we should be looking for here are strange process parent/child relationships, orphaned processes (processes with no parent), and processes that seem out of place, such as strange or misspelled process names. We see no clear evidence of any of this type of activity:

Output from pstree command.
Output from pstree command.

Let’s dig a bit deeper. One of my goto Volatility modules for quick wins is “malfind”. “Malfind” will enumerate the Virtual Address Descriptors (VADs) tables for each process running on the system, and attempts to find anomalies and possible evidence of code injection.

vol.py -f memdump.img --profile=Win7SP1x64 malfind

After running “malfind”, we can see an anomaly right off the bat – possible code injection into “svchost.exe” (PID 1468) process:

Output of malfind command.
Output of malfind command.

We can see above that the memory permission for this region is “PAGE_EXECUTE_READWRITE”, which means that this area of memory possibly contains executable code. We can also see the “MZ” header synonymous with Windows PE files, so this is highly likely malicious code injection. For closer inspection, let’s dump out this region of memory into a file using “vaddump”:

vol.py -f memdump.img --profile=Win7SP1x64 vaddump -p 1468

We can now inspect this area of memory by simply running the “strings” command on the dumped memory region we are interested in (“0x1a0000”):

strings -n8 svchost.exe.7e4aa060.0x00000000001a0000-0x00000000001affff.dmp | less

Output of strings command.
Output of strings command.

There are several interesting strings here. There is a reference to “aPLib”, which is a library for compressing and packing executable files. This means that the injected malicious code was likely packed, which is definitely a red flag and out of place in a process such as “svchost.exe”. Also, there are references to a user agent string, references to DLL files and a DAT file, and several references to possible API function calls.

A quick Google search shows that many of these strings are actually part of the Command & Control functionality of BlackEnergy3:

  • DownloadFile – Retrieves a file from the Internet.
  • RkLoadKernelImage – Used to load code into kernel memory address space.
  • RkLoadKernelObject – Used to load a new driver module into kernel memory from userland memory.
  • SrvAddRequestBinaryData – Used to append binary data to the C2 HTTP POST data (for C2 communication and payload download).
  • Srv* – These commands are used for C2 communication.
  • “main.dll” – The internal name of BlackEnergy’s primary DLL file.

The presence of these kernel-related functions signal that we are dealing with a rootkit.

Hunting for Rootkits

After our brief analysis of the injected code into svchost.exe, we know we are dealing with some sort of rootkit behavior. Rootkits typically will load a kernel module or driver into kernel memory space. Let’s hunt for this.

“Modscan” is able to scan kernel memory for loaded drivers and modules, and is the perfect command to use here:

vol.py -f memdump.img --profile=Win7SP1x64 modscan

Output of modscan command.
Output of modscan command.

There are a few potentially suspicious modules listed here, but one in particular stands out: “adp94xx.sys”. I was able to determine that this module is out of place by Googlng the other good, benign modules. The only way to know what is not normal is to know what is normal – so it’s good to do some Googling or have a list of normal drivers handy 😉 Let’s dump this kernel driver from memory, using the base address listed above:

vol.py -f memdump.img --profile=Win7SP1x64 moddump -D ./ --base=0xfffff88003fbf000

Once again, I use the strings command to run a quick inspection of this file:

strings driver.fffff88003fbf000.sys | less

Output of strings command.
Output of strings command.

We can see several kernel function calls here. Running the same strings command but for Wide strings (16-bit little-endian) encoding, we can see a bit more:

strings -e l driver.fffff88003fbf000.sys | less

Output of encoded strings.
Output of encoded strings.

A few items stick out to here. The most obvious is that this driver file appears to be published by Microsoft and is called the “AMD IDE driver”. In addition, we can see several Windows API functions. One example is “SeImpersonaltePrivilege”, which is a Windows API function that can be used to impersonate privileges and access tokens, and is used in some rootkits and privilege escalation exploits. This function is just a clue into the functionality of this driver. Finally, we see a reference to “svchost.exe”, which is what we saw earlier in malscan!

A quick Google search for “AMD IDE driver” and “adp94xx.sys” reveal a few discrepancies. First, “AMD IDE driver” is a real driver name, but does not seem to relate to the file name “adp94xx.sys”. Second, the “adp94xx.sys” could be a legitimate driver, but is related to Adaptec, and not to AMD IDE drivers. This discrepancy proves that hunting for kernel rootkits is a lot about knowing what is and what is not normal, and knowing how to Google 😉

We can dump the imports from this module as well:

vol.py -f memdump.img --profile=Win7SP1x64 impscan –base=0xfffff88003fbf000

Output of impscan.
Output of impscan.

There are a few imports we should focus on here. One function of interest is “KeStackAttach”. According to Microsoft, KeStackAttachProcess attaches a specified process thread to the address space of another process. This functionality can be used to run code from the kernel module rootkit in the context of a userland process, which essentially serves as a very stealthy way to run code.

As a quick tip, we can also extract the imports in a format that can be imported into IDA for later analysis:

vol.py -f memdump.img --profile=Win7SP1x64 impscan --base=0xfffff88003fbf000 –output=idc >> module-imports-ida.idc

Later, we can look at this module in IDA or another disassembler in order to better understand it. This is out of the scope of this post, but this is something that should be done during an investigation.

Wrapping Up

From the investigation above, we can make several inferences (or at least, educated guesses) from this data. 

  • Malicious code was injected into the “svchost.exe” process. Once executed, this code likely downloads an additional module from the Internet (using the DownloadFile function).
  • The malware may have executed its rootkit behavior be leveraging its “RkLoadKernelObject” function, which allows code execution in the context of the kernel.
  • Once in kernel memory, the rootkit is able to hide on the system, and inject additional malicious code into other userland processes, further embedding itself in the system in stealthy way.

This of course is not a complete investigation of BlackEnergy3, but shows what can be done to quickly triage rootkit behaviors. You can likely see that hunting rootkits, and memory hunting in general, takes a combined approach of cross-referencing the output of multiple tools, Googling things, and understanding what is and what is not normal Windows behavior.

Bonus: For sticking with me this long, you may have noticed 2 “iexplore” processes in the “pstree” output:

Internet Explorer processes from pslist output.
Internet Explorer processes from pslist output.

These are actually the product of a special module that BlackEnergy3 is able to deploy called the “Ibank” module. This module injects itself into Internet Explorer processes and is able to steal banking credentials from its victims 🙂

As always, thanks for reading.

— @d4rksystem

Hiding Virtual Machines from Malware – Introducing VMwareCloak & VBoxCloak

Hiding Virtual Machines from Malware – Introducing VMwareCloak & VBoxCloak

Many malware families are still using fairly trivial techniques for the detection of virtual machine environments. Once malware detects that it may be running in a virtual machine, it may terminate itself, or worse, execute code that will cause a diversion and potentially lead the malware analyst down the wrong paths :O

Malware often uses the following techniques for virtual machine detection:

Registry Enumeration

Registry enumeration is one of the most common techniques that evasive malware may use to determine if it is running in a VM. Some registry keys malware may look for is hardware information, system BIOS information, and any other registry keys and values that contain references to hypervisors such as VMware Workstation and VirtualBox. Many of these registry keys can be renamed or removed without heavily affected the performance or usability of the VM!

File & Directory Enumeration

Malware may enumerate files and directories on the system to get an understanding of the environment it is running in. Malware may look for files and directories that reference common hypervisors, such as “VMware” or “VBox” directories in the “C:\Programs” directories. Malware may also enumerate the “C:\Windows” directory, typically looking for hypervisor-related drivers and system files. An interesting fact is that many of these files (even system and driver files!) can be removed or renamed without affecting the VM, since these files are loaded into memory and not often accessed from the disk!

Process Enumeration

Finally, malware often enumerates the running processes on the system to determine if any hypervisor-related processes are running. Typically, hypervisors such as VirtualBox and VMware have processes running that are used to enable “helper” related functionalities such as drag-and-drop, clipboard sharing, and shared drives. These processes are often not required for the general functionality of the VM, so they can be safely killed in order to better hid the VM from malware.

Because these detection techniques are fairly trivial, we as malware analysts can also use trivial methods to bypass them! I wrote VMwareCloak (for VMware Workstation) and VBoxCloak (for VirtualBox) for just this reason. These tools are Powershell scripts that are designed to sanitize your Windows sandbox VM’s. The scripts kill processes, and remove or rename registry keys, files, and directories that may lead malware to believe it is running in a virtualized environment.

You can download the scripts here:

For VirtualBox: https://github.com/d4rksystem/VBoxCloak
For VMware: https://github.com/d4rksystem/VMwareCloak

To run the scripts, simply execute your chosen script as an Admin on your Windows VM:

If all goes well, your VM will be sanitized and the evasive malware may now run as if it was not in a VM! (I have tested this script with several malware families. However, these scripts will not work for all malware, especially more advanced variants that are, for example, using hardware detection or timing-based detection techniques.)

A bit more information can be found in my writeup here:

Enjoy! Feel free to yell at me when you inevitably find bugs in the script 😉