Tools · Identity defense · 01 / 05
BloodHound CE for defenders: measure who can reach Tier Zero
Collect your lab domain with SharpHound under an approved change, load it into BloodHound Community Edition, and count the users and computers with any path to Domain Admins.
The defender’s question
BloodHound models Active Directory as a graph: users, groups, computers, and the rights between them, such as group membership, local admin, sessions, and ACL edges like GenericAll or WriteDacl. Attackers use it to find one path. A defender uses it to count all paths into Tier Zero, the accounts and systems that control the domain, and to make that number shrink.
Collection reads the directory and, for session data, queries computers. Run it from an admin workstation under a change ticket, and tell the SOC first so the LDAP volume is expected.
Starting BloodHound CE and collecting
BloodHound CE runs as containers. The quick start downloads a compose file and prints a one-time admin password in the logs. SharpHound CE writes a zip of JSON files that the web interface ingests. DCOnly collects from domain controllers only, which avoids touching every workstation on a first run.
curl -L https://ghst.ly/getbhce -o docker-compose.yml docker compose up -d docker compose logs bloodhound | grep -i 'initial password' # on the lab admin workstation, as a regular domain user .\SharpHound.exe -c DCOnly --zipfilename lab-dconly.zip --outputdirectory C:\Temp\bh
Counting paths with Cypher
The Explore view accepts Cypher. The first query counts enabled users with any path to the Domain Admins group, whose SID ends in -512. The second lists non-admin principals with direct control edges over Tier Zero objects, which are often the cheapest fixes.
MATCH p = shortestPath((u:User {enabled: true})-[*1..]->(g:Group))
WHERE g.objectid ENDS WITH '-512' AND NOT u.admincount
RETURN count(DISTINCT u)
MATCH (n)-[r:GenericAll|WriteDacl|WriteOwner|GenericWrite]->(t:Tag_Tier_Zero)
WHERE NOT n:Tag_Tier_Zero
RETURN n.name, type(r), t.nameWorked review result
The lab domain has 640 enabled users. 212 have a path to Domain Admins. Almost all of them pass through one edge: the Helpdesk group holds GenericAll on a server OU that contains a Tier Zero backup server. That single delegation is the finding, written with the group, the right, the OU, and why the backup server is Tier Zero.
The next lesson removes it and re-collects to prove the count dropped.
Diagram
A Tier Zero exposure review
- Approve
Change ticket and SOC notice before collection.
CHG-2291: SharpHound DCOnly from ADM-01
- Collect
Read the directory into a zip.
.\SharpHound.exe -c DCOnly --zipfilename lab-dconly.zip
- Count
How many users can reach Domain Admins?
MATCH p=shortestPath((u:User)-[*1..]->(g:Group)) WHERE g.objectid ENDS WITH '-512' RETURN count(DISTINCT u)
- Choke point
Find the edge most paths share.
Helpdesk -[GenericAll]-> OU=Servers (contains BKP-01)
Check yourself
1. Why does a defender count paths rather than find one?
2. What does a Domain Admins group objectid end with?
3. Why use the DCOnly collection method on a first run?