BloodHound / SharpHound
BloodHound collection, import, and attack path analysis: bloodhound-python, SharpHound, critical Cypher queries, shortest-path to DA, ACL abuse chains, delegation paths, and how to read BloodHound output into actionable attacks.
BloodHound graphs AD relationships that are invisible in raw LDAP output — group memberships, ACL edges, session data, and delegation flags — then finds the shortest attack path to Domain Admin. Run collection first, then mark your owned nodes and follow the edges.
Collection
bloodhound-python (from Linux — no agent needed)
# Full collection (all data types)
bloodhound-python -d corp.local -u user -p 'password' -c All -ns DC_IP
# With hash (Pass-the-Hash)
bloodhound-python -d corp.local -u user --hashes :NTLM_HASH -c All -ns DC_IP
# Specific collection methods
bloodhound-python -d corp.local -u user -p 'password' \
-c Group,LocalAdmin,Session,Trusts,ObjectProps,ACL -ns DC_IP
# Stealth — skip session enumeration (less noise)
bloodhound-python -d corp.local -u user -p 'password' -c Group,ObjectProps,ACL -ns DC_IP
# Output to directory
bloodhound-python -d corp.local -u user -p 'password' -c All -ns DC_IP -o /tmp/bh/
SharpHound (Windows — runs as current user)
# PowerShell import
Import-Module .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Temp\
# Standalone EXE
.\SharpHound.exe -c All --outputdirectory C:\Temp\
.\SharpHound.exe -c All --zipfilename bh_data.zip
# Stealth options
.\SharpHound.exe -c Group,ObjectProps,ACL --NoSaveCache
.\SharpHound.exe -c All --throttle 1000 --jitter 20
# Target specific DC
.\SharpHound.exe -c All --domaincontroller DC_IP
NetExec LDAP collection
nxc ldap DC_IP -u user -p 'password' --bloodhound --collection All
Import into BloodHound
# Start Neo4j (BloodHound backend)
sudo neo4j start
# Default credentials: neo4j / neo4j (change on first login)
# BloodHound GUI — drag and drop the zip/JSON files into the UI
# Or use the Upload Data button in the top-right
# BloodHound CE (community edition) via Docker
docker run -d -p 8080:8080 -p 7474:7474 -p 7687:7687 specterops/bloodhound-ce
First Steps After Import
- Set owned nodes: right-click a node → Mark as Owned
- Set high-value targets: Workstations / Servers / DCs are auto-tagged
- Run “Find Shortest Paths to Domain Admins” from the Analysis menu
- Run “Find Principals with DCSync Rights” to see who can replicate
- Check the “Outbound Object Control” panel for your owned user
Essential Cypher Queries (Raw Queries tab or BloodHound GUI)
All paths from owned nodes to Domain Admins
MATCH p=shortestPath((n:User {owned:true})-[*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'}))
RETURN p
Find Kerberoastable users and their admin rights
MATCH (u:User {hasspn:true}) RETURN u.name, u.admincount ORDER BY u.admincount DESC
Find AS-REP roastable users
MATCH (u:User {dontreqpreauth:true}) RETURN u.name
Computers with unconstrained delegation (not DCs)
MATCH (c:Computer {unconstraineddelegation:true}) WHERE NOT c.name CONTAINS 'DC' RETURN c.name
Users with constrained delegation
MATCH (u:User) WHERE u.allowedtodelegate IS NOT NULL RETURN u.name, u.allowedtodelegate
Find all ACL paths from a user to Domain Admins
MATCH p=allShortestPaths((u:User {name:'JSMITH@CORP.LOCAL'})-[:GenericAll|GenericWrite|WriteOwner|WriteDacl|Owns|AddMember|ForceChangePassword*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'})) RETURN p
All objects with GenericAll over another object
MATCH (n)-[r:GenericAll]->(m) RETURN n.name, type(r), m.name LIMIT 50
Find local admin rights for a user across all computers
MATCH (u:User {name:'JSMITH@CORP.LOCAL'})-[:AdminTo]->(c:Computer) RETURN c.name
Find computers where domain users have local admin (high-risk)
MATCH (g:Group {name:'DOMAIN USERS@CORP.LOCAL'})-[:AdminTo]->(c:Computer) RETURN c.name
Groups with DCSync privileges
MATCH p=(n)-[:DCSync|GetChanges|GetChangesAll]->(d:Domain) RETURN n.name, type(relationships(p)[0])
Shortest path from owned computer to Domain Admin
MATCH p=shortestPath((c:Computer {owned:true})-[*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'})) RETURN p
Reading BloodHound Edges
| Edge | Attack | Tool |
|---|---|---|
MemberOf | Group membership | — |
AdminTo | Local admin | PsExec/WMI/evil-winrm |
HasSession | User logged in on host | PTH or token impersonation |
GenericAll | Full control — reset password, add member, write SPN | PowerView |
GenericWrite | Write specific attributes (SPN → Kerberoast, logon script) | PowerView |
WriteOwner | Take ownership → then WriteDACL | PowerView |
WriteDacl | Modify DACL → grant yourself GenericAll | PowerView |
Owns | Same as WriteOwner | PowerView |
ForceChangePassword | Change password without knowing old one | PowerView |
AddMember | Add user to group | PowerView |
AllowedToDelegate | Constrained/unconstrained delegation | Rubeus |
AllowedToAct | RBCD — request tickets as any user | Rubeus |
DCSync | Replicate domain hashes | secretsdump/mimikatz |
ReadLAPSPassword | Read local admin LAPS password | PowerView/nxc |
ReadGMSAPassword | Read gMSA managed password | PowerView/nxc |
CanRDP | Remote Desktop access | xfreerdp/mstsc |
Attack Workflow
1. Mark foothold users/computers as Owned
2. Run "Shortest Paths from Owned Principals"
3. Find the easiest edge:
- MemberOf a group with AdminTo → PTH to host → dump LSASS → new creds → loop
- GenericAll on user → ForceChangePassword → log in as them
- WriteSPN → Kerberoast → crack hash → new creds
- WriteDACL on domain obj → grant DCSync → dump all hashes
4. Execute the edge with PowerView/Rubeus/impacket
5. Mark new objects as Owned, re-run paths