🏢Active DirectoryPasswordPermissionsAccounts

Usuario AD no puede cambiar su contraseña: auditar ACE Deny

Audite las ACE Deny Change Password antes de cambiar la directiva AD. Inspeccione la DACL y restaure el cambio propio solo en cuentas aprobadas.

Younes AZABARPor Younes AZABAR12 min de lectura
Usuario AD no puede cambiar su contraseña: auditar ACE Deny

Usuario AD no puede cambiar su contraseña: ¿qué significa esta configuración?

Al investigar el caso usuario AD no puede cambiar su contraseña, inspeccione la lista de control de acceso discrecional (DACL) del usuario antes de cambiar la directiva de contraseñas del dominio. Es posible que se le haya denegado el derecho extendido Change Password. Se trata de una restricción de control de acceso al cambio de contraseña por el propio usuario, una cuestión distinta de si un administrador puede restablecerla.

Empiece por la cuenta exacta y la operación que falló. Registre si la persona intentó cambiar su propia contraseña o pidió a un operador del soporte que estableciera una nueva. Un restablecimiento administrativo correcto no demuestra que el cambio por el usuario esté permitido. Asimismo, un fallo de ese cambio no identifica por sí solo una ACE Deny como causa: todavía es necesario leer la DACL.

Esta guía examina una condición de permisos concreta, sin prescribir una nueva antigüedad o longitud de contraseña. Mantenga separada la revisión más amplia de la directiva: la seguridad de contraseñas en Active Directory cubre las directivas de dominio, la caducidad, los ajustes de cuenta y el almacenamiento de credenciales. Cambiar esos controles no sustituye a determinar qué ACE se aplican a la cuenta investigada.

Funcionamiento: permiso de cambio propio y restablecimiento administrativo

Microsoft identifica el derecho extendido User-Change-Password con el nombre para mostrar Change Password y el GUID ab721a53-1e2f-11d0-9819-00aa0040529b. Las pruebas pertinentes están en el descriptor de seguridad del objeto de usuario. No deduzca este estado mediante una prueba ordinaria de bits de userAccountControl: la condición del colector revisada aquí no utiliza ese atributo.

El procedimiento de modificación LDAP de Microsoft describe una configuración estándar con ACE específicas de objeto para dos entidades de seguridad: Everyone y SELF. La denegación del permiso utiliza ADS_ACETYPE_ACCESS_DENIED_OBJECT; su concesión utiliza el tipo Allow específico de objeto correspondiente.

Elemento que registrarValor para esta revisiónPor qué importa
Tipo de objetoab721a53-1e2f-11d0-9819-00aa0040529bIdentifica Change Password en lugar de otro permiso de objeto
Entidad EveryoneS-1-1-0Una entidad aceptada por el predicado del colector
Entidad SELFS-1-5-10La otra entidad aceptada por ese predicado
Sentido de la ACEDenyUna entrada Allow no satisface el detector
DestinoNombre distintivo exacto del usuarioPermite asociar la prueba con la cuenta correcta

Conserve la distinción entre la configuración documentada y la condición del detector. El ejemplo de lectura de Microsoft reconoce el estado estándar de denegación cuando las ACE de ambas entidades son Deny. El colector utiliza una condición OR: basta una ACE Deny coincidente para cualquiera de las entidades para satisfacer su predicado. Registre una única ACE coincidente como una condición de una sola entidad que requiere revisión; no la describa como la configuración completa de dos ACE del ejemplo de Microsoft.

El restablecimiento administrativo de contraseña es una cuestión de permisos distinta. El artículo sobre ResetNightmare trata de un exploit de una operación de contraseña Kerberos y de su distinción respecto de los derechos delegados Reset Password. Aporta contexto para separar las operaciones, no pruebas de que esta restricción de cambio propio cause ese exploit. Evalúe esa exposición separada mediante los requisitos previos y las indicaciones de remediación del artículo enlazado.

Detección: leer la DACL de forma independiente

Paso 1: elegir una cuenta y conservar el contexto

Utilice el nombre distintivo de la cuenta, en lugar de un nombre para mostrar supuesto. Anote el propietario, el estado habilitado o deshabilitado, el propósito empresarial, el controlador de dominio consultado y la hora de inspección. Incluya las cuentas deshabilitadas en el inventario si lo concilia con este predicado del colector: Detect() no tiene filtro Disabled. El estado de la cuenta puede afectar a la prioridad de remediación, pero no debe eliminar silenciosamente una entrada de la revisión de permisos.

Para una identidad de servicio, identifique quién se encarga de los cambios de contraseña antes de clasificar la restricción como no deseada. La cuestión es si la restricción es intencionada y está respaldada por un proceso con un responsable. La etiqueta de cuenta de servicio por sí sola no es prueba suficiente para una excepción.

Paso 2: recuperar y filtrar las reglas de acceso

El procedimiento de lectura LDAP de Microsoft lee ntSecurityDescriptor, obtiene su DACL y examina ObjectType, la entidad de seguridad y AceType. También advierte que los nombres de las entidades están localizados. Compare los SID conocidos en lugar de fijar en el código nombres de cuentas en inglés.

La siguiente adaptación PowerShell de solo lectura utiliza ADSI mediante .NET en una estación de administración Windows. Sustituya el controlador de dominio y el DN de ejemplo por valores verificados. Lee directamente el descriptor de seguridad del directorio, fuera del analizador de ACL del colector. Estos comandos no se han ejecutado contra un dominio para este artículo.

Add-Type -AssemblyName System.DirectoryServices
$dc = 'dc01.example.test'
$dn = 'CN=Example User,OU=Users,DC=example,DC=test'
$entry = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$dc/$dn"
$entry.psbase.Options.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$descriptor = $entry.psbase.ObjectSecurity
$rules = @($descriptor.GetAccessRules(
    $true, $true, [System.Security.Principal.SecurityIdentifier]
))
$changePassword = [guid]'ab721a53-1e2f-11d0-9819-00aa0040529b'
$matchingDenies = @($rules | Where-Object {
    $_.ObjectType -eq $changePassword -and
    $_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny -and
    $_.IdentityReference.Value -in @('S-1-1-0', 'S-1-5-10')
})
$matchingDenies | Select-Object IdentityReference, ObjectType,
    AccessControlType, ActiveDirectoryRights, IsInherited,
    InheritanceType, InheritanceFlags, PropagationFlags | Format-List
$entry.psbase.Dispose()

Las referencias de API documentan ObjectSecurity, SecurityMasks y GetAccessRules. Se solicitan tanto las reglas explícitas como las heredadas, y las identidades de las entidades se devuelven como SID. Mantenga disponibles las reglas sin filtrar para una revisión más amplia de la DACL; el filtro selecciona deliberadamente solo la condición de este artículo.

Si falla el enlace o la recuperación del descriptor de seguridad, conserve el error y marque la cuenta como no inspeccionada. Una DACL ilegible no es una DACL vacía. No sustituya un fallo de inspección por un resultado aparentemente correcto y limpio.

Paso 3: interpretar la forma sin exagerar el resultado

Resultado observadoQué registrarSiguiente acción
Everyone y SELF tienen entradas Deny específicas de objeto coincidentesPosible configuración de denegación para ambas entidadesConfirmar el derecho de acceso de control y la aplicabilidad de las reglas, y revisar la intención antes de un cambio dirigido
Solo una entidad tiene una ACE Deny coincidenteCondición de una sola entidad aceptada por el predicado del detectorInspeccionar toda la DACL; no descartarla porque falte la otra entrada
No se devuelve ninguna ACE Deny coincidente tras una lectura correctaNo se encontró esta condición específicaContinuar el diagnóstico; no es un veredicto completo de acceso efectivo ni de directiva de contraseñas
No se pudo recuperar la DACLFaltan pruebasResolver el fallo de lectura antes de sacar conclusiones

La salida incluye información sobre derechos y herencia para que el revisor pueda inspeccionar su aplicabilidad. El filtro no comprueba la máscara de acceso ni la aplicabilidad de la herencia. Antes de clasificar una pareja como la configuración estándar de Microsoft, compárela con la máscara ADS_RIGHT_DS_CONTROL_ACCESS y los indicadores de ACE del procedimiento de modificación. Es un inventario específico de ACE, no una implementación completa de la comprobación de acceso de Windows. Los permisos amplios, otras entidades y las disposiciones de ACL no estándar requieren más evaluación. No cuente dos ACE coincidentes de una cuenta como dos cuentas afectadas, ni lecturas distintas del mismo DN como identidades diferentes.

Remediación: restaurar el cambio propio solo para cuentas aprobadas (Remediation)

Paso 1: documentar la intención y el estado anterior

Asigne un responsable a cada cuenta revisada y conserve las pruebas de la DACL antes de editarla. Registre si el cambio propio debe estar disponible, quién aprobó la decisión y qué dependencia operativa debe comprobarse. Si se mantiene una restricción, documente el motivo empresarial, el equipo responsable, el procedimiento de gestión de contraseñas y el momento de revisión. Evite conceder o retirar permisos en toda una OU solo porque un usuario informó de un fallo.

Revise las reglas explícitas y heredadas antes de seleccionar la modificación. Si la restricción procede de una regla heredada, identifique su origen y la población afectada. Eleve esa decisión de alcance al responsable del directorio, en lugar de tratar un cambio en un nivel superior como una corrección de una cuenta individual.

Paso 2: realizar un cambio dirigido

Microsoft documenta CannotChangePassword en Set-ADAccountControl. Su ejemplo describe el ajuste del descriptor de seguridad del usuario. La adaptación siguiente elimina la restricción de una sola cuenta aprobada; primero previsualícela con -WhatIf.

Set-ADAccountControl -Identity 'CN=Example User,OU=Users,DC=example,DC=test' -Server 'dc01.example.test' -CannotChangePassword $false -WhatIf

Una vez aprobados el destino y el cambio, ejecute la operación sobre la cuenta individual con confirmación:

Set-ADAccountControl -Identity 'CN=Example User,OU=Users,DC=example,DC=test' -Server 'dc01.example.test' -CannotChangePassword $false -Confirm

Son adaptaciones de comandos documentadas, no comandos ejecutados durante esta revisión. Una vista previa no demuestra que la escritura posterior haya funcionado. Capture el resultado de la operación real y compruebe si hay errores antes de pasar a la validación.

Para una implementación LDAP personalizada, siga el procedimiento de modificación de Microsoft: localice las entradas Change Password de ambas entidades, cambie su AceType específico de objeto a Allow, añada las entradas que falten con la máscara de acceso de control y el indicador de tipo de objeto documentados, y escriba y confirme el descriptor de seguridad. Siga el paso de ordenación de ACL al crear entradas. No sustituya toda la DACL por una pareja mínima de reglas ni elimine permisos ajenos al problema para que la cuenta parezca conforme.

Paso 3: volver a leer y verificar la operación prevista

Después de escribir, recupere de nuevo el descriptor de seguridad y repita el procedimiento de lectura de Microsoft. Compare ambas entidades, el GUID y AceType con el estado anterior. Mantenga visibles las restricciones heredadas que queden. Una respuesta correcta del comando es un artefacto intermedio; la DACL posterior al cambio es la prueba de permisos.

Organice después una comprobación controlada del cambio propio por el propietario de la cuenta mediante el flujo habitual de cambio de contraseña. Mantenga ese resultado separado del de la DACL. Si la operación sigue fallando, investigue el error real y otros controles aplicables en lugar de alterar repetidamente la ACL o debilitar la directiva del dominio. Un restablecimiento por el soporte no es la verificación de que se ha restaurado el cambio propio.

Cómo detecta EtcSec esta condición

El identificador de catálogo de esta condición es USER_CANNOT_CHANGE_PASSWORD. En la implementación revisada de cannot-change.go, Detect() examina las entradas de ACL suministradas y selecciona aquellas con:

  • un ObjectType igual al GUID Change Password, comparado sin distinguir mayúsculas de minúsculas;
  • un AceType que contiene DENIED tras convertirlo a mayúsculas;
  • una entidad igual a Everyone S-1-1-0 o SELF S-1-5-10.

Convierte los DN de los objetos seleccionados a minúsculas en un mapa y los coteja con los DN de usuarios. Así deduplica las ACE coincidentes por DN de cuenta antes de construir la lista de usuarios afectados. El Count del hallazgo procede de esa lista y no hay filtro Disabled. Una ACE Allow no satisface el predicado, y la implementación no lee un indicador userAccountControl para establecer esta condición. Tampoco comprueba la máscara de acceso ni la aplicabilidad de la herencia, por lo que una coincidencia del predicado no es por sí sola un veredicto completo de acceso efectivo.

El límite de la recopilación es la limitación actual. En public/internal/providers/ldap/acl_parser.go, parseACE() solo acepta los tipos de ACE ACCESS_ALLOWED y ACCESS_ALLOWED_OBJECT. Los demás tipos devuelven nil, incluidas las ACE Deny necesarias aquí. Un predicado correcto sobre las entradas suministradas no demuestra que la detección funcione a través de la vía de recopilación LDAP. Este artículo no afirma haber probado el colector de extremo a extremo ni haberlo validado en un dominio real.

Qué conservar en el registro de revisión

Para cada cuenta, conserve el DN exacto, el controlador consultado, la marca temporal, los SID coincidentes de las entidades, ObjectType, el sentido Deny o Allow, los derechos y el contexto de herencia. Guarde los errores de inspección en lugar de descartar lecturas fallidas. Asocie los registros anteriores y posteriores con la misma identidad, junto con la aprobación del cambio o el responsable de la excepción.

La decisión de cierre debe indicar qué se ha establecido: una restricción mantenida con un motivo documentado, un permiso cambiado y releído de forma independiente, o una investigación adicional que sigue abierta. Registre un resultado funcional de cambio propio solo cuando esa comprobación se haya realizado realmente. No convierta esta revisión de fuentes, un ejemplo de comando, una operación de restablecimiento o un recuento cero del colector en prueba de una rotación correcta por el propio usuario.

Fuentes

Explore las páginas de identidad que apoyan este tema