A ticket arrives with a number in it. Event 4625, four hundred times in six minutes, against one account. The number looks like the finding. It is closer to a filing reference: it tells you which template Windows used to write the line, and very little about whether anything happened.
The Windows Security log is one of the richest evidence sources in an investigation and one of the least legible on first contact. The identifiers are dense, the numbering carries thirty years of history, and the detail that settles the case usually sits in a field below the ID rather than in the ID itself. Here is what the number does and does not carry.
An event ID is scoped, not global#
An event ID is unique only within the provider that wrote it. Every Windows event record names a provider, a channel, and an ID, and only the three together identify anything.
The Security channel makes the point concretely. Event 4624, a successful logon, is written by the provider Microsoft-Windows-Security-Auditing. Event 1102, the audit log being cleared, appears in the same Security channel but is written by Microsoft-Windows-Eventlog. Two providers, one channel, no shared numbering scheme between them.
This is why 7045 is a perfectly reasonable thing to ask about and an unreasonable thing to look up in a Security-log reference: service installation is a System-channel event from a different writer entirely. Our Windows event ID decoder covers the 371 Security-log events in Microsoft's Active Directory monitoring guidance and says so plainly, rather than guessing at identifiers outside that set.
The renumbering that broke the runbooks#
Windows Vista and Server 2008 renumbered the security events. Most identifiers moved up by exactly 4096. 528 became 4624, 592 became 4688, 624 became 4720. The rule is tidy enough that people memorised it and stopped checking.
It does not hold everywhere. Of the 142 events in that corpus that publish a legacy identifier, 129 follow the rule and 13 do not, and the exceptions are not obscure. Audit-log-cleared went from 517 to 1102, which is the provider split from the previous section surfacing in the numbering: a different writer, a different range. System audit policy changed went from 612 to 4719, eleven clear of where arithmetic would put it.
A detection rule ported from a pre-2008 runbook by adding 4096 is therefore right about nine times in ten and quietly wrong the rest of the time, sometimes on the events most worth alerting on. The decoder accepts legacy identifiers directly for that reason. Type 517 and it returns 1102.
One event swallowed ten#
Modern 4625 replaces ten separate pre-Vista identifiers: 529 through 537, and 539. Under the old scheme, why a logon failed was encoded in the event ID, so a rule could alert on one failure reason and ignore another.
Vista collapsed all of them into one event and moved the reason into two fields, Status and Sub Status. Microsoft describes Status as the reason the logon failed and Sub Status as additional information about it; in practice the specific reason often lands in Sub Status while Status carries something generic. Both hold NTSTATUS values. These are the ones worth recognising on sight:
| Code | What it means |
|---|---|
| 0xC0000064 | No such user account. A run of these across different names is enumeration. |
| 0xC000006A | Correct user name, bad password. |
| 0xC000006D | Bad user name or authentication information. |
| 0xC000006F | Logon outside the account's authorised hours. |
| 0xC0000070 | Logon from an unauthorised workstation. |
| 0xC0000072 | The account is disabled. |
| 0xC000015B | The account lacks that logon right on this machine. |
| 0xC0000193 | The account has expired. |
| 0xC0000234 | The account is locked out. |
| 0xC000005E | No logon servers available to service the request. |
| 0xC0000192 | The Netlogon service was not started. |
// status and sub status values documented for event 4625
The distinction earns its keep during triage. Two hundred failures carrying 0xC0000064 across many different usernames is somebody mapping your account names. Two hundred carrying 0xC000006A against a single name is somebody working on a known account. Same event ID, two different incidents, and the ID alone cannot separate them.
The last two rows deserve their own note. Microsoft flags 0xC000005E and 0xC0000192 as typically infrastructure or availability problems rather than security ones, which is worth knowing before escalating a wave of failures that turns out to be a domain controller having a bad afternoon.
Logon type is the field that decides what happened#
A successful logon is not one thing. 4624 carries a Logon Type, and the gap between two of its values is the gap between a service ticking over and a person at a keyboard.
| Type | Title | What it indicates |
|---|---|---|
| 0 | System | The System account, for example at startup. |
| 2 | Interactive | Someone logged on to this computer directly. |
| 3 | Network | A user or computer logged on from the network. |
| 4 | Batch | A batch server running a process on a user's behalf. |
| 5 | Service | The Service Control Manager started a service. |
| 7 | Unlock | The workstation was unlocked. |
| 8 | NetworkCleartext | Network logon where the password reached the authentication package unhashed. |
| 9 | NewCredentials | A token was cloned with different credentials for outbound connections. |
| 10 | RemoteInteractive | Terminal Services or Remote Desktop. |
| 11 | CachedInteractive | Locally cached credentials; no domain controller was contacted. |
| 12 | CachedRemoteInteractive | As RemoteInteractive; used for internal auditing. |
| 13 | CachedUnlock | Workstation logon. |
// logon types published for event 4624
Notice the gaps: no 1, no 6. These are constants lifted from an internal enumeration, not a vocabulary anyone designed for readers.
Type 3 is the workhorse and the noisy one, covering file share access and most machine-to-machine authentication. Type 2 is somebody physically present. On a busy domain controller the ratio between the types tells you more about the shape of a day than any individual event does.
Type 8 attracts more alarm than it should. It means the password reached the authentication package in unhashed form, and Microsoft's own note is a corrective worth quoting: the built-in authentication packages all hash credentials before sending them across the network, so the credentials do not traverse the network in plaintext. It usually points at an application doing its own basic-auth style handling, which is still worth knowing about, just not for the reason people assume.
Type 11 is the one that surprises people mid-investigation. The credentials were cached locally and no domain controller was contacted to verify them, so disabling an account in Active Directory does not, on its own, stop that logon from succeeding on a laptop that is off the network.
The rating is not a severity#
Microsoft publishes a criticality rating beside each event in its Active Directory monitoring guidance, and it is the field most often misread. Across those 371 events, 9 are rated High, 1 Medium to High, 77 Medium, and 284 Low.
4625 is rated Low. So are 4624, 4688, and 4720, a user account being created. The rating answers a monitoring question: should a programme raise something on every one of these across a domain? For an event a domain controller writes thousands of times a day, obviously not. Read as a severity score by an analyst triaging one alert, it points the wrong way, because the failed logon in front of you may be the most important line in the case.
The High-rated events are the rare ones. 4719, system audit policy changed. 4765 and 4766, SID History added to an account and an attempt that failed. 4794, an attempt to set Directory Services Restore Mode. 4964, special groups assigned to a new logon. Several only appear at all if somebody configured them to, which is exactly why they repay recognising on sight.
One band below sits 1102, the audit log cleared, the only event in the list rated Medium to High. Microsoft's guidance on it is blunt: you should not normally see this, there is rarely a legitimate need to clear the Security log manually, and it warrants finding out why it happened.
The events you are not recording#
Everything above assumes the relevant audit policy is switched on. Several of the most useful ones are not, by default.
Audit Process Creation, which produces 4688, ships as Not configured. Microsoft recommends enabling Success auditing for it on domain controllers, member servers, and workstations alike, which is a fair measure of how much it is missed when absent.
Enabling it is only half the job. The Process Command Line field stays empty until a second policy is turned on, "Include command line in process creation events", also Not Configured out of the box. Without it, a 4688 tells you wscript.exe started and not what it was told to run. With it, you get the script.
That second setting carries a cost Microsoft states in the policy text: command lines are written to the Security log in plain text, and anyone who can read that log can then read them. Command lines carry passwords and tokens more often than anybody would like. Turning it on is usually still the right call, and it should be a decision rather than an accident.
One more worth wiring up. If advanced audit policy settings are being overwritten by the older basic audit policy, Windows records that as 4719, the High-rated event from the previous section. An audit configuration silently reverting is a monitoring gap on its own, and occasionally the opening move of something worse.
Reading an event without a runbook#
- Establish the provider and channel, not just the ID. An identifier is unique only within its writer, so "event 1102" is ambiguous until you know which log it came from.
- Resolve legacy identifiers rather than converting them. If a runbook handed you a pre-2008 number, look it up. Our event ID decoder takes a current ID, a legacy ID, a keyword, or a pasted log line, and runs entirely in your browser.
- Read the discriminating field before the summary. Logon Type for
4624, Status and Sub Status for4625. The ID names the category; these decide the case. - Treat the criticality rating as a volume hint. It describes what a domain-wide monitoring programme should alert on, not how serious the event in your queue is.
- Pivot to the addresses. The Source Network Address in a logon event is where the rest of the investigation usually lives. Paste a batch of them into log IP triage to see which deserve attention first, then run the interesting one through IOC enrichment for geo, ASN, hosting and Tor-exit context. If two logons for one account came from far apart, the impossible travel calculator will tell you whether the gap is genuinely impossible or just uncertain, and why those alerts fire covers the traps in that check.
- Resist concluding from one event. A single record establishes about as much as a single indicator does, which is a point what an indicator of compromise actually tells you makes at greater length.
None of this makes the Security log friendly. It does make it readable: a number that names a template, a provider that gives the number its meaning, and two or three fields underneath carrying the part you actually needed. The identifier gets you to the right page. It is rarely the answer on it.
Decode an event without leaving the ticket
Type a current ID, a pre-Vista legacy ID, a keyword, or paste a log line. It returns the meaning, Microsoft's monitoring rating, and the legacy identifier it replaced, and it runs entirely in your browser.
Decode an event →