ADGPO-003: GPO sin vincular
- Plataforma
- Active Directory
- Categoría
- AD Group Policy
- Severidad
- Low
- Pilar de Zero Trust
- Governance (peso 1)
- Fixtures de referencia
- 3
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
Las GPO que no están vinculadas a ningún sitio, dominio u OU no se aplican y representan configuración sin usar. Las GPO sin vincular pueden contener configuraciones sensibles, credenciales en GPP o scripts que podrían aprovecharse si un atacante las vincula posteriormente a una OU de destino
Por qué importa
Unlinked GPOs are not a vulnerability on their own, which is why this check is rated Low. They become a vulnerability under three conditions. First, content that should have been retired is left in place: GPP cpassword values (CVE-2014-1812) remain readable by any authenticated user from SYSVOL regardless of whether the GPO is linked, because SYSVOL is world-readable to the Authenticated Users group by default. Second, a delegated principal with Edit settings or Edit, delete, modify security rights on the GPO can re-link it: if a help-desk group, an application service account, or a stale delegation holds gPLink write on a high-value OU (for example the Domain Controllers OU or a Tier 0 server OU), they can attach an unlinked GPO that contains an attacker-controlled startup script or scheduled task and obtain code execution as SYSTEM on every machine in that OU at the next gpupdate cycle. Third, unlinked GPOs frequently retain weaker DACLs than active ones because change-control processes do not cover them, making them easier to modify by lower-tier principals (T1484.001, Group Policy Modification). The blast radius scales with where the GPO is eventually linked: a script GPO linked at the domain root or at the Domain Controllers OU yields full domain compromise.
Ruta de ataque
Step 1: Discovery. The attacker, authenticated as any domain user, enumerates SYSVOL with a simple file listing of \\<domain>\SYSVOL\<domain>\Policies\ to obtain the GUID list of every GPO, then queries LDAP for groupPolicyContainer objects to retrieve display names and gPCFileSysPath. They compare against gPLink values on OUs (Get-ADOrganizationalUnit -Filter * -Properties gPLink) to identify unlinked candidates. PowerView surfaces the same data via Get-DomainGPO -Properties displayname,gpcfilesyspath and Get-DomainOU -Properties gplink. Step 2: Content harvest. For each unlinked GPO the attacker reads the SYSVOL contents. They run Get-GPPPassword (PowerSploit) or gpp-decrypt against Groups.xml, ScheduledTasks.xml, Services.xml, DataSources.xml, Drives.xml, and Printers.xml to extract cpassword values and decrypt them with the published AES key. Any plaintext credentials, service account passwords, or local administrator passwords recovered are added to the credential set. Step 3: ACL review. The attacker enumerates the nTSecurityDescriptor on each unlinked GPO via Get-DomainObjectAcl to find any non-default Allow ACE granting WriteProperty on gPCMachineExtensionNames, WriteProperty on gPCUserExtensionNames, or write access to the SYSVOL folder for the GPO. They concurrently enumerate writeable gPLink attributes on OUs using Find-InterestingDomainAcl or a BloodHound GPLink edge query. Step 4: Weaponize. The attacker uses SharpGPOAbuse (FSecureLABS) or pyGPOAbuse to inject an immediate scheduled task or a startup script into a GPO they can modify. Example: SharpGPOAbuse --AddComputerTask --TaskName "Update" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c net user attacker P@ss /add && net localgroup administrators attacker /add" --GPOName "Unlinked-Legacy-Policy". Step 5: Link. Using the writeable gPLink they identified in step 3, they link the now-weaponized GPO to the target OU: Set-ADOrganizationalUnit -Identity "OU=Tier0,DC=contoso,DC=com" -Add @{gPLink="[LDAP://cn={GUID},cn=policies,cn=system,DC=contoso,DC=com;0]"}. If no writeable gPLink is available, they use the GPO content (cpassword or script) for lateral movement via the credentials harvested in step 2. Step 6: Execute and clean up. They wait one Group Policy refresh interval (90 minutes default, or force with gpupdate /force on the foothold), confirm code execution, then either remove the link or leave a deniable persistence mechanism via a benign-looking scheduled task.
Cómo lo evalúa Guerrilla
Guerrilla performs a four-stage enumeration. Stage 1, GPO inventory: it binds to CN=Policies,CN=System,<domain DN> with an LDAPFilter of (objectClass=groupPolicyContainer) and collects distinguishedName, cn (the {GUID}), displayName, gPCFileSysPath, whenCreated, whenChanged, and nTSecurityDescriptor for every GPO. Stage 2, link inventory: it reads gPLink on the domain root, on every (objectClass=organizationalUnit) via Get-ADOrganizationalUnit -Filter * -Properties gPLink, and on every (objectClass=site) under CN=Sites in the Configuration NC. Stage 3, parsing: each gPLink value is split on the "][" delimiter, the cn={GUID} fragment is extracted from each [LDAP://...] entry, and a HashSet of all linked GUIDs is built. Stage 4, diff and classify: the check computes (all GPO GUIDs) minus (all linked GUIDs), and for each unlinked GPO it reads the SYSVOL contents via the gPCFileSysPath UNC, scans for GPP XML files known to carry cpassword, enumerates Scripts.ini, psscripts.ini, and Machine\Scripts and User\Scripts directories, and reports the discovered payloads alongside the AD DACL. The check also flags GPOs where the SYSVOL folder is missing (orphaned AD object) or where the AD object is missing (orphaned SYSVOL folder), since both indicate a broken or partially deleted GPO and a hygiene problem.
Valor recomendado
Ninguna GPO sin vincular a menos que esté documentada como plantilla o copia de seguridad con los controles de acceso apropiados
Remediación
Identifique las GPO sin vincular comparando todos los GUID de GPO con los atributos gPLink de todas las OU, sitios y la raíz del dominio. Revise cada GPO sin vincular para determinar si debe vincularse, archivarse o eliminarse. Elimine el contenido sensible de las GPO sin vincular que se conserven como plantillas.
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 |
|---|---|
| clean | PASS |
| known-bad | WARN |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- CM-2, CM-7
- MITRE ATT&CK
- T1484.001