- ¿Qué es gMSA?
- ¿Cómo puede un atacante leer las contraseñas que rotan automáticamente?
- ¿Cómo funciona el almacenamiento de contraseñas?
- ¿Cómo se construye la msDS-ManagedPassword?
- Cómo recuperar la clave y construir la contraseña
- Recapitulación de la generación de contraseñas gMSA
- Cómo implementar GetKey y la generación de contraseñas offline
- ¿Qué es el ataque Golden GMSA?
- Cómo se arma el ataque Golden GMSA
- Ejemplo de ataque Golden GMSA
- Cómo detectar un ataque Golden GMSA
- Cómo defenderse de los ataques Golden GMSA
Este artículo presenta un nuevo ataque dirigido a las cuentas de servicio gestionadas por grupo (gMSA), denominado «ataque Golden GMSA», que permite a los atacantes extraer los atributos de la clave raíz del Servicio de Distribución de Claves (KDS) y, a continuación, generar la contraseña de todas las gMSA asociadas sin conexión.
TL;DR
Un atacante con altos privilegios puede obtener todos los ingredientes para generar la contraseña de cualquier gMSA en el dominio en cualquier momento con dos pasos:
- Recuperar varios atributos de la clave raíz KDS del dominio
- Utiliza el GoldenGMSA para generar la contraseña de cualquier gMSA asociado a la clave, sin una cuenta privilegiada.
Lecturas relacionadas
gMSA 101
Por lo general, las contraseñas de las cuentas de servicio no se cambian con regularidad, lo que las pone en riesgo, sobre todo porque pueden ser objeto de ataques a través de ataques de «kerberoasting» ataques de «kerberoasting». Una gMSA (cuenta de servicio gestionada por grupo; la «g» minúscula es un misterio) es un tipo especial de cuenta en Active Directory (AD) introducida en Windows Server 2012 para resolver precisamente este problema. El único propósito de este objeto es ser utilizado como cuenta de servicio, con la importante característica de la rotación de contraseñas. Una cuenta gMSA puede ser utilizada por uno o más servidores con servicios compatibles.
La contraseña del gMSA se gestiona mediante AD. Se renueva automáticamente cada 30 días por una contraseña generada aleatoriamente de 256 bytes, lo que hace que sea imposible descifrarla. Como describe la documentación de Microsoft :

La contraseña se calcula basándose en un secreto que cambia periódicamente y en atributos sin nombre de la gMSA. El secreto utilizado se almacena en el objeto clave raíz KDS.
¿Cómo es posible que la contraseña rote automáticamente?
La idea en la que se basa este tipo de cuenta es interesante. Los controladores de dominio (DC) con permisos de escritura gestionan la contraseña de la gMSA y la renuevan cada 30 días (por defecto). Cuando un servidor que utiliza esta cuenta necesita acceder a la gMSA, primero solicita la contraseña más reciente al DC recuperando un atributo denominado msDS-ManagedPassword. Este atributo es un objeto binario de gran tamaño (BLOB) que contiene la contraseña.

El atributo msDS-GroupMSAMembership de un gMSA especifica quién está autorizado a obtener la contraseña. El DC escribible, a su vez, utiliza este atributo para validar que la persona que llama está autorizada a obtenerla. Hasta aquí, podemos ver una forma directa de abusar de ello: Si un atacante obtiene acceso a una cuenta que tiene acceso a msDS-ManagedPassword, el atacante puede leer la contraseña para el gMSA específico.
Almacenamiento de contraseñas
Los DC no suelen almacenar contraseñas en sus bases de datos, sino sólo secretos derivados de contraseñas. Esto plantea una pregunta: Supongamos que el DC con permisos de escritura no almacena la contraseña en texto claro; ¿cómo puede recuperarse leyendo el atributo msDS-ManagedPassword? Resulta que msDS-ManagedPassword es un atributo atributo construidolo que significa que este atributo no se almacena en el AD, sino que se calcula cuando un usuario autorizado intenta leerlo.
¿Cómo se construye la msDS-ManagedPassword?
Ahora sabemos que la contraseña la generan bajo demanda los DC con derechos de escritura. También sabemos que cualquier DC con derechos de escritura puede generar el atributo, y que el resultado siempre será el mismo. Esta página muestra cómo se genera la contraseña, pero no es lo suficientemente detallada como para permitirnos generarla nosotros mismos.
Buscar la función que construye este atributo nos llevaría a ntdsai.dll!dbGetConstructedAtt, que es la función responsable de construir atributos.

Podemos ver una llamada a dbGetManagedServiceAccountPasswordpero interesa sólo en la contraseña y no todo el ManagedPasswordBlob. En más en la función finalmente nos lleva nos a a llamada a la función KdsCli.dllKdsGetGmsaPasswordBasedOnKeyId.

Repasemos los parámetros de esta función:
- _SecurityDescriptor es un descriptor de seguridad (SD) predefinido, codificado en ntdsai.dll, que concede permisos de lectura y escritura a S-1-5-9 (controladores de dominio de empresa), como se muestra en la siguiente captura de pantalla:

- _SID es el ObjectSID del gMSA deseado.
- _MsdsManagedPasswordID es un atributo del objeto gMSA que, entre otras cosas, hace referencia por GUID a la instancia de la Clave Raíz KDS utilizada por el gMSA para la generación de contraseñas.
No encontramos documentación formal para este atributo, pero más vueltas nos ayudaron a averiguar cómo construirlo nosotros mismos con los parámetros que se muestran en la captura de pantalla de abajo.

- _OutPassword es un puntero a un buffer que almacenará la contraseña.
- El tamaño de la contraseña es el número de bytes que se escribirán en OutPassword. Tiene un valor predeterminado de 256.
Recuperación de la clave y construcción de la contraseña
El flujo de ejecución llega finalmente a la función GetKeyFromKdsService, que invoca al método RPC GetKey.

Podemos ver que los parámetros coinciden con la documentación de [MS-GKDI]

Nota interesante: GetKey realiza comprobaciones de acceso contra el TargetSD proporcionado por el llamante, lo que significa que podemos invocar esta función con un descriptor de seguridad que nos conceda acceso, y el DC devolverá una clave. Desafortunadamente, el SD también se utiliza en el cálculo de la clave. Así que, aunque siempre podemos cambiar el DS para saltarnos las comprobaciones de acceso, a menos que el DS proporcionado sea válido, obtendremos una clave inválida. El único descriptor de seguridad válido que da como resultado una clave válida es el codificado que mencionamos antes (gmsaSecurityDescriptor), otorgando acceso sólo a controladores de dominio empresariales (S-1-5-9).
Si el llamador tiene los permisos requeridos, este método genera una clave y la devuelve en una estructura Group Key Envelope (GKE). Después de obtener la clave, podemos finalmente llamar a kdscli.dll!_GenerateGmsaPassword para generar la contraseña.

Los parámetros sexto y séptimo son opcionales y no afectan a la contraseña. Por lo tanto, para este propósito, podemos simplemente establecerlos en null.
Recapitulemos de la generación de contraseñas gMSA
Una contraseña gMSA se genera llamando a una función que reside en kdscli.dll (no se exporta, por desgracia), que tenemos en cualquier endpoint de Windows. Llamar a esta función requiere tres cosas:
- SID
- msds-ManagedPasswordID de la gMSA (puede recuperarse mediante una consulta LDAP)
- GKE, que puede generarse llamando al método GetKey en el DC con privilegios elevados a través de RPC.
Implementación de GetKey y generación de contraseñas offline
Hemos intentado simplificar al máximo la generación de contraseñas gMSA, hasta el punto de poder hacerlo offline. La única llamada RPC en el proceso es para GetKey. Así que decidimos revertirlo y portarlo a código C# que genera una GKE.
Descubrimos que la clave cambia periódicamente, como documenta Microsoft. Pero la clave se deriva de atributos del objeto clave raíz KDS y tres enteros (L0KeyID, L1KeyID, L2KeyID) derivados de una marca de tiempo, como se muestra en la siguiente captura de pantalla.

La marca de tiempo actual se almacena en el atributo msDS-ManagedPasswordID del gMSA, legible por todos los usuarios del dominio por defecto, por lo que podemos recuperar la marca de tiempo y generar esos enteros.
Los únicos datos que utiliza el DC para generar las contraseñas, y de los que no disponemos, son los siguientes atributos de la clave raíz del KDS:
- cn
- msKds-SecretAgreementParam
- msKds-RootKeyData
- msKds-KDFParam
- msKds-KDFAlgorithmID
- msKds-CreateTime
- msKds-UseStartTime
- msKds-Versión
- msKds-DomainID
- msKds-PrivateKeyLength
- msKds-PublicKeyLength
- msKds-SecretAgreementAlgorithmID
La recuperación de esos atributos requiere derechos de lectura y ampliados sobre el objeto clave raíz KDS, que por defecto sólo tienen los administradores de dominio. Sin embargo, estos valores NO se modifican periódicamente.
Esto significa que si comprometemos esos valores, podemos usarlos para calcular un GKE para cualquier gMSA asociado con la clave raíz del KDS y generar su contraseña offline.
El ataque dorado de la GMSA
El ataque «Golden GMSA» se produce cuando un atacante extrae los atributos relevantes de una clave raíz KDS y, a continuación, los utiliza para generar fuera de línea la contraseña de las cuentas gMSA asociadas. El ataque «Golden GMSA» es en cierto modo similar al ataque «Golden Ticket», que permite a los atacantes que comprometen la cuenta krbtgt falsificar tickets de concesión de tickets (TGT) siempre y cuando la contraseña de krbtgt no se modifique.
Una diferencia notable entre un ataque Golden Ticket y el ataque Golden GMSA es que no conocemos una forma de rotar el secreto de la clave raíz KDS. Por lo tanto, si una clave raíz KDS se ve comprometida, no hay forma de proteger los gMSAs asociados a ella. La única mitigación en tal escenario es crear nuevos gMSAs con una nueva clave raíz KDS.
Armar el ataque Golden GMSA
Hemos convertido el ataque Golden GMSA en una herramienta que puede descargar aquí.
La herramienta GoldenGMSA Attack puede recuperar los atributos necesarios de un objeto de clave raíz KDS especificado o utilizar los valores proporcionados por el usuario para generar una GKE. La herramienta también puede recuperar el msDS-ManagedPasswordID a partir de un SID de gMSA y, por supuesto, generar la contraseña de la gMSA sin conexión.
Un atacante puede potencialmente usar la contraseña para comprometer servicios que usan el gMSA falsificando un Silver Ticket u obteniendo un ticket de servicio Kerberos para cuentas privilegiadas a través de S4U2Self. Si la gMSA tiene privilegios elevados, el atacante podría utilizarla para comprometer otros recursos y, en algunos casos, comprometer todo el bosque.
Ejemplo de ataque Golden GMSA
Un atacante puede utilizar la herramienta GoldenGMSA para enumerar todos los gMSAs y sus claves raíz KDS asociadas. Un atacante con privilegios elevados también puede utilizar la herramienta GoldenGMSA para volcar las claves raíz KDS.

El atacante puede utilizar posteriormente el KDS volcado root key BLOB para generar la contraseña de la gMSA completamente fuera de línea.

La contraseña está codificada en Base64 porque podría incluir caracteres no imprimibles.
Detección de un ataque Golden GMSA

El compromiso de un KDS root kno genera eventos de seguridad por defecto. Los defensores deben configurar un SACL en el KDS root kos objetos para todos los que lean el sitio msKds-RootKeyData atributo. Una vez la lista de control de acceso al sistema (SACL) cualquier intento deintento de volcar los datos clave de un KDS root key generará evento de seguridad 4662 en el DC donde el tipo de objeto es msKds-ProvRootKey y el nombre no es un DCcomo se muestra en la siguiente captura de pantalla:
Defensa contra los ataques de Golden GMSA
Las cuentas de servicio gestionadas por grupo son una gran característica de Active Directory que mitiga algunos riesgos asociados a las cuentas de servicio, como los ataques Kerberoasting. Sin embargo, las contraseñas asociadas a las gMSA se generan utilizando entradas que no pueden rotarse si se ven comprometidas, lo que permite a los atacantes con altos privilegios volcar claves raíz KDS y generar las contraseñas de las gMSA asociadas sin conexión mientras existan.
Los defensores deben supervisar el acceso anormal a las claves raíz KDS, como los no DC que leen el atributo msKds-ProvRootKey y los eventos de inicio de sesión anormales vinculados a cuentas gMSA.
