ADPRIV-019: Disabled Accounts in Privileged Groups

Plataforma
Active Directory
Categoría
AD Privileged Account Security
Severidad
High
Pilar de Zero Trust
Identity (peso 3)
Fixtures de referencia
3
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

For each privileged group in scope, the check resolves the group by SID or distinguishedName, recursively expands membership through nested groups and foreign-security-principals, and for every resolved principal reads userAccountControl. Any member with the ACCOUNTDISABLE flag set (bit 0x2, decimal 2) is reported as a finding. The privileged group set evaluated includes: - Domain Admins (S-1-5-21-<domain>-512) - Enterprise Admins (S-1-5-21-<root>-519) - Schema Admins (S-1-5-21-<root>-518) - Administrators (S-1-5-32-544) - Account Operators (S-1-5-32-548) - Backup Operators (S-1-5-32-551) - Server Operators (S-1-5-32-549) - Print Operators (S-1-5-32-550) - DNSAdmins - Group Policy Creator Owners (S-1-5-21-<domain>-520) - Cert Publishers (S-1-5-21-<domain>-517) - Any group with adminCount = 1 (SDProp-protected populations) For every flagged member the check captures sAMAccountName, distinguishedName, objectSid, the resolved userAccountControl bitmask, the discovered path to the group (direct or via a nested chain), pwdLastSet, lastLogonTimestamp, and the timestamp at which the account was disabled where the value is recoverable from the replication metadata of userAccountControl.

Por qué importa

Disabling an account is a hygiene action, not a security boundary. The ACCOUNTDISABLE flag is a single bit in a writable attribute on the user object. Any of the following operations clears it in one LDAP call and immediately restores the full set of privileges the account holds through every group it still belongs to: an attacker with WriteProperty on userAccountControl, a member of Account Operators (which by default can manage non-protected user objects), a helpdesk role with delegated user-management rights, an attacker who has compromised any account that owns the disabled object, and any principal with GenericAll, GenericWrite, or WriteDacl on the user. Because the disabled state does not remove the principal from Domain Admins, Enterprise Admins, or any other Tier-0 group, the moment the bit flips the account holds full privilege. Worse, the account has often been ignored by the password rotation policy and by Protected Users enrollment, so the credential material that was current at the moment of disablement is still valid. Stale disabled DAs and EAs are a routine finding in incident response engagements and have been observed used by Conti, BlackCat, and other intrusion sets as the path of least resistance: rather than escalate privileges from scratch, the operator re-enables a forgotten admin account whose presence in the privileged group nobody noticed. The condition is also a strong indicator of broken offboarding: if disabled accounts have not been removed from privileged groups, the offboarding process is not enforcing Tier-0 cleanup, which means active orphaned admin accounts are likely present elsewhere as well.

Ruta de ataque

1. Reconnaissance: from any authenticated context the attacker enumerates privileged group membership with a single LDAP call (Get-ADGroupMember "Domain Admins" -Recursive, net group "Domain Admins" /domain, BloodHound SharpHound -CollectionMethod Group). Default-readable groups expose the full roster including disabled members. 2. Target selection: the attacker filters the roster for userAccountControl values with bit 0x2 set. A disabled member of Domain Admins, Enterprise Admins, or Administrators is a high-value target because it carries Tier-0 privilege but is typically unmonitored, excluded from MFA enforcement, and excluded from password rotation policies. 3. Re-enable primitive: the attacker needs only WriteProperty on userAccountControl for the target object. This right is held by Account Operators by default on non-protected users, by any helpdesk delegation that includes user-account management, by the object owner, and by any principal granted GenericAll or GenericWrite on the user. With one LDAP write (Enable-ADAccount, or a raw modify clearing bit 0x2) the account is live again with all of its group memberships intact. 4. Authentication: the attacker authenticates as the re-enabled account. If pwdLastSet is older than the rotation cadence the password is often known to the operator from prior dumps, breach corpora, or a default ("Welcome1", "Password123", the documented offboarding password). If the password is unknown but the attacker has Reset Password rights on the object (commonly delegated alongside Enable), they reset it to a known value. 5. Privilege use: as a member of Domain Admins (or equivalent), the account runs DCSync to extract krbtgt (mimikatz lsadump::dcsync, impacket-secretsdump), modifies GPOs linked to the Domain Controllers OU, adds backdoor ACEs to AdminSDHolder, or forges Golden Tickets. 6. Cleanup: the attacker re-disables the account after the operation to suppress detection, leaving the krbtgt-derived Golden Ticket as the persistent path. From the defenders perspective the account looks unchanged: still disabled, still a member of Domain Admins, no obvious indicator that it was briefly used.

Cómo lo evalúa Guerrilla

Guerrilla resolves each privileged group by well-known SID or by name, reads the member attribute, and recursively expands nested groups and foreign-security-principals in PowerShell rather than relying on -Recursive alone (which silently drops cross-domain references). For every resolved principal the check pulls userAccountControl, sAMAccountName, distinguishedName, pwdLastSet, lastLogonTimestamp, and msDS-ReplAttributeMetaData for userAccountControl in a single LDAP call. The disabled state is evaluated by bitwise AND against ACCOUNTDISABLE (0x2): ($uac -band 2) -eq 2. The check binds via LDAP (no AD PSDrive dependency) so it runs against any reachable DC and does not require RSAT loaded locally. Findings are emitted with the offending member DN, the group DN, the nested path (direct or via Group-A -> Group-B), the full userAccountControl decode, and the most recent enable / disable event from the replication metadata where available, so an analyst can determine whether the disabled state is recent (likely a cleanup that did not finish) or historical (likely an offboarding failure from years ago).

Valor recomendado

No disabled accounts in any privileged groups

Remediación

Identify disabled accounts in privileged groups using Get-ADGroupMember 'Domain Admins' -Recursive | Get-ADUser | Where-Object {$_.Enabled -eq $false}. Repeat for all privileged groups. Remove disabled accounts from all privileged group memberships immediately

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 ADPRIV-019
EscenarioVeredicto esperado
cleanPASS
known-badFAIL
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
AC-2(3), AC-2
ANSSI
R38
CIS AD Benchmark
4.6.2
MITRE ATT&CK
T1078.002, T1098