Windows Event Log Forensics: EVTX, Event IDs and Hunting
A practitioner guide to Windows event logs: EVTX format, key channels, Security and Sysmon event IDs, audit policy, cleared-log recovery and hunting tools.
Windows event logs are the closest thing to a flight recorder that most Windows hosts have: logons, process launches, service installs, PowerShell and remote access all land there when auditing allows it. By the end of this guide you will know where the logs live and how they roll over, which channels and event IDs answer which questions, what the default audit policy silently misses, and how to recover evidence after someone clears the logs.
EVTX format and location
Since Windows Vista, logs are stored as binary XML in .evtx files under %SystemRoot%\System32\winevt\Logs. Each channel gets its own file, and a / in the channel name becomes %4 on disk, so Microsoft-Windows-PowerShell/Operational is stored as Microsoft-Windows-PowerShell%4Operational.evtx. XP and Server 2003 used the older .evt format in System32\config. The Windows event logs artifact page summarizes the layout.
Internally an EVTX file has a 4 KB file header (signature ElfFile) followed by 64 KB chunks (signature ElfChnk). Each chunk holds event records that start with the magic bytes 2A 2A 00 00 and carry their own EventRecordID and timestamp. Records use templates stored inside the chunk, which matters later: a chunk is self-contained enough to be parsed on its own when carved out of free space.
The path of a classic log can be changed. Check HKLM\SYSTEM\CurrentControlSet\Services\EventLog\<LogName> (value File) and, for the newer channels, HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\<Channel> before assuming the default folder is complete.
Retention, size and rollover
Logs have a size limit, not a time limit. On Windows 7 and later Security, System and Application default to roughly 20 MB, and many Operational channels are much smaller (often around 1 MB). When full, the default behaviour is to overwrite the oldest events. Two other modes exist: archive the log when full (the AutoBackupLogFiles value, which leaves Archive-<Log>-<timestamp>.evtx files next to the live log) and do not overwrite.
Practical consequences:
- On a domain controller or busy file server the Security log may cover only a few hours. Always note the oldest record per log before stating "no event was found".
- Enterprise GPOs frequently raise the sizes; read the actual
MaxSizerather than assuming defaults. - Logs forwarded to a SIEM or Windows Event Forwarding collector may outlive the local copy. Ask for them early.
# Size, mode and record count for a log
wevtutil gl Security
Get-WinEvent -ListLog Security, System, 'Microsoft-Windows-PowerShell/Operational' |
Select-Object LogName, MaximumSizeInBytes, LogMode, RecordCount, FileSize
# Oldest surviving event in a collected file
Get-WinEvent -Path E:\case\Logs\Security.evtx -Oldest -MaxEvents 1 | Select-Object TimeCreated, RecordId
Channels that matter
| Channel | Why you open it |
|---|---|
Security | Authentication, privilege use, process creation, account and policy changes |
System | Service installs (7045), service state, log clearing (104), boot and shutdown (6005/6006/6008) |
Application | Application crashes, installers, some security products |
Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | RDP and console sessions: 21 logon, 22 shell start, 23 logoff, 24 disconnect, 25 reconnect |
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational | 1149: RDP user authentication succeeded at the network level, with source IP |
Microsoft-Windows-PowerShell/Operational | 4103 module logging, 4104 script block logging |
Microsoft-Windows-Sysmon/Operational | Sysmon telemetry, only if Sysmon is installed |
Microsoft-Windows-TaskScheduler/Operational | 106 task registered, 140 updated, 141 deleted, 200/201 action started/completed |
Microsoft-Windows-Windows Defender/Operational | 1116/1117 detection and action, 5001 real-time protection disabled, 5007 configuration change |
Microsoft-Windows-WMI-Activity/Operational | 5857 provider loaded, 5860 temporary and 5861 permanent event subscriptions |
Microsoft-Windows-Bits-Client/Operational | 3 job created, 59/60 transfer started/stopped with the URL, 4 job completed |
RDP specifics are on the RDP connections page, PowerShell on the PowerShell page, Defender on the Windows Defender page, and WMI and BITS on the WMI repository and BITS jobs pages. Some channels, TaskScheduler in particular, may be disabled or very small depending on the build and configuration, so their absence is not proof that nothing happened.
Core Security event IDs
Logons and sessions
4624 (successful logon) and 4625 (failed logon) are the backbone of any intrusion timeline. The field that turns them into a story is LogonType (see logon type):
| Logon type | Meaning | Typical source |
|---|---|---|
| 2 | Interactive | Console logon, runas without /netonly |
| 3 | Network | SMB share access, PsExec-style tools, WinRM (network auth) |
| 4 | Batch | Scheduled tasks |
| 5 | Service | Services starting under an account |
| 7 | Unlock | Workstation unlock |
| 8 | NetworkCleartext | Basic auth, some IIS scenarios |
| 9 | NewCredentials | runas /netonly, some credential-injection tools |
| 10 | RemoteInteractive | RDP |
| 11 | CachedInteractive | Domain logon with cached credentials, no DC reachable |
For 4625, read Status and SubStatus: 0xC000006A is a wrong password for a valid account, 0xC0000064 a non-existent user, 0xC0000234 a locked-out account. A burst of 0xC0000064 against many names looks like spraying or enumeration, while repeated 0xC000006A on one account looks like guessing.
4634 is a logoff and 4647 a user-initiated logoff; pair them with 4624 on TargetLogonId to get session duration, knowing that network logons often log off within seconds. 4648 (logon with explicit credentials) shows the account typing credentials for another identity, which is common with runas and lateral movement tools; it is logged on the source machine. 4672 (special privileges assigned) follows a 4624 whenever the new session holds admin-level privileges, so 4624 plus 4672 with the same logon ID means an administrative session.
Process creation
4688 records a new process with its image path, parent process (Windows 10 and later) and token elevation type. It is only produced when Audit Process Creation is enabled, and the CommandLine field is only populated when the policy Include command line in process creation events is set (registry value ProcessCreationIncludeCmdLine_Enabled under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit). That setting is native to Windows 8.1 and Server 2012 R2 and later; older systems needed an update. Link a 4688 back to its session through SubjectLogonId, which matches the TargetLogonId of the originating 4624.
Persistence and account changes
- 4697 (Security) and 7045 (System): a service was installed. 7045 is logged by the Service Control Manager regardless of audit policy; 4697 needs Audit Security System Extension. See the services page.
- 4698: scheduled task created, with the full task XML in the event. 4699 deleted, 4702 updated. Requires Audit Other Object Access Events. See the scheduled tasks page.
- 4720 user account created, 4722 enabled, 4724 password reset attempt by another account, 4728 member added to a security-enabled global group, 4732 member added to a security-enabled local group (for example Administrators).
Tampering
- 1102: the Security log was cleared, with the account that did it. It is written whatever the audit policy.
- 104 (System): another log was cleared.
- 4719: system audit policy was changed. An attacker disabling process or logon auditing right before acting is a strong signal.
- 1100: the Event Log service shut down. Outside a matching reboot (6006, then 6005 at next boot) it deserves attention.
Audit policy: what is and isn't logged by default
Default audit policy varies by Windows version and is usually overridden by domain GPOs, so never guess: collect auditpol /get /category:* from the live system, or read the effective policy from the Security hive and GPO files on a dead box. As a rough rule on a stock Windows 10/11 client:
- Logged: logon and logoff (4624, 4625, 4634, 4647), special logon (4672), user account and security group management (4720, 4732...), audit policy change (4719), log clearing (1102), and 7045 in System.
- Not logged: process creation (4688), scheduled task object events (4698), service install in Security (4697), file and registry object access, and detailed Kerberos service ticket events on member machines.
Missing categories are the single biggest reason an investigation "finds nothing" in the Security log. When they are off, fall back to Prefetch, Amcache, the TaskScheduler and PowerShell channels, and Sysmon if present.
# Effective audit policy on a live host
auditpol /get /category:*
# Is command-line capture enabled?
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -ErrorAction SilentlyContinue
Sysmon essentials
Sysmon is a free Sysinternals driver and service that writes rich ETW-sourced telemetry to Microsoft-Windows-Sysmon/Operational. Its value depends entirely on the configuration file deployed, so collect the config (from the registry or the deployment share) along with the log. The five IDs you will use most:
| Sysmon ID | Event | What it gives you |
|---|---|---|
| 1 | Process creation | Command line, hashes, parent process and command line, ProcessGuid, LogonId |
| 3 | Network connection | Process, source and destination IP and port; often filtered heavily by configs |
| 11 | File create | Files dropped by a process, with creation time |
| 13 | Registry value set | Run keys, services and other persistence writes |
| 22 | DNS query | Domain requested and the process that asked |
ProcessGuid is unique per process instance, unlike PIDs that are reused, so pivot on it to build a process tree. Also useful: 7 (image loaded), 8 (CreateRemoteThread), 10 (process access, for example to lsass.exe) and 19 to 21 (WMI event subscriptions).
PowerShell 4103 and 4104
4104 (script block logging) records the text of script blocks as they are compiled, after deobfuscation layers such as -EncodedCommand or Invoke-Expression strings are resolved. It is enabled by the policy value EnableScriptBlockLogging under HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging. Even without that policy, PowerShell 5 logs script blocks it considers suspicious as warning-level 4104 events, which regularly saves investigations. Long scripts are split across several 4104 records sharing a ScriptBlockId, numbered with MessageNumber and MessageTotal; reassemble them before reading.
4103 (module logging) records pipeline execution details and parameter bindings for the modules configured under ModuleLogging. It is noisier but shows what commands actually ran with which arguments. The classic Windows PowerShell log adds 400/403 (engine start and stop) with a HostApplication field containing the launching command line, which works even on hosts with no other PowerShell logging.
# Reassemble script blocks from a collected Operational log
Get-WinEvent -FilterHashtable @{Path='E:\case\Logs\Microsoft-Windows-PowerShell%4Operational.evtx'; Id=4104} |
ForEach-Object {
$d = ([xml]$_.ToXml()).Event.EventData.Data
[pscustomobject]@{
Time = $_.TimeCreated.ToUniversalTime()
BlockId = ($d | Where-Object Name -eq 'ScriptBlockId').'#text'
Part = ($d | Where-Object Name -eq 'MessageNumber').'#text'
Text = ($d | Where-Object Name -eq 'ScriptBlockText').'#text'
}
} | Sort-Object BlockId, {[int]$_.Part}
Recovering from cleared logs
A 1102 or 104 tells you that a log was cleared and who did it. Getting the content back is a separate job, and anti-forensics rarely wipes every copy:
- Volume Shadow Copies. A shadow copy taken before the clearing holds the old
.evtxfiles intact. Mount it, or let EvtxECmd process shadow copies directly. See the Volume Shadow Copies page. - Carving EVTX chunks. Clearing creates a new file; the clusters of the old one are released, not wiped. Because each 64 KB
ElfChnkchunk is self-describing, file carving of unallocated space (and of memory images, pagefile and hiberfil) can recover whole chunks. Tools such as EVTXtract (Willi Ballenthin) also try to rebuild individual records whose templates are missing. - Archive files and forwarded copies. Look for
Archive-*.evtx, SIEM data, EDR telemetry and backups. - Other channels. Clearing
Securitydoes not touchPowerShell/Operational,TaskScheduler/Operationalor Sysmon. Attackers often forget them.
Also check for tampering that avoids 1102: a stopped Event Log service (1100, or a gap between records without a reboot), jumps in EventRecordID, or a log whose first record starts long after the last boot. The dedicated anti-forensics guide goes further.
Tools
EvtxECmd
Eric Zimmerman's EvtxECmd parses EVTX into a normalized CSV. Its maps (one YAML per channel and event ID) extract the useful EventData fields into consistent columns such as UserName, RemoteHost and ExecutableInfo, which makes Timeline Explorer filtering fast.
# Update maps, then parse a folder of collected logs
EvtxECmd.exe --sync
EvtxECmd.exe -d E:\case\Logs --csv E:\out --csvf evtx.csv
# Only a few IDs, from a single file
EvtxECmd.exe -f E:\case\Logs\Security.evtx --csv E:\out --inc 4624,4625,4648,4672,4688
# Include shadow copies of a mounted volume, deduplicating records
EvtxECmd.exe -d F:\Windows\System32\winevt\Logs --vss --dedupe --csv E:\out
Hayabusa and Chainsaw
Both apply Sigma-style detection rules across a whole folder of logs in minutes, which makes them ideal first passes.
# Hayabusa: update rules, build a timeline, summarize logons
hayabusa update-rules
hayabusa csv-timeline -d ./Logs -o hayabusa.csv
hayabusa logon-summary -d ./Logs
# Chainsaw: Sigma hunt and keyword search
chainsaw hunt ./Logs -s sigma/ --mapping mappings/sigma-event-logs-all.yml -r rules/
chainsaw search mimikatz -i ./Logs
Treat their output as leads, not conclusions: rules fire on admin tooling, and a clean result only means no rule matched.
Get-WinEvent
Built-in, scriptable and fine for targeted questions on live or collected logs. Use -FilterHashtable or -FilterXPath so filtering happens in the API instead of piping everything through Where-Object.
# RDP and network logons in a time window, with key fields
$start = [datetime]'2026-09-20T00:00:00Z'
Get-WinEvent -FilterHashtable @{Path='E:\case\Logs\Security.evtx'; Id=4624; StartTime=$start} |
ForEach-Object {
$d = @{}; ([xml]$_.ToXml()).Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
if ($d.LogonType -in '3','10') {
[pscustomobject]@{ Time=$_.TimeCreated.ToUniversalTime(); User=$d.TargetUserName
Type=$d.LogonType; Ip=$d.IpAddress; Workstation=$d.WorkstationName; LogonId=$d.TargetLogonId }
}
}
# Services installed, straight from the System log
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Service Control Manager'; Id=7045}
Common mistakes
- Reading times in local time.
TimeCreatedis stored in UTC; Event Viewer and some exports display local time. Normalize to UTC before merging, as explained in UTC and local time. - Treating event IDs as global. An ID only means something together with its provider and channel: 4104 in PowerShell/Operational is unrelated to any other 4104.
- Concluding absence from an empty result without checking audit policy and the oldest surviving record.
- Trusting
WorkstationNameblindly. It is supplied by the client and can be spoofed or empty; preferIpAddressand correlate with the source host. - Ignoring the small channels. TerminalServices, TaskScheduler, Defender and WMI-Activity often hold the only trace of an action.
A hunting workflow
- Collect every
.evtxfile (KAPEEventLogstarget or Velociraptor), plus shadow copies, the SYSTEM and SOFTWARE hives andauditpoloutput if live. The acquisition and triage guide covers the collection side. - Establish coverage: for each important log, note size, retention mode, oldest record and which audit categories were enabled.
- Look for tampering first: 1102, 104, 1100, 4719, record ID gaps.
- Run Hayabusa or Chainsaw for fast leads, then parse everything with EvtxECmd for the full picture.
- Scope authentication: 4624/4625 by logon type, source IP and account; 4648 and 4672; RDP 1149 and 21/24/25. Suspicious remote logons feed the lateral movement guide.
- Follow the session: chain
TargetLogonIdto 4688 or Sysmon 1, then to 4104, 7045, 4698 and Defender events. Persistence findings continue in hunting Windows persistence. - Timeline: merge the parsed CSV with file system and registry artifacts in a super timeline, all in UTC.
Microsoft's audit policy recommendations are worth reading alongside your findings, both to know what should have been logged and to advise the client on what to turn on next time.
Area 03
Event Logs
The artifact cheat sheets behind this guide: location by Windows version, what each one proves and the tools to parse it.