ADSTALE-003: Cuentas deshabilitadas con pertenencias a grupos
- Plataforma
- Active Directory
- Categoría
- AD Stale & Obsolete Objects
- Severidad
- Medium
- 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 cuentas de usuario y de equipo deshabilitadas que conservan su pertenencia a grupos de seguridad siguen apareciendo en las evaluaciones de control de acceso basadas en grupos y pueden crear confusión en las revisiones de acceso. Aunque las cuentas deshabilitadas no pueden autenticarse, sus pertenencias a grupos pueden restaurarse si la cuenta se vuelve a habilitar, y las pertenencias conservadas inflan el tamaño de los grupos y complican el análisis de mínimo privilegio
Por qué importa
Disabling an account is not the same as deprovisioning it. The Windows access check evaluates group membership at token build time, so a disabled account that is re-enabled immediately inherits every right and ACL grant carried by its old groups, with no human in the loop to notice that a long-dormant principal just became Domain Admin again. Three real-world failure modes drive the severity. First, helpdesk and Account Operators can re-enable user accounts by design, which means any compromise of those tiers turns the pool of disabled-but-privileged accounts into a ready-made list of one-click escalations. Second, attackers who land in the directory routinely scan for disabled accounts with elevated group membership because re-enabling an existing account is quieter than creating a new one and survives most "new admin account" detections. Third, group-based access reviews (SailPoint, Saviynt, Entra ID Governance, native AD reporting) typically count members without filtering on userAccountControl, which means disabled accounts inflate the apparent population of every privileged group and dilute the signal of legitimate access certification. The cleanup is cheap, the blast radius if missed is the forest.
Ruta de ataque
1. Attacker obtains rights to enable disabled accounts. This is granted by default to Account Operators, by delegation to most helpdesk OUs, and is held implicitly by anyone with GenericAll, GenericWrite, or WriteProperty on userAccountControl over the target OU. 2. Attacker enumerates disabled accounts that still hold privileged group membership: Get-ADUser -Filter {Enabled -eq $false} -Properties MemberOf,adminCount | Where-Object { $_.adminCount -eq 1 -or $_.MemberOf -match "Admins|Operators" }. The same query runs in BloodHound as MATCH (u:User {enabled:false})-[:MemberOf*1..]->(g:Group) WHERE g.admincount=true RETURN u,g. 3. Attacker selects a disabled account with the desired privilege (commonly a former IT staff member still in Domain Admins, a decommissioned service account in Backup Operators, or a contractor account in a custom application admin group). 4. Attacker re-enables the account with Enable-ADAccount or by clearing the ACCOUNTDISABLE bit directly: Set-ADUser -Identity victim -Enabled $true. The group memberships are already attached, no Add-ADGroupMember call is required. 5. Attacker resets the password (often allowed by the same helpdesk delegation that allowed re-enable) and authenticates as a fully privileged principal. 6. After use, the attacker disables the account again to restore the appearance of a stale tombstone, leaving the privileged memberships intact for the next round. The trail in security event logs looks like routine account hygiene rather than privilege escalation, which is why this technique consistently appears in Mandiant M-Trends and Microsoft DART case write-ups of human-operated ransomware.
Cómo lo evalúa Guerrilla
Guerrilla issues a single LDAP query filter (&(|(objectCategory=person)(objectCategory=computer))(userAccountControl:1.2.840.113556.1.4.803:=2)) which uses the LDAP_MATCHING_RULE_BIT_AND OID to match the ACCOUNTDISABLE bit on userAccountControl. For each result it requests memberOf, primaryGroupID, adminCount, lastLogonTimestamp, whenChanged, and objectSid. The primary group is resolved by combining the domain SID with the primaryGroupID RID. Every memberOf entry that is not the primary group DN is emitted as a residual membership. Findings are tagged with three severity uplifts: adminCount=1 on the disabled account, membership in a built-in protected group (matched against the well-known RIDs 512, 518, 519, 520, 544, 548, 549, 550, 551, 552, 555, 557, 562, 573, 578, 580), and lastLogonTimestamp older than the configured stale threshold (default 180 days). The check is purely read-only and runs as part of invoke-adaudit with no writes to the directory.
Valor recomendado
Todas las cuentas deshabilitadas eliminadas de todos los grupos de seguridad excepto Domain Users
Remediación
Identifique las cuentas deshabilitadas con pertenencias a grupos no predeterminadas usando Get-ADUser -Filter {Enabled -eq $false} -Properties MemberOf. Elimine todas las pertenencias a grupos de seguridad (excepto el grupo principal) de las cuentas deshabilitadas. Implemente un flujo de trabajo automatizado que elimine las pertenencias a grupos cuando se deshabiliten las cuentas. Incluya la limpieza de pertenencias a grupos en el proceso de baja de cuentas
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
- AC-2(3), AC-6
- CIS AD Benchmark
- 9.2.1