PowerShell has gained popularity with SysAdmins and for good reason. Itās on every Windows machine (and now some Linux machines as well), has capabilities to interact with almost every service on every machine on the network, and itās a command-line utility. For the same exact reasons, PowerShell has also become a favourite method of attackers interacting with a victim machine. Because of this, organizations have gotten wise to this attack vector and have put measures in place to mitigate its use. But thereās another way! Many donāt know of another built-in Windows utility that actually pre-dates PowerShell and can also help them in their hackingĀ pentesting engagements. That tool is Windows Management Instrumentation (WMI). This tutorial will be a small introduction to not only understand the usage of WMI to enumerate information from local and remote machines, but weāll also show you how to start and kill processes! So letās jump into WMI 101 for pentesters.
Background on WMI
I will keep this article at an introductory level to understand how to enumerate information at a high level. But as with most tutorials, letās define some terms and provide some historical background. This may get dry but stick with me.
Windows Management Instrumentation (WMI) is Microsoftās implementation of Web-based Business Management Standards (WBEM), the common information model (CIM) and the Distributed Management Task Force (DMTF). Microsoft has officially stated:
āWindows Management Instrumentation (WMI) is the infrastructure for management data and operations on Windows-based operating systems.ā
So what does that mean? Simply, WMI stores a bunch of information about the local machine and allows you to access that data as well as manage Windows computers locally and remotely.
WMI came pre-installed in Windows 2000. It was made available as a download forĀ Windows NT andĀ Windows 95/98. For historical purposes, Monad, was born in 2002 with its first public appearance in 2003. In the spring of 2006, Monad was renamed Windows PowerShell and didnāt make a final release until November of 2006.
By default, WMI can be accessed by the Windows Script Host (WSH) languages such as VBScript and JScript. From Windows 7 PowerShell can be also used to access WMI. Furthermore, the IWbem COM API can be used with C/C++ and the āSystem.Managementā namespace with .Net languages such as C#, VB.Net and F#. Almost every popular programming languages such as Python, Ruby, PHP, Delphi, et al have third-party libraries or built-in libraries which support WMI.
The command-line interface to access WMI is called the Windows Management Instrumentation Command-line (WMIC). However, WMI can also be accessed directly with PowerShell. From PowerShell v3 onwards, CIM (Common Information Model) cmdlets can be found. The CIM cmdlets can be used to interact with WMI over WS-MAN (WinRM). These CIM cmdlets will aid us when WMI is blocked but WinRM is allowed on the target machine.
Exploring Namespaces
WMI namespaces can be explored in several different ways from using WMIC directly or by using PowerShell.
Using WMIC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
C:\>wmic /namespace:\\root path __namespace Name subscription DEFAULT CIMV2 msdtc Cli SECURITY SecurityCenter2 RSOP District PEH StandardCimv2 WMI directory Policy Interop Hardware ServiceModel SecurityCenter Microsoft aspnet Appv |
Using PowerShell
1 |
Get-WmiObject -namespace "root" -class "__Namespace" | Select Name |
Another method is by using WQL, the WMI Query Language. Microsoftās documentation defines WQL as, āa subset of standard American National Standards Institute Structured Query Language (ANSI SQL) with minor semantic changes to support WMI.ā So, we can use commonly understood SQL statement in quotes such as:
1 |
Get-WmiObject -Query āSelect * from __Namespaceā -Namespace Root | select Name |
Exploring Classes
To get a list of WMI classes of a specific Namespace using PowerShell, we can use the āListā parameter. In this example we are listing the classes of default namespace, āroot\cimv2ā.
1 2 3 4 5 6 7 8 9 10 |
PS C:\>Get-WmiObject -Namespace root\cimv2 -List ā¦ Output Omitted ā¦ Win32_ShadowContext {} {Caption, ClientAccessible, Description Differential...} Win32_MSIResource {} {Caption, Description, SettingID} Win32_ServiceControl {} {Arguments, Caption, Description, Event...} Win32_Property {} {Caption, Description, ProductCode, Property...} Win32_Patch {} {Attributes, Caption, Description, File...} Win32_PatchPackage {} {Caption, Description, PatchID, ProductCode...} ā¦ Output Omitted ā¦ |
Another method is by using āGet-CimClassā cmdlet:
1 |
Get-CimClass -Namespace root\cimv2 |
If we want only the classes that start with āwin32ā inside the āroot\cimv2āĀ namespace, we can use a wildcard like this:
1 |
Get-WmiObject -Namespace root\cimv2 -Class *Win32* -List |
Furthermore, the tool WMI Explorer can be used to have a better view of the namespaces, classes and methods with descriptions and examples.
In summary, each Namespace contains Classes. Classes contain:
- Properties ā Information that can be retrieved.
- Methods ā Functions that be performed.
- Instances ā Instances of the class objects. Each instance with Methods and Properties.
- Events ā Produces notifications about changes in WMI data and services.
WMI Query Language ā WQL
We briefly mentioned WQL in an example above, but letās dive a little deeper. WQL queries can be directly accessed by the āwbemtest.exeāĀ binary and using PowerShell. WQL is used in scripting languages and programming languages when accessing WMI. For this article I will not go in depth regarding each type, however WQL Queries can be categorized as follows:
- Instance Queries
- Event Queries
- Meta Queries
Once you open the wbemtest binary, click on Connect and create a new connection to the required namespaces as shown above. If you are creating a connection to a remote machine, you can provide the credentials in this dialog box. In this example, I will connect to the default namespace āroot\cimv2ā.
After creating the connection, click on āQueryāĀ to test a WQL query. In this example I will use the following query to enumerate files on the disk from the path āC:\tempā
1 |
Select * From Cim_DataFile Where Drive = "C:" And Path = "\\temp\\" |
It will enumerate the files on the ātempĀ“Ā folder and display the file name.
This is the PowerShell syntax for the same request:
1 |
Get-WmiObject -Query 'Select FileName From Cim_DataFile Where Drive = "C:" And Path = "\\temp\\"' |
WMI Verbs
The following is for usage with WMIC:
- List ā List Information
- Get ā Retrieve values
- Call ā Execute a method
- Set ā Set value of a property
- Create ā Creates a new instance
- Delete ā Deletes an instance
- Assoc ā Displays the Associators
Putting WMI All Together
Using WMIC
The following command can be used to list the aliases used in WMIC for the corresponding WQL Query.
1 |
wmic alias list brief |
The list is much longer than what you see in the screenshot above. I highly recommend you try this on your own machine to see what I mean. Much lower in the list, you will find the āprocessāĀ alias, and it uses the āSelect * from Win32_Processā WQL query. By using the alias, we can shorten the command in the following way:
1 |
wmic process where name='lsass.exe' list brief |
In this next example, I am using the āgetā verb to retrieve specific properties from the class.
1 |
wmic process where name='winword.exe' get name, executablepath |
This is an example of using the method āGetOwnerāĀ to retrieve the owner of the target process.
1 |
wmic process where name='winword.exe' call GetOwner |
To create a process we can use the āCreateāĀ method. This is widely used by pentesters and in malware to create a remote process.
1 |
wmic process call create 'calc.exe' |
To kill a process the āTerminateāĀ method can be used.
1 |
wmic process where name='notepad.exe' call Terminate |
Using PowerShell
Now letās try some similar activities using PowerShell. This time, letās look for Word.
1 |
Get-WmiObject -Class Win32_Process -Filter 'name="winword.exe"' |
Next, weāll filter our data even more to get the information we want.
1 |
Get-CimInstance -Class Win32_Process -Filter "name='winword.exe'" -Property Caption, ProcessID, ExecutablePath |
Using WQL
And how would this look using PowerShell and some WQL? Here, I am selecting the Caption, Process ID and the Executable Path properties from the āwinword.exeāĀ process.
1 |
Get-WmiObject -Query "Select Caption,ProcessID,ExecutablePath from Win32_Process where name='winword.exe'" -Namespace root\cimv2 |
Using the CIM cmdlets you can retrieve all information or retrieve a specific property like this:
1 |
(Get-CimInstance -Query "Select * from Win32_Process where name='winword.exe'" -Namespace root\cimv2).ProcessID |
Listing all the methods of the āWin32_ProcessāĀ Class can be done like this:
1 |
(Get-WmiObject -Class Win32_Process -List).Methods |
For executing a method, the āInvoke-WmiMethodāĀ is used:
1 |
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList @(calc.exe) |
Using CIM we can call a method like this:
1 |
Invoke-CimMethod -ClassName Win32_Process -Name Create -Arguments @{Commandline = 'calc.exe'} |
Remote WMIC
We also mentioned above that the same tools can be used over the network. This is the syntax you can use to accomplish the above example in remote computers:
WMIC
1 |
wmic /NODE:"servername" /USER:"yourdomain\administrator" /PASSWORD:password OS GET Name |
Powershell
And, as we did before, hereās how it can be done using PowerShell:
1 2 |
$cred = Get-Credential domain\user Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList @(calc.exe) -ComputerName servername -Credential $cred |
Furthermore, in Linux the toolĀ āpth-wmicāĀ can be used to pass-the-hash instead of the password:
1 |
pth-wmic -U domain/adminuser%LM:NT //host "select * from Win32_ComputerSystem" |
Conclusion
As you can see, WMI has loads of functionality, most of which have yet to be explored in this article. But even in the little we explored, you can clearly see that WMI can be used as an alternative when PowerShell is monitored or blocking certain scenarios. In a future article, we can play with WMIās power in other ways good for pentesters such as using it as a C2C in engagements.
I hope this article covered the fundamentals of WMI usage and encouraged you to continue researching on your own. With that in mind, hereās a little homework. As with all useful technologies, there will eventually be a new version to expand on the capabilities proven by the previous version. Windows Management Instrumentation (WMI) is no different as it also has been updated to theĀ Windows ManagementĀ InfrastructureĀ (MI). Microsoft says that MI is fully backwards compatible while reducing dev time and has tighter integration with Powershell. Go check it out and share what you discover.
Thanks ? keep it up
thank you