Under-the-hood: WMImplant Invoking PowerShell
WMImplant is a powerful PowerShell based tool that enables its users to conduct nearly any post-exploitation action and exclusively using WMI to do so. We’ve blogged about out-of-the-box detection opportunities for WMImplant, how to copy files, searching for sensitive files, and more, but now we want to talk about how WMImplant actually invokes PowerShell on the system targeted by its user. There’s a little bit of command-line avoidance that’s conducted and is worth documenting so you know exactly how your tool works (we don’t blindly run tools right?).
Traditionally, when starting a new process on a system with the Win32_Process class, the user would specify the exact command that should run, and the system will run the command. For example, you could start notepad.exe on your local system with the following command:
From a command-line auditing perspective, “notepad.exe” would be logged and any defender (or software) that reviews the logs would see that “notepad.exe” was started via the command line. However, this is not how WMImplant runs PowerShell, or other commands, on the remote system.
WMImplant – Maneuvering Around the Command Line
When working on WMImplant, I was lucky enough to get to bounce ideas off of another great red teamer, Daniel Bohannon. When I started talking about everything I wanted WMImplant to do, he said he had a great addition for me that would help make WMImplant even more useful from a red team perspective when running commands on a system. Rather than just running the command, you can have it read in dynamically to running your commands directly on the command line.
Daniel quickly wrote some code and developed the following process:
- WMImplant will create a random environmental variable on the targeted system with the Win32_Environment class, and the contents of the environmental variable is the actual command that the WMImplant user wants to run
- WMImplant will spawn a PowerShell process via Win32_Process class. The instance of PowerShell will read in the contents of the newly created environmental variable and use an obfuscated version of Invoke-Expression to execute its contents
- Finally, WMImplant will remove the environmental variable from the targeted system
When following this process, from a command line perspective all that is observed is PowerShell reading in the contents of the environmental variable and executing them, but the contents of that environmental variable are not known. Here’s an example when running the command “ipconfig”.
As you can see, the actual command that is run on the command line is the obfuscated Invoke-Expression command which reads in the contents of the environmental variable “ClzJ7”. The environmental variable’s contents has multiple PowerShell commands which saves the output from “ipconfig /all”, encodes the results into an integer array, and stores it in the DebugFilePath WMI property.
To look more at the specifics of the PowerShell code enabling this, check out FortyNorth Security’s WMImplant repository, or the specific lines here. If you have any questions at all about this, don’t hesitate to contact us. And if you’d like to learn more about WMImplant or other tools to help you on your test, be sure to sign up for our Intrusion Operations class at Blackhat USA in Las Vegas!