During my CRTE work the technique that surprised me most was not a flashy memory trick. It was a certificate. Active Directory Certificate Services (AD CS) is deployed in a huge number of enterprises, it is often owned by a team that does not think of it as a security boundary, and a single misconfigured template can hand a low-privileged user a path to domain admin. SpecterOps mapped this landscape in their "Certified Pre-Owned" research and gave the escalation paths the "ESC" names that are now standard. Certipy, by ly4k, made them practical to find and to fix. As of 2026 the catalog runs from ESC1 to ESC17.
I care about AD CS because certificates are quietly powerful. A certificate is an identity you can authenticate with, it is typically valid for a year or more, and it does not care if the victim later changes their password. Steal a password and a reset locks you out. Obtain a certificate for that account and you keep access across the reset. That persistence is exactly why this is worth understanding from both sides.
Start where the defender should: enumerate
Every engagement and every hardening review starts the same way, by asking the CA what templates it offers and who can enroll:
certipy find -u user@corp.local -p '***' -dc-ip 10.0.0.1 -vulnerable
That single question surfaces the misconfigurations below. The reason I lead with it is that it is also the defender's tool. If a red teamer can run certipy find, so can you, and you should, on a schedule.
ESC1: the template that lets you name yourself
ESC1 is the archetype. A certificate template is configured so that a low-privileged user can enroll, the certificate is valid for client authentication, and critically the enrollee is allowed to supply the Subject Alternative Name. The SAN is the field the domain uses to decide who the certificate is for. If I can request a client-auth certificate and set its SAN to the domain administrator, the CA issues me a certificate that authenticates as that administrator.
The attacker's action is a single certificate request specifying an arbitrary identity, for example requesting a cert as administrator through a vulnerable template. No exploit, no memory corruption. Just a request the CA was misconfigured to honor.
Detection and defense: the request and issuance are logged on the CA as events 4886 (request) and 4887 (issued). The tell is a certificate whose subject or SAN does not match the requesting account, especially a low-privileged user obtaining a certificate that names a privileged one. The fix is to remove the "enrollee supplies subject" flag on authentication templates, require manager approval, and tightly scope enrollment rights. ESC1 is almost always a template that should never have shipped that way.
ESC8: relaying the machine to the CA's web endpoint
ESC8 is a different shape. Many AD CS deployments expose an HTTP-based enrollment endpoint (the web enrollment or certificate enrollment web service). Those endpoints often accept NTLM authentication. If an attacker can coerce a privileged machine account into authenticating and relay that authentication to the enrollment endpoint, the CA issues a certificate for the relayed identity. Coerce a domain controller, relay it, and you now hold a certificate for a DC.
The point I want to make is architectural, not procedural: this works because authentication (NTLM) is being accepted somewhere it can be relayed, with no channel binding to stop it. The certificate service is the target, but the weakness is the relayable auth in front of it.
Detection and defense: the durable fix is to remove NTLM from the CA web endpoints, enable Extended Protection for Authentication (channel binding), and require HTTPS. On the detection side, relay activity tends to show authentication for a machine account arriving from an unexpected host, followed immediately by a certificate issuance (4886/4887) for that account. Coercion attempts against DCs are their own well-known signal worth alerting on.
The rest of the family, in one breath
The other ESC paths rhyme with these two. ESC2 and ESC3 abuse templates with overly broad usage (an "Any Purpose" EKU, or an enrollment-agent EKU that lets you request on behalf of others). ESC9 and ESC10 turn on the certificate-to-account mapping introduced by the May 2022 updates (CVE-2022-26923), where a missing security extension lets a certificate be mapped to the wrong identity. The later numbers extend into CA configuration and access-control weaknesses. The details differ, but the theme is constant: a certificate ends up trusted to speak for someone it should not.
The defender's playbook
Because I do detection engineering as much as offense, this is the part that actually matters. AD CS is very defensible once you decide to look at it:
- Audit the templates. Run
certipy find -vulnerableyourself and treat every flagged template as a finding. Most ESC1 and ESC2 issues are a single checkbox that should be unchecked. - Turn on CA auditing. Enable issuance auditing and collect events 4886 and 4887 (request and issuance), plus 4899/4900 for template and CA changes. Alert on a subject/SAN that does not match the requester, and on any privileged identity appearing in a certificate requested by a non-privileged account.
- Kill relay on the web endpoints. Remove NTLM, require HTTPS, and enable Extended Protection for Authentication. This closes ESC8 at the source rather than trying to detect every coercion primitive.
- Watch for certificate-based logons that skip the password. A certificate authentication for a sensitive account, from an unusual host, with no preceding interactive logon, is a strong signal that a stolen or forged certificate is in play.
- Constrain enrollment and approval. Least privilege on who can enroll, manager approval on sensitive templates, and short validity periods shrink both the odds and the blast radius.
What AD CS taught me
The lesson I took from AD CS is that the most dangerous misconfigurations are the boring, administrative ones. Nobody exploited a zero-day here. Somebody checked a box on a certificate template years ago, and it sat there as a domain-admin path that no password policy or EDR would ever flag. That is why I run certipy find on the blue side, not just the red side. The same command that finds the path also proves you closed it.
Resources
- SpecterOps "Certified Pre-Owned" whitepaper (Will Schroeder, Lee Christensen): the foundational AD CS abuse research
- Certipy (ly4k): enumeration and abuse tool, with a privilege-escalation wiki covering ESC1-ESC17: https://github.com/ly4k/Certipy
- Microsoft AD CS auditing guidance (events 4886 / 4887 / 4899 / 4900)
- Guidance on mitigating CVE-2022-26923 and the certificate SID-mapping updates