The Return of Ghost Emperor’s Demodex
A Comprehensive Look at the Updated Infection Chain of Ghost Emperor’s Demodex Rootkit.
Executive Summary
- In late 2023, Sygnia’s Incident Response team was engaged by a client whose network was compromised and was leveraged to penetrate one of its business partner’s network.
- During the investigation, several servers, workstations, and users were found to be compromised by a threat actor who deployed various tools to communicate with a set of C2 servers.
- One of these tools was identified as a variant of Demodex, a rootkit previously associated with the threat group known as GhostEmperor.
- GhostEmperor is a sophisticated China-nexus threat group known to target mostly South-East Asian telecommunication and government entities, first disclosed by Kaspersky in a blog published in September 2021.
- GhostEmperor employs a multi-stage malware to achieve stealth execution and persistence and utilizes several methods to impede analysis process.
- Usually, once the threat group gains initial access to the victim’s network by using vulnerabilities such as ProxyLogon, a batch file is executed to initiate the infection chain.
- In this blog we describe a new infection chain deployed by GhostEmperor, which includes several loading schemes and various obfuscation techniques utilized by the threat group.
Introduction
During Sygnia’s analysis of the forensic findings extracted from the victim’s environment, the team found strong resemblance to the multi-stage tool which was described in Kaspersky’s blog from 2021. However, our investigation yielded some alterations in the infection chain and a slightly different C++ DLL variant.
Among these alterations, the variant we analyzed incorporates an EDR evasion technique and uses a reflective loader to execute the Core-Implant. Additionally, we identified the use of different file names and registry keys. The variant we encountered appears to have been compiled in July 2021, suggesting it might be a more recent version than the one originally analyzed by Kaspersky.
This blog post focuses on the key differences we identified and analyzed in the infection chain and the loading scheme operations.
WMIExec
WMIExec is a command-line tool used for executing commands on remote Windows systems through Windows Management Instrumentation (WMI).
It is part of the Impacket Toolkit, which is an open-source collection of modules written in Python for programmatically constructing and manipulating network protocols, that is commonly used by threat actors and red teams.
During our investigation, we observed that the threat actor used this tool to run a batch file, initiating the infection chain on the victim’s compromised machine. The output logs were saved to a file located at c:\windows\temp
using a local SMB path. The following command was executed:
cmd.exe /Q /c c:\windows\vss\1.bat > \127.0.0.1\C$\Windows\Temp[generated_string] 2>&1
Batch File
The batch file starts the infection by installing the malware and obtaining persistency by the following actions:
It starts by dropping a CAB file named “1.cab” to C:\Windows\Web. CAB is a compressed archive format commonly utilized in Windows to bundle multiple files.
The batch file then uses expand.exe – a native Windows tool used for file extraction from compressed Cabinet files (.cab), to extract these four files:
- prints1m.dll – Service DLL.
- Service.ps1 – encrypted Powershell.
- config.REG – registry dump of AES decryption key.
- AesedMemoryBinX64.REG – registry dump of AES-encrypted shellcode containing the Core-Implant.
Next, the batch file imports the two registry files using the reg.exe import [file]
command to set two registry keys with encrypted values, which will be used later to execute the next stage.
The threat actor employs several LOLBins such as reg.exe and expand.exe within the batch file to achieve stealthiness as they are legitimate and signed Microsoft built-in tools which do not arouse any suspicion.
The Batch file proceeds and executes an encrypted PowerShell script, passing a decryption key as a parameter. This script contains an encrypted blob, which, once decrypted using the provided key, reveals another PowerShell script that is executed.
PowerShell script
The decrypted PowerShell script creates a new service named “WdiSystem” that loads the malicious Service DLL (prints1m.dll). It also creates a service group called “WdiSystemhost” and runs the malicious service within this group. By running the malicious service within the context of the “WdiSystemhost” service group, the threat actor masquerades the malware’s execution as a legitimate Windows system process, as it resembles the authentic and legitimate WdiSystemHost (“Windows Diagnostic System Host” service).
To accomplish this technique, the script carries out the following steps:
- Creates a service by invoking the New-Service PowerShell command with svchost.exe as the binary path of the service.
- Creates a service group named “WdiSystemhost” by adding a new registry key in
HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentCersion\SvcHost
:
The lowercase “host” in the name suggests it is a rogue version. The original name is “WdiSystemHost”
- Wires the malicious service DLL (prints1m.dll) to the service by setting a “ServiceDll” registry key with the DLL’s path as the value, located in
HKLM:\SYSTEM\CurrentControlSet\Services\WdiSystem\Parameters
.
- Runs the service by invoking the Start-Service PowerShell command.
- Launches the malicious service DLL (prints1m.dll) as a service which is executed within the service group.
Prints1m.dll – Service DLL
This Service DLL dynamically loads all of the necessary functions it requires for operation by navigating through an internal OS structure named Process Environment Block, which contains the already loaded libraries and functions in the process.
The Kernel32 library, loaded by default in every process, is used by the malware to access the LoadLibraryA function, which is responsible for loading DLLs into the process.
Subsequently, an encrypted configuration located at the DLL’s data section (offset 0x4050) is decrypted using a custom decryption scheme, which contains the following parameters:
- Initial sleep time.
- Registry paths of the shellcode location (which was established by the batch file).
- A list of module and function names required for operation (offset 0x45F0).
The service uses this list to create an in-memory Import Address Table, loading the modules it requires using the LoadLibraryA function, and traverses each module’s export table to obtain the necessary functions.
After setting up an anti-hooking technique (which will be described in the next section), the service
initiates the next stage by spawning a new thread. It then sleeps for 15 seconds before attempting to decrypt and execute the next stage, which is retrieved from the registry keys set by the batch file. In case of failure, it retries at intervals of 30 to 60 seconds until successful execution is achieved.
EDR Evasion and Anti-User-Mode Hooking Technique
Antivirus and EDR solutions typically inject DLLs into the address space of running applications to facilitate user-mode hooking, thus identifying and preventing malicious activity within the processes.
During our investigation we observed that the threat actor added an evasion technique to the Service DLL by setting a specific mitigation policy to the process:
Mitigation policies, such as ASLR, DEP and CFG, are security measures implemented by the OS to mitigate attacks and vulnerabilities such as Buffer Overflows and Code Injections. Some of these mitigation policies are enabled in the process by default. In our investigation, the threat actor set up a particular mitigation named “ProcessSignaturePolicy” which forbid loading DLLs that are not signed by Microsoft to the process.
This means that any security solution trying to inject a DLL not signed by Microsoft will fail to do so. This technique helps circumvent analysis tools by limiting user-mode hooking.
The fact that many antivirus vendors employ DLLs with a legitimate Microsoft signature, and that some security solutions inject their DLLs prior to the invocation of SetProcessMitigationPolicy, limits the effectiveness of this method.
Shellcode and Reflective loader
The Service DLL reads two encrypted registry keys that were set by the batch file:
“AKey” – an AES decryption key
“inputlog” – an AES-encrypted shellcode containing the core-implant.
The service employs the AES algorithm to decrypt the encrypted shellcode retrieved from the “inputlog” registry key. It sets the decryption key from the “AKey” value and uses a null byte array as the Initialization Vector (IV). The shellcode consists of a Position-Independent shellcode functioning as a reflective loader, alongside a corrupted Portable Executable (PE) file, positioned at offset 0x4000. Certain headers within the PE file have been deliberately stripped to enhance resistance to analysis and detection. Specifically, the “MZ” and “PE” headers have been nullified, and the DOS Stub has been removed.
The shellcode loads the core-implant DLL using a reflective loader which performs the following steps:
- Allocates memory for the core-implant DLL.
- Parses the custom PE headers of the core-implant.
- Moves each section to its proper location in the allocated memory.
- Performs relocation of the code and data sections to match the new base address.
- Resolves the import table.
- Sets proper memory protections.
- Executes the now-ready Core-Implant by calling its Entry Point.
Core-Implant
The Core-Implant handles two main tasks – managing Command and Control (C2) communication and installing the Demodex kernel rootkit. To load Demodex, the threat actor had to bypass the Driver Signature Enforcement (DSE) security feature, which blocks unsigned drivers.
To do that, the threat actor leveraged “Cheat Engine”, an open-source tool used for video game cheating, and utilized its signed driver, dbk64.sys, to manipulate memory and execute code in kernel space. the threat actor used this driver to map and execute a shellcode in kernel space which patches the IOCTL Dispatcher of the dbk64.sys driver. This modification adds functionality to the driver that enables it to load the Demodex driver.
An analysis of the Core-Implant’s metadata shows that the threat actor modified the compilation and export-table timestamp of the Core-Implant to 12 Feb 2016. However, the timestamp of the debug section is set to 02 July 2021, which might indicate that this is the actual time this implant was created.
Appendix – IOC
Description | Hash |
---|---|
Service DLL – prints1m.dll | MD5: 4bb191c6d3a234743ace703d7d518f8f SHA1: 43f1c44fa14f9ce2c0ba9451de2f7d3dd1a208de |
PowerShell script – service.ps1 | MD5: 95e3312de43c1da4cc3be8fa47ab9fa4 SHA1: a59cca28205eeb94c331010060f86ad2f3d41882 |
Cheat Engine driver – dbk64.sys | MD5: d8ebfd26bed0155e7c4ec2ca429c871d SHA1: bab2ae2788dee2c41065850b2877202e57369f37 |
C2 Domain | imap.dateupdata[.]com |
C2 IP | 193.239.86.168 |
By clicking Subscribe, I agree to the use of my personal data in accordance with Sygnia Privacy Policy. Sygnia will not sell, trade, lease, or rent your personal data to third parties.