BloodHound for Red Teams: Cypher Queries, Attack Paths, Edge Filtering
Cybersecurity
BloodHound is more than Shortest Path to Domain Admins. A red team handbook of custom Cypher queries, edge filtering, and ingest hygiene for messy enterprise data.
By Arjun Raghavan, Security & Systems Lead, BIPI · November 28, 2024 · 10 min read
Most operators run BloodHound, click Shortest Path to Domain Admins, screenshot the result, and move on. That is fine for a CTF. On a real network with 80,000 nodes and a noisy ingest, the default queries either return nothing useful or return everything and crash the browser. The value of BloodHound is in the Cypher you write yourself.
Collection that doesn't get you caught
SharpHound has loud defaults. The All collection method touches every host, runs SessionLoop, and lights up EDR. For most assessments, separate your collection into stealthy passes.
- SharpHound.exe -c Group,Trusts,ACL,Container,GPOLocalGroup, no host touch, pure LDAP
- Add Session and LoggedOn only against a sampled subset of hosts, throttled with Throttle and Jitter
- Use the netonly mode from a non-domain-joined host with runas /netonly to avoid event 4624 spikes
- bloodhound.py from impacket is often quieter and easier to run from Linux
The queries that matter
The pre-built queries are a starting point. The ones that win engagements are custom. Examples we keep in our notebook.
Find Kerberoastable accounts in Tier 0:
- MATCH (u:User {hasspn:true})-[:MemberOf*1..]->(g:Group) WHERE g.name CONTAINS 'DOMAIN ADMINS' OR g.name CONTAINS 'ENTERPRISE ADMINS' RETURN u.name
Computers where a non-admin user has admin via nested groups:
- MATCH p=(u:User {enabled:true})-[:MemberOf*1..]->(g:Group)-[:AdminTo]->(c:Computer) WHERE NOT u.name CONTAINS 'ADMIN' RETURN p LIMIT 200
Shortest path from owned to high value, with edge filtering to remove noise:
- MATCH (n {owned:true}), (m {highvalue:true}), p=shortestPath((n)-[:MemberOf|HasSession|AdminTo|CanRDP|ExecuteDCOM|AllowedToDelegate|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|AddMember|AllExtendedRights*1..]->(m)) RETURN p
Edge filtering for sanity
Default queries include CanPSRemote, CanRDP, and HasSession, which on a flat network produce a hairball. Filter to control-plane edges only when looking for privilege paths, and add session edges only when looking for credential theft opportunities.
The right Cypher question is not what can reach Domain Admins. It is which compromised user gives me the shortest path with the fewest noisy hops.
Marking owned and high value correctly
Mark every credential you have, including service accounts and machine accounts. Mark Tier 0 assets as high value even when SharpHound does not auto-flag them, including ADCS CAs, Azure AD Connect sync servers, backup servers with admin rights to DCs, and EDR management consoles.
Ingest hygiene
Old ingests pollute results. Drop the database between engagements. If you must keep history, use property tags like client and run_date on every node so you can filter by collection.
BloodHound CE and operator workflow
BloodHound Community Edition shifts the data model and API. The Cypher above still works with minor adjustments. The Posture and Path Finding panels are useful, but operators should still write custom Cypher for anything past the trivial cases.
BloodHound is a force multiplier when you treat it like a query language with a visualisation, not the other way around. Operators who learn Cypher outperform operators who do not, every engagement.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.