Over the past year or two, I think everyone has seen an increasing use of WMI by attackers everywhere. WMI is very interesting medium for carry out various actions across hosts on a network. While for the most use cases you will need local administrative rights, once obtained you can easily query, search, and compromise remote machines all over WMI. Matt Graeber spoke about using WMI for C2 at Blackhat and really sparked my interest. He then went on to release Invoke-WmiCommand which is a proof of concept script for executing powershell on a remote system and using WMI for its C2 channel. After learning a lot about how he implemented this, I decided to play around with WMI and see what actions I can do on remote systems over WMI and started working on WMIOps.

Github Repo: https://github.com/ChrisTruncer/WMIOps

Since that point about a month ago, I’ve got to a point where I am able to push out the initial version of WMI-Ops, written in powershell, which performs various actions over WMI on targeted machines. Some of these functions are essentially wrappers for built-in powershell cmdlets, but were written because I find it easier to interact with them in this manner. The functions included within the initial release of WMI-Ops, and a brief description of what they do are:

Invoke-ExecCommandWMI – This function will run any command you give it on the targeted system. This will not return output of the command to the console.

– This function will run any command you give it on the targeted system. This will not return output of the command to the console. Invoke-KillProcessWMI – This function is used to kill a process on a remote system via process ID or process name on the targeted system.

– This function is used to kill a process on a remote system via process ID or process name on the targeted system. Get-RunningProcessesWMI – This function will return all running processes on the targeted machine.

– This function will return all running processes on the targeted machine. Get-ProcessOwnersWMI – This function will return every user account that has a process running on the targeted system.

– This function will return every user account that has a process running on the targeted system. Find-ActiveUsersWMI – This function will attempt to determine if a user is currently active at the targeted system. This works by checking to see if LogonUi.exe or a screen saver is currently running on the remote system. If either process is running, I am assuming the user is not currently at their desktop.

– This function will attempt to determine if a user is currently active at the targeted system. This works by checking to see if LogonUi.exe or a screen saver is currently running on the remote system. If either process is running, I am assuming the user is not currently at their desktop. Invoke-CreateShareandExecute – This function creates a network share on the local host. A user-specified file is then copied into the share and permissions are set for both the file and the share to be accessible by Everyone. Next, the function uses WMI to call/run the user specified file on the target machine and runs the file via UNC path. This needs to be run from an elevated command/powershell prompt.

– This function creates a network share on the local host. A user-specified file is then copied into the share and permissions are set for both the file and the share to be accessible by Everyone. Next, the function uses WMI to call/run the user specified file on the target machine and runs the file via UNC path. This needs to be run from an elevated command/powershell prompt. Invoke-RemoteScriptWithOutput – This function uses WMI to spawn powershell on a remote machine to download a user-specified powershell script (downloaded using IEX cradle), run the script and post back the function’s/script’s output over HTTPS to a user controlled server.

– This function uses WMI to spawn powershell on a remote machine to download a user-specified powershell script (downloaded using IEX cradle), run the script and post back the function’s/script’s output over HTTPS to a user controlled server. Find-UserSpecifiedFileWMI – This function takes a filename or extension and searches for the location of the file(s) on the remote system. The path, along with additional information, is returned for any file(s) found matching the search string.

– This function takes a filename or extension and searches for the location of the file(s) on the remote system. The path, along with additional information, is returned for any file(s) found matching the search string. Invoke-FileTransferOverWMI – This function uses WMI to upload or download a file from the local system to the target system. For uploads, the function reads the local file, base64 encodes it, and stores it in the local registry. It then uses WMI to spawn powershell on the targeted system which connects back to the local system, reads registry value, base64 decodes it, and then writes it to a user specified location on the target system’s disk.

This is essentially my first script I’ve developed in powershell, and I certainly expect to have many “learning moments” on more proper methods of developing these same functions in powershell, so please let me know if I’ve developed something improperly.

Finally, I wouldn’t have been able to write this without the work of multiple other people who’s work I referenced throughout the writing of this script. Matt Graeber, Chris Campbell, Will Schroeder, Evan Pena, Justin Warner, Matt Nelson, and Chris Ross‘s powershell work served as great references for how to write in powershell, and for working with WMI in powershell. Thanks for all your guys work and ability to release it for others to use and reference.