BloodHound

Map Active Directory attack paths — SharpHound collection & Cypher

BloodHound Cheat Sheet

BloodHound maps Active Directory attack paths using graph theory. Collectors (SharpHound / AzureHound / the Python ingestor) gather objects, ACLs, sessions, and trusts; the GUI then reveals shortest paths to Domain Admin. For authorized testing only.

1. Collect with SharpHound

Run from a domain-joined or domain-reachable host. Drops .json files zipped together.

# .exe collector — grab everything
SharpHound.exe -c All

# PowerShell module
Import-Module .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All

# Specify domain + DC, write to a folder
SharpHound.exe -c All -d domain.local --domaincontroller 10.10.10.10 --outputdirectory C:\loot

# Stealthier / targeted runs
SharpHound.exe -c DCOnly                 # LDAP-only, no host touches (quiet)
SharpHound.exe -c Session --loop --loopduration 02:00:00   # poll sessions over 2h
SharpHound.exe -c All --stealth          # only "stealth" enumeration targets
-c / CollectionMethod Gathers
All Everything below except GPOLocalGroup
Group Group memberships
LocalAdmin,RDP,DCOM,PSRemote Local group membership on hosts
Session Logged-on user sessions (re-run with --loop)
ACL DACLs on objects (the juicy edges)
Trusts Domain trusts
DCOnly Pull only from the DC over LDAP (no host enumeration)
ObjectProps Attributes: pwdlastset, description, etc.

Useful flags: --zipfilename out.zip, --randomizefilenames, --collectallproperties, --throttle 1000 / --jitter 30 (ms, evade detection), --excludedcs.

2. Collect without dropping a binary

# Python collector (bloodhound-python) — run from Linux
bloodhound-python -u user -p 'Password123' -d domain.local -ns 10.10.10.10 -c All
bloodhound-python -u user --hashes :<NThash> -d domain.local -ns 10.10.10.10 -c All -k

# Via NetExec (LDAP)
nxc ldap dc.domain.local -u user -p pass --bloodhound -c All --dns-server 10.10.10.10

3. AzureHound (Entra ID / Azure)

azurehound -u user@tenant.com -p 'Password' list --tenant tenant.com -o output.json
azurehound -j <jwt> list --tenant <tenant-id> -o output.json     # with a refresh/JWT token

4. Load data into the GUI

Community Edition (Docker)

curl -L https://ghst.ly/getbhce | docker compose -f - up    # bring up BHCE
# GUI: http://localhost:8080  → log in, then drag-drop the zip under Administration > File Ingest

Legacy (neo4j + Electron app)

neo4j console            # start DB (default bolt://localhost:7687, neo4j/neo4j)
bloodhound               # launch the app, log in, drag the zip onto the window

5. Pre-built analytics queries

In the GUI sidebar (Analysis tab), the high-value queries:

Right-click any node → Mark as Owned / Mark as High Value to seed path queries.

6. Cypher (raw queries)

The query box accepts Cypher. Examples:

// Kerberoastable users
MATCH (u:User {hasspn:true}) RETURN u

// AS-REP roastable (no Kerberos pre-auth)
MATCH (u:User {dontreqpreauth:true}) RETURN u

// Users with paths to Domain Admins
MATCH p=shortestPath((u:User)-[*1..]->(g:Group))
WHERE g.objectid ENDS WITH '-512' RETURN p LIMIT 25

// Computers with unconstrained delegation
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c

// What can an owned user reach? (mark owned first)
MATCH p=shortestPath((n {owned:true})-[*1..]->(m)) RETURN p

// Sessions of Domain Admins (find where to hunt for creds)
MATCH (u:User)-[:MemberOf*1..]->(g:Group)
WHERE g.objectid ENDS WITH '-512'
MATCH p=(c:Computer)-[:HasSession]->(u) RETURN p

7. Reading edges & tips

Edge Abuse
MemberOf Inherited group rights
AdminTo Local admin → dump creds / exec
HasSession Creds of that user may be in LSASS on the host
GenericAll / GenericWrite Full/partial control → reset pw, set SPN, RBCD
WriteDacl / Owns Rewrite the object's DACL → grant yourself rights
ForceChangePassword Reset the target's password
AllowedToDelegate Constrained delegation abuse (S4U)
DCSync (GetChanges+GetChangesAll) Replicate hashes from the DC

Authorized testing only. Practice on the AYSEC pro-labs. See also Impacket and Mimikatz.