PASS-THE-HASH
EVENT 4624
NTLMSSP
EVENT 4776
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting Pass-the-Hash: NTLM Logon Anomalies and Event 4624

Pass-the-hash looks like a normal NTLM logon because it is one. The detection is in who, from where, to how many hosts and why NTLM was used at all.

Scroll

With a captured NT hash an attacker authenticates as the account without ever knowing the password. No single event proves it, so detection builds a profile: which accounts and sources normally use NTLM, where Kerberos is expected, and how many destinations one source touches in a short window.

Signals at a Glance

SignalWhereATT&CK
Type 3 logon, AuthenticationPackage NTLM, LogonProcess NtLmSsp from a workstation to many serversEvent 4624T1550.002
Account that normally uses Kerberos now authenticating with NTLMEvent 4624, baselineT1550.002
Credential validation (4776) with a blank or non-domain workstation nameDC Event 4776T1550.002
Logon type 9 with LogonProcess seclogo and Advapi (mimikatz sekurlsa::pth on the source)Event 4624, 4648T1550.002
Local administrator (RID 500) network logons across hostsEvent 4624, 4672T1078.003

NTLM Where Kerberos Is Expected

Inside a healthy domain, most server-to-server and workstation-to-server authentication uses Kerberos. NTLM appears when a client connects by IP address, reaches a non-domain host or when a tool supplies a hash directly. That makes the combination of an account, a source and a destination the unit to baseline. A Key Length of 0 on an NTLM type 3 logon is an older heuristic; treat it as a weak extra signal, not a rule:

// Sentinel (KQL) - NTLM network logons fanning out from one source
SecurityEvent
| where EventID == 4624 and LogonType == 3
| where AuthenticationPackageName == "NTLM" and LogonProcessName has "NtLmSsp"
| where TargetUserName !endswith "$" and TargetUserName !in~ ("ANONYMOUS LOGON")
| summarize dests=dcount(Computer), hosts=make_set(Computer, 20),
            weakKey=countif(KeyLength == 0), first=min(TimeGenerated), last=max(TimeGenerated)
          by TargetUserName, IpAddress
| where dests >= 5
| order by dests desc
// tune/validate: exclude vulnerability scanners, backup servers and jump hosts via an allowlist.

On the domain controller, Event 4776 records the NTLM validation. A workstation name that is empty or does not exist in your asset inventory is common when a tool such as Impacket runs from a non-domain Linux host:

index=wineventlog EventCode=4776 Error_Code=0x0
| eval ws=coalesce(Source_Workstation, "")
| lookup asset_inventory hostname AS ws OUTPUT hostname AS known
| where ws="" OR isnull(known)
| stats count dc(Logon_Account) as accounts values(Logon_Account) as who by ws, host
| sort - count
# tune/validate: field names depend on the Windows add-on; asset_inventory is your CMDB lookup.

Context That Separates Attack From Admin

Vetted sources

Use the SigmaHQ pass-the-hash and overpass-the-hash rules, Elastic and Splunk ESCU NTLM content and MITRE CAR analytics for credential reuse, and validate with Atomic Red Team. Microsoft documents NTLM auditing and restriction policies. Baseline your own environment first: scanners, legacy applications and IP-based connections all produce legitimate NTLM.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026