7 BloodHound Cypher Queries That Find Real AD Privilege Paths (Not the Default Ones)

Manish Garg
Manish Garg Associate of (ISC)² · RingSafe
Apr 25, 2026
8 min read

Last updated: April 26, 2026

BloodHound docs is the most-installed and least-actually-understood tool in the Active Directory pentester’s toolkit. Most engineers run the default “Shortest Path to Domain Admins” query, screenshot the result, and move on. They miss 80% of what BloodHound was built to find. This article is a tour of the Cypher queries that surface real misconfigurations — the ones that mature defenders fix and immature defenders ignore.

Why default queries miss the real findings

The packaged BloodHound queries (Shortest Paths to Domain Admins, Find Computers Where User Has Local Admin, etc.) catch the obvious cases. They are designed to demonstrate what BloodHound can do, not to find every privilege escalation path in your environment. Real-world AD compromise paths usually involve at least one of the following that the canned queries do not surface:

  • A custom group with delegated rights that is treated as low-privilege but is actually tier-0 effective
  • A computer object with WriteOwner on a privileged user (allowing computer-account-coerce attacks)
  • A service account in Tier-1 with SeDebugPrivilege on tier-0 hosts via group membership three layers deep
  • An old print server that is in Server Operators and reachable from every user workstation
  • A GPO linked to the Domain Controllers OU with edit rights granted to a group of help-desk staff

Each of these requires a Cypher query specifically written to look for it. Fortunately, BloodHound’s data model is rich enough to support exactly this kind of inquiry.

Mental model: BloodHound is a graph database

BloodHound runs on Neo4j. Every AD object is a node, every right or membership is an edge. The edges have types: MemberOf, AdminTo, HasSession, CanRDP, WriteDacl, GenericAll, AddKeyCredentialLink, ForceChangePassword, and dozens more.

The Cypher language lets you ask: “Find me a path from any user in <low-privilege group> to any privileged target, where the path uses any combination of these edge types.” Once you understand that, BloodHound becomes a tool for asking specific operational questions, not just running canned reports.

Setting up: SharpHound collection

Before queries, you need data. From a domain-joined host:

SharpHound.exe -c All,GPOLocalGroup,Session,LoggedOn,Trusts

Or from a Linux box with credentials, using the Python collector:

bloodhound-python -d corp.local -u alice -p Welcome123 -ns 10.0.0.5 -c All

Upload the resulting ZIP to BloodHound CE (or BloodHound 5+). Now you have a graph.

Query 1: High-impact users with active sessions on high-impact hosts

Why this matters: a user with active session on a host means their tokens are in memory. If you compromise the host, you become them. Domain Admins logging into workstations is a tier-0 violation that pentesters love and admins forget about.

MATCH (u:User)-[:HasSession]->(c:Computer)
WHERE u.admincount = true
RETURN u.name, c.name
ORDER BY u.name

This shows every privileged-account session. The output should be empty in a mature environment (Domain Admins should only authenticate to Domain Controllers, never to workstations or member servers). If you see DomainAdmin1 with a session on HELPDESK-WS01, that is one credential-dump away from total compromise.

Query 2: Non-standard groups with effective Domain Admin rights

Why this matters: AD admins often create custom groups (e.g., SQL_Operators, Backup_Team) and grant them rights that, three transitive memberships deep, equal Domain Admin. The group looks innocent in the org chart and lethal in the graph.

MATCH p=shortestPath((g:Group)-[*1..]->(t:Group {name:'DOMAIN [email protected]'}))
WHERE g.name <> 'DOMAIN [email protected]'
  AND g.name <> '[email protected]'
  AND g.name <> 'ENTERPRISE [email protected]'
RETURN g.name, length(p) AS hops
ORDER BY hops, g.name

Output shows every group with a transitive privilege escalation path to Domain Admins, ordered by how many hops away. Anything with hops 1-3 deserves immediate review.

Query 3: Computers with unconstrained delegation outside the DC OU

Why this matters: a computer with unconstrained delegation captures the TGT of every user who authenticates to it. Compromise that computer, and you can impersonate any user who has ever connected to it (including, often, Domain Admins triggered to connect by the printer-bug exploit). Unconstrained delegation should be on Domain Controllers only.

MATCH (c:Computer {unconstraineddelegation: true})
WHERE NOT (c)-[:MemberOf*1..]->(:Group {name:'DOMAIN [email protected]'})
RETURN c.name, c.operatingsystem
ORDER BY c.name

Every result is a high-priority finding. Common offenders: legacy print servers, old Exchange servers, file servers set up before 2010 with delegation enabled “to make Kerberos work.”

Query 4: Users with WriteDACL/Owns/GenericAll on privileged objects

Why this matters: writing the DACL of an object means you can grant yourself any right on it. GenericAll is full control. Owns implicitly carries WriteOwner, which converts to GenericAll. These edges to high-privilege accounts are a one-step privilege escalation.

MATCH (u:User)-[r:WriteDacl|Owns|GenericAll|GenericWrite|WriteOwner|AddSelf|AddKeyCredentialLink|AllExtendedRights|ForceChangePassword]->(t)
WHERE t.admincount = true OR t.highvalue = true
RETURN u.name, type(r) AS edge, t.name, labels(t)[0] AS target_type
ORDER BY u.name

Each row is a potential privilege escalation. AddKeyCredentialLink on a privileged user is the Shadow Credentials attack chain — write a public key to the target, request a certificate via PKINIT, become them. ForceChangePassword on a Domain Admin is exactly what it says.

Query 5: Foreign-domain accounts with rights in this domain

Why this matters: in multi-domain forests or trusted environments, accounts from other domains often retain rights inherited from a long-forgotten merger or vendor relationship. These are blind spots in your IAM review.

MATCH (n)-[r]->(t)
WHERE n.objectid CONTAINS 'S-1-5-21'
  AND t.objectid CONTAINS 'S-1-5-21'
  AND split(n.objectid, '-')[3] <> split(t.objectid, '-')[3]
RETURN DISTINCT n.name, type(r), t.name
LIMIT 50

Use this in any environment with trust relationships. The findings often shock the IAM owner.

Query 6: Sessions of high-value users on Tier-2 (workstation-tier) machines

Why this matters: tier-zero credentials should never reach a tier-two device. This query finds the tier-zero/tier-two crossover that breaks the whole tiering model.

MATCH (u:User {highvalue: true})-[:HasSession]->(c:Computer)
WHERE NOT (c)-[:MemberOf*1..]->(:Group)
       WHERE c.operatingsystem CONTAINS 'Server'
RETURN u.name, c.name, c.operatingsystem

Every result is a Tier-0 administrator who logged into a workstation. That workstation is now a stepping stone to that admin’s credentials.

Query 7: GPOs that grant elevated rights to broad groups

Why this matters: a GPO that adds users to local administrators on a host gives you AdminTo on that host. A GPO that does this for “Domain Users” on workstations gives you AdminTo across the entire workstation fleet.

MATCH (g:GPO)-[:GpLink]->(o)-[:MemberOf*0..]->(c:Computer)
MATCH (u:User)-[:MemberOf*1..]->(broad:Group)
WHERE broad.name IN ['DOMAIN [email protected]','AUTHENTICATED [email protected]']
RETURN g.name, count(DISTINCT c) AS hosts_affected
ORDER BY hosts_affected DESC

Tune for your environment. The names of broad groups will differ.

How to think about output

BloodHound output is not a vulnerability list. It is a graph — and the right way to engage with it is conversational. Each query you run answers a specific question; the answer suggests the next question.

An example train of thought from a real engagement:

  1. “Who has paths to Domain Admin?” → 47 paths surface, mostly through one custom group.
  2. “What is that custom group used for?” → It is the Help-Desk Tier-2 group, members reset user passwords for the support team.
  3. “What edges does it have to Domain Admin?” → ForceChangePassword on a service account in Domain Admins (because the service account was put in Help-Desk’s reset scope by mistake five years ago).
  4. “Who is in Help-Desk Tier-2?” → 23 users including 4 contractors with shared mailboxes.
  5. “Has any of them been phished in the last year?” → 2 yes, per the security awareness platform.

From query to org-chart-level finding in five steps. Without BloodHound, you would never have found the privilege chain. Without conversational follow-up, BloodHound’s graph is a colourful poster.

How to find your next BloodHound finding

Build your own query library. Every engagement, when you find a new privilege chain manually, write a Cypher query that detects it and add it to a personal repo. Over a year, you will accumulate 30-50 environment-tested queries that your competitors do not have.

Some starting points beyond the queries above:

  • Resource-Based Constrained Delegation paths — find computers where a user can write msDS-AllowedToActOnBehalfOfOtherIdentity, enabling RBCD attacks.
  • Pre-Windows 2000 compatible accounts — these have weak password defaults and are often forgotten.
  • Stale machine accounts with high privileges — old laptops still in DA-equivalent groups.
  • Accounts where userAccountControl includes DONT_REQ_PREAUTH — AS-REP Roasting candidates.
  • Certificate templates marked as ESC1-vulnerable — BloodHound 5+ ingests Certipy data.

Defender perspective

If you operate AD, run BloodHound against yourself before the next pentester does. The findings will be your prioritised hardening backlog.

  • Run SharpHound with admin credentials (you collect more edges than an attacker can).
  • Run the queries above plus the canned ones.
  • For every result, ask: is this intentional? If not, file a remediation ticket.
  • After remediation, re-run BloodHound and verify the path is gone.
  • Add tier separation enforcement (Authentication Policies, Privileged Access Workstations) so future drift is detectable.

The takeaway

BloodHound’s value is not in the screenshot. It is in the conversation between you, the graph, and your next question. Default queries are the introduction. Custom Cypher is the actual practice. The teams that compromise your AD in 30 minutes during a red-team are not running canned scripts; they are asking specific operational questions of a graph database. The teams that defend successfully are doing the same thing first.

Need a real pentest?

Get a VAPT scoping call

Senior practitioner-led VAPT — not a checklist run by juniors. CVSS-scored findings, free retest, attestation letter. India's SMBs and SaaS teams.

Book VAPT scoping call Replies in 4 working hrs · India-only · Senior consultants