General

Atributo userAccountControl de Active Directory explicado

Portada del artículo «Atributo userAccountControl de Active Directory explicado» de Trucos Informáticos

Si administras Active Directory, antes o después te encontrarás con un valor numérico que parece sacado de la nada: userAccountControl = 66048, 514 o 544. Es el atributo userAccountControl (UAC), un único número que resume casi todo el estado de una cuenta de usuario o de equipo: si está habilitada, si su contraseña caduca, si puede iniciar sesión sin contraseña, si usa tarjeta inteligente o si es de confianza para delegar. En esta guía aprenderás a leerlo, a decodificarlo con PowerShell, a buscar cuentas por una característica concreta y a usarlo para detectar configuraciones peligrosas.

Qué es userAccountControl y cómo funciona

El atributo guarda un número entero que es la suma de varios indicadores (flags), donde cada uno ocupa un bit distinto. Cada opción de la pestaña Cuenta de un usuario en Usuarios y equipos de Active Directory (la casilla «La contraseña nunca caduca», «La cuenta está deshabilitada»…) activa uno de esos bits. Como los valores son potencias de dos, cualquier combinación se puede representar con un único número y descomponerse después sin ambigüedad.

Por ejemplo, una cuenta de usuario normal vale 512 (NORMAL_ACCOUNT). Si la deshabilitas se le suma el indicador ACCOUNTDISABLE (2), y queda en 514. Si además marcas «La contraseña nunca caduca» (65536), pasa a ser 66050. Los indicadores son acumulativos, por eso un valor tan grande como 66048 es solo 512 + 65536: una cuenta normal, habilitada, cuya contraseña no caduca.

Tabla de indicadores

Esta es la lista de indicadores que documenta Microsoft, con su valor en hexadecimal y en decimal. Ldp.exe muestra los valores en hexadecimal, y ADSI Edit, en decimal:

IndicadorHexDecimalSignificado
SCRIPT0x00011Se ejecutará el script de inicio de sesión.
ACCOUNTDISABLE0x00022La cuenta está deshabilitada.
HOMEDIR_REQUIRED0x00088Se requiere carpeta principal.
LOCKOUT0x001016Cuenta bloqueada (ver nota más abajo).
PASSWD_NOTREQD0x002032No se requiere contraseña.
PASSWD_CANT_CHANGE0x004064El usuario no puede cambiar la contraseña (se gestiona como permiso).
ENCRYPTED_TEXT_PWD_ALLOWED0x0080128Permite almacenar la contraseña con cifrado reversible.
NORMAL_ACCOUNT0x0200512Cuenta de usuario típica.
INTERDOMAIN_TRUST_ACCOUNT0x08002048Cuenta de confianza entre dominios.
WORKSTATION_TRUST_ACCOUNT0x10004096Cuenta de equipo (estación o servidor miembro).
SERVER_TRUST_ACCOUNT0x20008192Cuenta de equipo de un controlador de dominio.
DONT_EXPIRE_PASSWORD0x1000065536La contraseña no caduca nunca.
SMARTCARD_REQUIRED0x40000262144Obliga a iniciar sesión con tarjeta inteligente.
TRUSTED_FOR_DELEGATION0x80000524288Confiable para delegación Kerberos.
NOT_DELEGATED0x1000001048576La cuenta no se delega aunque el servicio sea de confianza.
USE_DES_KEY_ONLY0x2000002097152Solo cifrado DES para las claves de Kerberos.
DONT_REQ_PREAUTH0x4000004194304No requiere preautenticación Kerberos.
PASSWORD_EXPIRED0x8000008388608La contraseña ha caducado.
TRUSTED_TO_AUTH_FOR_DELEGATION0x100000016777216Habilitada para delegación (sensible a la seguridad).
PARTIAL_SECRETS_ACCOUNT0x0400000067108864Cuenta de un controlador de solo lectura (RODC).

Una nota importante de la documentación: en dominios con nivel funcional de Windows Server 2003 o superior, los indicadores LOCKOUT y PASSWORD_EXPIRED se sustituyeron por un atributo calculado distinto, msDS-User-Account-Control-Computed. Por eso no debes confiar en el bit 16 de userAccountControl para saber si una cuenta está bloqueada; usa en su lugar la propiedad LockedOut de PowerShell (lo vemos más abajo).

Valores comunes y qué significan

  • 512: usuario normal, habilitado.
  • 514: usuario normal, deshabilitado (512 + 2).
  • 544: usuario habilitado que no requiere contraseña (512 + 32). Es una configuración que conviene revisar.
  • 546: usuario deshabilitado sin contraseña requerida (512 + 2 + 32).
  • 66048: usuario habilitado con la contraseña sin caducidad (512 + 65536).
  • 66050: usuario deshabilitado con contraseña sin caducidad (512 + 2 + 65536).
  • 262656: usuario habilitado que requiere tarjeta inteligente (512 + 262144).
  • 4096: cuenta de equipo (estación de trabajo o servidor miembro).
  • 532480: cuenta de equipo de un controlador de dominio (8192 + 524288).

Cómo leer el atributo con PowerShell

Con el módulo de Active Directory instalado puedes leerlo directamente:

Get-ADUser -Identity l.gomez -Properties userAccountControl | Select-Object Name, userAccountControl

# Y las propiedades ya calculadas, más fáciles de interpretar
Get-ADUser -Identity l.gomez -Properties Enabled, LockedOut, PasswordExpired, PasswordNeverExpires, PasswordNotRequired |
    Select-Object Name, Enabled, LockedOut, PasswordExpired, PasswordNeverExpires, PasswordNotRequired

Para ver qué indicadores activos tiene un valor, puedes usar una pequeña función que descomponga el número con el operador -band (AND bit a bit):

function Get-UacFlags {
    param([int]$Valor)
    $banderas = [ordered]@{
        SCRIPT = 1; ACCOUNTDISABLE = 2; HOMEDIR_REQUIRED = 8; PASSWD_NOTREQD = 32
        PASSWD_CANT_CHANGE = 64; ENCRYPTED_TEXT_PWD_ALLOWED = 128; NORMAL_ACCOUNT = 512
        INTERDOMAIN_TRUST_ACCOUNT = 2048; WORKSTATION_TRUST_ACCOUNT = 4096; SERVER_TRUST_ACCOUNT = 8192
        DONT_EXPIRE_PASSWORD = 65536; SMARTCARD_REQUIRED = 262144; TRUSTED_FOR_DELEGATION = 524288
        NOT_DELEGATED = 1048576; USE_DES_KEY_ONLY = 2097152; DONT_REQ_PREAUTH = 4194304
        TRUSTED_TO_AUTH_FOR_DELEGATION = 16777216; PARTIAL_SECRETS_ACCOUNT = 67108864
    }
    $banderas.GetEnumerator() | Where-Object { $Valor -band $_.Value } | ForEach-Object Key
}

Get-UacFlags 66050     # NORMAL_ACCOUNT, ACCOUNTDISABLE, DONT_EXPIRE_PASSWORD

Cómo buscar cuentas por un indicador

Aquí está el uso más práctico del atributo: encontrar todas las cuentas que tienen un indicador concreto. Para ello se usa una regla de coincidencia bit a bit de LDAP, cuyo identificador es 1.2.840.113556.1.4.803 (AND) y 1.2.840.113556.1.4.804 (OR):

# Cuentas deshabilitadas (bit 2)
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' | Select-Object Name, SamAccountName

# Cuentas cuya contraseña no caduca (bit 65536)
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=65536)' | Select-Object Name, SamAccountName

# Con la sintaxis de filtro de PowerShell
Get-ADUser -Filter 'userAccountControl -band 65536' | Select-Object Name

Las cuentas deshabilitadas que no deberían seguir ahí, las que tienen la contraseña sin caducidad y las que no requieren contraseña son, en conjunto, una de las primeras revisiones de higiene del directorio. Si quieres aprender a gestionar las bajas y el ciclo de vida de las cuentas, consulta la guía de usuarios y grupos de Active Directory.

Cómo modificar el atributo (con cuidado)

Siempre que puedas, usa los cmdlets específicos en lugar de editar el número a mano: son más legibles y evitan errores.

Disable-ADAccount -Identity l.gomez
Enable-ADAccount  -Identity l.gomez
Set-ADUser -Identity l.gomez -PasswordNeverExpires $false
Set-ADAccountControl -Identity l.gomez -DoesNotRequirePreAuth $false

Si necesitas cambiar un bit concreto de forma directa, hazlo con operaciones de bits para no pisar los demás: leer, modificar solo ese bit y volver a escribir.

$u = Get-ADUser -Identity l.gomez -Properties userAccountControl
# Activar "la contraseña nunca caduca" (OR bit a bit)
Set-ADUser -Identity $u -Replace @{ userAccountControl = ($u.userAccountControl -bor 65536) }
# Desactivarlo (AND con el complemento)
Set-ADUser -Identity $u -Replace @{ userAccountControl = ($u.userAccountControl -band (-bnot 65536)) }

Haz siempre una prueba con una cuenta de laboratorio, y recuerda que algunos valores solo los puede establecer el propio servicio de directorio.

Indicadores que debes vigilar por seguridad

  • DONT_REQ_PREAUTH (4194304): permite solicitar un ticket sin demostrar la contraseña, y es la base del ataque conocido como AS-REP roasting, que permite intentar romper la contraseña sin conexión. Solo debería estar activo en casos muy justificados.
  • TRUSTED_FOR_DELEGATION (524288): la delegación sin restricciones permite a un servicio suplantar a los usuarios que se conectan a él. Fuera de los controladores de dominio, conviene revisarla y sustituirla por delegación restringida.
  • PASSWD_NOTREQD (32): cuentas que pueden tener contraseña vacía. Debe revisarse cada una.
  • DONT_EXPIRE_PASSWORD (65536): aceptable en cuentas de servicio justificadas (idealmente cuentas administradas de grupo), no en usuarios normales.
  • ENCRYPTED_TEXT_PWD_ALLOWED (128): almacena la contraseña con cifrado reversible; solo se debería usar si una aplicación antigua lo exige.
  • USE_DES_KEY_ONLY (2097152): restringe a un cifrado obsoleto y débil.
# Cuentas que no requieren preautenticación Kerberos
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' | Select-Object Name, SamAccountName

# Cuentas con delegación sin restricciones (excluyendo controladores de dominio)
Get-ADObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' |
    Where-Object { $_.DistinguishedName -notlike '*OU=Domain Controllers*' } | Select-Object Name, ObjectClass

Estos informes conviene generarlos de forma periódica, por ejemplo con una tarea programada; en la guía de tareas programadas con PowerShell verás cómo hacerlo. Y si necesitas repasar el uso de Get-ADUser y los filtros, consulta los 10 comandos de PowerShell imprescindibles.

Cuentas de equipo y controladores de dominio

El atributo también existe en los objetos de equipo. Los valores por defecto que documenta Microsoft son 4096 para una estación de trabajo o servidor miembro, y 532480 (0x82000) para un controlador de dominio, que es la suma de SERVER_TRUST_ACCOUNT (8192) y TRUSTED_FOR_DELEGATION (524288). Un controlador de solo lectura (RODC) añade además el indicador PARTIAL_SECRETS_ACCOUNT.

Preguntas frecuentes

¿Por qué el valor de una cuenta bloqueada no cambia en userAccountControl?

Porque el bloqueo de cuenta se almacena en otro atributo (lockoutTime) y se expone mediante msDS-User-Account-Control-Computed. Para consultarlo, usa Get-ADUser -Properties LockedOut o Search-ADAccount -LockedOut.

¿Qué diferencia hay entre 512 y 544?

544 es 512 más 32: la cuenta es normal pero tiene el indicador PASSWD_NOTREQD, lo que significa que puede existir sin contraseña. Es una diferencia importante desde el punto de vista de la seguridad.

¿Cómo sé qué indicadores tiene un valor cualquiera?

Descomponlo en potencias de dos o usa la función Get-UacFlags de esta guía: va comprobando cada bit con -band.

Conclusión

El atributo userAccountControl es la suma de indicadores independientes, por lo que cada valor se puede descomponer siempre de una única manera. Aprende los más comunes (512, 514, 544, 66048), usa la regla de bits de LDAP para buscar cuentas por un indicador y revisa con regularidad las configuraciones sensibles, como la falta de preautenticación o la delegación sin restricciones. Y para cambiarlo, prefiere los cmdlets específicos antes que editar el número a mano.

Guías relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *