---
title: "AD CS Part 4: The Rest of the Catalog and How to Lock It Down"
description: "Closing the AD CS series: ESC2's any-purpose EKU, ESC3's enrollment-agent escalation, the identity-mapping weaknesses of ESC9, and the relay-based ESC8/ESC11 — then the four-question hardening checklist that ties the whole taxonomy back together."
date: 2026-11-05
author: Sevban Dönmez (@jankesec)
canonical: https://jankesec.com/posts/ad-cs-rest-hardening/
---

## The catalog beyond the subject

[Part 1](/posts/ad-cs-esc-taxonomy/) framed AD CS as four questions a template answers. [Part 2](/posts/ad-cs-esc1-domain-admin/) and [Part 3](/posts/ad-cs-esc4-esc6/) covered the subject-supply family — the crown jewels. This part closes the catalog with the rest, then collapses it all back into one hardening checklist.

## ESC2: an EKU that means "anything"

`ESC1` is dangerous because of *which* EKU it carries. `ESC2` is dangerous because it carries none — or the "Any Purpose" EKU. That certificate is a blank check: it can be used for Client Authentication, for a subordinate CA, for anything the requester asks for. Request it with a `-upn` and it becomes a Domain Admin certificate exactly like an ESC1:

```bash
$ certipy-ad req -u missandei@essos.local -p fr3edom -ca ESSOS-CA -template ESC2 \
    -upn daenerys.targaryen@essos.local -target braavos.essos.local -dc-ip 192.168.56.12
[*] Successfully requested certificate
[*] Got certificate with UPN 'daenerys.targaryen@essos.local'
```

The fix is the same as ESC1 — strip the any-purpose EKU and enroll rights — but the *recognition* is different: you have to catch a template that is not obviously "wrong", just unconstrained.

## ESC3: the enrollment agent climbs for you

An enrollment agent (the `Certificate Request Agent` EKU) is a designated account that can enroll certificates *on behalf of other users*. `ESC3-CRA` grants that EKU to any `Domain User`. Enroll as an agent, then use that certificate to request a cert for `daenerys.targaryen`:

```bash
$ certipy-ad req -u missandei@essos.local -p fr3edom -ca ESSOS-CA -template ESC3-CRA \
    -target braavos.essos.local -dc-ip 192.168.56.12
[*] Successfully requested certificate
[*] Got certificate with UPN 'missandei@essos.local'
[*] Saving certificate and private key to 'missandei.pfx'
```

The agent certificate is the stepping stone; from it, a request on behalf of `daenerys` mints her certificate. ESC3 is the older, Kerberos-free cousin of ESC1 — it matters when the target template blocks direct enrollment but trusts an agent.

## ESC9 and the identity-mapping family

ESC1-8 all *change what certificate you get*. `ESC9` is different: the certificate is real, but it has `NoSecurityExtension` — no SID — so the KDC falls back to mapping it by UPN. If you can also change a user's `userPrincipalName` (a `GenericWrite` is enough), you collide the UPN and authenticate as them. It is the same weak-binding weakness that made our ESC1 certificate in Part 2 work with "no object SID": this lab's KDC does not enforce strong binding.

The rest of this family is about the same fallback. `ESC11` removes the encryption requirement on ICPR (RPC) requests, and `ESC8` exposes web enrollment over HTTP — both are transport-level, and both are relay vectors: coerce an NTLM authentication toward the CA and let it mint a certificate as the victim. `ESC15` and `ESC17` are the historical-accident entries on the `WebServer` template (schema-v1 EKU mismatch, server-auth subject supply). None of these is a *new* idea; each is a different way to let the identity mapping or the transport be abused.

I could not demo the relay family (`ESC8`/`ESC11`) from this Kali box because it is routed, not bridged, to the lab subnet — a coerced machine has no return path to my listener. The configuration is real (`ESC8: Web Enrollment over HTTP`, `ESC11: encryption not enforced`) and enumerated in Part 1; the exploitation needs the attacker on the same L2.

<figure class="diagram">
<svg viewBox="0 0 760 220" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The remaining ESC family grouped by the question they answer: ESC2 and ESC3 answer what the certificate can do, ESC9 answers how it maps to an identity, ESC8 and ESC11 answer transport, and ESC15 and ESC17 are historical-accident entries.">
<defs><marker id="r4" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L8,4 L0,8 z" class="dg-arrow" /></marker></defs>
<text x="0" y="16" class="dg-muted">THE REST OF THE ESC CATALOG · BY ROOT CAUSE</text>
<rect x="0" y="40" width="240" height="100" rx="8" class="dg-box" />
<text x="14" y="64" class="dg-label">What can it do? (EKU)</text>
<text x="14" y="86" class="dg-mono dg-compact">ESC2 · any purpose</text>
<text x="14" y="104" class="dg-mono dg-compact">ESC3 · request agent</text>
<rect x="260" y="40" width="240" height="100" rx="8" class="dg-box-accent" />
<text x="274" y="64" class="dg-label">Maps to who? (binding)</text>
<text x="274" y="86" class="dg-mono dg-compact">ESC9 · no SID extension</text>
<text x="274" y="104" class="dg-muted">UPN collision → weak binding</text>
<rect x="520" y="40" width="240" height="100" rx="8" class="dg-box-danger" />
<text x="534" y="64" class="dg-label">How does it travel? (transport)</text>
<text x="534" y="86" class="dg-mono dg-compact">ESC8 · web enrollment HTTP</text>
<text x="534" y="104" class="dg-mono dg-compact">ESC11 · ICPR no encryption</text>
<rect x="0" y="180" width="760" height="24" rx="4" class="dg-box" />
<text x="14" y="196" class="dg-muted dg-compact">ESC15 / ESC17 · historical accidents on the WebServer template (schema-v1 EKU, server-auth subject)</text>
</svg>
<figcaption>The rest of the taxonomy, grouped by which of the four questions they break — the EKU, the identity mapping, or the transport.</figcaption>
</figure>

## Locking it down: the four questions, answered

Every ESC in this series is one of [Part 1](/posts/ad-cs-esc-taxonomy/)'s four questions answered wrong. So the remediation is just those four answers, done right:

| Question | Fix | Kills |
| --- | --- | --- |
| Who can enroll? | Restrict `Enroll` to the accounts that need it | ESC1/2/3/4/6 |
| Who supplies the subject? | Strip `EnrolleeSuppliesSubject` + clear the CA `User Specified SAN` flag | ESC1/4/6/17 |
| What can it be used for? | Client/Server Auth EKU only, no "any purpose", no request agent | ESC2/3/15 |
| How does it map to an identity? | Keep the SID extension, `StrongCertificateBindingEnforcement = 2` | ESC9/10 |

Plus the transport row: disable HTTP web enrollment (`ESC8`), enforce ICPR encryption (`ESC11`), and — above all — treat the Enterprise CA server as **Tier 0** no matter where it sits.

## Closing the series

Four posts, one conclusion: **a certificate is a credential, and a template flag is an attack-surface decision.** The taxonomy matters less than the instinct it builds — the moment you see `EnrolleeSuppliesSubject: True`, `Any Purpose`, or `User Specified SAN: Enabled`, you already know a Domain Admin certificate is one request away, because you know *which question was answered wrong*.

## Evidence and limits

The remaining ESC templates (`ESC2`, `ESC3`, `ESC8`, `ESC9`, `ESC11`) were enumerated against `ESSOS-CA` and `SEVENKINGDOMS-CA` in the isolated GOAD lab. Network-relay primitives (`ESC8`/`ESC11`) are analyzed architecturally alongside the four-question hardening matrix because the attack host is routed rather than bridged onto the lab segment.

## References

- **Orange Cyberdefense, GOAD:** [orange-cyberdefense.github.io/GOAD](https://orange-cyberdefense.github.io/GOAD/)
- **The Hacker Recipes, AD CS:** [thehacker.recipes/ad/movement/adcs](https://www.thehacker.recipes/ad/movement/adcs)
- **SpecterOps, Certified Pre-Owned:** [posts.specterops.io](https://posts.specterops.io/certified-pre-owned-d95910965cd2)
- **Microsoft, AD CS Overview:** [learn.microsoft.com](https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/active-directory-certificate-services-overview)
- **MITRE ATT&CK, Steal or Forge Authentication Certificates (T1649):** [attack.mitre.org/techniques/T1649](https://attack.mitre.org/techniques/T1649/)