🏢Active DirectoryPasswordConfig

Contraseña en texto claro y cifrado reversible Active Directory: la trampa del atributo userPassword explicada

Dos configuraciones de Active Directory pueden dejar contraseñas recuperables en texto claro: el atributo userPassword y el flag UAC de cifrado reversible. Así se detectan y corrigen ambas.

Younes AZABARPor Younes AZABAR10 min de lectura
Contraseña en texto claro y cifrado reversible Active Directory: la trampa del atributo userPassword explicada

El problema de la contraseña en texto claro y cifrado reversible Active Directory

Contraseña en texto claro y cifrado reversible Active Directory: esta exposición es una de las pocas configuraciones incorrectas que se saltan por completo el flujo habitual de un atacante — sin hash que crackear, sin ticket que reenviar, solo una contraseña literal alojada en el directorio, a diferencia de un hash NT robado y reutilizado mediante Pass-the-Hash. Active Directory está diseñado para no almacenar nunca una copia utilizable de una contraseña: cada valor unicodePwd se hashea de forma unidireccional (hash NT y claves Kerberos de largo plazo) antes de llegar a la base de datos, y el atributo en sí no puede leerse de vuelta mediante LDAP. La documentación del protocolo MS-SAMR de Microsoft es explícita sobre el único caso que rompe esta garantía: el almacenamiento de la contraseña en texto claro para un objeto solo se configura cuando el valor Effective-PasswordReversibleEncryptionEnabled de la cuenta está activado, o cuando su atributo userAccountControl contiene el bit ENCRYPTED_TEXT_PWD_ALLOWED (0x0080) — tras lo cual el siguiente establecimiento o cambio de contraseña escribe una copia descifrable en supplementalCredentials.

Este artículo cubre dos modos de fallo distintos, a nivel de atributo, que terminan ambos con un atacante en posesión de una credencial en claro utilizable directamente desde el directorio:

  • El atributo LDAP heredado userPassword, que algunos entornos rellenan directamente con una cadena literal.
  • El flag de cifrado reversible en userAccountControl, que indica a cada controlador de dominio que conserve una copia descifrable de la contraseña junto a los hashes habituales.

Ambos están marcados como Críticos en el catálogo de auditoría de etc-collector (PASSWORD_CLEARTEXT_STORAGE, REVERSIBLE_ENCRYPTION) porque comprometer cualquiera de los dos le da a un atacante la contraseña literal, no solo un hash que crackear o reenviar. Esa distinción importa operativamente: un hash crackeado o una sesión reenviada pueden contenerse rotando una credencial y revisando qué tocó, pero una contraseña en claro recuperada suele reutilizarse en otros sitios — cuentas personales, otros sistemas, otros dominios — así que el radio de impacto de cualquiera de las dos exposiciones se extiende mucho más allá del objeto de AD donde se encontró.

⚠️

⚠️ Advertencia: este es un mecanismo distinto de las credenciales en texto claro de WDigest (que expone contraseñas en la memoria de LSASS en un host comprometido) y de las contraseñas dejadas en los campos de descripción de AD (metadatos de texto libre, no un atributo de almacenamiento de contraseñas). Los dos mecanismos siguientes viven en la propia lógica de gestión de contraseñas del directorio, no en un canal secundario.

Cómo funciona

El atributo userPassword

userPassword es un atributo LDAP estándar (definido fuera del esquema de Microsoft, en los estándares de directorio derivados de la RFC 4519) que Active Directory también reconoce bajo ciertas condiciones. Según MS-ADTS §3.1.1.3.1.5.2, AD solo permite a los clientes escribir y usar userPassword para establecer la contraseña de una cuenta cuando:

  • el DC funciona como AD LDS, o
  • el DC es AD DS, el nivel funcional del dominio es Windows Server 2003 o superior, y
  • la heurística fUserPwdSupport en el atributo dSHeuristics está activada.

Cuando esta heurística está desactivada (el valor por defecto en AD DS), userPassword es simplemente un atributo ordinario, sin indexar, sin semántica especial — que es exactamente la trampa: muchos administradores y scripts de aprovisionamiento (herramientas de migración LDAP, jobs de sincronización de RRHH, integraciones Unix/LDAP heredadas) todavía escriben una cadena de contraseña literal en userPassword por costumbre o por necesidad de interoperabilidad. A diferencia de unicodePwd, este atributo es legible por cualquiera con derechos de lectura genérica sobre el objeto, así que una simple búsqueda LDAP (userPassword=*) puede volcar cada valor en claro que se haya escrito ahí alguna vez — sin necesidad de escalada de privilegios, sin crackeo de hashes, sin nada que reenviar.

ldapsearch -x -H ldap://dc01.corp.local -D "[email protected]" -W \
  -b "DC=corp,DC=local" "(userPassword=*)" sAMAccountName userPassword

El flag UAC de cifrado reversible

El segundo mecanismo es el bit ENCRYPTED_TEXT_PWD_ALLOWED (decimal 128 / hex 0x0080) dentro de userAccountControl, expuesto en el objeto de usuario como el atributo ms-DS-User-Encrypted-Text-Password-Allowed y, en el módulo de PowerShell de AD, como la propiedad de cuenta AllowReversiblePasswordEncryption. Activarlo no escribe por sí mismo una contraseña en claro — cambia lo que ocurre en el siguiente establecimiento o cambio de contraseña: AD almacena la nueva contraseña en supplementalCredentials en una forma descifrable con la propia clave de cifrado del dominio, además de los hashes habituales.

Este flag existe para dar soporte a protocolos de autenticación heredados que necesitan la contraseña real para calcular un challenge-response, principalmente CHAP para RADIUS/IAS de acceso telefónico y VPN, y despliegues antiguos de IIS Digest Authentication. La propia documentación de Microsoft sobre políticas de seguridad es directa sobre el compromiso que implica: activarlo «es esencialmente lo mismo que almacenar versiones en texto plano de las contraseñas», y nunca debería activarse a nivel de dominio salvo que una aplicación lo requiera de verdad.

Si un dominio necesita esto para un pequeño conjunto de cuentas de servicio heredadas, acotar el alcance importa: una Fine-Grained Password Policy (Password Settings Object) puede establecer msDS-PasswordReversibleEncryptionEnabled únicamente en la OU o el grupo que lo necesite, en lugar de activar el ajuste «Almacenar contraseñas con cifrado reversible» en la Default Domain Policy para todas las cuentas del dominio.

🚨 Peligro: MITRE ATT&CK T1556.005 documenta esto como una técnica adversaria activa, no solo como una configuración incorrecta heredada: con derechos suficientes, un atacante puede ejecutar Set-ADUser -AllowReversiblePasswordEncryption $true contra una cuenta objetivo, esperar (o forzar) un restablecimiento de contraseña, y luego recuperar la contraseña en claro desde la siguiente credencial almacenada de la cuenta — convirtiendo un simple derecho de escritura en una puerta trasera permanente de recolección de credenciales que sobrevive a la rotación de contraseñas.

Por qué esto sigue apareciendo en entornos modernos

Ninguno de los dos mecanismos es una reliquia que solo afecte a dominios de la era Windows 2000. userPassword reaparece cada vez que una organización ejecuta herramientas de sincronización de identidad originalmente construidas para OpenLDAP u otro directorio RFC-4519 y apuntadas a Active Directory sin ajustes — el job de sincronización escribe el campo para el que fue construido, y nada en AD lo impide si dSHeuristics lo permite. El cifrado reversible reaparece de la misma manera: un dispositivo RADIUS, un concentrador VPN heredado, o una vieja aplicación de intranet que usa IIS Digest Authentication se configura una vez, la política a nivel de dominio se activa para que funcione, y el ajuste sobrevive tranquilamente a la aplicación que lo necesitaba — a menudo durante años, en todas las cuentas del dominio, mucho después de que nadie recuerde por qué está ahí.

Ambos casos comparten la misma causa raíz: el ajuste es un interruptor a nivel de dominio u objeto, pero la necesidad real es casi siempre estrecha — una aplicación, una integración, un protocolo heredado. Nada obliga a una revisión cuando la dependencia desaparece, así que la exposición persiste como pura deuda técnica hasta que una auditoría, o un atacante, la encuentra. Merece un lugar en la misma lista de vigilancia que las configuraciones incorrectas de seguridad de Active Directory más comunes que sobreviven años después de su justificación original.

Detección

IndicadorID de eventoFuenteDescripción
Atributo userPassword con valorConsulta LDAP(userPassword=*) devuelve algún objeto; el atributo es legible sin más, no se necesita escalada de privilegios
dSHeuristics permite escrituras en userPasswordConsulta LDAP en el Configuration NCEl carácter fUserPwdSupport en CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,... no es 0/2
userAccountControl tiene el bit 128 activado4738Registro de seguridad (DC)Los cambios de «User Account Control» listan Encrypted Text Password Allowed; también se dispara en 4720 al crear una cuenta con el flag ya activado
La cuenta tiene AllowReversiblePasswordEncryption = TrueAD PowerShell / filtro LDAP bitwiseExposición permanente, independiente de cuándo se activó el flag
# Cuentas con cifrado reversible actualmente activado
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} `
  -Properties AllowReversiblePasswordEncryption, PasswordLastSet |
  Select-Object SamAccountName, PasswordLastSet

# Filtro LDAP bitwise-AND equivalente (matching-rule OID 1.2.840.113556.1.4.803)
Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=128)" `
  -Properties userAccountControl | Select-Object SamAccountName
💡

💡 Consejo: Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} solo muestra el estado actual. Alerte también sobre el Event ID 4738, para que un cambio del flag en una cuenta privilegiada se detecte en el momento en que ocurre, no semanas después en el siguiente ciclo de auditoría.

Para userPassword, al ser un atributo genérico que AD no indexa ni protege especialmente por defecto, un barrido LDAP programado en busca de (userPassword=*) en todo el dominio es la única forma fiable de detectarlo; no existe un evento de seguridad dedicado para la escritura en este atributo, así que las reauditorías periódicas importan tanto como el barrido inicial.

Remediación

💡

💡 Solución rápida: desactive «Almacenar contraseñas con cifrado reversible» en la Default Domain Policy salvo que pueda nombrar la aplicación heredada específica que lo requiere.

  1. Audite antes de tocar nada. Ejecute ambas consultas anteriores en todo el dominio y registre cada resultado — desactivar el flag o vaciar userPassword fuerza un cambio de contraseña para esa cuenta, así que planifique la rotación con los propietarios de la cuenta de antemano.
  2. Desactive el cifrado reversible a nivel de dominio mediante Directiva de grupo (Configuración del equipo > Directivas > Configuración de Windows > Configuración de seguridad > Directivas de cuenta > Directiva de contraseñas > «Almacenar contraseñas con cifrado reversible» = Deshabilitado), salvo que exista una dependencia específica de CHAP/RADIUS o IIS Digest Authentication heredada.
  3. Si existe una dependencia legítima, acótela con una Fine-Grained Password Policy (msDS-PasswordReversibleEncryptionEnabled) aplicada únicamente a la OU o el grupo que ejecuta esa aplicación — nunca a nivel de dominio.
  4. Vacíe cualquier valor userPassword encontrado, y vuelva a desactivar fUserPwdSupport en dSHeuristics salvo que el DC ejecute intencionadamente AD LDS o una integración documentada lo necesite.
  5. Fuerce un restablecimiento de contraseña para cada cuenta afectada. Desactivar el flag o vaciar el atributo no elimina retroactivamente el material de credencial ya escrito en supplementalCredentials — solo el siguiente cambio de contraseña lo hace.
  6. Bloquee el acceso de escritura a userAccountControl y userPassword para usuarios estándar; ambos solo deberían ser modificables por la administración de identidad de tier-0, y cualquier concesión de GenericAll/GenericWrite que los alcance merece el mismo escrutinio que una ruta hacia Domain Admin.
  7. Conecte el Event ID 4738 a su SIEM con una alerta cuando Encrypted Text Password Allowed aparezca en la lista de atributos modificados, acotada como mínimo a cuentas privilegiadas y de servicio, y repita los barridos LDAP de forma recurrente en lugar de tratar esto como una limpieza puntual.
  8. Documente cualquier excepción restante. Si una aplicación heredada realmente sigue necesitando el cifrado reversible, registre el propietario, la fecha de revisión y el plan de retirada — una excepción no documentada es indistinguible de una excepción pasada por alto en la siguiente auditoría.

Cómo detecta esto EtcSec

El catálogo de auditoría de EtcSec sigue ambos mecanismos como comprobaciones distintas de severidad Crítica: PASSWORD_CLEARTEXT_STORAGE marca cualquier objeto donde userPassword tenga un valor, y REVERSIBLE_ENCRYPTION marca cualquier cuenta con AllowReversiblePasswordEncryption (el bit UAC ENCRYPTED_TEXT_PWD_ALLOWED) activado. Ambos se encuentran en la categoría Password junto a controles relacionados como el cumplimiento de la política de contraseñas y los secretos cPassword de GPO SYSVOL — juntos cubren el puñado de formas en que un directorio puede acabar reteniendo una contraseña que un atacante ni siquiera necesita crackear.

ℹ️

ℹ️ Nota: EtcSec comprueba automáticamente esta vulnerabilidad en cada auditoría de AD. Ejecute una auditoría gratuita para verificar que su entorno no expone ninguno de los dos flags.

Explore las páginas de identidad que apoyan este tema