SIEM 202 — Detecting remote PsExec

by | Nov 24, 2020 | Cybersecurity, DFIR, Information Technology, InfoSec, SIEM, SIEM 200 series

In this post I’ll explain how to detect an attacker that uses PsExec to connect to your computer when you don’t have visibility over the attacker’s computer.

Note: In this post I use Logz.io for my examples, but I recently switched to Humio. For more details: https://www.tristandostaler.com/why-i-switched-from-logz-io-to-humio/


For this post, I assume you’ve read my SIEM 100 series where I explain the basics of Logz.io. I’ll be using the stack I created in this series to demonstrate what to do.


PsExec is a tool provided by Microsoft in the Sysinternals suite: https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
Like they explain:
 

PsExec is a light-weight telnet-replacement that lets you execute processes on other systems, complete with full interactivity for console applications, without having to manually install client software. PsExec’s most powerful uses include launching interactive command-prompts on remote systems and remote-enabling tools like IpConfig that otherwise do not have the ability to show information about remote systems.

https://docs.microsoft.com/en-us/sysinternals/downloads/psexec

PsExec can be use as an adversary to pivot between computers and/or elevate privileges. It is rather easy to detect when executed on a monitored endpoint, but what happens when a remote computer not monitored use it to connect to a monitored endpoint?

It turns out it can be detected by looking for a chain of 3 events, distinctive of PsExec behavior when remote connecting.

Note: Sysmon is needed to detect this behavior. You can read my post SIEM 201 — What is Sysmon on the subject.

The 3 events are:

  1. An incoming connection is made on the port 445 or 135 (Sysmon event ID 3 AND destination port: 445 OR 135)
  2. An executable file is created in C:\Windows\ (Sysmon event ID 11 AND target filename: C:\\Windows\\[^\\]+\.exe)
  3. The executable from the step 2 is executed (Sysmon event ID 1 AND image: C:\\Windows\\[^\\]+\.exe. The image should be the same as the target filename of the step 2)

The result should have no false positive (it would detect the normal usage of PsExec, so make sure to whitelist your allowed users).

In a Lucene query format, it should give something like this (adapt the field names to your context):

(event.code: 3 AND winlog.event_data.DestinationPort: (135 OR 445)) OR (event.code: 11 AND winlog.event_data.TargetFilename: /C:\\Windows\\[^\\]+\.exe/) OR (event.code: 1 AND winlog.event_data.Image: /C:\\Windows\\[^\\]+\.exe/)

Then, you can correlate the winlog.event_data.Image with the winlog.event_data.TargetFilename, but with a simple hack that don’t give a lot of false positive, that’s not necessary: you can simply make sure that the number of unique event.code in your results is equal to 3. This is what I’ll be doing. Head over to Logz.io and login to your account.

The same logic can be applied to detect SCShell, WMIExec and SMBExec, but the detection details are a bit different; I might write another blog for these ones.

In practice

The first thing to do is to simulate a remote PsExec execution so we can detect it. First download and extract PsExec which is bundled with a few tools called the PsTools: https://download.sysinternals.com/files/PSTools.zip

In the location of the extraction, open PowerShell as Administrator (File -> Open Windows PowerShell -> Open Windows PowerShell as administrator). For me the working directory of PowerShell is “C:\Users\User\Downloads\PSTools”. Then execute the following command:

(Get-NetIPAddress).IPAddress | Where-Object {($_ -ne "127.0.0.1") -and ($_ -ne "::1") -and ($_ -notlike "*:*")} | %{.\PsExec.exe \\$_ cmd}

After running this command, you will be in a cmd.exe context. You can simply write “exit” to go back to PowerShell. At this point you generated a remote PsExec execution, we now need to find it in the logs.

Now in Kibana search the query (it’s the same as above):

(event.code: 3 AND winlog.event_data.DestinationPort: (135 OR 445)) OR (event.code: 11 AND winlog.event_data.TargetFilename: /C:\\Windows\\[^\\]+\.exe/) OR (event.code: 1 AND winlog.event_data.Image: /C:\\Windows\\[^\\]+\.exe/)

We can see that we get the pattern I described above:

Now click on Create alert.

I recommend using a Group by on “beat_agent.hostname” because if you have more than 1 computer or server, the event could get mixed between computers and you could get a lot of false positives.

Now, to use the small hack I described above, so we don’t have to correlate events, in the “Trigger if…” section, check that the unique count of event.code is equal to 3. That way, the alert will trigger if and only if the 3 events are met in a small period of time:

We need this little hack because on Logz.io we can only do 2 step correlations and we would need 3 steps for this specific detection case. There are other platforms that allow to correlate more events, so you could do the correlation logic, but there are also some platform that don’t allow correlation so this hack could come in handy.

Conclusion

That’s it, you can now detect when a hacker uses PsExec to move laterally. Of course, you might need to whitelist some source IP or source IP range if you use PsExec legitimately in your context to allow known Administrators VLAN to use it.

Feel free to leave your comment down here for any questions or comments.

Subscribe!

See more Posts: