Saltar al contenido
03 · DelegaciónParte 2 de 4Intermedio

Eliminar la delegación sin restricciones en servidores AD

Encuentre las cuentas no DC con delegación sin restricciones, identifique qué depende de ellas y migre a delegación restringida o RBCD sin interrupciones.

Florian Amette8 min de lectura

Un servidor de confianza para la delegación sin restricciones conserva una copia del TGT de Kerberos de cada usuario que se autentica ante él. Quien obtenga derechos de administrador local en ese servidor puede extraer esos tickets y reutilizarlos en cualquier parte del dominio, y con las técnicas de coerción de autenticación (PrinterBug, PetitPotam y similares) un atacante ni siquiera tiene que esperar a que se conecte un administrador: puede hacer que un controlador de dominio se autentique ante el host y capturar el propio TGT del DC. A partir de ahí, DCSync está a un solo comando.

La guía principal sobre delegación explica los tres modelos de delegación y cómo inventariarlos. Esta guía profundiza en la parte que paraliza la mayoría de los proyectos: averiguar por qué un servidor tiene el indicador, demostrar si algo lo usa realmente y sustituirlo por una alternativa acotada sin romper la aplicación que lo justificó hace diez años.

Medir: construir el inventario exacto

El indicador es el bit 0x80000 (TRUSTED_FOR_DELEGATION, 524288 en decimal) de userAccountControl. Consúltelo con un filtro LDAP bit a bit para detectar equipos, usuarios y cuentas de servicio administradas en una sola pasada, y después excluya los DC grabables por su grupo principal (516).

PowerShell
Import-Module ActiveDirectory

$filter = '(userAccountControl:1.2.840.113556.1.4.803:=524288)'
Get-ADObject -LDAPFilter $filter -Properties samAccountName, objectClass, primaryGroupID,
        servicePrincipalName, operatingSystem, whenChanged, lastLogonTimestamp |
    Where-Object { $_.primaryGroupID -ne 516 } |
    Select-Object samAccountName, objectClass, operatingSystem, whenChanged,
        @{n='LastLogon';e={[datetime]::FromFileTime($_.lastLogonTimestamp)}},
        @{n='SPNs';e={$_.servicePrincipalName -join '; '}} |
    Sort-Object objectClass, samAccountName |
    Export-Csv .\unconstrained-delegation.csv -NoTypeInformation

Ejecútelo en todos los dominios del bosque: el indicador es por cuenta, y un dominio secundario con un servidor de archivos olvidado es tan útil para un atacante como la raíz. Para cada resultado, registre el responsable, las aplicaciones que aloja y la fecha en que se estableció el indicador. whenChanged es solo un indicio; si tiene habilitada la auditoría del evento 5136 sobre los objetos de equipo (consulte auditoría y detección en AD), busque cambios en userAccountControl en ese objeto para encontrar la fecha real y la cuenta que hizo el cambio.

Anote también qué cuentas están obsoletas. Un objeto de equipo deshabilitado o inactivo desde hace tiempo con el indicador es la victoria más fácil: nada puede depender de él, así que elimine el indicador y después deshabilite o borre el objeto mediante su proceso habitual de ciclo de vida.

Auditar: demostrar qué delega realmente

Que el indicador esté activo no significa que algo dependa de él. Muchos servidores lo recibieron como solución general durante alguna antigua sesión de diagnóstico. Necesita evidencias desde dos lados.

En el servidor: inicios de sesión con suplantación de nivel de delegación

El evento 4624 en Windows Server 2016 y posteriores incluye un campo ImpersonationLevel. Cuando un cliente reenvía su TGT al servidor, el inicio de sesión se registra con el nivel de suplantación Delegation (%%1840). Recopílelos durante una o dos semanas, incluyendo un cierre de mes o un ciclo de procesos por lotes si la aplicación lo tiene.

PowerShell
# Ejecutar en el servidor candidato (o consultarlo en remoto con -ComputerName)
$xpath = "*[System[EventID=4624] and EventData[Data[@Name='ImpersonationLevel']='%%1840']]"
Get-WinEvent -LogName Security -FilterXPath $xpath -MaxEvents 5000 |
    ForEach-Object {
        $x = [xml]$_.ToXml()
        $d = @{}; $x.Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
        [PSCustomObject]@{
            Time        = $_.TimeCreated
            User        = "$($d.TargetDomainName)\$($d.TargetUserName)"
            LogonType   = $d.LogonType
            Process     = $d.ProcessName
            SourceIP    = $d.IpAddress
        }
    } | Group-Object User, Process | Sort-Object Count -Descending |
    Select-Object Count, Name

Los inicios de sesión de nivel de delegación de administradores interactivos (RDP, consola) no demuestran una necesidad de la aplicación; son simplemente administradores exponiendo sus TGT. Los inicios de sesión de red (tipo 3) gestionados por w3wp.exe, sqlservr.exe o un servicio de negocio son los que hay que investigar.

En la aplicación: ¿adónde va el segundo salto?

Para cada proceso que recibe inicios de sesión delegados, identifique el back-end con el que se comunica como el usuario: un recurso compartido, una instancia SQL, una API HTTP, otro directorio LDAP. Pregunte al responsable de la aplicación, lea la configuración (web.config con <identity impersonate="true" />, orígenes de datos de SSRS configurados con «Windows integrated security», servidores vinculados de SQL que usan «Be made using the login's current security context») y confírmelo con una traza de red si es necesario. El resultado de este paso es una lista corta de SPN de destino, como cifs/fs01.corp.example.com o MSSQLSvc/sql01.corp.example.com:1433.

Si el servidor no muestra inicios de sesión de red de nivel de delegación procedentes de procesos de servicio durante todo el periodo, es casi seguro que no necesita delegación en absoluto.

Aplicar: eliminar o sustituir el indicador

Servidores sin dependencia

Elimine el indicador y siga adelante. Configurar la delegación (establecer el indicador o editar msDS-AllowedToDelegateTo) requiere SeEnableDelegationPrivilege en los controladores de dominio, que de forma predeterminada solo tienen los Administrators de los DC, así que ejecute estos cambios desde una sesión de administración Tier 0.

PowerShell
Set-ADComputer -Identity FS-LEGACY01 -TrustedForDelegation $false
# Para una cuenta de servicio basada en usuario
Set-ADAccountControl -Identity svc-legacyapp -TrustedForDelegation $false

Los tickets Kerberos existentes en el servidor conservan sus TGT reenviados hasta que caducan, así que planifique un reinicio del servidor en la misma ventana de cambios. Esto purga los tickets almacenados en LSASS y garantiza que nada siga funcionando silenciosamente con credenciales antiguas, lo que ocultaría una dependencia real hasta el día siguiente.

Servidores con un doble salto real

Sustituya la delegación sin restricciones por un modelo acotado. Tiene dos opciones, tratadas en profundidad en delegación restringida y RBCD de forma segura:

  • Delegación restringida de Kerberos (KCD), configurada en la cuenta del front-end mediante msDS-AllowedToDelegateTo. Use la variante «Kerberos only» siempre que los usuarios lleguen al front-end con Kerberos; la transición de protocolo solo es necesaria cuando se autentican con formularios, certificados o NTLM.
  • Delegación restringida basada en recursos, configurada en el back-end mediante msDS-AllowedToActOnBehalfOfOtherIdentity. Útil cuando el back-end está en otro dominio o cuando el responsable del back-end debe controlar quién puede delegar en él.
PowerShell
# Opción 1: KCD, solo Kerberos, desde WEB01 al recurso compartido y la instancia SQL que necesita
Set-ADComputer -Identity WEB01 -TrustedForDelegation $false
Set-ADComputer -Identity WEB01 -Add @{
    'msDS-AllowedToDelegateTo' = @(
        'cifs/fs01.corp.example.com', 'cifs/fs01',
        'MSSQLSvc/sql01.corp.example.com:1433'
    )
}

# Opción 2: RBCD, el back-end confía en el front-end
Set-ADComputer -Identity SQL01 -PrincipalsAllowedToDelegateToAccount (Get-ADComputer WEB01)

Si la aplicación se ejecuta con una cuenta de servicio de dominio en lugar de la cuenta de equipo, configure la delegación en esa cuenta y aproveche la ocasión para migrarla a una gMSA (consulte el hardening de cuentas de servicio). La delegación configurada en una cuenta de usuario con contraseña estática es un control más débil que la misma configuración en una cuenta administrada.

Aplique el cambio servidor por servidor, reinicie y pruebe el doble salto como un usuario normal. Conserve el valor anterior de userAccountControl en el registro de cambio para que la reversión sea un único comando.

Dependencias entre bosques

Desde las actualizaciones de Windows de julio de 2019, la delegación de TGT a través de confianzas de bosque está deshabilitada de forma predeterminada (el atributo de confianza que se controla con netdom trust <trust> /domain:<forest> /EnableTGTDelegation:No). Si una aplicación antigua dependía de la delegación sin restricciones para usuarios procedentes de un bosque de confianza, ya se ha roto o se ha rediseñado. No vuelva a habilitar la delegación de TGT en la confianza para rescatarla; use en su lugar RBCD, que funciona a través de los límites de confianza. La guía de hardening de confianzas y bosques trata el lado de la confianza.

Controles compensatorios mientras dura la migración

Algunos servidores tardarán meses en corregirse. Hasta entonces, reduzca lo que pueden recolectar:

  • Añada todas las cuentas de administración Tier 0 y Tier 1 a Protected Users o active "Account is sensitive and cannot be delegated". Así sus TGT nunca se reenvían al servidor.
  • Detenga el Print Spooler en los controladores de dominio y aplique las mitigaciones de coerción de bloquear la coerción de autenticación, lo que elimina el paso de «hacer que el DC se conecte a mí».
  • Trate los servidores restantes como Tier 0 en su modelo de administración: restrinja quién es administrador local y no permita que las cuentas de Tier 1 o del service desk inicien sesión en ellos.

Verificar

Vuelva a ejecutar la consulta de inventario en todos los dominios. Los únicos resultados deben ser los DC grabables (ya filtrados) y una lista de excepciones documentada explícitamente que se reduzca cada trimestre.

PowerShell
Get-ADObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' `
    -Properties primaryGroupID |
    Where-Object { $_.primaryGroupID -ne 516 } |
    Measure-Object | Select-Object Count

Después, confirme que nada vuelve a introducir el indicador. Habilite la auditoría de cambios de userAccountControl en los objetos de equipo y de usuario y genere una alerta ante cualquier evento 4742 (equipo modificado) o 4738 (usuario modificado) cuyo campo User Account Control muestre "'Trusted For Delegation' - Enabled" en un servidor que no sea DC. Las nuevas compilaciones de servidores deben comprobarse con la misma consulta en su canalización de aprovisionamiento, y es una de las comprobaciones de una evaluación de PingCastle, así que el análisis periódico detecta las desviaciones.

Por último, pruebe de extremo a extremo las aplicaciones migradas como usuario estándar, desde un cliente sin tickets en caché, incluidos los informes programados o los trabajos por lotes que se ejecutan por la noche.

Qué rompe

  • Las aplicaciones IIS con autenticación de Windows y suplantación que leen una ruta UNC, consultan SQL o llaman a otra API protegida por Kerberos como el usuario fallan con errores de «acceso denegado» o de inicio de sesión anónimo en el segundo salto hasta que se configura KCD o RBCD con los SPN correctos.
  • Los orígenes de datos de SSRS y SharePoint configurados con Windows integrated security dejan de generar informes para los usuarios cuando se elimina la ruta de delegación sin sustituirla.
  • Los servidores vinculados de SQL Server que usan el contexto de seguridad actual del inicio de sesión fallan con "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'".
  • Los servidores antiguos de impresión, fax y gestión documental a veces dependían de los TGT reenviados para escribir los resultados en los recursos compartidos personales de los usuarios; esto se manifiesta como trabajos fallidos en lugar de un error claro.
  • Las aplicaciones que registran SPN por IP o alias: si los usuarios se conectan a través de un CNAME o del nombre de un equilibrador de carga sin un SPN correspondiente, KCD no servirá de nada hasta que se corrija el SPN, porque el cliente recurre a NTLM y una ruta KCD solo Kerberos no puede delegar un inicio de sesión NTLM.

Lecturas relacionadas: el tema Delegación para la serie completa, establecer ms-DS-MachineAccountQuota en 0 para cerrar la vía de creación de cuentas de equipo que los atacantes usan para abusar de RBCD una vez eliminada la delegación sin restricciones, y la entrada del glosario sobre la delegación sin restricciones para disponer de una definición breve que compartir con los responsables de las aplicaciones.

Preguntas frecuentes

¿Puedo simplemente desmarcar «Trust this computer for delegation to any service» y seguir adelante?

Técnicamente sí, y en la mayoría de los servidores no ocurre nada porque el indicador nunca fue necesario. Pero cuando una aplicación realiza de verdad un doble salto Kerberos, como un sitio IIS que lee un recurso compartido o consulta SQL Server como el usuario, el segundo salto falla de inmediato. Dedique primero una semana a recopilar evidencias de inicios de sesión y tickets para saber si el servidor delega realmente, y prepare la sustitución por delegación restringida antes de eliminar el indicador.

¿Es tan peligrosa la delegación sin restricciones en una cuenta de servicio de usuario como en un equipo?

Sí. El indicador TRUSTED_FOR_DELEGATION funciona igual en los objetos de usuario: cualquier servicio que se ejecute con esa cuenta recibe los TGT reenviados de los usuarios que se conectan. A menudo es peor, porque la contraseña de la cuenta de servicio suele ser estática, la conocen varias personas y es válida en varios hosts. Cualquiera que recupere esa contraseña o comprometa un host que ejecute el servicio puede recolectar los TGT reenviados, así que trate también estas cuentas como un hallazgo crítico.

¿Necesitan los controladores de dominio la delegación sin restricciones? ¿Debo eliminarla también ahí?

Los controladores de dominio grabables son de confianza para la delegación sin restricciones por diseño, y no debe tocarlo. Precisamente por ello, un DC al que se fuerza a autenticarse ante un host comprometido con delegación sin restricciones entrega su propio TGT. Eliminar el indicador del resto de servidores, mantener detenido el Print Spooler en los DC y bloquear las vías de coerción cierran juntos esa ruta. Los controladores de dominio de solo lectura no tienen el indicador.

Eliminar la delegación sin restricciones en servidores AD

Guías relacionadas