Domain Accounts and Groups¶
On a domain controller, accounts and groups live in Active Directory instead of the local SAM. Everything in the Accounts group still applies: compare to the README, remove what isn't authorized, fix what is. The tools change.
Tools¶
| Task | Tool |
|---|---|
| Users, groups, OUs | Active Directory Users and Computers (dsa.msc) |
| Domain-wide policy | Group Policy Management (gpmc.msc) |
| Command line | net user /domain, net group /domain, and the ActiveDirectory PowerShell module (installed with the DC role; on a member, Install-WindowsFeature RSAT-AD-PowerShell) |
List domain accounts and admins¶
net user /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
net group "Schema Admins" /domain
PowerShell gives you the columns that matter:
Get-ADUser -Filter * -Properties Enabled, PasswordNeverExpires, PasswordNotRequired, LastLogonDate, AdminCount |
Select SamAccountName, Enabled, PasswordNeverExpires, PasswordNotRequired, LastLogonDate, AdminCount | Sort SamAccountName
Compare the list to the README's authorized users, then look at the flags. PasswordNotRequired True means the account can have a blank password. PasswordNeverExpires True exempts it from the domain policy. AdminCount 1 means the account is, or once was, in a protected group.
Privileged groups¶
Membership in any of these is domain-wide control. The README lists who the domain administrators are; everyone else comes out.
| Group | Grants |
|---|---|
| Domain Admins | Administrator on every machine in the domain |
| Enterprise Admins | Everything, across every domain in the forest. Usually empty. |
| Schema Admins | Can change the AD schema. Usually empty. |
| Administrators (on the DC) | Administrator on domain controllers. Domain Admins and Enterprise Admins are members through nesting. Only the people responsible for the DC belong here (STIG WN22-DC-000010). |
| Account Operators | Create and modify most accounts and groups |
| Server Operators | Log on to DCs, manage services, back up and restore |
| Backup Operators | Read anything on the DC, including the AD database, which holds every password hash |
| Group Policy Creator Owners | Create GPOs, which run on every machine they're linked to |
| DnsAdmins | Can load a DLL into the DNS service, which runs as SYSTEM on the DC |
foreach ($g in 'Domain Admins','Enterprise Admins','Schema Admins','Administrators','Account Operators','Server Operators','Backup Operators','Group Policy Creator Owners','DnsAdmins') {
"== $g"; Get-ADGroupMember $g -Recursive | Select -Expand SamAccountName
}
-Recursive matters: a user put into a group that's inside Domain Admins is a domain admin.
Remove:
Remove-ADGroupMember "Domain Admins" -Members hacker -Confirm:$false
Disable, remove, create¶
Disable-ADAccount hacker
Remove-ADUser hacker -Confirm:$false
New-ADUser carol -AccountPassword (Read-Host -AsSecureString) -Enabled $true -ChangePasswordAtLogon $true
Set-ADUser bob -PasswordNeverExpires $false -PasswordNotRequired $false
Domain account flags can also be bulk-fixed:
Get-ADUser -Filter {PasswordNotRequired -eq $true} | Set-ADUser -PasswordNotRequired $false
Get-ADUser -Filter {PasswordNeverExpires -eq $true} | Set-ADUser -PasswordNeverExpires $false
Leave krbtgt alone; it's disabled by design and the domain doesn't work without it.
The built-in domain accounts¶
Administrator (the domain one, not a local one) can't be deleted. Rename it and give it a long password, the same as on a standalone machine. Guest is disabled by default; make sure it still is (Get-ADUser Guest | Select Enabled). krbtgt signs every Kerberos ticket; its password should have been reset within the last 180 days (STIG WN22-DC-000430). Check with:
Get-ADUser krbtgt -Properties PasswordLastSet | Select PasswordLastSet
If it's old, reset it twice, waiting a few minutes between (each reset invalidates tickets signed with the old key, and two resets clear the history): Set-ADAccountPassword krbtgt -Reset -NewPassword (Read-Host -AsSecureString). On a one-DC competition domain this is safe; on a real multi-DC domain you'd wait for replication in between.
Inactive and never-used accounts¶
The domain remembers last logon. Accounts unused for 35 days should be disabled (the same rule as the STIG on a standalone machine):
Search-ADAccount -AccountInactive -TimeSpan 35 -UsersOnly | Select SamAccountName, LastLogonDate
Search-ADAccount -AccountInactive -TimeSpan 35 -UsersOnly | Disable-ADAccount
Check the README first: a listed user who hasn't logged in yet is authorized, not inactive.
Local accounts on domain machines¶
On a domain-joined workstation or member server, people should have domain accounts, not local ones (STIG WN11-00-000085). A local account is outside the domain's password policy, auditing, and disablement, and if its password is the same on two machines it's a lateral-movement path. On each member, net user should show only the built-in accounts and any local administrator the organization uses for emergencies, and that one should be managed by LAPS (Member Servers in a Domain).
Verify¶
Get-ADGroupMember "Domain Admins" -Recursive | Select -Expand SamAccountName
Get-ADUser -Filter {Enabled -eq $true} | Select -Expand SamAccountName
Get-ADUser -Filter {PasswordNotRequired -eq $true -or PasswordNeverExpires -eq $true} | Select SamAccountName
The first two match the README; the third is empty.
Example¶
net group "Domain Admins" /domain lists Administrator, alice, svc_backup, guest2. README: alice is the only domain admin. Remove svc_backup and guest2 from the group, then check whether either account should exist at all. Get-ADGroupMember Administrators -Recursive also turns up helpdesk, nested through a group called IT; the README doesn't give helpdesk administrator rights on the DC, so IT comes out of Administrators.