Home / Blog / Cheat Sheets

Beginner Cheat Sheets

Windows Logon Events Cheat Sheet: Event IDs, Types and Failure Codes

A shift-ready reference for Windows logon event IDs, logon types and failure codes, with KQL, SPL and PowerShell to show who logged on, from where and how.

Almost every Windows investigation comes back to the same question: who logged on, from where and how? This cheat sheet puts the event IDs, logon types and failure codes you need in one place, so that newer analysts can read an authentication alert with confidence and experienced ones have a quick reference on shift.

Start with4624 for success, 4625 for failure
Read firstLogon type, source address, sub status
Where to lookTarget host for logons, domain controller for Kerberos
>

Scenario: An alert reports 300 failed logons against FS-02 from 10.0.4.22 in ten minutes, followed by a successful logon for svc-backup. You need to work out whether this is a misconfigured service or an attack. The answer is sitting in three fields: the logon type, the sub status and the source address.

Which event IDs should you know?

All of these appear in the Windows Security log, provided the relevant audit policies are enabled. Keep in mind where each one is written, because a query against the wrong host type returns nothing and proves nothing.

Event IDMeaningLogged onWhy it matters
4624Successful logonTarget hostYour main record of access
4625Failed logonTarget hostBrute force, spraying, stale credentials
4634LogoffTarget hostSession end, matched on Logon ID
4647User initiated logoffTarget hostInteractive sessions the user ended
4648Logon with explicit credentialsHost running the processA process used another account's credentials
4672Special privileges assignedTarget hostAdmin-equivalent logon session
4740Account locked outDomain controllers, member servers, workstationsShows the caller computer behind a lockout
4768Kerberos TGT requestedDomain controllerInitial domain authentication, including unknown users
4771Kerberos pre-authentication failedDomain controllerWrong passwords against domain accounts
4776NTLM credential validationAuthoritative host, so the DC for domain accountsNTLM use and failures
4778Session reconnectedHost with the sessionRDP reconnects and fast user switching
+

Tip: A 4625 only appears on the host the user tried to access. For a domain-wide view of bad passwords, add 4771 and 4776 from your domain controllers.

What does each logon type mean?

The logon type tells you how the session was created, and it is usually the fastest way to judge whether a logon makes sense. The last column shows whether Microsoft lists the type as leaving reusable credentials in the LSA session. That matters when you assess what an attacker could steal from a host after an administrator has logged on to it.

TypeNameWhat it usually meansReusable credentials
0SystemSystem account activity, such as startupNot listed
2InteractiveLogon at the keyboard or consoleYes
3NetworkAccess over the network, such as a file shareNo, except with delegation
4BatchScheduled tasksYes
5ServiceA service started by the Service Control ManagerYes
7UnlockA workstation was unlockedNot listed
8NetworkCleartextPassword passed to the authentication package in unhashed form, such as IIS BasicYes
9NewCredentialsSame local identity, different credentials for outbound connections, such as runas /netonlyYes
10RemoteInteractiveRemote Desktop or Terminal ServicesYes
11CachedInteractiveLogon with cached credentials, DC not contactedNot listed
12CachedRemoteInteractiveAs type 10, used for internal auditingNot listed
13CachedUnlockUnlock using cached credentialsNot listed
i

Note: Failed RDP attempts are not always logged as type 10. With Network Level Authentication on, a failure commonly appears as a 4625 with logon type 3, because it fails before the remote session exists. Do not filter out type 3 when you investigate failed RDP.

What do the failure codes tell you?

In a 4625, Status gives the reason and SubStatus often gives the more precise one. Read the sub status first. If it is 0x0, fall back on the status. Most of these codes also appear as the Error Code in event 4776.

CodeMeaningWhat to think
0xC0000064Username does not existMany of these across names suggests enumeration or a bad wordlist
0xC000006ACorrect username, wrong passwordThe account is real, so guessing is more of a concern
0xC000006DGeneric bad username or authentication informationCheck the sub status for the detail
0xC000006FOutside authorised hoursValid credentials, possibly used at an odd time
0xC0000070Unauthorised workstationValid credentials used from a host they are not allowed on
0xC0000071Password expiredOften a stale service or scheduled task
0xC0000072Account disabledAttempts on leavers' accounts deserve a look
0xC000015BLogon type not granted on this hostCorrect credentials, wrong logon right, worth checking who tried
0xC0000193Account expiredOften contractors or old accounts
0xC0000224Must change password at next logonUsually new or recently reset accounts
0xC0000234Account locked outPair with 4740 to find the caller computer

Kerberos result codes

Kerberos failures on domain controllers use different codes. You will see these in 4771, and 0x6 in 4768.

CodeNameMeaning
0x6KDC_ERR_C_PRINCIPAL_UNKNOWNUsername does not exist
0x12KDC_ERR_CLIENT_REVOKEDCredentials revoked, such as a disabled or locked account
0x17KDC_ERR_KEY_EXPIREDPassword has expired
0x18KDC_ERR_PREAUTH_FAILEDWrong password
0x25KRB_AP_ERR_SKEWClock difference too great, usually a time sync fault

Which fields answer who, where and how?

Each question maps to a few fields. The names below are the Windows event names and, in brackets, the Microsoft Sentinel SecurityEvent columns.

WhoNew Logon Account Name (TargetUserName). The Subject fields show the account that requested the logon, which is often a machine account.
Where fromSource Network Address (IpAddress) and Workstation Name (WorkstationName). A value of "-" means no network source was recorded.
HowLogon Type (LogonType), Logon Process (LogonProcessName) and Authentication Package (AuthenticationPackageName), such as Kerberos or NTLM.
With what rightsElevated Token (ElevatedToken) and a matching 4672. Together they show whether the session had admin-level privileges.
Which sessionLogon ID (TargetLogonId) links the logon to later activity and to the logoff. Linked Logon ID (TargetLinkedLogonId) ties together the two logons of a split-token admin session.

Which patterns should you escalate?

These combinations come up regularly. None of them is proof on its own, so confirm each against what the account and host normally do.

Failures, then success

High
Indicator

Many 4625 events with 0xC000006A for one account from one source, then a 4624 from the same source.

Response

Treat the credentials as compromised until shown otherwise. Review what the session did. T1110 Brute Force.

Password spraying

High
Indicator

One source, many usernames, few attempts for each. Spraying is designed to stay below lockout limits, so expect few lockouts.

Response

Check for any success from the source and identify the targeted accounts. T1110.003 Password Spraying.

Possible pass the hash

High
Indicator

A 4624 of type 9 with seclogo as the logon process, or type 3 using NTLM with a key length of 0. Both appear in the Sigma rule "Pass the Hash Activity 2".

Response

Rule out runas /netonly and check the host for credential tool activity. T1550.002 Pass the Hash.

Unusual RDP

Med
Indicator

A type 10 between workstations, from a server to a workstation, or from a public address.

Response

Confirm with the user, check 4778 reconnects and trace the source host. T1021.001 Remote Desktop Protocol.

Service account misuse

Med
Indicator

An account that normally logs on as type 4 or 5 suddenly appears with type 2 or 10.

Response

Service accounts rarely need interactive sessions. Identify the source and ask the owner. T1078 Valid Accounts.

New task or service logon

Med
Indicator

A type 4 or 5 logon for an account that has not used one on that host before.

Response

Look for a recent 4698 (scheduled task created) or 4697 (service installed) on the same host.

Keep these queries to hand

Adjust the thresholds and time ranges to suit your environment. Splunk field names depend on how your Windows data is ingested, so check them first.

Microsoft Sentinel

Spraying from one sourceKQL
SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == 4625
| where IpAddress !in ("-", "")
| summarize Attempts = count(),
            Users = dcount(TargetUserName),
            Hosts = dcount(Computer),
            Reasons = make_set(SubStatus, 5)
    by IpAddress
| where Users >= 10
| sort by Users desc
Success after repeated failuresKQL
let lookback = 1h;
let failures = SecurityEvent
    | where TimeGenerated > ago(lookback)
    | where EventID == 4625
    | summarize Failures = count(), LastFailure = max(TimeGenerated)
        by TargetUserName, IpAddress
    | where Failures >= 5;
SecurityEvent
| where TimeGenerated > ago(lookback)
| where EventID == 4624
| where LogonType in (3, 10)
| project SuccessTime = TimeGenerated, TargetUserName, IpAddress, Computer,
          LogonType, AuthenticationPackageName
| join kind=inner failures on TargetUserName, IpAddress
| where SuccessTime > LastFailure
| project SuccessTime, TargetUserName, IpAddress, Computer, LogonType,
          AuthenticationPackageName, Failures

Microsoft Defender XDR

The DeviceLogonEvents table stores the logon type as text instead of a number, so check the values in your tenant if a filter returns nothing.

RDP logons from public addressesKQL
DeviceLogonEvents
| where Timestamp > ago(24h)
| where ActionType == "LogonSuccess"
| where LogonType == "RemoteInteractive"
| where RemoteIPType == "Public"
| project Timestamp, DeviceName, AccountDomain, AccountName, RemoteIP, Protocol
| sort by Timestamp desc

Splunk

Spraying from one sourceSPL
index=wineventlog EventCode=4625 earliest=-1h
| stats count AS attempts dc(user) AS users values(Sub_Status) AS sub_status BY src
| where users>=10
| sort - users
i

Note: Classic Windows event sourcetypes tend to expose Sub_Status and Logon_Type, whereas XML ingestion tends to use SubStatus and LogonType. Run a quick search over one event to see which you have.

PowerShell on a single host

Use this when the host is not sending logs to your SIEM. Reading the Security log needs elevated rights.

Recent failed logons on this hostPowerShell
$events = Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4625
    StartTime = (Get-Date).AddHours(-24)
} -MaxEvents 200 -ErrorAction SilentlyContinue

foreach ($e in $events) {
    $xml = [xml]$e.ToXml()
    $d = @{}
    foreach ($n in $xml.Event.EventData.Data) { $d[$n.Name] = $n.'#text' }
    [pscustomobject]@{
        Time      = $e.TimeCreated
        User      = $d['TargetUserName']
        LogonType = $d['LogonType']
        Status    = $d['Status']
        SubStatus = $d['SubStatus']
        Source    = $d['IpAddress']
    }
}

Key takeaways

  1. Read logon type, source address and sub status first: together they explain most authentication alerts.
  2. 4625 lives on the target host, while 4768 and 4771 live on domain controllers, so query the right place.
  3. 0xC0000064 means the username is wrong and 0xC000006A means the password is wrong, which changes how you read an attack.
  4. Failed RDP can appear as type 3, so do not rely on type 10 alone.
  5. A failure run followed by a success from the same source is the pattern to check first.

Bookmark this page, and test the queries against your own data while things are quiet. Knowing how normal logons look in your estate, including which accounts use which logon types, is what makes the odd one stand out when an alert arrives.