Monitoring with PowerShell: Monitoring psexec execution

A bunch of bad actors these days uses the great psexec tool by Sysinternals/Microsoft to try to move through the network latterly. PSExec allows you to remotely execute commands on different computers through a very simple command line interface. PSexec also allows you to execute commands or scripts as the SYSTEM account.

We use PSExec professionally to run specific tooling that requires the highest privileges, this means that just flat out blocking PSExec execution on our networks is not possible. We do want to know whenever people do execute this, so we can use it as an early warning system. Please note that this does not capture PSexec clones such as CDEXec and PAexec.

Grabbing PSExec usage actually did not look that hard – you either look for the service it creates, or for the currently running file, so the following simple script would solve it I thought.

The Scripts

#FindPsexec service
$PSExecmon = get-service PSEXESVC
if (!$PSExecmon) {
    $PSExecHealth = "Healthy - no PSExec service found."
}
else {
    $PSExecHealth = "Unhealthy - PSExec service found"
}

But after checking some of my older scripts I’ve actually found the -r option for PSExec. The -R parameter allows you to change both the servicename and the executable name, making it a little harder to find now. To solve this, we can look for the specific executable where the description is set to PSExec.

#FindPsexec service
$PSExecmon =  get-process | Where-Object { $_.description -like "*psexec*" }
if (!$PSExecmon) {
    $PSExecHealth = "Healthy - no PSExec service found."
}
else {
    $PSExecHealth = "Unhealthy - PSExec service found"
}

But now you’re saying “But Kelvin, what is someone removes the personal identifying properties?! You won’t find it but it will still run.” And I’d say you’re absolutely right about that. So let’s try a third option;

$Procs = Get-Process | Where-Object { $_.Path -ne $null }
$PSExecmon = foreach ($Proc in $procs) {
    $Sig = Get-AuthenticodeSignature $proc.path
    if ($Sig.SignerCertificate.Thumbprint -eq "3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC") { $proc }
}
if (!$PSExecmon) {
    $PSExecHealth = "Healthy - no PSExec service found."
}
else {
    $PSExecHealth = "Unhealthy - PSExec service found"
}

This last option does have a downside too; Microsoft used the same signing certificate for the PSTools as they did for a .NET installer. This might generate one or two false positives, but it does seem the best way to detect PsExec usage right now. We’ve loaded this up in our RMM and are running this job to make sure we can see whenever PSExec is executed. With this option you could also stop the process automatically.

And that’s it! Hopefully it helps prevent lateral movement in your networks too. As always, Happy PowerShelling!

Recent Articles

The return of CyberDrain CTF

CyberDrain CTF returns! (and so do I!)

It’s been since september that I actually picked up a digital pen equivalent and wrote anything down. This was due to me being busy with life but also my side projects like CIPP. I’m trying to get back into the game of scripting and blogging about these scripts. There’s still so much to automate and so little time, right? ;)

Monitoring with PowerShell: Monitoring Acronis Backups

Intro

This is a monitoring script requested via Reddit, One of the reddit r/msp users wondered how they can monitor Acronis a little bit easier. I jumped on this because it happened pretty much at the same time that I was asked to speak at the Acronis CyberSummit so it kinda made sense to script this so I have something to demonstrate at my session there.

Monitoring with PowerShell: Monitoring VSS Snapshots

Intro

Wow! It’s been a while since I’ve blogged. I’ve just been so swamped with CIPP that I’ve just let the blogging go entirely. It’s a shame because I think out of all my hobbies it’s one I enjoy the most. It’s always nice helping others achieve their scripting target. I even got a couple of LinkedIn questions asking if I was done with blogging but I’m not. Writing always gives me some more piece of mind so I’ll try to catch up again. I know I’ve said that before but this time I’ll follow through. I’m sitting down right now and scheduling the release of 5 blogs in one go. No more whining and no more waiting.