Windows Event Log Credential Stuffing

Detecting Credential Stuffing and Brute Force in Windows Event Logs

Why this matters

Credential stuffing and password spraying against Windows do not need malware — they need a list of usernames and a list of passwords, and the only place the attempt is recorded is the Security event log. Event ID 4625 is generated on every failed logon, and its Status and SubStatus codes carry more information than most reviews use. The failure mode is almost never a lack of logging; it is that 4625 events are high-volume and noisy, so the handful that represent an actual campaign — same source IP, many accounts, then one success — get buried.

Indicators to look for in Windows Event Logs

  • Event ID 4625 in volume from a single IpAddress, with Status: 0xC000006D (bad username or password) — the top-level failure code on our sample
  • SubStatus: 0xC000006A — the password was wrong for an account that exists (spraying/brute force) versus 0xC0000064 (account does not exist, enumeration)
  • LogonType: 3 — a network logon rather than a console attempt, which is what remote attacks produce
  • The same TargetUserName failing repeatedly (brute force) or many different TargetUserName values each failing once or twice (password spraying)
  • A 4624 successful logon from the same IpAddress after a run of 4625 failures — this is the compromise moment, often with a WorkstationName like ATTACKER-VM and NTLM as the authentication package
  • Follow-on 4672 (special privileges assigned), 4720 (account created), or 4728 (member added to Domain Admins) from the newly logged-on identity

How LogTriage detects this

The Windows Event Log parser maps each 4625 to a failed POST /windows/logon with status 401, preserving the Status/SubStatus as the failure reason and the IpAddress as the source. Grouped by source IP inside a session window, a run of failed logons that crosses the credential-stuffing threshold (three or more auth attempts at a 50%+ failure rate) raises a credential_stuffing pattern, and the severity escalates to critical when a successful authentication (a 4624 mapped to a 200) appears in the same session — the “failures then success” signature. The attacker IP is also checked against LogTriage’s confirmed-malicious CIDR ranges; our sample’s 185.220.101.45 sits in a Tor exit subnet already in the IOC set, which floors the event score independently of the pattern logic. A published Sigma rule, LTR-0012 for Windows 4625 password spraying, encodes the same SubStatus-and-LogonType logic and is validated against these exact sample files.

Detection / evidence checklist

  • Group 4625 events by IpAddress and count distinct TargetUserName values — many accounts means spraying, one account means brute force
  • Read the SubStatus on each failure to separate bad-password (0xC000006A) from bad-username (0xC0000064)
  • Confirm LogonType 3 to establish the attempts were remote
  • Search for a 4624 success from the same source IP in the minutes after the failures — that is the account to treat as compromised
  • Pull 4672, 4720, and 4728 for the compromised identity to scope privilege escalation and persistence
  • Reset the affected account and any account that authenticated successfully from the attacker’s IP

Frequently Asked Questions

What is the difference between SubStatus 0xC000006A and 0xC0000064 on a 4625 event?
Both appear on Event ID 4625 (failed logon) with a top-level Status of 0xC000006D. SubStatus 0xC000006A means the account exists but the password was wrong — the signature of password spraying and brute force. SubStatus 0xC0000064 means the account name itself does not exist — the signature of username enumeration. Separating them tells you whether the attacker already knows valid usernames or is still guessing them.
Why does LogonType matter when reading 4625 events?
LogonType 3 is a network logon — the attempt arrived over SMB, RDP-brokered auth, or another remote channel rather than at the physical console (LogonType 2). Remote failed logons in volume against one or many accounts are the brute-force and spraying pattern; console failures are usually a mistyped password. Our sample brute-force export is entirely LogonType 3 from a single external IP.
Can LogTriage read a raw .evtx file, or does it need XML?
Both. The parser reads Event Viewer / wevtutil XML exports directly, and reads binary .evtx files when the optional python-evtx dependency is present. If you cannot install that, export first with wevtutil qe Security /f:xml > events.xml and upload the XML.
Which Windows Event IDs does the parser extract beyond 4625?
The security-relevant set includes 4624 (successful logon), 4648 (explicit-credential logon), 4672 (special privileges assigned), 4688 (process creation), 4720 (account created), 4728 (member added to a global group), and the Kerberos 4768/4769/4771 events. A password-spray that ends in a 4624 success from the same attacker IP is the escalation the parser is built to surface.

Related Resources

See this detection run on a real report

Try the live demo with a pre-loaded malicious log set — no signup required — or upload your own log file and get a full AI-reviewed threat report in minutes.