Esta página está traducida automáticamente y pendiente de revisión humana. Una guía de remediación de seguridad que no puedes verificar es una afirmación, así que el original en inglés está a un clic. English.

ADCS-016: ESC16 - Configuración incorrecta de UPN en el SAN

Plataforma
Active Directory
Categoría
AD Certificate Services
Severidad
High
Pilar de Zero Trust
Identity (peso 3)
Fixtures de referencia
3
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

ESC16 explota una configuración incorrecta en la que StrongCertificateBindingEnforcement está establecido en 1 (modo de compatibilidad) y las plantillas de certificado con CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT o CT_FLAG_SUBJECT_ALT_REQUIRE_UPN permiten al solicitante establecer el UPN en el SAN. La asignación débil permite que los certificados se asignen a los usuarios basándose únicamente en el UPN, sin la extensión de seguridad OID, lo que habilita la suplantación

Por qué importa

The szOID_NTDS_CA_SECURITY_EXT extension is what Microsoft added in KB5014754 to fix CVE-2022-26923 (the Certifried bug). It embeds the objectSid of the requester into the issued certificate so the KDC can perform a strong, SID-based binding rather than a string-based lookup on userPrincipalName or dNSHostName. When a CA is configured to omit that extension (ESC16), every certificate it issues is downgraded back to weak mapping. If at least one DC is still running with StrongCertificateBindingEnforcement = 1 (the default through February 2025) or 0, those DCs will accept the weak mapping and resolve the certificate to whatever account currently owns the UPN named in the SAN. The exploit becomes a UPN swap: an attacker who controls any account with an enrollment right on any client-auth-capable template sets their own userPrincipalName to administrator (or any other privileged accounts UPN with the suffix stripped, exploiting the implicit mapping rules), requests a certificate, resets the UPN back, and authenticates via PKINIT as the privileged account. Because the CA omits the SID extension, the KDC cannot detect that the requester was not actually the privileged account. ESC16 is particularly insidious because the misconfiguration is set once at the CA level and affects every template, including hardened ones. It is also frequently introduced by administrators trying to work around interoperability issues with third-party PKI consumers (load balancers, NDES, legacy SCEP clients) that fail to parse the new extension. Microsoft began rejecting weak mappings outright in the February 2025 enforcement wave and removed the ability to revert to Compatibility mode entirely on September 9, 2025, but a large installed base of stale CAs and unpatched DCs (especially read-only DCs and Windows Server 2012 R2 / 2016 systems in extended support) still satisfies both legs of the condition.

Ruta de ataque

1. Enumerate the CA configuration. The attacker runs certipy find -u low@corp.example.com -p Pass -dc-ip <dc> -enabled -vulnerable. Certipy queries the policy DisableExtensionList on each CA via MS-RRP and flags any CA where 1.3.6.1.4.1.311.25.2 is present as ESC16. Certify.exe enum-cas --hide-admins produces equivalent output, reporting Disabled Extensions: <unknown> (1.3.6.1.4.1.311.25.2). 2. Confirm a target DC is in Compatibility mode. certutil -dcinfo verify or remote registry against HKLM\SYSTEM\CurrentControlSet\Services\Kdc\StrongCertificateBindingEnforcement shows a value of 0 or 1, or absence of the key. Event ID 39 / 40 / 41 in the System log on the DC is a defenders signal that weak mapping is occurring; the attacker assumes it is until proven otherwise. 3. Identify a usable template. Any template with Domain Users or Authenticated Users enrollment, a Client Authentication style EKU, and either CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT or CT_FLAG_SUBJECT_ALT_REQUIRE_UPN works. The built-in User template often qualifies because it builds the SAN from the requesters UPN. 4. UPN swap. The attacker modifies their own userPrincipalName to match the target. With write permission to their own userPrincipalName (which is the default unless explicitly removed via dsHeuristic fNoUserPrincipalNameMappingOnSelf or an ACL), they run: Set-ADUser low -UserPrincipalName administrator. If the target UPN already exists, the attacker uses the target without the suffix (administrator) which still resolves under weak mapping. 5. Enroll. certipy req -u low@corp.example.com -p Pass -ca CORP-CA -template User. The CA stamps administrator into the SAN UPN and, because of the DisableExtensionList entry, omits the SID extension entirely. 6. Revert the UPN to avoid detection. Set-ADUser low -UserPrincipalName low. The certificate is already issued and remains valid for its full lifetime. 7. Authenticate. certipy auth -pfx administrator.pfx -dc-ip <dc>. The KDC, running in Compatibility mode, falls back to UPN mapping, finds the administrator account, and issues a TGT for the Domain Administrator. With UnPAC-the-hash the attacker also recovers the NT hash. 8. Persistence and lateral movement. The TGT is used for DCSync, krbtgt extraction, or Golden Ticket forging. The issued certificate survives password resets and persists until its NotAfter date or explicit revocation. 9. Optional chain with ESC9. If the CA also has CT_FLAG_NO_SECURITY_EXTENSION on a template (ESC9), the attacker does not even need DisableExtensionList; ESC16 simply scales the same primitive to every template the CA issues.

Cómo lo evalúa Guerrilla

Guerrilla discovers CAs by querying the forest configuration NC for (objectClass=pKIEnrollmentService) under CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration. For each CA it extracts dNSHostName and the CN, then queries the policy module via: - certutil.exe -config "<dNSHostName>\<CA-Name>" -getreg policy\DisableExtensionList (preferred, uses MS-RRP / MS-WCCE from any domain-joined host), or - direct remote registry against HKLM\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA-Name>\PolicyModules\<ModuleId>\DisableExtensionList using Get-ItemProperty over WinRM where available. The REG_MULTI_SZ is scanned for 1.3.6.1.4.1.311.25.2. In parallel the check enumerates DCs via (objectClass=nTDSDSA) under Sites and reads HKLM\SYSTEM\CurrentControlSet\Services\Kdc\StrongCertificateBindingEnforcement on each. The finding fires only when at least one CA has the OID suppressed AND at least one DC has the registry value at 0, 1, or absent. The check also surfaces template-level enablers: it pulls msPKI-Certificate-Name-Flag, pKIExtendedKeyUsage, and the nTSecurityDescriptor of every published template under CN=Certificate Templates,CN=Public Key Services and reports templates where low-privileged principals can enroll for a Client Authentication-capable certificate with enrollee-supplied subject or UPN-driven SAN. No agent install, AD CS RSAT, or CA database access is required.

Valor recomendado

StrongCertificateBindingEnforcement establecido en 2; ninguna plantilla que permita un UPN en el SAN especificado por el solicitante con inscripción de bajo privilegio

Remediación

Establezca StrongCertificateBindingEnforcement en 2 en todos los controladores de dominio, en HKLM\SYSTEM\CurrentControlSet\Services\Kdc. Revise todas las plantillas que permiten firmantes especificados por el solicitante o requieren el UPN en el SAN. Restrinja la inscripción en estas plantillas a principales autorizados. Pruebe la autenticación basada en certificados tras imponer la asignación sólida a fin de identificar posibles incompatibilidades antes de la implementación completa.

Veredictos probados con fixtures

Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.

Escenarios de veredicto de ADCS-016
EscenarioVeredicto esperado
cleanPASS
known-badFAIL
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
IA-5(2), CM-6, AC-6
MITRE ATT&CK
T1649, T1556