HackBlue

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.

13 min read · practice only with authorization

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.

Snippet
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.

Snippet
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.name

Worked 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

  1. Approve

    Change ticket and SOC notice before collection.

    Note
    CHG-2291: SharpHound DCOnly from ADM-01
  2. Collect

    Read the directory into a zip.

    Command
    .\SharpHound.exe -c DCOnly --zipfilename lab-dconly.zip
  3. Count

    How many users can reach Domain Admins?

    Cypher
    MATCH p=shortestPath((u:User)-[*1..]->(g:Group)) WHERE g.objectid ENDS WITH '-512' RETURN count(DISTINCT u)
  4. Choke point

    Find the edge most paths share.

    Finding
    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?