Configure el atributo primaryGroupID de una cuenta de usuario en 512 y esta se convierte en miembro de pleno derecho de Domain Admins en cada inicio de sesión. Esto es la suplantación de primaryGroupID: Domain Admins ocultos que Active Directory calcula directamente en el token Kerberos de la cuenta, pero que ADSI Edit, un filtro LDAP crudo (member=...), y la mayoría de las exportaciones de auditoría nunca ven — porque solo la mitad de cómo AD calcula la pertenencia a grupos se almacena realmente en el objeto grupo.
Qué Es primaryGroupID
Todo objeto de usuario y equipo en Active Directory lleva un atributo primaryGroupID: un único entero que almacena el identificador relativo (RID) del grupo primario de la cuenta. Es un remanente de los requisitos de conformidad POSIX de Windows NT, de antes de que AD soportara grupos anidados arbitrarios, y hoy en día suele permanecer intacto en su valor por defecto — tanto es así que un hilo reciente de r/activedirectory simplemente preguntaba para qué sirve realmente el campo "Primary Group" de un objeto de usuario.
Los valores por defecto, confirmados con la propia documentación de auditoría de eventos de Microsoft y con la investigación de Semperis sobre este atributo:
| Tipo de objeto | primaryGroupID por defecto | Nombre del grupo |
|---|---|---|
| Usuario | 513 | Domain Users |
| Equipo | 515 | Domain Computers |
| Controlador de dominio | 516 | Domain Controllers |
| DC de solo lectura | 521 | Read-only Domain Controllers |
El que importa para este artículo: el RID 512 es Domain Admins.
A diferencia de la pertenencia a grupos ordinaria — que vive en el atributo multivalor member del objeto grupo, con un enlace inverso memberOf correspondiente en el usuario — la pertenencia al grupo primario se almacena únicamente en la cuenta, como un solo entero. El propio objeto grupo no registra nada al respecto.
Cómo Calcula Realmente Active Directory "Quién Está en Este Grupo"
"Quién está en Domain Admins" no es una única consulta. La pertenencia efectiva es la unión de dos elementos distintos:
- Toda cuenta listada en el atributo
memberdel grupo Domain Admins. - Toda cuenta cuyo atributo
primaryGroupIDsea igual a 512 — el RID de Domain Admins — sin importar lo que diga el atributomember.
Solo la primera mitad se almacena en el objeto grupo. La segunda mitad se almacena por completo en la cuenta, y nada en el grupo registra que ese enlace existe. Las herramientas que resuelven la pertenencia consultando directamente el objeto grupo reconstruyen ambas mitades y muestran el panorama completo. Las herramientas que simplemente leen el valor bruto member del grupo solo ven la primera mitad.
La investigación de TrustedSec sobre este comportamiento (Brandon Colley, publicada en enero de 2026) demuestra la división directamente: consultar Get-ADGroupMember "Domain Admins" sobre el grupo devuelve una cuenta cuyo acceso a Domain Admins proviene únicamente de primaryGroupID — el cmdlet resuelve la unión. Active Directory Users and Computers y Active Directory Administrative Center hacen lo mismo cuando se abre la pestaña de miembros del grupo. Pero la misma investigación muestra que dos herramientas caen en el otro lado de la división:
- ADSI Edit, al examinar directamente el atributo
member, no lista la cuenta. - Un filtro LDAP crudo como
(member=CN=...)— el tipo sobre el que se construyen la mayoría de los scripts de exportación caseros, los trabajos de reporting basados en CSV, y los pipelines de ingesta SIEM — la pasa por alto por la misma razón: está consultando el atributo que nunca fue tocado.
Hay una segunda brecha, más estrecha, en la misma investigación: Get-ADGroupMember -Recursive recorre grupos anidados para expandir la pertenencia, pero no detecta una cuenta cuyo grupo primario esté configurado en un grupo anidado dentro de Domain Admins en lugar de Domain Admins mismo. La recursividad expande la cadena member; no vuelve a ejecutar la unión de primaryGroupID en cada nivel de anidamiento — el mismo punto ciego transitivo cubierto en el anidamiento peligroso de grupos.
Suplantación de primaryGroupID: los Domain Admins Ocultos que Active Directory Nunca Lista
Un atacante (o un script) con acceso de escritura sobre el atributo primaryGroupID de un usuario objetivo — un derecho GenericWrite, GenericAll, o un WriteProperty acotado delegado en algún lugar dentro de una OU, la misma clase de arista de abuso de ACL que BloodHound ya mapea sobre objetos de usuario — lo configura en 512. Active Directory solo acepta esta escritura sobre una cuenta que ya es miembro explícito del grupo objetivo — las propias indicaciones de Microsoft sobre cómo establecer el grupo primario mediante programación y la investigación de Tenable sobre este atributo confirman ambas que un simple Set-ADUser -Replace @{primaryGroupID=512} falla contra una cuenta que aún no es miembro, y que solo una omisión del servicio de directorio como DCShadow puede establecerlo en una cuenta que nunca fue miembro en absoluto. El camino ordinario son tres comandos, no uno:
Add-ADGroupMember -Identity "Domain Admins" -Members jdoe
Set-ADUser -Identity jdoe -Replace @{primaryGroupID=512}
Remove-ADGroupMember -Identity "Domain Admins" -Members jdoe -Confirm:$false
En la siguiente solicitud de TGT Kerberos de la cuenta, el RID del grupo primario se incorpora al token exactamente igual que cualquier otro SID de grupo. La cuenta ahora se autentica con acceso equivalente a Domain Admins. Una vez completado el tercer comando, el atributo member de Domain Admins vuelve a su lista original, de modo que un diff programado de exportaciones de grupos o una lectura estática del atributo member ya no tiene nada que detectar después del hecho — aunque la breve adición y eliminación generan cada una un evento estándar de cambio de pertenencia a grupo en el camino, así que una alerta en tiempo real sobre esos eventos específicos (a diferencia de un diff de exportación periódico) sí tiene una ventana para detectarlo. Por eso esta técnica se lee como una suplantación de primaryGroupID: Domain Admins ocultos que Active Directory incorpora en cada token, pero que el control creado para detectar nuevos administradores nunca ve.
El investigador de seguridad Yuval Gordon documenta, en una publicación del blog de Semperis, una extensión adicional de esta idea: combinar el cambio de primaryGroupID con una Access Control Entry de denegación de lectura sobre el propio atributo primaryGroupID del usuario, de modo que incluso las herramientas conscientes de la unión (ADUC, Get-ADGroupMember) ya no puedan leer el valor y dejen de reportar la pertenencia por completo. Es una técnica real — pero Gordon es explícito sobre dónde deja de funcionar:
"Este truco no puede funcionar en miembros de grupos protegidos como Domain Admins... esta técnica no funcionará en miembros de ningún grupo protegido por el proceso SDPROP y AdminSDHolder, ya que dependemos de la DACL, que en ese caso simplemente se revertirá a la DACL de AdminSDHolder cada hora aproximadamente."
El ciclo SDProp de AdminSDHolder (aproximadamente cada 60 minutos) vuelve a aplicar una ACL plantilla a toda cuenta que considere miembro de un grupo protegido, lo que borra la ACE de denegación. Como un simple cambio de primaryGroupID=512 no toca en absoluto la DACL de la cuenta, SDProp no lo revierte — solo neutraliza el truco de ocultación mediante ACE de denegación, no la suplantación subyacente. El ejemplo funcional del propio Gordon apunta en cambio a un grupo de prueba no protegido, no a DnsAdmins — el mismo artículo señala por separado que la técnica también funciona contra grupos ordinarios como DnsAdmins, que tiene su propio camino bien conocido hacia Domain Admins. La versión simple — configurar primaryGroupID directamente en 512, sin la ACE — no se ve afectada por AdminSDHolder de todos modos, que es precisamente por lo que vale la pena auditarla directamente.
Detección
Este es un caso en el que la supervisión de Event ID de Windows realmente juega a su favor. La propia referencia de auditoría de seguridad de Microsoft para el Event ID 4738 ("Se cambió una cuenta de usuario", bajo la subcategoría Audit User Account Management) documenta un campo Primary Group ID en los datos de atributos modificados del evento, y su propia tabla de recomendaciones de supervisión lo indica claramente:
| Campo a supervisar | Razón para supervisarlo |
|---|---|
| Primary Group ID distinto de 513 | Normalmente, el valor de Primary Group es 513 para usuarios de dominio y locales. Otros valores deben ser supervisados. |
Dos verificaciones independientes, que corresponden a las dos cosas que realmente hay que detectar:
Tiempo Real — Auditar el Cambio en Sí
Con Audit User Account Management habilitado, cada escritura de primaryGroupID genera el Event ID 4738 en el DC que la procesó, con el nuevo RID en el campo Primary Group ID. Genere una alerta ante cualquier 4738 donde ese campo esté poblado y el nuevo valor no sea 513 (o 515/516/521 para equipos y DC).
Punto en el Tiempo — Barrido de Cuentas Ya Suplantadas
La investigación de TrustedSec ofrece un comando directo para esto:
Get-ADUser -property primaryGroup,primaryGroupID -Filter {-not(primaryGroupID -like "513")}
Ejecutado contra un dominio con una línea base limpia, los únicos resultados esperados son los controladores de dominio (516), los RODC (521), y — si su entorno todavía los aprovisiona — cuentas de servicio mapeadas a POSIX con una razón documentada. Cualquier cuenta de usuario ordinaria que muestre 512, o cualquier RID privilegiado que no debería tener, es el hallazgo.
Ninguna de las dos verificaciones depende en absoluto de leer el objeto grupo Domain Admins — que es precisamente el punto. Una revisión construida sobre Get-ADGroupMember "Domain Admins" ejecutada directamente contra el grupo sí lo detectaría también, según la misma investigación; una revisión construida sobre una exportación LDAP del atributo member, o una herramienta que trate esa exportación como verdad absoluta, no lo hará.
Remediación
- Ejecute el barrido anterior en cada dominio del bosque, no solo en el que aloja Domain Admins — el abuso de primaryGroupID contra un grupo anidado/local en un dominio hijo es igual de invisible para las exportaciones del atributo
member. - Restablezca cualquier cuenta no conforme a su valor por defecto correcto (513 para usuarios estándar) salvo que exista una razón de negocio documentada y vigente para un valor distinto.
- Habilite Audit User Account Management en todos los controladores de dominio si aún no está activo, para que el Event ID 4738 se genere realmente y se reenvíe a su SIEM.
- Reconstruya cualquier revisión de acceso privilegiado automatizada que consulte
memberdirectamente — mediante ADSI Edit, un filtro LDAP crudo(member=...), o un script de exportación construido de la misma manera — para que en su lugar invoqueGet-ADGroupMembersobre el grupo, o una explícitamente unión un barrido deprimaryGroupID. La revisión que se suponía era la red de seguridad es precisamente el control que esta técnica neutraliza. - Audite quién posee
WriteProperty/GenericWrite/GenericAllsobre objetos de usuario, y quién puede añadir miembros a Domain Admins directamente — el camino ordinario hacia esta técnica requiere ambos: derechos para añadir brevemente la cuenta objetivo a Domain Admins, y derechos para escribir suprimaryGroupID. Cualquiera de los dos delegado por debajo de las OU de administración integradas es, por sí solo, un hallazgo.
Cómo Detecta Esto EtcSec
El control PRIMARYGROUPID_SPOOFING de EtcSec ejecuta la misma clase de barrido como control continuo: cada auditoría compara el primaryGroupID de cada cuenta con su valor por defecto esperado y marca las cuentas cuyo grupo primario difiere sin una razón documentada, cerrando exactamente la brecha que deja abierta una exportación limitada al atributo member. Los hallazgos aparecen junto a la revisión de permisos de escritura (ACL_WRITE_PROPERTY_EXTENDED) que muestra quién podía realizar el cambio en primer lugar, y junto a la supervisión de grupos privilegiados (PRIVILEGED_GROUP_MEMBER_CHANGES) para que pueda ver, lado a lado, qué rutas de escalada de privilegios cubre realmente su alertado sobre el atributo member.
Explore las páginas de identidad que apoyan este tema
