Windows Fundamentals · beginner · ~11 min

Windows users, groups, and SIDs

**What you will learn** - Explain how Windows identifies every account with a **SID** (Security Identifier) and why names are only labels on top of it. - Read a SID: distinguish the domain/machine portion from the trailing **RID**, and recognise well-known SIDs like `S-1-5-18` (SYSTEM) and RID **500** (built-in Administrator). - Tell **local** accounts (SAM database) apart from **domain** accounts (Active Directory), and know which built-in groups grant real power. - Enumerate group membership safely with `whoami`, `net`, and PowerShell **on a machine you own or are authorized to test**. - Apply the defensive view: which memberships to monitor, what to log, and how to detect suspicious changes to privileged groups.

Overview

Security objective. The asset protected here is administrative control of a Windows machine or domain — the ability to read any file, change any setting, or move to other computers. The threat is privilege escalation and lateral movement: an attacker (or a curious insider) who lands as a low-privileged user and tries to reach SYSTEM on one host or Domain Admin across the network. In this lesson you learn to read Windows identity correctly so you can both understand how escalation targets are chosen and, more importantly, detect and prevent unauthorized membership in high-value groups.

This lesson has no prerequisites — it is a foundation for the Windows and Active Directory tracks. Everything else (NTFS permissions, tokens, Kerberos) is built on the idea introduced here: Windows makes access-control decisions about SIDs, not names.

A SID looks like S-1-5-21-3623811015-3361044348-30300820-1013. Windows stores permissions against that string. If an administrator renames Administrator to Frank, the SID is unchanged, so the account keeps every permission it had. This single fact — identity is the SID, not the label — is why defenders track SIDs in logs and why the name of an account tells you almost nothing about its power.

The next lesson, NTFS permissions and ACLs (win-ntfs-permissions), shows how those SIDs appear inside file and folder access-control lists.

Why it matters

In authorized professional work this knowledge sits on both sides of the fence:

  • Blue team / IT / detection engineering. You cannot secure what you cannot name. Auditors and defenders continuously answer "who is in Administrators and Domain Admins, and should they be?" Group-membership drift — an unexpected account added to a privileged group — is one of the highest-signal indicators of compromise. Monitoring is done by SID because renaming an account does not change it.
  • Authorized penetration testing / red team. With written scope and permission, one of the first non-destructive steps after gaining a foothold is enumeration: which local admins exist, which are domain accounts, and where the machine sits relative to the domain. This tells the tester the realistic impact of a finding without changing anything.
  • Incident response. During a live investigation, translating SIDs to names (and back) across event logs is routine. Attackers rename accounts and create look-alikes; the SID is the anchor that survives.

Because the same enumeration commands are used to defend and to assess, the professional difference is authorization and intent: you run them only on systems you own or have explicit written permission to test, and you prefer prevention and detection over exploitation.

Core concepts

Each concept below is taught on its own: a definition, a plain explanation, how it works, when it applies, and a pitfall.

1. Security principal

  • Definition. Anything Windows can grant rights to: a user, a group, or a computer account.
  • Plain explanation. When you log in, Windows does not think "this is Alice." It thinks "this is the principal with SID S-1-5-21-…-1104."
  • How it works. At logon Windows builds an access token containing your SID plus the SIDs of every group you belong to. That token is checked against object permissions.
  • When/when-not. Every access decision uses principals. You never grant a permission to a raw name at the kernel level — the name is resolved to a SID first.
  • Pitfall. Two accounts with the same name on different machines are completely different principals with different SIDs. Same label, different identity.

2. SID and RID

  • Definition. A SID (Security Identifier) is a unique, immutable value identifying a principal. The RID (Relative Identifier) is the last dash-separated number.
  • Plain explanation. Read S-1-5-21-A-B-C-500 as: S = it is a SID; 1 = revision; 5 = the NT Authority; 21-A-B-C = the machine or domain identifier; 500 = the RID, which picks the specific account within that machine/domain.
  • How it works. The machine/domain part is generated once at install (or domain creation). Accounts are then handed sequential RIDs. Some RIDs are well-known and fixed everywhere.
  • When/when-not. Use the RID to spot special accounts fast (RID 500 = built-in Administrator, RID 501 = Guest). Do not assume a high RID means low privilege — a normal user can be placed in Administrators.
  • Pitfall. Renaming Administrator does nothing to its power because RID 500 is unchanged. "We renamed the admin account" is weak security by itself.

3. Well-known SIDs (SYSTEM and friends)

  • Definition. Fixed SIDs that mean the same thing on every Windows system.
  • Plain explanation. S-1-5-18 is SYSTEM (the operating system's own account). Locally it is more powerful than Administrator. S-1-5-19/S-1-5-20 are LocalService / NetworkService (limited service accounts). S-1-1-0 is Everyone.
  • How it works. Core OS services run as SYSTEM, which is why compromising a SYSTEM service is a common local-escalation goal — and why defenders watch what runs as SYSTEM.
  • When/when-not. Recognise these in logs and ACLs instantly. But note SYSTEM's power is local: it is not automatically Domain Admin.
  • Pitfall. Assuming "Administrator is the top account." On the local box, SYSTEM outranks it.

4. Local vs domain accounts

  • Definition. Local accounts live in one machine's SAM database; domain accounts live in Active Directory and are recognised by every domain-joined machine.
  • Plain explanation. A local Administrator only controls its own PC. A Domain Admins member controls (by default) every machine in the domain — the crown jewels.
  • How it works. A domain-joined machine trusts the domain controller to vouch for domain SIDs; local SIDs are only meaningful on that one host.
  • When/when-not. Local accounts matter for single-host escalation and password re-use across hosts; domain accounts matter for lateral movement and domain takeover.
  • Pitfall. Confusing MACHINE\Administrator (local) with DOMAIN\Administrator (domain). They are different principals with different SIDs and very different blast radius.

5. High-value groups

  • Definition. Groups whose membership confers wide control: Administrators (full control of a machine), Domain Admins and Enterprise Admins (control across a domain/forest), plus sensitive ones like Backup Operators and Account Operators.
  • Plain explanation. Group membership is inherited into your token, so adding an account to Administrators instantly makes it an admin — no reboot needed for new logons.
  • How it works. Windows expands nested group memberships when building the token.
  • When/when-not. These groups are exactly what to inventory and monitor. Membership should be rare, justified, and reviewed.
  • Pitfall. Ignoring "almost-admin" groups. Backup Operators can read/write protected files and is a classic overlooked escalation path.
THREAT MODEL — Windows identity on one host (authorized lab)

        [ Low-priv user login ]              <-- entry point / foothold
                |  builds access token (user SID + group SIDs)
                v
  +-------------------------------------------------+
  | TRUST BOUNDARY: standard user  ->  local admin   |
  |   crossed by: membership in Administrators,      |
  |               abusing a SYSTEM service,           |
  |               weak service/file permissions       |
  +-------------------------------------------------+
                |
                v
        [ SYSTEM  S-1-5-18 ]  = full local control    <-- asset (local)
                |  reuse creds / harvest domain token
                v
  +-------------------------------------------------+
  | TRUST BOUNDARY: one host  ->  the domain         |
  |   crossed by: Domain Admin credentials found on   |
  |               the host, lateral movement          |
  +-------------------------------------------------+
                v
     [ Domain Admins ] = control of every domain host <-- asset (domain)

Assets:   local admin/SYSTEM control; domain-wide control.
Entry:    an authenticated low-priv session.
Boundaries: standard-user->admin, and single-host->domain.

Knowledge check

  1. What asset is protected by monitoring Domain Admins membership? (Control of every machine in the domain.)
  2. Where is the trust boundary that a local-privilege-escalation crosses? (Standard user → local Administrator/SYSTEM on the same host.)
  3. What insecure assumption is behind "we renamed Administrator, so we're safe"? (That power is tied to the name; it is tied to RID 500 / the SID, which did not change.)
  4. Which Windows log entry best signals abuse of these concepts? (Security event 4732/4728 — a member added to a security-enabled local/global group.)
  5. Why run enumeration only in an authorized lab? (These commands read account and group data; running them on systems you do not own or have written permission to test is unauthorized access.)

Syntax notes

The core built-in commands are read-only when used as shown. Run them only on a machine you own or are authorized to test.

whoami /user            # your account name + your SID
whoami /groups          # every group SID in your access token
whoami /priv            # privileges your token currently holds

net user                # list local user accounts (SAM)
net localgroup          # list local groups
net localgroup Administrators   # who is a local administrator

PowerShell (Windows 10/11, Server 2016+) gives structured output:

Get-LocalUser                       # local accounts as objects
Get-LocalGroupMember Administrators # members of the local admins group

Annotated: whoami /user prints one line ending in the SID; the final -500 (if present) means the built-in Administrator. Get-LocalGroupMember returns each member's Name, SID, and PrincipalSource (Local vs ActiveDirectory) — the SID column is the one to record for logs, because it survives renames.

Lesson

Windows access control is built on security principals — users, groups, and computers. Each principal is identified by a SID.

SID, not name

A Security Identifier (SID) is the real identity of an account, for example S-1-5-21-…-1001.

Names are only labels. Permissions are stored against the SID, not the name.

The last part of a SID is the RID (Relative Identifier). It distinguishes one account from another. The built-in Administrator is always RID 500.

Local vs domain accounts

  • Local accounts live in a single machine's SAM database.
  • Domain accounts live in Active Directory and work across every machine in the domain (covered in the AD track).

Key built-in groups

  • Administrators — full control of the machine.
  • Users — standard, limited access.
  • SYSTEM (S-1-5-18) — the operating system itself; more powerful than Administrator locally.
  • Domain Admins — administrators across the entire domain (the crown jewels).

Why a pentester cares

Enumerating who is in Administrators and Domain Admins, and which accounts are local versus domain, is step one of Windows post-exploitation.

The goal of most escalation is to become SYSTEM locally, or Domain Admin in the domain.

You ultimately track SIDs, not names, because a renamed account keeps its original SID.

Code examples

The example is a small, read-only PowerShell audit that any defender or authorized tester can run. It follows an INSECURE-STATE → SECURE-STATE → VERIFY shape: first it reveals a risky configuration, then shows the remediation, then re-checks that the fix took effect. No exploitation is performed.

1. WARNING: intentionally vulnerable — use only in a local, isolated, authorized lab. Do not deploy.

This represents the starting state of a lab VM where an ordinary account was wrongly granted local admin. Reproduce it only inside a throwaway VM you own.

# LAB SETUP (throwaway VM only). Creates the risky state to detect.
# 'labuser' is a stand-in low-priv account that should NOT be admin.
New-LocalUser -Name 'labuser' -Password (Read-Host -AsSecureString 'pw') -FullName 'Lab User'
Add-LocalGroupMember -Group 'Administrators' -Member 'labuser'   # <-- the misconfiguration

2. DETECT the problem (read-only audit)

# Inventory: who really holds local admin, with SIDs and source.
Get-LocalGroupMember -Group 'Administrators' |
    Select-Object Name, SID, PrincipalSource, ObjectClass |
    Format-Table -AutoSize

# Flag any *user* (not a group/service) that is a local admin.
Get-LocalGroupMember -Group 'Administrators' |
    Where-Object { $_.ObjectClass -eq 'User' -and $_.PrincipalSource -eq 'Local' }

3. SECURE fix (remediate — remove unneeded membership)

# Remediation: revoke the unnecessary admin rights. Least privilege.
Remove-LocalGroupMember -Group 'Administrators' -Member 'labuser'

4. VERIFY the fix rejects bad state and accepts good state

# The audit must now REJECT 'labuser' as admin (returns nothing) ...
$stillAdmin = Get-LocalGroupMember -Group 'Administrators' |
    Where-Object { $_.Name -like '*labuser' }
if ($stillAdmin) { Write-Host 'FAIL: labuser still admin' -ForegroundColor Red }
else             { Write-Host 'PASS: labuser is not a local admin' -ForegroundColor Green }

# ... and must still ACCEPT the legitimate built-in Administrator (RID 500).
Get-LocalGroupMember -Group 'Administrators' |
    Where-Object { $_.SID -like 'S-1-5-*-500' } |
    ForEach-Object { Write-Host "PASS: RID-500 admin present -> $($_.SID)" -ForegroundColor Green }

Expected output. Step 2 lists the built-in Administrator and labuser (the problem). After step 3, step 4 prints PASS: labuser is not a local admin and PASS: RID-500 admin present -> S-1-5-21-…-500. The verification proves the remediation removed the bad membership while keeping the legitimate one.

Lab cleanup / reset

Remove-LocalUser -Name 'labuser'   # delete the stand-in account

Then revert the VM snapshot so the environment is clean for the next exercise.

Line by line

Walking through the audit-and-fix example:

  1. New-LocalUser + Add-LocalGroupMember — lab setup only. This deliberately creates the insecure state: an ordinary account (labuser) placed in Administrators. In real defensive work you never create this; you find it.
  2. Get-LocalGroupMember -Group 'Administrators' — reads the members of the local admins group as objects. Piping to Select-Object Name, SID, PrincipalSource, ObjectClass surfaces the four facts that matter: the label, the immutable identity, whether it is Local or ActiveDirectory, and whether it is a User or Group.
  3. The Where-Object filter — narrows to local user admins. Groups in Administrators are often expected (e.g. Domain Admins); a lone local user is the classic drift to flag.
  4. Remove-LocalGroupMember — the remediation. It revokes membership; the account still exists but no longer inherits admin rights into new tokens.
  5. Verification block — re-runs the audit. $stillAdmin should now be empty, proving the bad state is rejected. The second check confirms the RID-500 account is still present, proving the fix did not over-correct and remove legitimate access.
Step Admins group contains Audit verdict
After setup Administrator (RID 500), labuser FAIL — extra local-user admin
After remediation Administrator (RID 500) PASS — only expected admins
RID-500 check Administrator present PASS — legitimate access intact

The SID column is the load-bearing detail: even if labuser were later renamed, matching on its SID would still identify it in logs.

Common mistakes

  • WRONG: "We renamed Administrator to Frank, so attackers can't find the admin." → WHY wrong: power lives in RID 500/the SID, not the name; enumeration finds RID 500 regardless of label. → CORRECTED: disable or tightly control the built-in account and enforce least privilege; treat renaming as cosmetic, not a control. → Recognise/prevent: audit by SID (S-1-5-*-500), not by name.
  • WRONG: Treating MACHINE\Administrator and DOMAIN\Administrator as the same account. → WHY wrong: they are different principals with different SIDs and vastly different blast radius (one host vs the whole domain). → CORRECTED: always note the scope/prefix and the PrincipalSource. → Recognise/prevent: check the SID prefix — domain SIDs share the domain identifier; local SIDs share the machine identifier.
  • WRONG: "Administrator is the most powerful account, so I only watch it." → WHY wrong: locally, SYSTEM (S-1-5-18) outranks Administrator, and services run as SYSTEM. → CORRECTED: monitor what runs as SYSTEM and protect service configurations. → Recognise/prevent: inventory services and their run-as identity.
  • WRONG: Only inventorying Administrators and Domain Admins. → WHY wrong: groups like Backup Operators, Account Operators, and Server Operators grant near-admin capability. → CORRECTED: include all sensitive built-in groups in reviews. → Recognise/prevent: keep a documented list of privileged groups and audit each.
  • WRONG: Running enumeration commands against machines outside your scope "just to check." → WHY wrong: reading accounts on systems you do not own or lack written authorization for is unauthorized access. → CORRECTED: confirm scope in writing first; use an isolated lab VM to practise. → Recognise/prevent: keep an authorization checklist and stop at the scope boundary.

Debugging tips

  • Get-LocalGroupMember fails with a translation error (a member SID cannot be resolved to a name). This is common when a domain account was added then deleted, or the DC is unreachable. Fall back to net localgroup Administrators, which shows the raw entries, and record the SID rather than the name.
  • net user shows fewer accounts than expected. net user lists SAM (local) accounts only; domain accounts will not appear. Confirm whether the box is domain-joined with systeminfo | findstr /i domain before concluding an account is "missing."
  • whoami /groups doesn't show a group you just added yourself to. Group membership is baked into the token at logon. Log off and back on (or start a new session) to get a fresh token, then re-check.
  • PowerShell Get-Local* cmdlets are unavailable. They ship in the Microsoft.PowerShell.LocalAccounts module (Windows 10/Server 2016+). On older systems use net commands instead.
  • Questions to ask when results look wrong: Am I on the machine I think I am (hostname)? Am I looking at local or domain scope (PrincipalSource)? Is the account identified by a name that could have been renamed — should I be matching on SID? Do I actually have permission to be running this here?

Memory safety

Security & safety: detection and logging for identity changes.

The highest-value defensive signal in this topic is a change to privileged group membership. Configure auditing and monitor these Windows Security events:

  • 4732 — a member was added to a security-enabled local group (e.g. local Administrators).
  • 4728 — a member was added to a security-enabled global group (e.g. Domain Admins).
  • 4733 / 4729 — a member was removed from those groups.
  • 4720 — a user account was created; 4738 — a user account was changed.
  • 4672 — special privileges assigned to a new logon (a proxy for admin/SYSTEM-level logons).

What to log for each event: timestamp (UTC), the actor SID and account performing the change, the target account SID that was added/removed, the group SID affected, the source host, the result (success/failure), and a correlation id to tie the change to a session or ticket. Logging the SID — not just the name — is essential because renames don't change it.

What to NEVER log: passwords or password hashes, Kerberos tickets or NTLM secrets, session tokens/cookies, private keys, or unnecessary personal data. An account audit needs identities and decisions, not credentials.

Events that signal abuse: a new or unexpected account appearing in Administrators/Domain Admins; a disabled privileged account suddenly re-enabled; group changes outside a change-management window; a burst of 4672 special-privilege logons from an unusual host.

How false positives arise: legitimate onboarding, break-glass admin use, backup software running as a service account, or IT automation that manages groups. Reduce noise by allow-listing known automation SIDs and correlating changes with approved change tickets — investigate the unexplained deltas, not every change.

Real-world uses

Authorized real-world use case. A security team runs a weekly privileged-access review: an automated read-only job enumerates Administrators on every server and Domain Admins in the domain, records each member's SID and PrincipalSource, and diffs it against last week's baseline. Any new member triggers a ticket asking "who approved this, and is it still needed?" This is exactly the audit pattern from the code example, scaled up.

Professional best-practice habits

  • Least privilege. Admin group membership is rare, time-boxed, and justified. Use just-in-time elevation where available.
  • Secure defaults. Keep the built-in Administrator disabled or tightly restricted; use named admin accounts so actions are attributable to a person.
  • Validation. Reconcile every privileged member against an approved list; unexplained members are incidents until proven otherwise.
  • Logging. Audit group-change events (4728/4732) centrally and alert on additions to sensitive groups.
  • Error handling. Record SIDs so renamed or deleted accounts remain traceable in historical logs.
Beginner Advanced
Scope One host you own; whoami, net localgroup Whole domain; automated, scheduled baselining
Focus Read SIDs, find local admins Detect drift, tier admin access, alert in a SIEM
Output A manual inventory Diffed reports + tickets + dashboards

Always operate within written authorization; the same commands are defensive when run on assets you own and unauthorized when run elsewhere.

Practice tasks

All tasks are lab-only: use a Windows VM you own or a provided training range. Never run against systems outside your written scope.

Authorization checklist (complete before any task):

  • I own this VM or have explicit written permission to test it.
  • The VM is isolated (host-only/NAT network, disposable snapshot taken).
  • I will only run read-only enumeration except where a task explicitly sets up a lab state.
  • I know the cleanup/reset steps and will run them afterward.

Beginner 1 — Read your own identity

  • Objective. Find your own SID and understand its parts.
  • Requirements. Run whoami /user. Identify the machine/domain portion and the RID.
  • Output. Write down the full SID and label which segment is the RID.
  • Hints. The RID is the final dash-separated number.
  • Concepts. SID, RID.

Beginner 2 — Inventory local admins

  • Objective. List everyone with local administrator rights.
  • Requirements. Use Get-LocalGroupMember -Group 'Administrators' (or net localgroup Administrators). Record each member's Name and SID.
  • Output. A table of admins with their SIDs and PrincipalSource.
  • Constraints. Read-only; change nothing.
  • Hints. Note which entries are groups vs individual users.
  • Concepts. High-value groups, local vs domain, SID.

Intermediate 1 — Spot the built-in accounts

  • Objective. Identify the built-in Administrator and Guest by RID, regardless of their current names.
  • Requirements. Enumerate local users with SIDs; find the accounts ending in -500 and -501.
  • Output. Map each well-known RID to its (possibly renamed) account.
  • Hints. Rename the built-in Administrator in your lab first, then prove you can still find it by RID.
  • Concepts. RID 500/501, why renaming is cosmetic.

Intermediate 2 — Detect membership drift

  • Objective. Build a tiny drift detector.
  • Requirements. Save the current Administrators membership to a baseline file. Add a stand-in account to the group (lab state), then re-enumerate and diff against the baseline to flag the new member. Include the SID in your report.
  • Output. A diff clearly identifying the added account.
  • Constraints. Lab VM only; snapshot first.
  • Defensive conclusion. Remove the added account and re-run the diff to VERIFY it is gone.
  • Hints. Compare-Object compares two membership lists.
  • Concepts. Detection, logging by SID, remediation + verification.

Challenge — Privileged-group audit report

  • Objective. Produce a mini privileged-access review for your lab host.
  • Requirements. Enumerate Administrators, Backup Operators, and (if domain-joined in your lab) Domain Admins. For each member record Name, SID, PrincipalSource, and whether it is expected. Map which Security event IDs would fire if someone were added to each group.
  • Output. A short report: findings table + a monitoring recommendation naming events 4728/4732.
  • Constraints. Read-only enumeration; lab only.
  • Defensive conclusion. For any unexpected member, state the remediation (remove membership, least privilege) and the verification step (re-enumerate and confirm removal). Then reset the VM snapshot.
  • Hints. Reuse the audit-and-verify structure from the code example.
  • Concepts. Least privilege, detection/logging, mitigation verification, reporting.

Summary

  • Windows identifies principals by SID, not name. Permissions are stored against the SID, so a renamed account keeps all its power — always audit and log by SID.
  • Read a SID: the trailing RID picks the account. RID 500 = built-in Administrator, 501 = Guest; S-1-5-18 = SYSTEM, which outranks Administrator locally.
  • Local (SAM) vs domain (Active Directory) accounts differ in blast radius: one host versus the whole domain. MACHINE\AdministratorDOMAIN\Administrator.
  • High-value groupsAdministrators, Domain Admins, and the often-forgotten Backup Operators/Account Operators — are what to inventory and monitor.
  • Key commands (read-only, authorized hosts only): whoami /user, whoami /groups, net localgroup Administrators, Get-LocalGroupMember.
  • Common mistakes: thinking a rename hides the admin, confusing local and domain accounts, forgetting SYSTEM outranks Administrator, and running enumeration outside your authorized scope.
  • Defensive core: detect changes to privileged groups via events 4728/4732 (adds) and 4733/4729 (removes); log timestamp, actor SID, target SID, group SID, source, result, correlation id; never log secrets. Every finding gets a remediation and a verification that the fix worked.
  • Remember: decoding an identity is not the same as being authorized to touch it — practise only on systems you own or are explicitly permitted to test.