ADCS Certificate Persistence
Certificates obtained through ADCS remain valid for the entire certificate lifetime, regardless of password changes. A certificate issued for a Domain Admin account continues to authenticate as that account even after a full password reset or account lockout, making ADCS-based persistence among the hardest to detect and remove without revoking the certificate or disabling PKINIT.
Two tiers of persistence:
Certificate for a specific account: valid until the certificate expires (typically 1 year for user templates, 2 years for computer templates)
Stolen CA private key (Golden Certificate): forge certificates for any account, indefinitely, signed by the trusted CA
Before using these techniques, confirm ADCS is deployed and working with ADCS Misconfiguration Discovery.
Obtain certificate for privileged account
Request a user certificate for a Domain Admin account. The certificate authenticates via PKINIT and produces an NT hash on every use, even after the account's password has been changed. This is valid as long as the certificate has not been revoked.
[*] Saved certificate and private key to 'administrator.pfx' # certipy auth output (run after any password change): [*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
[*] Getting credentials using U2U
CredentialInfo:
[0] NTLM: fc525c9683e8fe067095ba2ddc971889
Steal CA private key — forge any certificate
If you have local admin on the CA server (typically a DC or dedicated CA host), you can export the CA private key and root certificate. With these you can forge a certificate for any account in the domain, signed by the trusted CA, with any validity period. This is permanent access regardless of certificate revocation lists (CRLs are checked for enrolled certs, but forged certs don't appear in the CRL).
[*] Saved CA certificate and private key to '$CA_NAME.pfx' # certipy forge: [*] Saving forged certificate and private key to 'administrator_forged.pfx' # certipy auth: [*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
Certificate persistence via ESC3 (enrollment agent)
ESC3 certificates (enrollment agent templates) let you request certificates on behalf of other users. This persists even after credential rotation: with an enrollment agent certificate you can always issue a new certificate for any target account.
[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
Detection and remediation:
Monitor for certificate requests by privileged accounts (Event ID 4886 + 4887 on CA)
Revoke issued certificates after credential compromise — locate in Certificate Authority MMC under Issued Certificates
CA private key theft has no native detection. Enable CA audit logging (Event ID 4870) and watch for
certutil -exportpfxorcertipy ca -backupequivalent eventsForged certificates (from stolen CA key) cannot be revoked via CRL. The only remediation is revoking and reissuing the CA certificate itself — a major operation requiring all issued certs to be re-enrolled
References
-
Certipy (GitHub)github.com/ly4k/Certipy (opens in new tab)
ca -backup, forge, auth, req subcommands for all ADCS persistence chains
-
Certify (GitHub)github.com/GhostPack/Certify (opens in new tab)
Windows-side certificate requests, enrollment agent, /onbehalfof flag
-
Rubeus (GitHub)github.com/GhostPack/Rubeus (opens in new tab)
asktgt /certificate + /getcredentials for UnPAC-the-Hash
-
Certified Pre-Owned — SpecterOpsposts.specterops.io/certified-pre-owned-d95910965cd2 (opens in new tab)
Original ESC1-8 research by Will Schroeder and Lee Christensen, covers persistence paths
Was this helpful?
Your feedback helps improve this page.