Unsuccessful login attempts, attacksis the most common starting signal. Almost all attackers, from ransomware gangs to penetration testing teams, attempt credential guessing to gain initial access to Windows systems. Good news: Windows writes these attempts to the Security Log. Bad news:no one reads these logs.
In this guide, we will cover Windows Event ID 4625 in depth: which fields are critical, what LogonTypes mean, how to read SubStatus codes, and most importantly —SIEM rules for real-time brute force detectionhow to write.
What is Event ID 4625?
Event ID 4625 means "An account failed to log on" in Windows Security Log. This event is generated when an account unsuccessfully tries to log in — wrong password, non-existent user, disabled account, etc.
This event in the Security Log,Audit LogonOccurs if the policy is active. It is on by default in modern Windows Server versions (2016+).
TargetUserName, IpAddress, LogonType, SubStatus, workstationname. The quality of a brute force detection depends on your correct interpretation of these 5 fields.
Structure of a 4625 event
A typical XML output looks like this (simplified):
<EventData>
<Data Name="SubjectUserSid">S-1-5-18</Data>
<Data Name="SubjectUserName">DC01$</Data>
<Data Name="TargetUserName">admin</Data>
<Data Name="TargetDomainName">COMPANY</Data>
<Data Name="Status">0xC000006D</Data>
<Data Name="SubStatus">0xC000006A</Data>
<Data Name="LogonType">3</Data>
<Data Name="AuthenticationPackageName">NTLM</Data>
<Data Name="workstationname">ATTACKER-PC</Data>
<Data Name="IpAddress">203.0.113.45</Data>
<Data Name="IpPort">49832</Data>
</EventData>
This event tells us:
TargetUserName=admin— adminTrying to log in with accountIpAddress=203.0.113.45— source this external IPLogonType=3— network logon (SMB, remote resource access)SubStatus=0xC000006A— wrong password(clearest brute force signal)workstationname=ATTACKER-PC— attacker's machine name (may be spoofed but clue)
Understanding LogonTypes
LogonType of the login processHowshows that it has been done. The detection priority of each is different.
| Tip | Name | Meaning | Brute Force Risk |
|---|---|---|---|
| 2 | interactive | Console/keyboard (physical session) | Medium |
| 3 | Network | SMB, network share, RPC | High |
| 4 | Batch | Scheduled task | Low |
| 5 | Service | Windows service startup | Low |
| 7 | Unlock | Screen unlock | Low (but there is a stalker scenario) |
| 8 | NetworkCleartext | Clear text network auth | High (usually misconfiguration) |
| 10 | Remoteinteractive | RDP oturumu | Very High |
| 11 | Cachedinteractive | Cache credentials | Low |
The three most critical types are:Type 3 (Network), Type 10 (RDP)AndType 8 (Cleartext). Brute force alarms should be triggered on these three first.
LogonType 10 — RDP Brute Force
RDP (Remote Desktop Protocol) brute force is one of the favorite entry vectors of ransomware gangs in 2023-2024. If a single RDP port is open to the internet, you will be visible in Shodan.Takes less than 48 hours.
Reading SubStatus Codes
SubStatus field, a login attemptWhy does it fail?says it is. This code directly affects your brute force detection quality.
| SubStatus | Meaning | Attack Gauge |
|---|---|---|
0xC0000064 |
User not found | User enumeration (user browsing) |
0xC000006A |
wrong password | Brute force |
0xC0000234 |
Account locked | Successful lockout (attacker exceeded the limit) |
0xC0000072 |
Account disabled | Trying old account (should be) |
0xC0000193 |
Account expired | old account |
0xC0000070 |
Workstation restriction | Trying from unknown location |
0xC0000071 |
Password expired | low priority |
0xC0000133 |
time difference | Saat senkronu sorunu |
The two most critical codes for detection are: 0xC0000064 (user count) and 0xC000006A (brute force). If you combine the two, you capture both phases of the attack.
Real Time Alarm Rules
Theory is enough. Nowpractical. 4 basic rules you should write in your SIEM:
Rule 1: Classic Brute Force
10+ failed logins in 10 minutes from the same IP.
SELECT
src_ip,
COUNT(*) AS fail_count,
ARRAY_AGG(DISTINCT username) AS targeted_users,
MIN(ts) AS first_attempt,
MAX(ts) AS last_attempt
FROM logs
WHERE event_type = 'auth'
AND action = 'login_fail'
AND event_id = 4625
AND (extra->>'sub_status') = '0xC000006A'
AND ts > NOW() - INTERVAL '10 minutes'
AND src_ip IS NOT NULL
AND src_ip != ''
GROUP BY src_ip
HAVING COUNT(*) >= 10;
Rule 2: Credential Stuffing
from the same IPwith different users5+ failed logins — this isn't classic brute force,stolen credential listattempt.
SELECT
src_ip,
COUNT(*) AS fail_count,
COUNT(DISTINCT username) AS unique_users,
ARRAY_AGG(DISTINCT username ORDER BY username) AS users
FROM logs
WHERE event_id = 4625
AND ts > NOW() - INTERVAL '15 minutes'
AND src_ip IS NOT NULL
GROUP BY src_ip
HAVING COUNT(DISTINCT username) >= 5
AND COUNT(*) >= 8;
Rule 3: RDP Attack
Especially LogonType=10 for aggressive threshold.
SELECT
src_ip,
username,
COUNT(*) AS attempts
FROM logs
WHERE event_id = 4625
AND (extra->>'logon_type')::int = 10 -- RDP
AND ts > NOW() - INTERVAL '5 minutes'
GROUP BY src_ip, username
HAVING COUNT(*) >= 3;
The threshold for RDP is lower (3 in 5 minutes) becauseRDP brute force has a high chance of successand immediate intervention is required.
Rule 4: User Enumeration
Before an attackervalid userstries to find (0xC0000064), then guesses the password. If you catch this first phase, you can block the attacker while he is still innocent.
SELECT
src_ip,
COUNT(*) AS enum_attempts,
COUNT(DISTINCT username) AS unique_targets
FROM logs
WHERE event_id = 4625
AND (extra->>'sub_status') = '0xC0000064' -- user not found
AND ts > NOW() - INTERVAL '30 minutes'
GROUP BY src_ip
HAVING COUNT(*) >= 15;
How to Deal with False Positives?
Brute force rulesproduce false positivestends to. The most common reasons:
- Registered device password has changed — The same user's password has changed, but a backup service is still trying the old password.
- Scheduled task password forgotten — A task that has been running for years crashes with a changed password in AD.
- slow laptop — Screen locked without user entering password, then clumsy login attempts.
- Mobile phone Wi-Fi — devices trying to connect with the old Wi-Fi password.
To distinguish real brute force from false positive, look for these signs:
- ✅ Coming from external (public) IP
- ✅ Target user
admin,admin, high-value accounts such as service accounts - ✅ Multi-user (credential stuffing)
- ✅ During non-attack hours (night, weekend)
- ✅ workstationname is suspicious (empty, Cyrillic, random)
Log Collection with NXLog
To send Windows Event Log to a SIEMNXLog community Editionthe most practical way. Free, 15+ years, stable.
A simple configuration:
<Input eventlog>
Module im_msvistalog
Query <QueryList>\
<Query Id="0">\
<Select Path="Security">\
*[System[(EventID=4624 or EventID=4625 or EventID=4740)]]\
</Select>\
</Query>\
</QueryList>
Exec $Message = to_json();
</Input>
<Output oxisec>
Module om_udp
Host siem.example.com
Port 5515
Exec to_syslog_ietf();
</Output>
<Route windows_auth>
Path eventlog => oxysec
</Route>
This configuration only collects 3 auth-related events (login success, login failure, account lockout). Instead of sending the entire Security Logselectiveis critical for both bandwidth, storage and SIEM performance.
Get started for free with the community plan →
Next Steps
In this guide, the basics of brute force detection are covered comprehensively. For readers who want to go further:
- GeoIP integration: Which country did the attacker IP come from — "Impossible Travel" detection
- Threat Intelligence: IP's AbuseIPDB score, Tor exit node, botnet list?
- UEBA: Learning the user's normal behavior and detecting deviations
- Automatic intervention: Automatic IP ban to firewall with Auto-mode
articles on these topics will come soon.
Summary
- Event ID 4625Windows is the standard signal for failed logins
- LogonType distinguishes attack type: Type 3 (Network), 10 (RDP), 8 (Cleartext) critical
- SubStatus gives the reason for failure:
0xC000006Abrute force,0xC0000064enumerasyon - Four basic rules: classic brute force, credential stuffing, RDP attack, user enumeration
- To deal with false positivesIP source + user + timeuse context
- Collection with NXLog is free and set up in 5 minutes