← Research Hub
Active Directory

BloodHound Advanced Queries

Custom Cypher queries, shortest path analysis to Domain Admins, Kerberoastable accounts, DCSync rights, LAPS targets, and ACL abuse paths for comprehensive AD enumeration.

Collection & Setup

BloodHound requires SharpHound (Windows) or BloodHound.py (Linux/remote) for collection. For CPTS, you'll typically use BloodHound.py from Kali since you start with domain credentials.

# BloodHound.py β€” collect all methods remotely
pip3 install bloodhound
bloodhound-python -u svc_user -p 'Password1!' -d corp.local -dc DC01.corp.local -c All --zip

# SharpHound β€” from a compromised Windows host
.SharpHound.exe -c All --zipfilename bh-data.zip

# Neo4j setup (required before BloodHound GUI)
sudo neo4j start
# Default creds: neo4j / neo4j β†’ change on first login
bloodhound &
Tip: Use -c All for comprehensive collection. If stealth matters, -c DCOnly queries only the DC (no computer sessions β€” faster but misses local admin paths).

Core Cypher Queries

BloodHound's built-in queries cover most attack paths. Use the Raw Query box (top of GUI) for custom Cypher. Neo4j query language β€” all nodes are labeled User, Computer, Group, Domain, GPO, OU, Container.

Find Shortest Path to Domain Admins

MATCH p=shortestPath((n)-[*1..]->(m:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
WHERE NOT n=m
RETURN p

All Kerberoastable Users

MATCH (u:User {hasspn:true}) WHERE u.enabled=true
RETURN u.name, u.serviceprincipalnames, u.admincount
ORDER BY u.admincount DESC

DCSync Rights (DS-Replication-Get-Changes-All)

MATCH p=(n)-[:DCSync|AllExtendedRights|GenericAll]->(m:Domain)
RETURN p

Accounts with AdminCount=1 (Protected Users)

MATCH (u:User {admincount:1}) WHERE u.enabled=true
RETURN u.name ORDER BY u.name

Computers with LAPS Disabled

MATCH (c:Computer {haslaps:false}) RETURN c.name, c.operatingsystem

Attack Path Analysis

Path from Owned User to DA

# Mark your compromised user as Owned first (right-click β†’ Mark as Owned)
MATCH p=shortestPath((u:User {owned:true})-[*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
RETURN p

Find All GenericWrite/GenericAll Paths

MATCH p=(u:User)-[:GenericWrite|GenericAll|WriteDacl|WriteOwner|Owns]->(n)
WHERE u.enabled=true
RETURN p LIMIT 50

ForceChangePassword Paths

MATCH p=(u:User)-[:ForceChangePassword]->(v:User)
RETURN u.name AS attacker, v.name AS target

Local Admin Rights (CanRDP / AdminTo)

MATCH p=(u:User)-[:AdminTo]->(c:Computer)
WHERE u.name = "SVC_SQL@CORP.LOCAL"
RETURN p

Custom Query Library

AS-REP Roastable Accounts

MATCH (u:User {dontreqpreauth:true}) WHERE u.enabled=true RETURN u.name

Users with Unconstrained Delegation

MATCH (c:Computer {unconstraineddelegation:true}) WHERE c.name <> "DC01.CORP.LOCAL"
RETURN c.name, c.operatingsystem

Constrained Delegation Targets

MATCH (u)-[:AllowedToDelegate]->(c:Computer) RETURN u.name, c.name

Groups with Dangerous Rights to Computers

MATCH p=(g:Group)-[:AdminTo|CanRDP|ExecuteDCOM|AllowedToDelegate]->(c:Computer)
WHERE g.name <> "DOMAIN ADMINS@CORP.LOCAL"
RETURN p LIMIT 100

Cross-Domain Trust Paths

MATCH p=(n)-[:HasForeignGroupMembership|HasForeignSecurityPrincipal]->(m)
RETURN p

Exam Tips

CPTS Strategy: Run BloodHound immediately after getting domain creds. Mark all compromised accounts as Owned as you go β€” BloodHound re-calculates paths from owned nodes. The "Find Shortest Paths to Domain Admins from Owned Principals" built-in query is your best friend.
  • If no path exists from your user, look for paths via groups your user is a member of
  • ReadGMSAPassword edges often lead to service account takeover β†’ privilege escalation
  • WriteSPN on a user = you can Kerberoast them (targeted Kerberoasting)
  • Always check Inbound Object Control panel on each node β€” lists who can attack this object
  • AddSelf right on a group = add yourself to that group, potentially gaining its privileges