Internal Network & Active Directory · beginner · ~10 min

AD objects: users, groups, computers, and OUs

By the end of this lesson you will be able to: - Name the four core Active Directory (AD) object types — users, groups, computers, and organizational units (OUs) — and describe what each represents. - Explain what an **attribute** is and read the security-relevant attributes on a user object (`memberOf`, `description`, `servicePrincipalName`, `userAccountControl` flags, `pwdLastSet`). - Identify the **high-value groups** (Domain Admins, Enterprise Admins, and the "almost-admin" groups) that defenders must protect and attackers seek. - Explain **transitive (nested) group membership** and trace how a user inherits rights through a chain of nested groups. - Recognize **risky account flags** (SPN set, Kerberos pre-authentication disabled, password-never-expires) and explain why each is a misconfiguration worth auditing. - Perform **authorized, read-only enumeration** as reconnaissance, apply the ethics/authorization rules that govern it, and **verify** that a remediation actually removed a finding.

Overview

Security objective. The asset you are learning to protect is the directory metadata inside Active Directory — the accounts, groups, machine records, and the attributes hanging off them. The threat is an attacker who has gained any authenticated foothold (a phished password, a weak service-account password) and now reads that metadata to find a path to privilege. By the end you will be able to detect the object-level misconfigurations that hand attackers that path — over-privileged accounts, dangerous flags, and secrets leaked into text fields — and prevent them before an incident.

In the prerequisite What is Active Directory? you learned that Active Directory is the central directory service most organizations use to manage who can log in and what they can touch. This lesson zooms in on the contents of that directory: the objects it stores.

Think of AD as a large, structured database. Almost everything in the environment is represented as an object: every employee account, every security group, every laptop and server, and the containers used to organize them. Each object is described by a set of named properties called attributes — much like rows and columns in a table, or fields in a struct.

Why does this matter for security? Because the directory is, by design, broadly readable. Any authenticated user — even a brand-new, unprivileged account — can query most objects and attributes. That means the first step of nearly every AD security assessment (and every real attack) is enumeration: listing objects and reading their attributes to build a map of the environment.

That map answers the questions that decide everything that follows:

  • Who is privileged? Which accounts belong to Domain Admins and other powerful groups.
  • What is misconfigured? Which accounts carry risky flags an attacker can abuse.
  • Where do secrets leak? Whether passwords or hints sit in fields like description.

From a defender's seat, the same enumeration is how you find and fix these problems before someone else exploits them. This lesson stays at the conceptual level — what the objects are and what to look for. The mechanics of querying AD over LDAP and the authentication protocols behind it (Kerberos and NTLM authentication) come in the next lessons.

Why it matters

Almost every AD attack path begins with object enumeration, which is exactly why defenders need to understand objects just as well as attackers do.

For attackers (in an authorized test): enumeration is reconnaissance that requires no exploitation. Reading attributes can hand over a privilege-escalation route on a plate — a service account with a weak password, an admin whose password never changes, or a literal credential typed into a description field. None of that requires firing a single exploit; it is just reading data the directory willingly returns.

For defenders: the same visibility is a gift. If you can enumerate your own directory, you can audit it: find over-privileged accounts, empty out leaked secrets, tighten group membership, and remove dangerous flags. Most catastrophic AD breaches trace back to a small misconfiguration that routine enumeration would have surfaced months earlier.

It also matters because AD is everywhere. The overwhelming majority of medium and large enterprises run Windows domains for identity. A single domain often governs thousands of accounts and machines, so one weak object can compromise the whole organization. Understanding objects is the foundation for the higher-level attacks and defenses you will study later (Kerberoasting, password spraying, AS-REP roasting, and attack-path analysis). Skipping it means treating those later techniques as magic instead of as the logical consequence of readable, misconfigured objects.

Core concepts

Active Directory stores everything as objects, and every object is described by attributes (named properties, like sAMAccountName or description). We will teach the four object types, then the groups and flags that carry the most security weight.

1. Object types

Definition. An AD object is a single entry in the directory representing a real-world thing — a person's account, a group, a machine, or a container.

The four you will meet most:

Object Represents Why it matters
User A login account (person or service) Holds credentials, group memberships, and risky flags
Group A collection that grants rights Membership = privilege; nesting hides inherited rights
Computer A domain-joined machine Has its own account; some have local admin reach
OU (organizational unit) A container for organizing objects Used to apply Group Policy and delegate control

How it works internally. Objects live in a hierarchical tree. OUs are containers that can hold users, computers, and other OUs. Each object has a unique distinguished name (DN) describing its full path, for example CN=Jane Doe,OU=Finance,DC=corp,DC=local. Attributes hang off each object as name/value pairs.

When OUs matter / when they don't. OUs are about organization and policy targeting — they are not security groups, and placing an account in an OU does not grant it a permission. A common beginner mistake is to confuse "in the Finance OU" with "a member of a Finance group." They are different concepts: OUs organize, groups authorize.

Domain: corp.local
|
+-- OU: Finance
|     +-- User: jane.doe   (attributes: sAMAccountName, memberOf, description, ...)
|     +-- Computer: FIN-PC-07
|
+-- OU: IT
|     +-- User: svc_backup (a SERVICE account that logs in as a program)
|
+-- Group: Domain Admins   (most powerful group in the domain)

Knowledge check: In your own words, what is the difference between an OU and a group? (Answer: an OU is a container for organizing objects and targeting Group Policy; a group is what actually grants rights. Being in an OU never grants a permission by itself.)

2. Attributes

Definition. Attributes are the fields that describe an object. Reading them is the whole point of enumeration.

Security-relevant attributes on a user include:

  • sAMAccountName — the short logon name (e.g., jane.doe).
  • memberOf — the groups this account belongs to.
  • description / info — free-text fields that sometimes contain passwords or hints (a real and common leak).
  • servicePrincipalName (SPN) — present on accounts that run services; an SPN makes an account a Kerberoasting target.
  • userAccountControl — a bitfield holding flags like password never expires and do not require Kerberos pre-authentication.
  • lastLogon / pwdLastSet — timing data that reveals stale or rarely changed accounts.

Pitfall. Treating description as harmless. Admins frequently type onboarding notes or even passwords there because it is convenient — and every authenticated user can read it.

Knowledge check: Which single attribute would you read first to find out whether an account is over-privileged? (Answer: memberOf — but only once you resolve it transitively, because nested groups do not appear in the direct list.)

3. Groups and transitive (nested) membership

Definition. A group is an object that bundles rights. Add a user to the group and the user gains the group's permissions.

How nesting works. Groups can contain other groups, and membership is transitive: if Group A is a member of Group B, then every member of A effectively belongs to B and inherits B's rights. This is powerful and dangerous, because the inheritance can be several layers deep and is easy to overlook.

Domain Admins
   ^
   | (member)
Helpdesk-Admins  <-- a group, not a person
   ^
   | (member)
jane.doe         <-- inherits Domain Admins rights, even though she is
                     NOT listed directly in Domain Admins

When to use nesting: legitimate administration uses it to manage rights at scale (e.g., a regional admin group nested into a global one). When it bites: auditors who only check direct membership of Domain Admins miss users who are admins through a chain. Always resolve membership transitively.

Pitfall. Reporting "Domain Admins has 3 members" by reading the group's direct member list, when nesting actually grants the rights to dozens of accounts.

Knowledge check (predict the result): Given the diagram above, is jane.doe a Domain Admin? Why or why not? (Answer: yes, effectively — her membership in Helpdesk-Admins, which is nested into Domain Admins, grants her Domain Admin rights even though her name is not in the Domain Admins direct list.)

4. High-value ("crown jewel") groups

Definition. Groups whose members can take full or near-full control of the domain or forest.

  • Domain Admins — full control of the domain. In a single-domain environment this is the prize.
  • Enterprise Admins — control across the entire forest (all domains).
  • Administrators (the built-in group, especially on a Domain Controller) — effectively domain control.
  • "Almost-admin" groupsAccount Operators, Backup Operators, Server Operators, DnsAdmins, Print Operators. Each has a well-known technique to escalate to full admin. They look harmless but are not.
  • Service accounts — not a group, but frequently over-privileged and protected by weak, rarely changed passwords.

Pitfall. Protecting only Domain Admins while leaving Backup Operators or DnsAdmins wide open. Defenders must treat the almost-admin groups as Tier-0 too.

5. Risky account flags

Three conditions (mostly bits inside userAccountControl, plus the presence of an SPN) turn an ordinary account into an attack surface:

Flag / attribute What it means Why it is risky
SPN is set Account runs a Kerberos service Enables Kerberoasting — its service ticket can be requested by any user and cracked offline
Pre-authentication disabled (DONT_REQ_PREAUTH) Account skips Kerberos pre-auth Enables AS-REP Roasting — a crackable hash returned without any password attempt
Password never expires Password is set once, forever A leaked or weak password stays valid indefinitely

Pitfall. Assuming these flags are exotic. They are extremely common in real domains because they were set years ago "to make something work" and never revisited. Routine enumeration is how you find them.

Knowledge check (find the misconfiguration): A service account has an SPN, password never expires, and a 9-year-old pwdLastSet. Name two distinct risks. (Answer: (1) the SPN makes it Kerberoastable — any user can request its ticket and crack the password offline; (2) with password-never-expires and a 9-year-old password, that password is almost certainly weak by modern standards and has never rotated, so a crack yields long-lived access.)

Threat model (single-domain AD)

Entry point                Trust boundary            Asset
-----------                --------------            -----
Any authenticated user --> (low-priv account can --> Directory metadata
(phished/weak password)     read most attributes)     (memberships, SPNs,
                                                       flags, descriptions)
                                  |
                                  v   misconfig found
                           Privilege escalation  -->  Domain Admins (game over)

The key insight: the trust boundary between "any user" and "reads sensitive metadata" is very thin. That is why minimizing what objects expose is a real control, not paranoia.

Knowledge check (authorization): Why must every technique below run only in an authorized lab? (Answer: even read-only enumeration of a directory you do not own or have written permission to test is unauthorized access under most computer-misuse laws and engagement rules — the read/write distinction does not make it legal.)

Syntax notes

This is a concept lesson, so there is no programming syntax. Instead, learn the shape of an object and the naming conventions you will see constantly when reading AD data.

Object:    user
DN:        CN=svc_sql,OU=IT,DC=corp,DC=local   <- full path (distinguished name)
Attributes (name : value):
  sAMAccountName        : svc_sql              <- short logon name
  memberOf              : CN=Domain Admins,... <- transitive memberships count too
  servicePrincipalName  : MSSQLSvc/db01:1433   <- presence => Kerberoasting target
  description           : "DB svc - see vault" <- NEVER store secrets here
  userAccountControl    : 0x10200              <- bitfield holding account flags

Key conventions:

  • DN reads right-to-left as a path: DC = domain component, OU = organizational unit, CN = common name.
  • sAMAccountName is the everyday logon name; computer accounts end in $ (e.g., FIN-PC-07$).
  • memberOf lists groups, but to get the true privilege you must resolve nested groups transitively.
  • userAccountControl is a number where individual bits are flags; tools decode it for you into readable names like PASSWORD_NEVER_EXPIRES and DONT_REQ_PREAUTH, so you rarely parse the raw hex by hand.

Lesson

Active Directory stores everything as objects, and each object has attributes (named properties). Enumerating these objects is the first move once you can query the directory.

The object types

  • Users — accounts with attributes such as username, group memberships, description (which sometimes holds passwords!), servicePrincipalName, last logon, and flags like "password never expires."
  • Groups — collections that grant rights. Nesting matters: membership is transitive, meaning a member of a nested group inherits the parent group's rights.
  • Computers — every domain-joined machine is an object with its own account.
  • Organisational Units (OUs) — containers used for structure and for targeting Group Policy.

High-value groups to hunt

  • Domain Admins / Enterprise Admins — full control over the domain or forest. This is the goal.
  • Administrators (on the Domain Controller) — effectively equivalent.
  • Account Operators, Backup Operators, DnsAdmins, Server Operators — "almost-admin" groups with known escalation tricks.
  • Service accounts — often over-privileged and protected by weak passwords.

What enumeration yields

Enumeration tells you:

  • Who belongs to the powerful groups.
  • Which accounts have risky flags (Kerberos pre-auth disabled, SPNs set, "password never expires").
  • Where credentials might be exposed (the description field, GPO files).

This map drives every later attack. Tools query AD over LDAP, which is covered in the next lesson.

Code examples

Because no programming is involved, the example is a realistic read-only enumeration session. It is shown in the INSECURE (what an attacker/what a misconfigured directory exposes) -> SECURE (remediation) -> VERIFY (prove the fix) shape.

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

The insecure state here is a directory that leaks a secret and grants admin through nesting. Reproduce it only in your own lab domain controller (an isolated VM). Setting up the bad state:

# AUTHORIZED LAB ONLY. Creates an intentionally-vulnerable state to study.
# Do NOT run against any directory you do not own / are not authorized to test.
Set-ADUser -Identity svc_sql -Description "DB service acct pw: <lab-placeholder-P@ss>"
# add a user to Domain Admins indirectly, through a nested group:
Add-ADGroupMember -Identity "Helpdesk-Admins" -Members jane.doe
Add-ADGroupMember -Identity "Domain Admins"   -Members "Helpdesk-Admins"

Now the read-only enumeration an assessor (or attacker) would run — it queries, it changes nothing:

# Read-only enumeration of objects/attributes. Assets touched: directory metadata.

# 1) Members of the crown-jewel group, resolving nesting transitively.
Get-ADGroupMember -Identity "Domain Admins" -Recursive |
    Select-Object name, objectClass

# 2) Accounts with an SPN set (potential Kerberoasting targets).
Get-ADUser -Filter { servicePrincipalName -like "*" } `
    -Properties servicePrincipalName, pwdLastSet |
    Select-Object sAMAccountName, servicePrincipalName, pwdLastSet

# 3) Accounts whose password never expires.
Get-ADUser -Filter { passwordNeverExpires -eq $true } `
    -Properties passwordNeverExpires |
    Select-Object sAMAccountName

# 4) Credentials accidentally left in the description field.
Get-ADUser -Filter { description -like "*" } -Properties description |
    Where-Object { $_.description -match "pass|pwd|secret" } |
    Select-Object sAMAccountName, description

Expected output (shape, not exact values). A short table per query, e.g.:

sAMAccountName  servicePrincipalName  pwdLastSet
--------------  --------------------  -----------
svc_sql         MSSQLSvc/db01:1433    1/3/2017 ...

Query 1's recursive result would include jane.doe even though she is not a direct member of Domain Admins. Query 4 would surface the svc_sql description leak.

2. SECURE — remediate the findings

# AUTHORIZED LAB ONLY. Fix each finding found above.

# Fix the leak: move the real secret to a vault, blank the description.
Set-ADUser -Identity svc_sql -Description "DB service acct - secret in vault"

# Fix over-privilege: remove the nested path to Domain Admins.
Remove-ADGroupMember -Identity "Domain Admins" -Members "Helpdesk-Admins" -Confirm:$false

# Reduce standing risk on the service account (rotate + require expiry, or use a
# group Managed Service Account so AD rotates the password automatically).
Set-ADUser -Identity svc_sql -PasswordNeverExpires $false

3. VERIFY — prove the fix rejects the bad state and accepts the good one

# Re-run the SAME read-only checks. A remediated directory returns EMPTY results.

# (a) jane.doe should no longer appear as an effective Domain Admin:
Get-ADGroupMember -Identity "Domain Admins" -Recursive |
    Where-Object { $_.name -eq "jane.doe" }        # expect: no output

# (b) no description should match a secret pattern:
Get-ADUser -Filter { description -like "*" } -Properties description |
    Where-Object { $_.description -match "pass|pwd|secret" }  # expect: no output

# (c) confirm the flag is cleared (should now be False):
(Get-ADUser svc_sql -Properties passwordNeverExpires).passwordNeverExpires

Why VERIFY matters. A fix you do not re-test is a hope, not a control. Empty results from (a) and (b), and False from (c), prove the finding is gone. This same before/after pattern is how a report's "retest" section is written.

Edge cases to expect. Some attributes are empty or hidden if your account lacks read rights on them; very large domains may return thousands of rows (page or filter with a tighter -Filter and -Properties); and passwordNeverExpires reported by the module already decodes the underlying userAccountControl bit for you, so you do not parse the raw number by hand.

Defender's version. A blue-teamer runs the enumeration queries on a schedule and alerts when a new account gains an SPN, when crown-group membership changes, or when a description matches a secret pattern. Same enumeration, opposite intent.

Line by line

Walking through the enumeration and verification step by step:

Step Command What happens What you learn
1 Get-ADGroupMember "Domain Admins" -Recursive Sends an LDAP query for the group's members; -Recursive expands nested groups The true admin set, including users who are admins only through nesting
2 Get-ADUser -Filter { servicePrincipalName -like "*" } Returns every user object that has any SPN value Which accounts are Kerberoasting candidates
3 Get-ADUser -Filter { passwordNeverExpires -eq $true } The module reads userAccountControl, decodes the flag, and matches Accounts whose password risk is permanent
4 `... description -like "*" ... -match "pass pwd secret"`
V `... -Recursive Where name -eq jane.doe` (empty) Re-runs step 1 after the fix and looks for the removed user

Tracing step 1 in detail. Suppose the domain has the chain jane.doe -> Helpdesk-Admins -> Domain Admins.

  • A non-recursive query would report Domain Admins members as just the direct entries (perhaps Administrator and Helpdesk-Admins).
  • With -Recursive, the query follows Helpdesk-Admins down and resolves its members, so jane.doe now appears in the result.
  • Conclusion: jane.doe is an effective Domain Admin. Reading only direct membership would have hidden that fact — which is exactly the kind of blind spot enumeration is meant to remove.

Tracing the verification. After Remove-ADGroupMember breaks the Helpdesk-Admins -> Domain Admins link, the recursive query no longer has a path from jane.doe up to Domain Admins, so she drops out of the result. The Where-Object { $_.name -eq "jane.doe" } filter therefore returns nothing — the empty result is the evidence that the over-privilege finding is closed.

Why the results are produced. None of the enumeration commands change state; they read attributes the directory exposes to authenticated users. The value comes entirely from interpreting the attributes correctly (transitive membership, decoded flags, free-text leaks) and from re-reading them after remediation to confirm the change.

Common mistakes

Mistake 1 — Reading only direct group membership.

  • Wrong approach: "Domain Admins lists 3 members, so only 3 people are admins."
  • Why it is wrong: membership is transitive. Nested groups can add many more effective admins that the direct list never shows.
  • Corrected approach: always resolve recursively (e.g., Get-ADGroupMember -Recursive) and report the full effective set.
  • How to recognize/prevent it: whenever you see a group, ask "is anything nested inside it?" before trusting the count.

Mistake 2 — Confusing OUs with groups.

  • Wrong approach: "jane is in the Finance OU, so she has Finance permissions."
  • Why it is wrong: OUs organize objects and target Group Policy; they do not grant permissions. Permissions come from groups.
  • Corrected approach: check the user's memberOf (groups), not which OU contains them.
  • How to recognize it: if your reasoning about access mentions an OU, you are probably looking at the wrong thing.

Mistake 3 — Ignoring "almost-admin" groups.

  • Wrong approach: hardening only Domain Admins and Enterprise Admins.
  • Why it is wrong: Backup Operators, Account Operators, DnsAdmins, and similar groups each have a documented path to full domain control.
  • Corrected approach: treat all of them as Tier-0; audit and minimize their membership too.
  • How to prevent it: keep a written Tier-0 inventory that explicitly lists the almost-admin groups.

Mistake 4 — Assuming the directory is private.

  • Wrong approach: "We put the password in description, but only admins can see the directory."
  • Why it is wrong: most attributes are readable by any authenticated user, including a freshly compromised low-privilege account.
  • Corrected approach: never store secrets in object attributes; store them in a vault, and audit description/info for accidental leaks.

Mistake 5 — Calling it fixed without re-testing.

  • Wrong approach: remove a user from a group or blank a description, then close the finding.
  • Why it is wrong: the change may have hit the wrong object, or a second nested path may still grant the right.
  • Corrected approach: re-run the exact same read-only enumeration and confirm an empty result before marking the finding remediated.

Debugging tips

Things that commonly go wrong while enumerating, and how to reason about them:

"Access denied" or empty attribute values.

  • Likely cause: your account lacks read permission on that attribute, or you are not authenticated to the domain.
  • Steps: confirm you are running as a domain account; check whether the attribute is one the directory restricts (some are protected/confidential); try a different, less-privileged attribute to confirm connectivity.

"Cannot find a module / command not recognized."

  • Likely cause: the ActiveDirectory PowerShell module (RSAT) is not installed in your lab box.
  • Steps: install RSAT in the lab VM, or fall back to a generic LDAP query tool. (Tooling/LDAP details are the next lesson's focus.)

A query returns thousands of rows.

  • Likely cause: a broad filter (-like "*") in a large domain.
  • Steps: narrow the -Filter, request only the attributes you need with -Properties, and page the results instead of dumping everything.

Membership numbers do not match between tools.

  • Likely cause: one tool shows direct members and another shows transitive members.
  • Steps: confirm whether each tool resolves nesting; compare like-for-like (always prefer the transitive view for security).

Verification query still returns the finding.

  • Likely cause: a second nested path still grants the right, or the remediation targeted the wrong object.
  • Steps: re-run the full recursive query (not a filtered one) and trace every path into the crown group; confirm the DN you edited matches the DN in the finding.

Questions to ask when results look wrong:

  • Am I looking at direct or transitive membership?
  • Is this attribute empty because it is unset, or because I cannot read it?
  • Am I confusing an OU (container) with a group (permission)?
  • Is the flag I am seeing decoded for me, or am I misreading a raw userAccountControl number?
  • After a fix, did I re-run the same check and get an empty result?

Memory safety

Security & safety

Authorization and ethics (read first). Enumeration touches a live identity system. Run these techniques only against systems you own or are explicitly, in-writing authorized to test — a personal lab domain controller, an isolated VM, or a sanctioned engagement with a signed scope. Never enumerate a third-party domain. Even though enumeration is read-only, unauthorized querying of someone else's directory is still unauthorized access.

Authorization checklist (before any lab work):

  • The domain runs on hardware/VMs I own, or I hold written authorization naming this scope.
  • The environment is isolated (host-only / internal network), not reachable from production or the internet.
  • I know the rollback/reset plan for the lab (snapshot before, restore after).
  • No real user data, real secrets, or real hostnames are used — only lab placeholders.

Threat model (single-domain AD):

Entry point                Trust boundary            Asset
-----------                --------------            -----
Any authenticated user --> (low-priv account can --> Directory metadata
(phished/weak password)     read most attributes)     (memberships, SPNs,
                                                       flags, descriptions)
                                  |
                                  v   misconfig found
                           Privilege escalation  -->  Domain Admins (game over)

The key insight: the trust boundary between "any user" and "reads sensitive metadata" is very thin. That is why minimizing what objects expose is a real control.

Defensive practices (at least as important as the offensive view):

  • Minimize crown-group membership. Keep Domain Admins, Enterprise Admins, and the almost-admin groups as small as possible; review them regularly. Resolve membership transitively when you audit.
  • Remove risky flags. Eliminate unnecessary SPNs; never disable Kerberos pre-authentication; enforce password expiry, and give service accounts long, unique, vaulted passwords (or use group Managed Service Accounts so AD rotates them automatically).
  • Scrub free-text fields. Audit description and info for anything resembling a secret; move real secrets into a password vault.
  • Least privilege for read. Where supported, mark sensitive attributes confidential so a low-priv account cannot harvest them.

Detection and logging. Defenders should baseline objects and alert on change. Log: timestamp, the actor (who queried/changed), the source host, the target object (DN), the result, and the security decision (allowed/denied), plus a correlation id to tie related events together. Watch specifically for: a new account gaining an SPN, membership changes to crown groups, accounts toggling passwordNeverExpires or pre-auth, and bulk/broad attribute reads (a signature of enumeration). Never log: passwords, Kerberos tickets or hashes, session cookies, private keys, or the leaked secret string you found — log only that a match occurred and where.

How false positives arise. Legitimate administration also reads AD in bulk (backup software, sync connectors, IAM tools, an authorized assessor). Baseline these known service identities and source hosts so their activity does not flood the alert queue; alert on deviation from the baseline, not on enumeration in the abstract.

Testing your fix (mitigation verification). After removing a leaked password from a description or trimming a group, re-run the same read-only enumeration and confirm the finding is gone — the description no longer matches the secret pattern, or the user no longer appears in the recursive Domain Admins membership. An empty result is your proof. Then restore the lab snapshot when finished.

Real-world uses

Concrete authorized real-world use. Internal penetration testers and red teams begin almost every engagement by enumerating AD objects: they map crown-group membership, list SPN accounts to plan Kerberoasting, and search description fields for leaked credentials — all under a signed scope. On the defensive side, blue teams and identity-governance tools run continuous AD audits that flag the very same conditions — over-privileged accounts, stale service accounts, dangerous flags — so they can be fixed before an incident. Attack-path analysis tools build a graph of these objects and relationships to show the shortest route from any user to Domain Admins, which defenders use to cut the most dangerous edges first.

Professional best-practice habits

Beginner rules:

  • Always confirm written authorization before enumerating anything.
  • Distinguish OUs (organization) from groups (permission) every time.
  • Resolve group membership transitively, never just directly.
  • Never store secrets in object attributes; treat description/info as public.
  • Re-run the same read-only check after any fix to verify it.

Advanced practices:

  • Maintain a Tier-0 inventory that includes the almost-admin groups, not just Domain/Enterprise Admins.
  • Replace standing service-account passwords with (group) Managed Service Accounts where possible, and rotate the rest.
  • Mark sensitive attributes confidential and baseline + alert on object changes (membership, flags, new SPNs), tuning out known service identities to control false positives.
  • Scope and rate-limit your own enumeration in production assessments to avoid disrupting the directory, and document every query for the engagement report and retest section.

Practice tasks

Work through these in order; each one builds on the last. Do every task only in your own authorized lab (an isolated VM domain controller), and snapshot before you start so you can reset afterward.

Beginner 1 — Classify the objects.

  • Objective: Given a small directory tree, label each entry as user, group, computer, or OU.
  • Requirements: Use a sample tree (build one in your lab or sketch one). For each object, write one sentence on what it represents.
  • Example input/output: Input FIN-PC-07$ -> Output: "Computer object (the $ suffix marks a machine account)."
  • Hints: Machine accounts end in $; OUs contain other objects; groups grant rights.
  • Concepts: object types, DN structure.

Beginner 2 — Read one user's attributes.

  • Objective: For a single lab user, list sAMAccountName, memberOf, description, and whether passwordNeverExpires is set.
  • Requirements: Note which attributes are empty vs. populated, and flag anything suspicious in description.
  • Constraints: Read-only; change nothing.
  • Hints: The module decodes passwordNeverExpires for you.
  • Concepts: attributes, risky flags, leaks.

Intermediate 1 — Resolve transitive membership.

  • Objective: Find the effective members of Domain Admins, including nested groups.
  • Requirements: Show both the direct member list and the recursive list, and explain any difference.
  • Example I/O: Direct: Administrator, Helpdesk-Admins -> Recursive adds jane.doe.
  • Hints: Use a recursive query; if there is no difference, add a nested group in your lab to create one.
  • Concepts: transitive/nested membership.

Intermediate 2 — Hunt risky flags.

  • Objective: Produce a list of accounts that have an SPN set OR have passwordNeverExpires, and rank them by pwdLastSet (oldest = highest risk).
  • Requirements: Output a small table of sAMAccountName, the risky condition, and pwdLastSet.
  • Constraints: Read-only enumeration only.
  • Hints: Combine two queries; sort by date.
  • Concepts: SPNs, account flags, attribute reading.

Challenge — Audit, remediate, and verify (defensive conclusion).

  • Objective: In your lab, plant a leaked password in one user's description and add a user to Domain Admins via a nested group. Then (a) write enumeration that detects both findings, (b) remediate them, and (c) re-run the enumeration to prove the findings are gone.
  • Requirements: Document the before/after output, what you would log for detection (timestamp, actor, source, target object, result, correlation id — never the secret itself), and which control fixed each issue.
  • Constraints: Lab only; never log the secret string. Restore the snapshot when done (lab cleanup/reset).
  • Defensive conclusion: the task is only complete when the verification queries return empty — remediation is proven, not assumed.
  • Hints: Map this to the threat model and the mitigation-verification steps from the safety notes.
  • Concepts: enumeration, transitive membership, leaks, detection/logging, mitigation verification.

Summary

  • AD stores everything as objectsusers, groups, computers, and OUs — each described by attributes (name/value properties). Remember: OUs organize; groups authorize.
  • Enumeration is reading those objects and attributes. It is the read-only first step of every AD attack and every AD audit, and it answers: who is privileged, what is misconfigured, where secrets leak.
  • The most important attributes to read are memberOf (resolved transitively, because nested groups inherit rights), servicePrincipalName (Kerberoasting target), the userAccountControl flags password-never-expires and pre-auth-disabled (AS-REP roasting), and description (a common credential leak).
  • The crown-jewel groups are Domain Admins and Enterprise Admins, plus the almost-admin groups (Backup/Account/Server Operators, DnsAdmins) — protect them all as Tier-0.
  • Key commands (lab): Get-ADGroupMember -Recursive for transitive membership; Get-ADUser -Filter { servicePrincipalName -like "*" } for SPNs; Get-ADUser -Filter { passwordNeverExpires -eq $true } for the flag; re-run the same query after a fix to VERIFY.
  • Common mistakes: reading only direct membership, confusing OUs with groups, ignoring almost-admin groups, assuming the directory is private, and closing a finding without re-testing.
  • Remember the ethics: enumerate only systems you are authorized to test, defend at least as hard as you probe, log the event (never the secret), and verify every fix by re-running the same read-only checks. The map you build here is the foundation for Kerberoasting, password spraying, and attack-path analysis.