ADGPO-017: Restricted Groups Analysis
- Plataforma
- Active Directory
- Categoría
- AD Group Policy
- Severidad
- High
- Pilar de Zero Trust
- Governance (peso 2)
- Fixtures de referencia
- 2
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
For every Group Policy Object in every domain the check reads the GptTmpl.inf file at \\<domain>\SYSVOL\<domain>\Policies\{GUID}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf and parses the [Group Membership] section. Two key formats are decoded: - <group>__Memberof = list of groups this group should be a member of. Replaces the Member Of property of <group>. - <group>__Members = list of principals that should be members of <group>. Replaces the entire Members list of <group>. Entries can reference SIDs directly (for example *S-1-5-32-544 for BUILTIN\Administrators), domain SIDs, or NT names (DOMAIN\GroupName). The check resolves every SID and name to a current principal where possible and tags entries that reference well-known broad SIDs: - S-1-1-0 (Everyone) - S-1-5-7 (ANONYMOUS LOGON) - S-1-5-11 (Authenticated Users) - S-1-5-4 (INTERACTIVE) - S-1-5-32-545 (BUILTIN\Users) - the domain Domain Users group (RID 513) - the domain Domain Computers group (RID 515) In addition the check parses the modern Group Policy Preferences XML at Preferences\Groups\Groups.xml (for both the Machine and User sides), which carries Local Users and Groups items with the userAction attribute (ADD or REMOVE) and the deleteAllUsers / deleteAllGroups flags. This is the GPP equivalent of Restricted Groups and supports add and remove semantics rather than replace, and it is increasingly the mechanism used by modern policies. The check captures the targeted group (by name or built-in alias), the listed principals, the action (REPLACE for [Group Membership], ADD or REMOVE for GPP), the GPO that contains the entry, the OUs the GPO is linked to (gPLink), and the security filtering (ApplyGroupPolicy ACEs on the GPC) so the operator can see exactly which machines and which users are affected.
Por qué importa
Restricted Groups is one of the few GPO surfaces that directly mutates the local SAM of every target machine, and it does so as SYSTEM at every group policy refresh (default 90 to 120 minutes). A single line in a GptTmpl.inf that reads *S-1-5-32-544__Members = *S-1-5-21-<domain>-513 adds Domain Users to local Administrators on every computer in scope, granting interactive local admin to every authenticated user in the domain. The legacy [Group Membership] semantics are particularly dangerous because the __Members form is replace, not merge: it overwrites the existing membership of the targeted local group with the listed principals only. An administrator who intends to add a single helpdesk group to Remote Desktop Users with the [Group Membership] form will silently strip every other member from that group on every machine. The same replace semantic on Administrators removes the local Administrator account from its own group on every endpoint, which has caused multiple production outages when a poorly tested GPO was linked to the Domain Root. The GPP Local Users and Groups form (Groups.xml under Preferences) is more flexible because it supports ADD and REMOVE per principal rather than replace, but it carries its own risks: an ADD entry for a broad group is the most common path that grants Domain Users local admin in environments that have migrated away from the legacy form. Attackers who can edit a GPO that contains Restricted Groups entries get a one-step path to local admin on every machine the GPO targets, which on a forest-wide-linked policy is functional Domain Admin equivalence. The check is rated High because exploitation requires only Edit settings on a single GPO and the blast radius is every member computer in the link scope.
Ruta de ataque
1. Discovery. The attacker, holding any authenticated foothold, runs Get-GPO -All and for each GPO inspects GptTmpl.inf and Preferences\Groups\Groups.xml. PowerView (Get-DomainGPOLocalGroup) and SharpHound (CollectionMethod GPOLocalGroup) automate this and produce a graph of GPO -> local group -> principal -> computer, surfacing both legacy Restricted Groups and GPP Local Users and Groups entries. BloodHound visualises the resulting edges (GPOLocalGroup or GPOAppliesTo into AdminTo) and lets the attacker click any user and see every machine where the user is a member of local Administrators by GPO. 2. Target selection. The attacker prioritises GPOs that link to Tier 0 (Domain Controllers OU, Tier 0 admin workstations), then any GPO linked at the Domain Root or to OUs containing privileged systems. A Restricted Groups entry on a DC-targeted GPO is forest compromise; a Restricted Groups entry on the Domain Root that adds a broad group to local Administrators is local admin on every member machine. 3. Edit primitive. With Edit settings, delete, modify security on a target GPO (the GPMC right that maps to write on the GPC plus write on the SYSVOL files), the attacker modifies GptTmpl.inf to add their principal to *S-1-5-32-544__Members, or adds a Local Users and Groups item to Groups.xml under Preferences with userAction=ADD targeting Administrators. Tools: SharpGPOAbuse Add-GPOGroupMember, PowerView Add-DomainGroupMember via GPO, or native gpedit.msc. SharpGPOAbuse increments versionNumber on the GPC so clients re-evaluate at next refresh. 4. Link primitive (alternate). With WriteProperty on the gPLink attribute of a container, the attacker links an attacker-controlled GPO that already contains a Restricted Groups payload to a sensitive OU. This is the path BloodHound surfaces as the WriteGPLink edge and combines with any GPO the attacker has write on. 5. Execution. At the next Group Policy refresh on each targeted machine, the Security CSE (scecli) or the Group Policy Preferences CSE applies the membership change. The attacker now has local admin (or RDP, or backup operator) on every machine in scope, with no agent installed and no malware deployed. 6. Lateral movement. The attacker authenticates to each targeted machine using the new local admin grant, harvests local credentials (LSASS, DPAPI, browser secrets), and pivots. A Restricted Groups entry on a DC-targeted GPO additionally promotes the attacker to BUILTIN\Administrators on the DC, which is equivalent to Domain Admin. 7. Cleanup. The attacker reverts the Restricted Groups entry. The local membership change does not roll back automatically (Restricted Groups is enforcing, not transactional), so the attacker must also manually remove their account from each local group, or wait one refresh cycle if the original (clean) policy is intact and re-applies.
Cómo lo evalúa Guerrilla
Guerrilla enumerates every GPO in every domain of the forest with Get-GPO -All. For each GPO it builds the SYSVOL path \\<domain>\SYSVOL\<domain>\Policies\{GUID}\ and reads two artifacts: - Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf: the check looks for a [Group Membership] section and parses every line of the form <principal>__Members = <list> and <principal>__Memberof = <list>. Each side of the equals sign is split on commas and every token starting with * is treated as a literal SID; other tokens are resolved as DOMAIN\Name. The targeted group is resolved from its SID or alias (well-known BUILTIN SIDs are mapped to friendly names so *S-1-5-32-544 surfaces as BUILTIN\Administrators). - Preferences\Groups\Groups.xml on both Machine and User sides: the check parses each <Group> and <User> element, reads the properties node for groupName, groupSid, action, deleteAllUsers, deleteAllGroups, and the contained <Member> entries with their name, sid, and action attributes (ADD or REMOVE). Every resulting (GPO, targeted group, principal, action) tuple is enriched with the GPOs link locations (gPLink on every OU, Site, and the Domain Root), the GpoStatus flag (so disabled-but-content GPOs are still surfaced; see ADGPO-004), and the ApplyGroupPolicy DACL on the GPC so the operator can see who the policy applies to. Findings are graded by severity: HIGH where a broad SID (Domain Users, Authenticated Users, Everyone, Domain Computers) lands in a privileged local group (Administrators, Backup Operators, Account Operators, Print Operators, Server Operators, Remote Desktop Users, or any group with SeDebugPrivilege equivalent on the target), MEDIUM where a large or unmanaged enterprise group lands in those groups, and INFO for routine entries that align with the documented baseline. The check also flags every legacy [Group Membership] __Members entry (replace semantics) as a separate hygiene signal because replace is almost never the intended behaviour outside of a hardening baseline and is the most common cause of silent membership wipes.
Valor recomendado
Restricted Groups configured to enforce least-privilege local admin membership; only authorized groups in local Administrators
Remediación
Review Restricted Groups settings in all GPOs. Verify that the local Administrators group is managed to include only authorized admin groups. Ensure that Restricted Groups do not add Domain Users or other broad groups to privileged local groups. Consider using Group Policy Preferences for more granular control (Add/Remove members without replacing the entire membership).
Veredictos probados con fixtures
Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.
| Escenario | Veredicto esperado |
|---|---|
| informational | PASS |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- AC-6, AC-6(1), CM-6
- MITRE ATT&CK
- T1484.001, T1098