HackBlue

Tools · Identity defense · 02 / 05

Closing an attack path in AD and proving it with a second collection

Remove an over-broad delegation found in BloodHound, re-collect the lab domain, compare the Tier Zero path count before and after, and catch a second path the first fix exposed.

12 min read · practice only with authorization

Making the change

The finding is that Helpdesk has GenericAll on OU=Servers. Helpdesk needs to reset passwords for user accounts, not to control servers. The fix removes the inherited ACE from the OU and grants a narrow Reset Password right on the user OU instead. dsacls shows the current entries before and after.

Snippet
dsacls "OU=Servers,DC=lab,DC=local" | findstr /i helpdesk
  Allow LAB\Helpdesk   FULL CONTROL   <Inherited from parent>

# remove from the parent where it was granted, then confirm
dsacls "OU=Servers,DC=lab,DC=local" | findstr /i helpdesk
(no output)

Measuring after the change

Collect again with the same method and import the new zip. Running the same counting query gives a number to put next to the first one. Keep both zips and both counts in the change ticket.

Snippet
Before (2026-10-20): users with a path to Domain Admins = 212
After  (2026-11-02): users with a path to Domain Admins = 9

Worked follow-up: the nine that remain

Nine users still have paths. All nine go through one computer, WS-ADM-03, where a Domain Admin has a logged-on session and the nine users are local administrators. That is a session edge, not an ACL: the admin used an ordinary workstation instead of a privileged access workstation.

The fix here is procedural and technical: Domain Admins sign in only to Tier Zero systems, enforced with a GPO that denies their logon elsewhere, and the nine local admin grants are reviewed. A third collection a week later shows zero.

Snippet
MATCH p = (u:User)-[:AdminTo]->(c:Computer)-[:HasSession]->(a:User)-[:MemberOf*1..]->(g:Group)
WHERE g.objectid ENDS WITH '-512'
RETURN c.name, collect(DISTINCT u.name), collect(DISTINCT a.name)

Making it a routine

Schedule the collection monthly and track the count as a metric. Session data changes daily, so a single snapshot can understate exposure; DCOnly plus a session collection from a sample of workstations gives a steadier picture.

Diagram

ACL paths versus session paths

They need different fixes.

ACL edge

Example. Helpdesk has GenericAll on OU=Servers

Lasts. Until someone changes the ACL

Fix. Remove or narrow the delegation

Session edge

Example. A Domain Admin is logged on to WS-ADM-03

Lasts. As long as the session

Fix. Restrict where Tier Zero accounts may sign in

Check yourself

1. How do you show an AD permission fix worked?

2. Nine remaining paths go through a workstation with a Domain Admin session. What kind of fix applies?

3. Why is a single collection a weak picture of session exposure?