Forensics - Perseverance
325 points
Last updated
325 points
Last updated
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?
First, we will need to install python-cim
via pip install python-cim
. It didn't work for me the first time but after running the same command a few times, the installation worked. Next, I used the provided show_filtertoconsumerbindings.py
script to dump the persistency locations. There is no documentation of the usage on the GitHub repository but reading the script tells us that it takes in 2 arguments.
type_
: Either "xp" or "win7"
path
: Path to the WMI CIM repository
Running the script revealed a hidden, base64-encoded powershell payload.
After decoding:
Running the UI python script was not without problems. There were some errors in the script and I had to debug and fix the python script so that it works.
An example is that I had to comment out line 76-79 of the script so that it doesn't throw an error.
Inside the UI, navigate to Objects\root\Namespaces\root\CIMV2\Class Definitions
.
Win32_MemoryArrayDevice
which we discovered earlier can be found.
This entry's Value
field contains what looks like a base64 encoded string so we shall throw it into CyberChef.
The output is gibberish but it feels like I am on the right path so, I added in the CyberChef "Magic" recipe to catch what I missed.
Turns out that the payload is compressed and if we inflate it, there is a Windows PE file (my favourite file format :)).
After converting the inflated payload to hex so that I can dump it out from CyberChef, I used Detect It Easy
to determine what kind of PE file it was.
Of course the next step is to decompile the file using dnSpy
.
By tracing the function calls, we know the execution flow goes like this, Main() -> GruntStager() -> ExecuteStager()
.
During the CTF, I did not read the decompiled code line by line and so I tried to base64 decode the obvious strings in the code and turns out all of them are useless. There is an IP that the binary talks to http://147.182.172.189:80
which I tried to ping and I found out that the IP is actually alive.
So I tried to debug the application by setting a breakpoint at the Assembly.Load
function to see what payload will be reflectively loaded. My guess is that the flag will most likely be in it.
Turns out that the Assembly.Load
function is never reached because there is an exception on line 128. The key size is wrong for the specified AES algorithm.
Naturally, the flag should be before line 128 and so I started to read the code line by line. As it turns out, the flag was at the very start!
A string was built at the start in stringBuilder
and is later used as the invalid key.
Flag: HTB{1_th0ught_WM1_w4s_just_4_M4N4g3m3nt_T00l}
A quick google search revealed that this is a WMI CIM repository. In order to parse these files, we will make use of python-cim
[], a tool developed by Mandiant's FLARE team. This tool was first introduced at Defcon 23 in 2015 and has not really been maintained. As such, the documentation was either lacking or outdated.
It appears that the payload is read from the ROOT\cimv2:Win32_MemoryArrayDevice
, "Value". From the DEFCON demo of the tool which can be found [], it seems like there's a GUI interface to browse through the repository which there is no documentation of. In the "samples" directory of the git repository, there is a sample script called ui.py
which I correctly guessed is the GUI tool that was demo-ed in DEFCON.
ExecuteStager()
.