Dechaining with WMI
To address these issues, we’ll first address the issue of
PowerShell being a child process of the Office program
by levereging the Windows Management Instrumentation (WMI) framework.
We can use WMI to query, filter, and resolve
a host of information on a Windows operating system.
We can also use it to invoke a multitude of actions,
and can even use it to create a new process.
Our goal is to use WMI from VBA
to create a PowerShell process
instead of having it as a child process of Microsoft Word.
We’ll first connect to WMI from VBA,
which is done through the GetObject method,
specifying the winmgmts: class name.
Winmgmt is the WMI service within the SVCHOST process
running under the LocalSystem account.
When performing an action, the Winmgmt WMI service
is created in a separate process
as a child process of its parent,
which means we can de-chain the PowerShell process from Microsoft Word.
WMI is divided into Providers
that contain different functionalities,
and each provider contains multiple classes that can be instantiated.
To create a PowerShell process, we want to use the Win32_Process class
from the Win32 provider.
This class represents a process on the operating system,
allowing us to perform process-specific actions
such as creating and terminating processes.
To create a new process, we’ll use the Get method
to select the class and invoke the Create method.
The Create method accepts four arguments.
The first is the name of the process including its arguments,
the second and third describe process creation information
that we do not need, and the fourth is a variable
that will contain the process ID of the new process
returned by the operating system.
When the macro is executed,
a new PowerShell prompt opens,
and Process Explorer reveals that PowerShell
is indeed running as a child process.
This could certainly work for our purposes,
however PowerShell is running as a 64-bit process,
which means we must update the PowerShell shellcode runner script accordingly.
We can update the PowerShell argument
for the Create method to include the entire download cradle.
When we run the embedded VBA,
the Meterpreter reverse shell
executes as expected
and it is completely de-chained from Microsoft Word.
Let’s scan the updated document with AntiScan.Me
Since seven products flag our code,
it would seem that our efforts have had little impact.
This is not necessarily surprising
since the VBA macro still contains the same
unobfuscated PowerShell download cradle as before.
However, this was an important step
since our new VBA macro does not use the Shell function
but rather the ambiguous GetObject,
Get, and Create methods,
which are more benign to most AV products.
In the next section, we’ll reap the benefits of avoiding the Shell method
and perform obfuscation of our VBA macro
to further reduce the detection rate.