LEVELING UP

Hunting Lateral Movement with Windows Event Logs and PowerShell

Advertisement

When an attacker breaches an endpoint inside an enterprise network, gaining an initial foothold is rarely the end game. To reach high-value targets like domain controllers, database servers, or financial systems, attackers must move laterally across the network.

Security Information and Event Management (SIEM) solutions are great, but understanding how to query and parse raw event logs directly on endpoints gives you a massive advantage during incident response or proactive threat hunting.

In this post, we will cover how to identify three common lateral movement techniques—PSExec, WMI, and WinRM—using native Windows Event Logs and simple PowerShell commands.

Key Windows Event IDs for Detection

Before running queries, you need to know which logs contain the telemetry required to spot lateral movement. Here are the core Event IDs to target:

  • Security Event ID 4624: Successful Account Logon (Look for Logon Type 3 for network logons and Logon Type 10 for RDP).
  • Security Event ID 4672: Special Privileges Assigned to New Logon (Indicates administrative elevation).
  • System Event ID 7045: A Service Was Installed in the System (Crucial for detecting PSExec and remote service installation).
  • Security Event ID 4688: A New Process Has Been Created (Requires command-line auditing enabled).
  • PowerShell Event ID 4104: Script Block Logging (Captures executed code in PowerShell scripts and interactive sessions).

Technique 1: Spotting PSExec Lateral Movement

PSExec (and similar tools like Sysinternals PSExec or Impacket’s psexec.py) works by connecting to the target machine over SMB (port 445), dropping an executable onto the ADMIN$ share, and creating a temporary Windows service to execute commands.

When PSExec creates this service, the Windows System log generates Event ID 7045.

To search for suspicious service creations using PowerShell, run the following command:

Get-WinEvent -FilterHashtable @{LogName=‘System’; Id=7045} | Where-Object { $.Message -match ‘PSEXESVC’ -or $.Message -match ‘cmd.exe’ } | Select-Object TimeCreated, Id, Message

Look closely at the Service Name and Image Path fields. Legitimate services typically reside in C:\Windows\System32 and have clear descriptions. Attackers often use random character names like ‘aX9q.exe’ or direct calls to ‘cmd.exe /c’ originating from user profile directories.

Technique 2: Detecting WMI-Based Lateral Movement

Windows Management Instrumentation (WMI) allows administrators (and attackers) to execute processes remotely using tools like wmic.exe or PowerShell’s Invoke-WmiMethod. Unlike PSExec, WMI does not create a new service, making it quieter.

However, WMI lateral movement triggers process creation events (Event ID 4688) on the target system where WmiPrvSE.exe spawns child processes such as cmd.exe or powershell.exe.

If process command-line auditing is enabled, you can run this script to detect parent-child anomalies:

$Events = Get-WinEvent -FilterHashtable @{LogName=‘Security’; Id=4688} -MaxEvents 5000 foreach ($Event in $Events) { $Xml = [xml]$Event.ToXml() $ParentProcess = ($Xml.Event.EventData.Data | Where-Object {$.Name -eq ‘ParentProcessName’}).‘#text’ $NewProcess = ($Xml.Event.EventData.Data | Where-Object {$.Name -eq ‘NewProcessName’}).‘#text’ $CommandLine = ($Xml.Event.EventData.Data | Where-Object {$_.Name -eq ‘CommandLine’}).‘#text’

if ($ParentProcess -like '*WmiPrvSE.exe*' -and ($NewProcess -like '*cmd.exe*' -or $NewProcess -like '*powershell.exe*')) {
    [PSCustomObject]@{
        TimeCreated = $Event.TimeCreated
        ParentProcess = $ParentProcess
        NewProcess = $NewProcess
        CommandLine = $CommandLine
    }
}

}

Seeing WmiPrvSE.exe launch cmd.exe or powershell.exe with encoded commands or download cradles is a major red flag indicating active remote execution.

Technique 3: Uncovering WinRM and PowerShell Remoting

WinRM (Windows Remote Management) runs on TCP ports 5985 (HTTP) and 5986 (HTTPS). Attackers increasingly favor PowerShell Remoting (Enter-PSSession, Invoke-Command) because it uses legitimate management channels.

To hunt for unauthorized WinRM sessions:

  1. Check for Event ID 4624 with Logon Type 3, where the Process Name is listed as wsmprovhost.exe.
  2. Review PowerShell Script Block Logging (Event ID 4104) under Microsoft-Windows-PowerShell/Operational.

Here is how to query PowerShell script blocks for malicious keywords across remote execution logs:

$LogPath = ‘Microsoft-Windows-PowerShell/Operational’ Get-WinEvent -FilterHashtable @{LogName=$LogPath; Id=4104} | Where-Object { $.Message -match ‘Invoke-Mimikatz’ -or $.Message -match ‘DownloadString’ -or $_.Message -match ‘Bypass’ } | Select-Object TimeCreated, Message

Script block logging unpacks obfuscated and layer-encoded PowerShell code, revealing the true payload regardless of how heavily the command was scrambled on the command line.

Building an Automated Threat Hunting Function

To streamline your hunts, combine these queries into a single reusable PowerShell function that scans for all three techniques in one pass:

function Hunt-LateralMovement { param([int]$Hours = 24) $StartTime = (Get-Date).AddHours(-$Hours) Write-Host ‘Searching System logs for suspicious service creation (PSExec)…’ -ForegroundColor Cyan Get-WinEvent -FilterHashtable @{LogName=‘System’; Id=7045; StartTime=$StartTime} -ErrorAction SilentlyContinue | Where-Object {$.Message -match ‘cmd.exe’ -or $.Message -match ‘powershell’ -or $_.Message -match ‘ADMIN$’} | Format-Table TimeCreated, Message -AutoSize

Write-Host 'Searching PowerShell Script Block logs for suspicious activity...' -ForegroundColor Cyan
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104; StartTime=$StartTime} -ErrorAction SilentlyContinue | Where-Object {$_.Message -match 'DownloadString' -or $_.Message -match 'EncryptedScript'} | Format-Table TimeCreated, Message -AutoSize

}

Run Hunt-LateralMovement -Hours 12 to quickly baseline an endpoint during an active triage session.

Conclusion and Next Steps

Detecting lateral movement does not require expensive enterprise tools. By understanding event signatures for PSExec, WMI, and WinRM, you can quickly write targeted scripts to expose adversary actions.

To level up your hunting capabilities:

  • Ensure Audit Process Creation and Command Line Auditing GPOs are enabled in your environment.
  • Turn on PowerShell Script Block Logging (Event ID 4104) and Module Logging.
  • Practice running these queries against benign lab traffic so you learn what baseline noise looks like before an incident occurs.

Photo by Daniel Balaure on Unsplash.