[RedDev Series #3] Spawn Process From WMI In C++

COM object provides another options to create a new process besides using common Windows APIs such as CreateProcess or ShellExecute.

For threat actor, the good way of this kind of process creation is that the wmiprvse.exe will break the process chain from its parent process as it is initiated from the COM object. So the new child process spawned will have no PID chain relationship with the initiator process wmi_create_process.exe. This will makes investigation slightly difficult.

Process chain break example from execution of wmiprvse.exe

Reproduce the PoC in C++

  1. Initialize the COM library by calling CoInitializeEx
CoInitializeEx(0, COINIT_MULTITHREADED);

2. Initiate a IWbemClassObject interface by calling CoCreateInstance. In order to call that interface, we have to pass the correct rclsid and riid into CoCreateInstance as shown as below.

REFCLSID rclsid = CLSID_WbemLocator; // Unmarshaler CLSID, 4590f811–1d3a-11d0–891f-00aa004b2e24REFIID riid = IID_IWbemLocator ; // Interface UUID, dc12a687–737f-11cf-884d-00aa004b2e24CoCreateInstance(rclsid, NULL, 1, riid, (LPVOID*)&wbemLocator);

2. Call the ConnectServer method from interface pointer wbemLocator. It will setting up the wbemServices object that bounds to the namespace ROOT\\CIMV2 there.

IWbemLocator interface only have one method which is ConnectServer

IWbemServices* wbemServices = NULL;wbemLocator->ConnectServer((BSTR)L"ROOT\\CIMV2", NULL, NULL, 0, NULL, 0, 0, &wbemServices);

3. Calling GetObject function from wbemService object which will retrieve information from object path Win32_ProcessStartup.

Output will be the oWin32ProcessStartupclass object pointer.

IWbemClassObject* oWin32ProcessStartup = NULL;                        wbemServices->GetObject((BSTR)L"Win32_ProcessStartup", 0, NULL, &oWin32ProcessStartup, NULL);

4. SpawnInstance create new instance of a class based on the object classoWin32ProcessStartupretrived from the steps above.

Output pStartupInstance class object pointer will pass into ProcessStartupInformation (Step 9) property later.

IWbemClassObject* pStartupInstance = NULL;oWin32ProcessStartup->SpawnInstance(0, &pStartupInstance);

5. Calling GetObject function from wbemService object which will retrieve information from object path Win32_Process.

Param oWin32Process will hold the result of the function called.

IWbemClassObject* oWin32Process = NULL;                        wbemServices->GetObject((BSTR)L"Win32_Process", 0, NULL, &oWin32Process, NULL);

6. GetMethod returns information about the requested method Create from object oWin32Process.

Param pInParamsDefinition will hold the result of the function called.

IWbemClassObject* pInParamsDefinition = NULL; oWin32Process->GetMethod((BSTR)L"Create", 0, &pInParamsDefinition, NULL);

7. SpawnInstance called by pInParamsDefinition object to create new instance of a class which will pass into ExecMethod class later.

Output pParamsInstanceclass object pointer will pass into ExecMethodfunction later.

IWbemClassObject* pParamsInstance = NULL;pInParamsDefinition->SpawnInstance(0, &pParamsInstance);

8. Setting up CommandLine property in pParamsInstance object.

VARIANT varCommand;                        
VariantInit(&varCommand);
varCommand.vt = VT_BSTR;
varCommand.bstrVal = wcCommandExecute; // Your command line here
pParamsInstance->Put((BSTR)L"CommandLine", 0, &varCommand, 0);

9. Setting up ProcessStartupInformationproperty in pParamsInstance object.

VARIANT vtDispatch;                        
VariantInit(&vtDispatch);
vtDispatch.vt = VT_DISPATCH;
vtDispatch.byref = pStartupInstance; // From step 4

pParamsInstance->Put((BSTR)L"ProcessStartupInformation", 0, &vtDispatch, 0);

10. Spawn the new process by calling ExecMethod from wbemServices with Win32_Process object path and Create method with a predefined pParamsInstance object from steps above.

IWbemClassObject* pOutParams = NULL;    wbemServices->ExecMethod((BSTR)L"Win32_Process", (BSTR)L"Create", 0, NULL, pParamsInstance, &pOutParams, NULL);

Extra

You can refer to the full source code and the Ghidra decompiled code which is quite useful when reversing the malware that use this kind of technique to spawn new process.

Full Source Code
Ghidra Decompiled Code

References:

--

--

--

Typical memes addict🐒 GitHub: https://github.com/ghoulgy 🍕Support my work: https://www.buymeacoffee.com/GhoulSec

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Snagajob’s streaming architecture, episode 0

How to bootstrap a proof-of-stake community

Setting Up Post-Processing In Unity

Download game The Cat Machine PC

How to Deploy a Spring Boot Application to AWS Elastic Beanstalk

vCenter Upgrade Error: `Exception Occurred in precheck phase`

How to prepare servers for Ansible… with Ansible

20 Best Tweets of All Time About hack fifa 2019

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
GhouLSec

GhouLSec

Typical memes addict🐒 GitHub: https://github.com/ghoulgy 🍕Support my work: https://www.buymeacoffee.com/GhoulSec

More from Medium

Malware Analysis —Banking Trojan: Dyre

Attack Simulation (Why it is Important!) Part 2 — Get one’s ducks in a row

Boss of the SOC v1

Understanding Anti-analysis Techniques used in Malware