ADTIER-007: Service Accounts with Interactive Logon Rights via Privileged Group
- Platform
- Active Directory
- Category
- Tier-0 Hygiene & Hybrid Identity Surface
- Severity
- High
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check executes the LDAP filter (&(objectCategory=person)(objectClass=user)(|(servicePrincipalName=*)(sAMAccountName=svc*)(sAMAccountName=sa-*)(sAMAccountName=service*)(sAMAccountName=*_svc)(sAMAccountName=*-svc))) to identify candidate service accounts via SPN presence or common naming conventions, then enriches each result with memberOf (recursively expanded via tokenGroups and the LDAP_MATCHING_RULE_IN_CHAIN OID 1.2.840.113556.1.4.1941). It flags any candidate whose recursive group membership includes a well-known privileged SID (S-1-5-32-544 Administrators, S-1-5-21-*-512 Domain Admins, S-1-5-21-*-519 Enterprise Admins, S-1-5-21-*-518 Schema Admins, S-1-5-21-*-520 Group Policy Creator Owners, S-1-5-32-548 Account Operators, S-1-5-32-549 Server Operators, S-1-5-32-550 Print Operators, S-1-5-32-551 Backup Operators) or any custom group with adminCount=1. For each finding the check also parses the Default Domain Controllers GPO (and any GPO linked to OUs that contain workstations or member servers) for the User Rights Assignment entries SeInteractiveLogonRight, SeRemoteInteractiveLogonRight, SeDenyInteractiveLogonRight, and SeDenyRemoteInteractiveLogonRight to determine whether the candidate account is explicitly denied interactive logon. Accounts that are members of a privileged group AND are not explicitly denied SeInteractiveLogonRight and SeRemoteInteractiveLogonRight at the workstation tier are returned as High-severity findings. Membership in Protected Users (CN=Protected Users,CN=Users) is recorded as a mitigating signal but does not by itself satisfy the check, because Protected Users restricts credential delegation and ticket lifetime but does not remove the interactive logon right.
Why it matters
Microsofts Active Directory tier model (Tier 0 = identity infrastructure, Tier 1 = servers, Tier 2 = workstations) only functions if credentials usable at one tier cannot land on hosts at a lower tier. A Domain Admin credential exposed on a Tier 2 workstation is, for blast-radius purposes, equivalent to the attacker already holding Domain Admin. Service accounts are the most common vector for this exposure because they were historically created as ordinary user accounts, granted "Domain Admin just to make it work," and then registered as the run-as identity for a service or scheduled task on a workstation or member server. Once the password is recovered (Kerberoasting yields it offline, GPP cpassword and SYSVOL scripts yield it in plaintext, registry hives and the Service Control Manager cache it on every host where the service runs, and Mimikatz extracts it from LSASS during any interactive session), the attacker can use it interactively. The combination of "privileged group membership" + "no Deny logon GPO" is the lateral-movement equivalent of leaving every server door unlocked because one master key opens them all. Defender for Identity, Mandiant M-Trends, and Microsoft DART consistently identify privileged service-account abuse as a top-three credential-theft pattern in ransomware and nation-state intrusions.
Attack path
Step 1: Initial access. The attacker holds credentials for any authenticated domain principal (phishing, password spray, NTLM relay, or a compromised endpoint). Step 2: Service-account discovery. LDAP enumeration with PowerView (Get-DomainUser -SPN), Impacket GetUserSPNs.py, or BloodHound surfaces every SPN-bearing user and their group memberships. BloodHound paths like (Domain Users) -[MemberOf]-> (Domain Admins) via a service account are the canonical finding. Step 3: Credential capture. The attacker chooses the cheapest extraction technique for the target account. Kerberoast (Rubeus.exe kerberoast /user:svc_sql /nowrap) yields an offline-crackable $krb5tgs$23$ ticket. GPP cpassword (Get-GPPPassword from PowerSploit) reads any cached XML in SYSVOL. LAPS-less local admin on any host the service ever ran on yields the password from HKLM\SECURITY\Policy\Secrets via Mimikatz lsadump::secrets. Step 4: Interactive logon. Because the account is in Domain Admins and there is no Deny GPO, the attacker authenticates interactively to a Tier 2 host: mstsc /v:workstation01 /user:CONTOSO\svc_sql, or runas /netonly to obtain a token. Windows happily accepts the logon because Domain Admins is in the default SeInteractiveLogonRight on every domain-joined Windows machine. Step 5: Credential theft from LSASS. The attackers interactive session causes LSASS to hold the service accounts TGT, NT hash, and (without Credential Guard) the plaintext password in WDigest or tspkg. Mimikatz sekurlsa::logonpasswords or comsvcs.dll MiniDump on lsass.exe extracts all of it. Procdump and Process Explorer accomplish the same with signed Microsoft binaries that evade naive AV. Step 6: Tier 0 traversal. With a Domain Admin TGT in hand the attacker authenticates directly to a domain controller: Rubeus.exe asktgs /service:cifs/dc01.contoso.local /ticket:<base64TGT>, then mounts \\dc01\C$, dumps NTDS.dit via ntdsutil ifm or VSS, and extracts the krbtgt hash. From that point the engagement supports Golden Tickets, DCSync, and full forest control. Step 7: Persistence. The attacker leaves the service account untouched (rotating its password would alarm SOC), and instead adds a secondary backdoor (a new account in Domain Admins, a Shadow Credential msDS-KeyCredentialLink on a low-noise account, or a Golden Ticket valid for 10 years).
How Guerrilla assesses it
Guerrilla performs two LDAP queries and one GPO parse. Query 1 identifies candidate service accounts: (&(objectCategory=person)(objectClass=user)(|(servicePrincipalName=*)(sAMAccountName=svc*)(sAMAccountName=sa-*)(sAMAccountName=service*)(sAMAccountName=*_svc)(sAMAccountName=*-svc))) with attributes [sAMAccountName, distinguishedName, servicePrincipalName, memberOf, userAccountControl, adminCount, lastLogonTimestamp, msDS-AllowedToDelegateTo, msDS-SupportedEncryptionTypes]. Query 2 expands each candidates effective group membership via the LDAP_MATCHING_RULE_IN_CHAIN OID (memberOf:1.2.840.113556.1.4.1941:=<groupDN>) against each well-known privileged group, which correctly handles nested groups. The GPO parse uses Get-GPO -All and Get-GPOReport -ReportType Xml against every GPO linked to the Domain root, the Domain Controllers OU, and any OU containing computer objects, then extracts the SecuritySettings/UserRightsAssignment nodes for SeInteractiveLogonRight, SeRemoteInteractiveLogonRight, SeDenyInteractiveLogonRight, and SeDenyRemoteInteractiveLogonRight. A finding is emitted when a candidate account is a (recursive) member of a privileged group AND its SID does not appear in SeDenyInteractiveLogonRight or SeDenyRemoteInteractiveLogonRight on any GPO applicable to non-Tier-0 hosts. The check additionally records Protected Users membership (CN=Protected Users,CN=Users,DC=...) and the msDS-NeverRevealGroup / msDS-RevealOnDemandGroup configuration of any RODC the account is exposed to. For runtime detection, Guerrilla recommends Audit Logon (Success) on workstations and member servers, with SIEM alerts on Event ID 4624 LogonType=2 (interactive) or LogonType=10 (RemoteInteractive) where the TargetUserName matches the privileged-service-account inventory.
Recommended value
Service accounts (heuristic: sAMAccountName starts with svc/sa/service or has SPN + no interactive logon recently) are explicitly denied 'Allow log on locally' and 'Allow log on through Remote Desktop Services' via the Default Domain Controllers Policy and a dedicated Tier-1/Tier-2 logon-restriction GPO.
Remediation
Identify service accounts (SPN-bearing, naming convention, or business inventory). Apply a Default Domain Policy GPO: Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment > 'Deny log on locally' = <service-accounts-group>. Add the same accounts to 'Deny log on through Remote Desktop Services'. Add them to Protected Users where supported (Server 2012 R2+).
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- AC-6
- CIS AD Benchmark
- 8.3.2
- MITRE ATT&CK
- T1078.002, T1003.001