What a Windows Security Event line looks like
The key=value sample below is fed verbatim into the engine to produce every parser on this page.
EventID=4625 TargetUserName=admin LogonType=3 IpAddress=203.0.113.45 IpPort=51234 Status=0xC000006D WorkstationName=WKSTN-07
EventID=4624 TargetUserName=jdoe LogonType=2 IpAddress=192.0.2.10 IpPort=50022 Status=0xC0000064 WorkstationName=WKSTN-11 Detected fields
The engine classified this sample as kv and consolidated 7 fields across 2 lines. Fields marked literal were identical on every sample line, so they are baked into the pattern as anchors rather than captured.
- eventid : number
- targetusername : literal
- logontype : number
- ipaddress : ipv4
- ipport : port
- status : literal
- workstationname : literal
Regex (named capture groups)
# sample: EventID=4625 TargetUserName=admin LogonType=3 IpAddress=203.0.113.45 IpPort=51234 Status=0xC000006D WorkstationName=WKSTN-07
# groups: eventid=4625, targetusername=admin, logontype=3, ipaddress=203.0.113.45, ipport=51234, status=0xC000006D, workstationname=WKSTN-07
^EventID=(?<eventid>-?\d+(?:\.\d+)?) TargetUserName=(?<targetusername>[A-Za-z]+) LogonType=(?<logontype>-?\d+(?:\.\d+)?) IpAddress=(?<ipaddress>\d{1,3}(?:\.\d{1,3}){3}) IpPort=(?<ipport>\d{1,5}) Status=(?<status>(?:\d+[A-Za-z]+\d+|\d+[A-Za-z]+\d+[A-Za-z]+)) WorkstationName=(?<workstationname>[A-Za-z]+-\d+)$ Grok pattern (Logstash / Elastic)
EventID=%{NUMBER:eventid} TargetUserName=%{NOTSPACE:targetusername} LogonType=%{NUMBER:logontype} IpAddress=%{IPV4:ipaddress} IpPort=%{INT:ipport} Status=%{NOTSPACE:status} WorkstationName=%{GREEDYDATA:workstationname} - note kv-structured input — consider the Logstash kv filter instead of (or after) grok
Wazuh decoder (OS_Regex XML)
<!--
Generated by LogForge - Wazuh decoder (OS_Regex dialect, not PCRE)
sample: EventID=4625 TargetUserName=admin LogonType=3 IpAddress=203.0.113.45 IpPort=51234 Status=0xC000006D WorkstationName=WKSTN-07
test with: /var/ossec/bin/wazuh-logtest
-->
<decoder name="windows-event-kv">
<prematch>^EventID=</prematch>
</decoder>
<decoder name="windows-event-kv">
<parent>windows-event-kv</parent>
<regex offset="after_parent">^(\d+) TargetUserName=(\w+) LogonType=(\d+) IpAddress=(\d+.\d+.\d+.\d+) IpPort=(\d+) Status=(\w+) WorkstationName=(\w+)</regex>
<order>eventid, targetusername, logontype, ipaddress, ipport, status, workstationname</order>
</decoder>
- note kv fields are extracted by same-named sibling decoders (offset="after_parent"), so per-line field order/absence is tolerated — the shared name is what makes Wazuh evaluate every sibling
- note decoder order and prematch specificity may need site-specific tuning (other decoders in your ruleset can shadow these) — validate with /var/ossec/bin/wazuh-logtest
rsyslog template / liblognorm rulebase
version=2
# windows_event — liblognorm v2 rulebase (generated by LogForge)
# Usage with rsyslog (mmnormalize runs liblognorm):
# module(load="mmnormalize")
# action(type="mmnormalize" rulebase="/etc/rsyslog.d/windows_event.rb" useRawMsg="on")
# Literal "%" is escaped as "%%"; raw tabs are written as \x09.
rule=windows_event:EventID=%eventid:number% TargetUserName=%targetusername:word% LogonType=%logontype:number% IpAddress=%ipaddress:ipv4% IpPort=%ipport:number% Status=%status:word% WorkstationName=%workstationname:word%
- note kv structure: rsyslog offers mmfields (fast, fixed single-char separator, untyped) and mmnormalize (this rulebase, typed fields + literal anchors); mmnormalize was chosen for typed extraction
- note chosen parser types: eventid=number, targetusername=word, logontype=number, ipaddress=ipv4, ipport=number, status=word, workstationname=word
FAQ
- Why does this parser target single-line Windows events instead of EVTX/XML?
- Because raw Windows Security logs are binary EVTX that render as multi-line XML — a text regex cannot parse that reliably, and you should use an EVTX reader for it. In practice a SIEM ingests events after a forwarder (NXLog, Winlogbeat, Snare) has flattened each one to a single line of key=value or JSON. This page parses that forwarded single-line form, which is what actually hits your pipeline.
- What does LogonType mean in event 4624 / 4625?
- LogonType classifies how the logon happened: 2 is interactive (console), 3 is network (e.g. SMB/share access), 10 is RemoteInteractive (RDP), 4 is batch (scheduled task), and 5 is service. It is central to detection — a network or RDP logon from an unexpected source, or a burst of type-3 failures, reads very differently from a normal interactive login.
- How do I tell password spraying from user enumeration in 4625 events?
- Look at the NTSTATUS Status/SubStatus code plus the username spread. 0xC0000064 means the user does not exist (enumeration), 0xC000006A means the password was wrong for a real account, and 0xC000006D is a generic bad-username/logon failure. Many 4625s from one IpAddress across many distinct TargetUserNames indicates spraying; repeated 0xC0000064 against different names indicates enumeration.
- Which fields matter most for Windows logon detection?
- EventID (4624 success vs 4625 failure), LogonType, TargetUserName, SubjectUserName, IpAddress, and WorkstationName, plus Status/SubStatus on failures. Correlating EventID + LogonType + IpAddress + TargetUserName covers brute force, spraying, enumeration, and anomalous RDP or network logons.
Try it on your own Windows Security Event lines
Paste a few real lines, review the detected fields, and copy whichever format your stack needs. Free, no account, nothing uploaded.
Open this sample in LogForge →