ADSTALE-009: Abandoned OUs

Plataforma
Active Directory
Categoría
AD Stale & Obsolete Objects
Severidad
Low
Pilar de Zero Trust
Governance (peso 0)
Fixtures de referencia
2
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

The check enumerates every Organizational Unit in the domain (objectClass=organizationalUnit) and reads, per OU, the count of direct child objects (users, computers, groups, contacts, nested OUs), the gPLink and gPOptions attributes, the description and info attributes, whenCreated and whenChanged, and the nTSecurityDescriptor (the OU DACL). An OU is flagged abandoned when (a) the direct child object count is zero, or below a configurable threshold (default 2 to account for placeholder containers), and (b) the OU was created more than 180 days ago, and (c) whenChanged indicates no recent administrative modification, and (d) the description and info attributes do not contain a documented-purpose marker (configurable string list, default looks for "staging", "reserved", "do-not-delete", "project", "DR", "pilot"). For every flagged OU the check additionally reports any non-default ACEs on the OU DACL (delegated rights such as Create Child, Write gPLink, Write DACL, Generic All to non-admin principals), any gPLink entries that point to GPOs that still exist and would still apply if a computer or user were moved into the OU, and the count of nested empty OUs underneath. The audit is read-only and runs against any reachable Domain Controller.

Por qué importa

Empty OUs are not benign because the OU object itself carries security state independent of its contents. Three concrete failure modes recur in assessments. First, orphaned delegations: when an OU was created for a project or a business unit, a help-desk team, a server administrator, or a third-party integrator was almost always delegated rights on it (Create Child Computer, Reset Password, Write Members on contained groups, Write gPLink). When the project shuts down nobody reviews the delegation, so the ACE persists on the empty container. An attacker who compromises any of those delegated principals inherits a writable scope inside the directory: they can create computer accounts in the OU (relevant to ADCS ESC8/relay and to LAPS retrieval primitives), create users they then move into privileged groups, or link a GPO they own to the OU and then move a Tier 0 computer into it. Second, GPO-link abuse: any principal with Write gPLink on an OU can attach an attacker-controlled GPO that delivers a startup script, scheduled task, or registry payload to every computer that lives or will live in the OU. Empty OUs are attractive for this because the action is invisible: there is nothing currently in scope to alert on. The attacker then waits for a legitimate move, or moves a target object themselves if they hold the right elsewhere. Third, structure confusion: a directory with hundreds of abandoned OUs makes Group Policy precedence, ACL audits, and tier-boundary enforcement materially harder to reason about. Reviewers miss the one OU that matters because it looks like all the other dead containers. Mandiant and Trimarc consistently report OU sprawl as a contributing factor in privilege escalations that hinged on a delegation nobody remembered granting.

Ruta de ataque

Step 1: Enumeration. Any authenticated principal can read the directory tree and the OU ACLs. The attacker runs PowerView Get-DomainOU, BloodHound (which collects OU ACLs and gPLink), or a raw LDAP query for (objectClass=organizationalUnit), then for each OU pulls nTSecurityDescriptor and gPLink. They filter to OUs with zero or near-zero child objects and to OUs where their current compromised identity, or a path-reachable identity, holds Write gPLink, Write DACL, Create Child, or Generic All. Step 2: Target selection. The attacker prefers an empty OU that sits at a position in the tree where moving a target object in is plausible (sibling of a server OU, sibling of a workstation OU, sibling of an admin-tier OU). An empty OU named "Decom_2019", "Project_X", "Test_OU", or "Migration_Staging" is the canonical signature. Step 3: GPO authoring. The attacker creates a new GPO (requires Group Policy Creator Owners membership, or a delegation that grants New GPO) or hijacks an existing GPO they already control via SYSVOL ACL or via a Write on the gPCFileSysPath. The GPO is configured with an Immediate Scheduled Task, a startup script, a registry preference that backdoors a service, or a software installation pointing to an attacker-served MSI. Step 4: Link the GPO. With Write gPLink on the abandoned OU, the attacker writes the GPO into the OU gPLink attribute. The OU is empty so no defender sees a behavioral change on any in-scope endpoint. There is no immediate Group Policy processing event to trigger an alert. Step 5: Move a target into scope. With Write Member on a group, or Move rights on a target computer object granted elsewhere, the attacker moves a high-value computer (a SQL server, a jump host, a Tier 0 admin workstation) into the abandoned OU. On the next Group Policy refresh (90 minutes by default, immediate on reboot or gpupdate /force) the attacker payload executes in the security context of SYSTEM on that endpoint. From SYSTEM on a Tier 0 host the path to domain compromise is short. Step 6: Cleanup. The attacker moves the compromised computer back to its original OU, unlinks the GPO, and deletes it. The abandoned OU returns to its inert state. Forensics is left with a single Event 5136 directory-change record per step, which is rarely correlated.

Cómo lo evalúa Guerrilla

Guerrilla calls Get-ADOrganizationalUnit -Filter * with a properties list of (Name, DistinguishedName, gPLink, gPOptions, Description, Info, whenCreated, whenChanged, nTSecurityDescriptor) and, for each OU, counts direct children with Get-ADObject -SearchBase $ou.DistinguishedName -SearchScope OneLevel -Filter *. OUs with a child count at or below the threshold (default 2) and a whenCreated older than 180 days and no documented-purpose marker in Description or Info are emitted as findings. For every flagged OU the check parses nTSecurityDescriptor to extract non-default ACEs (any ACE on a principal that is not SYSTEM, Domain Admins, Enterprise Admins, BUILTIN Administrators, Pre-Windows 2000 Compatible Access, Authenticated Users with default rights, or the Everyone read ACEs that ship by default) and tags ACEs that grant Write gPLink (ObjectType 0xf30e3bbe-3bb5-11d2-a42a-00c04fb946d3), Write DACL, Create Child for the Computer or User classes, Generic All, or Generic Write. The gPLink attribute is parsed for any [LDAP://cn={GUID},cn=policies,...] entries and each referenced GPO is resolved with Get-GPO to confirm whether the GPO still exists and would still apply on link enforcement. Nested empty-OU chains are reported as a single tree finding so the operator can collapse the entire dead branch in one change. The check runs against any reachable Domain Controller, requires only authenticated user rights, and is read-only. It emits no Event 5136, 5137, 5141 directory-modification records because nothing is changed.

Valor recomendado

No empty OUs without a documented purpose; OU structure reflects current organizational requirements

Remediación

Enumerate all OUs and count their child objects. Identify OUs with zero or very few objects. Review OU descriptions and any associated documentation to determine if the OU is planned for future use. Remove delegated permissions from abandoned OUs. Delete empty OUs that have no documented purpose after verifying they are not referenced by GPO links, scripts, or automation. Update OU structure documentation

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.

Escenarios de veredicto de ADSTALE-009
EscenarioVeredicto esperado
cleanPASS
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
CM-2
CIS AD Benchmark
9.5.1