Skip to content
08 · Object & ACL SecurityPart 4 of 4Advanced

Attack path management with BloodHound for defenders

Use BloodHound defensively: tag Tier Zero correctly, find choke points, fix attack paths in the right order, and track exposure over time with safe collection.

Florian Amette7 min read

Most Active Directory compromises follow a path rather than a single vulnerability. A helpdesk group can reset a server admin's password. That admin has a session on a server where a Domain Admin also logged on. A service account holds GenericWrite over a group nested into a group with control over a GPO linked to the Domain Controllers OU. Each step is a normal permission somebody granted on purpose. Together they are a route to domain control, and attackers find them with the same graph tools defenders have.

BloodHound turns directory data into that graph. The ACL pillar guide introduces it as an audit tool. This guide covers running it as an ongoing attack path management program: collecting safely, defining Tier Zero precisely, finding choke points, fixing in the order that removes the most paths per change, and measuring progress.

Collect safely

BloodHound Community Edition ingests data from SharpHound (on-premises AD) and AzureHound (Entra ID). BloodHound Enterprise adds continuous collection and choke-point scoring. Alternatives with similar models include Semperis Forest Druid (focused on Tier 0) and Adalanche. The method below applies to all of them.

Collection rules for a defensive program:

  • Dedicated account. A normal domain user with no extra rights is enough for LDAP data. Local group and session collection works better with rights on member computers, but do not use a Domain Admin to get them. Give the account a long random password, deny it interactive logon, and monitor its use.
  • Dedicated host. Run the collector from a Tier 0 management host or a hardened assessment VM, never a user workstation.
  • Tell the SOC. SharpHound traffic (mass LDAP queries, SAMR and session enumeration across hosts) is exactly what your detections should alert on. Allowlist the host and account for the collection window rather than tuning the detection away.
  • Protect the output. The ZIP files and the BloodHound database are a map of how to own your domain. Store them encrypted, restrict access to Tier 0 and the assessment team, and set a retention period.
  • Collect sessions repeatedly. A single session snapshot misses most exposure. Collect several times across a week, or use a continuous collector.

Define Tier Zero before looking at paths

A path is only an attack path if it ends somewhere that matters. BloodHound pre-tags obvious Tier Zero objects (Domain Admins, Enterprise Admins, domain controllers, the domain object and similar). In recent releases this has become Privilege Zones with a Tier Zero zone. The default tagging is a starting point, not your Tier Zero. Add everything with control over the control plane:

  • Entra Connect servers and their AD DS connector account, and ADFS servers.
  • AD CS enterprise CAs and certificate templates that allow authentication as anyone (ESC1-style misconfigurations).
  • Backup servers and accounts that can restore or read DC backups.
  • Hypervisor and storage management that hosts virtual DCs.
  • Configuration management and PAM systems that run code on DCs or hold Tier 0 credentials.
  • GPOs linked to the Domain Controllers OU or the domain root, and the OUs holding Tier 0 objects.
  • Accounts holding replication rights, as found in the DCSync rights audit.

The list comes from your Tier 0 inventory. If the graph and the inventory disagree, one of them is wrong, and both errors are findings. Anything reachable from Tier Zero with a control edge is Tier Zero too, whether you meant it to be or not.

Measure: queries that matter

The built-in pathfinding is useful for exploring. Programs run on a fixed set of saved queries whose results can be counted. These Cypher examples work in BloodHound CE's query view. Adjust the target to your own Tier Zero tagging:

Cypher
// Principals with a direct control edge onto Domain Admins or the domain object.
// Expect built-in admin groups and DCs; everything else needs an owner.
MATCH (n)-[r:GenericAll|GenericWrite|WriteDacl|WriteOwner|Owns|AddMember|AllExtendedRights|DCSync|GetChangesAll]->(t)
WHERE t:Domain OR (t:Group AND t.objectid ENDS WITH '-512')
RETURN n.name, type(r), t.name
Cypher
// Domain Admins with sessions on computers that are not domain controllers
MATCH (c:Computer)-[:HasSession]->(u:User)-[:MemberOf*1..]->(g:Group)
WHERE g.objectid ENDS WITH '-512'
  AND NOT (c)-[:MemberOf]->(:Group {name: 'DOMAIN CONTROLLERS@CORP.EXAMPLE.COM'})
RETURN DISTINCT c.name, u.name
Cypher
// Shortest paths from Domain Users to Domain Admins
MATCH p = shortestPath((s:Group)-[*1..]->(t:Group))
WHERE s.objectid ENDS WITH '-513' AND t.objectid ENDS WITH '-512'
RETURN p

Also track, per week: the number of principals with any path to Tier Zero, the share of enabled users with such a path, and the number of distinct first-degree edges into Tier Zero. Those three numbers are your program's KPIs.

Find the choke points

A choke point is an edge or node that many paths pass through. Removing one choke-point edge can break hundreds of paths. Removing the edge at the start of one path usually breaks just that one. BloodHound Enterprise calculates this. In CE you can approximate it:

  1. Export all shortest paths from large source groups (Domain Users, Authenticated Users, Domain Computers) to your Tier Zero targets.
  2. Count how often each edge appears across those paths.
  3. Sort by count, then by how close the edge is to Tier Zero.

Weight the count by the size of the source. A path that starts at Domain Users puts every employee account one phishing email away from Tier Zero. A path that starts at a single disabled service account is much less urgent, even if it is shorter. Also record which edges are structural (group membership, ACLs, GPO links) and which are transient (sessions). Structural edges are fixed once. Transient edges need a change in how people and tools work.

Edges one hop from Tier Zero almost always win. They sit on every path that reaches the target through them, and removing them is usually a single ACL or membership change on a well-known object.

Fix order

Work in this order. Each step removes more exposure per change than the next.

  1. Control edges into Tier Zero from outside it. GenericAll, WriteDacl, WriteOwner, Owns, AddMember and replication rights held by non-Tier-Zero principals on Tier Zero objects. Remove them, or accept the principal into Tier Zero and protect it accordingly. Check AdminSDHolder and the domain root first.
  2. Tier Zero credential exposure. HasSession edges from Tier Zero users onto lower-tier computers. The fix is operational: PAWs, logon restrictions and authentication policies, not ACL changes.
  3. Broad principals with control. Any edge that starts at Everyone, Authenticated Users, Domain Users or Domain Computers. These make every account a starting point.
  4. GPO and OU control over Tier Zero. Write rights on GPOs linked above Tier Zero objects, and gPLink write on those OUs.
  5. Local admin sprawl. AdminTo fan-out through shared local admin passwords or broad groups in local Administrators. Deploy Windows LAPS and remove domain groups from local admin.
  6. Delegation and certificate edges. AllowedToDelegate, AllowedToAct, AddKeyCredentialLink and AD CS ESC edges, handled with the respective area guides.

For ACL edges, remove the specific ACE rather than the principal's whole access. Back up the object's SDDL before you change it:

PowerShell
$dn  = 'CN=Tier0-Servers,OU=Groups,OU=Tier0,DC=corp,DC=example,DC=com'
$acl = Get-Acl "AD:\$dn"
$acl.Sddl | Out-File "C:\Tier0\Backup\$(Get-Date -f yyyyMMdd)-Tier0-Servers.sddl"

$acl.Access | Where-Object {
    $_.IdentityReference -eq 'CORP\Helpdesk-L2' -and -not $_.IsInherited -and
    $_.ActiveDirectoryRights -match 'GenericAll|GenericWrite|WriteDacl|WriteOwner|WriteProperty'
} | ForEach-Object { [void]$acl.RemoveAccessRule($_) }
Set-Acl "AD:\$dn" -AclObject $acl

If the edge is inherited, fix it on the parent OU where it is defined. Also check whether the object has inheritance blocked, which is typical for accounts touched by SDProp.

Verify

Every remediation sprint ends with a fresh collection, not a checkbox:

  • Rerun the saved queries. The specific edges you removed must be gone, and the path counts must go down.
  • Check that no new first-degree edges into Tier Zero have appeared. Regression usually comes from new application installs or delegation wizards.
  • Watch the KPIs over time. A falling "principals with a path to Tier Zero" count is the clearest proof that the program works.

Between collections, detect the same changes in real time. Event 5136 on Tier Zero objects (ACL and member changes) and 4728/4732/4756 for group membership should feed the same alerting pipeline as your other Tier 0 detections.

What it breaks

  • Delegations people forgot they depended on. Helpdesk or application teams lose the rights behind a path. Agree ownership and a rollback (the saved SDDL) before each change, and remove in small batches.
  • Admin habits. Removing Tier Zero sessions from member servers means admins stop using Domain Admin accounts for server work. Provide tiered admin accounts and PAWs first, or the sessions will come back.
  • Vendor tools with broad rights. Backup, IAM and monitoring products often request GenericAll on large OUs. Scope them down with the vendor, or move the product into Tier Zero and protect it.
  • The SOC's alert volume during collection windows, if not coordinated.

Related reading: the ACL pillar guide, Tier 0 and privileged access, and running a PingCastle assessment for a complementary, score-based view.

Frequently asked questions

Is it safe to run SharpHound in production?

Collection is read-only LDAP plus, optionally, SMB and RPC queries to member computers for sessions and local groups. It changes nothing, but it is noisy and looks exactly like attacker reconnaissance, so tell your SOC, use a dedicated collection account, run it from a Tier 0 or dedicated assessment host, and protect the output files and database as sensitive data because they are a complete map of your weaknesses.

What is the difference between an attack path and a misconfiguration finding?

A finding is a single fact, such as a group having GenericWrite on a user. An attack path is a chain of such facts that ends in Tier Zero. Many findings are harmless in isolation, and a few harmless-looking ones combine into a path from Domain Users to Domain Admins. Attack path management prioritises by what the chain reaches and how many principals can start it, not by the severity of each link.

How often should attack paths be re-collected?

ACL and group data change slowly, so a weekly collection is a good default and is what makes trend metrics meaningful. Session data changes by the minute, so a single snapshot underestimates exposure. Collect sessions several times across a working week, or use a continuous collector, and always re-collect after a remediation sprint to confirm the paths are really gone.

Attack path management with BloodHound for defenders

Related guides

Object & ACL Security

AdminSDHolder and SDProp: cleanup and monitoring

Baseline the AdminSDHolder ACL, find orphaned adminCount=1 accounts, reset their ACLs safely, trigger SDProp on demand, and alert on AdminSDHolder changes.

Intermediate
Group Policy & SYSVOL

Auditing GPO permissions and gPLink rights

Find who can edit, create and link GPOs in Active Directory: GPO ACLs, gPLink rights on OUs and sites, Group Policy Creator Owners and WMI filters.

Intermediate