Most identity threat detection strategies I see are built around the wrong events. Teams collect every security event, build elaborate dashboards showing "Total Logons" and "Failed Password Attempts," and wonder why they're not finding attackers.
Here's the truth: you don't need all the events. You need the right events - the ones that actually indicate identity compromise, privilege escalation, or lateral movement. This post covers the dozen or so event IDs that matter most for identity security, what they mean in real terms, and how to detect the attacks they reveal.
Before You Start: Make Sure the Events Exist
Half of the "we had no alert" findings I write up come down to the event never being generated. Most of the events below need Advanced Audit Policy enabled on your domain controllers (Computer Configuration → Policies → Windows Settings → Security Settings → Advanced Audit Policy Configuration):
- Account Logon: Credential Validation, Kerberos Authentication Service, Kerberos Service Ticket Operations (Success and Failure)
- Logon/Logoff: Logon, Special Logon
- Account Management: Security Group Management, User Account Management
- DS Access: Directory Service Access and Directory Service Changes - these also need a SACL on the objects you care about (the domain root, AdminSDHolder, GPO containers)
All of the PowerShell below reads events by field name rather than by position, which is far less fragile than the Properties[n] indexing you see in most examples. Load this helper first:
These scripts are for triage and threat hunting on a single DC. In production, the same logic belongs in your SIEM, running across every DC.
The Attack Categories
Let me structure this by attack type, not event ID. This is how attackers think - not in terms of Microsoft's event numbering scheme, but in terms of objectives. Your detection should match that.
1. Password Spraying and Brute Force
Event ID 4625 - An account failed to log on (logged on the machine being logged into)
Event ID 4771 - Kerberos pre-authentication failed (logged on DCs)
Event ID 4776 - The computer attempted to validate the credentials for an account (NTLM, logged on DCs)
A spray is one source trying a few passwords against many accounts, which keeps each account under the lockout threshold. So don't count failures per account - count distinct accounts per source:
For 4771, failure code 0x18 means a bad password. For 4625, sub-status 0xC000006A is a bad password and 0xC0000064 is a username that doesn't exist - a spray against a list of guessed names produces a lot of the latter.
2. NTLM Use Where It Shouldn't Be
Event ID 4776 is the DC validating an NTLM credential. NTLM is what Pass-the-Hash and NTLM relay rely on, so privileged accounts authenticating with NTLM deserve attention - in a healthy environment, Domain Admins should be using Kerberos almost exclusively.
Don't try to block NTLM on day one - you'll break things. Audit it first (see my Pass-the-Hash post), then restrict it.
3. Kerberoasting
Kerberoasting is when an attacker requests service tickets for accounts with a servicePrincipalName (SPN) and cracks them offline. It needs no privileges - any domain user can do it.
Event ID 4769 - A Kerberos service ticket was requested. This is the event that matters. (The attacker's TGT request, 4768, looks completely normal, so it tells you nothing here.) Look for:
- Ticket encryption type
0x17(RC4) - roasting tools ask for RC4 because it's far faster to crack than AES - Service names that are user accounts - exclude names ending in
$(computer accounts) andkrbtgt - One account requesting tickets for many different services in a short window
The highest-fidelity Kerberoasting detection is a honeypot. Create a user account with an SPN, a very long random password, and no real use. Nobody should ever request a ticket for it - so any 4769 for that service name is an alert with essentially zero false positives.
4. AS-REP Roasting
AS-REP roasting targets accounts with "Do not require Kerberos pre-authentication" enabled. Anyone can request a TGT for those accounts and crack part of the response offline - no credentials needed at all.
Event ID 4768 - A Kerberos authentication ticket (TGT) was requested. The field to watch is Pre-Authentication Type: a value of 0 means the TGT was issued without pre-authentication.
The better fix is the first query: there are very few legitimate reasons for that flag, so turn pre-authentication back on and the attack goes away.
5. Lateral Movement
Event ID 4624 - An account was successfully logged on (logged on the destination machine). The logon type tells you how:
- Type 3 (Network) - SMB, WinRM, PsExec-style remote execution, remote WMI
- Type 10 (RemoteInteractive) - RDP
- Type 9 (NewCredentials) with logon process
seclogo- this is what Mimikatz'ssekurlsa::pthandrunas /netonlyproduce on the source machine. It's a very useful Pass-the-Hash indicator.
Because 4624 is written on the destination, spotting one account fanning out across many machines is a SIEM correlation: group network logons by account and count distinct destination hosts over a short window. On a single host, you can hunt for the Pass-the-Hash pattern directly:
Event ID 4672 - Special privileges assigned to new logon. This fires whenever an account with admin-equivalent privileges (SeDebugPrivilege, SeTcbPrivilege, SeBackupPrivilege and similar) logs on. Its real value is telling you where your privileged accounts are logging on. A Tier 0 account generating 4672 on a workstation or member server is a tiering violation - and exactly how admin credentials end up in LSASS for an attacker to steal.
6. DCSync
DCSync is when an attacker pretends to be a domain controller and asks a real DC to replicate password hashes to it. It needs no code on the DC - just network access to it and the replication rights (Replicating Directory Changes and Replicating Directory Changes All) on the domain.
Event ID 4662 - An operation was performed on an object. The replication rights appear in the event's Properties field as GUIDs, not names, so match on the GUIDs:
Domain controllers replicate as their computer accounts (names ending in $), which is why those are excluded. Expect one legitimate hit if you run Entra Connect with password hash sync: the MSOL_ account. Allowlist it explicitly - and treat that server as Tier 0, because that account can DCSync.
7. Privileged Group and Directory Changes
Event IDs 4728, 4732, 4756 - A member was added to a security-enabled global / local / universal group. These are the events for "someone just added themselves to Domain Admins." Domain Admins is a global group (4728); Administrators and Backup Operators are domain local (4732); Enterprise Admins is universal (4756).
Event ID 5136 - A directory service object was modified. This catches the quieter persistence techniques: permission changes on AdminSDHolder, GPO modifications, and new ACEs on the domain root (for example, an attacker granting themselves DCSync rights).
My Detection Stack
Here's how I map these into correlation rules:
| Attack Type | Key Events | Correlation Rule |
|---|---|---|
| Password Spray | 4625, 4771, 4776 | One source failing against 10+ distinct accounts within 30 minutes |
| Kerberoasting | 4769 | One account requesting RC4 (0x17) tickets for 5+ distinct user-account SPNs within 10 minutes; any request for a honeypot SPN |
| AS-REP Roasting | 4768 | Any TGT issued with Pre-Authentication Type 0 |
| DCSync | 4662 | Replication GUIDs requested by any account that isn't a DC (allowlist the MSOL_ account) |
| Lateral Movement | 4624 (Type 3/10), 4672 | One account logging on to 5+ distinct hosts within 10 minutes; Tier 0 accounts logging on outside Tier 0 |
| Pass-the-Hash | 4624 (Type 9, seclogo), 4776 | NewCredentials logons with seclogo; NTLM validation for privileged accounts |
| Persistence | 4728/4732/4756, 5136 | Any privileged group addition outside a change window; any ACL change on AdminSDHolder or the domain root |
The thresholds are starting points. Tune them against a couple of weeks of your own baseline before you page anyone at 2 AM.
Final Thought
You don't need to collect every security event. You need the right events, monitored for the right patterns. Start with these and build your detection around actual attack patterns, not Microsoft's internal numbering scheme.
The attackers aren't looking at event IDs - they're thinking about what they want to achieve (credentials, access, persistence). Your detection should mirror that thinking. Identify the attack objectives first, then find the events that reveal those objectives.
Get these monitored correctly and tuned to your environment, and you'll catch the techniques that show up in the majority of identity intrusions - with a lot less noise than a "collect everything" approach.