Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ One of BloodHound’s key features is its flexibility through Cypher queries –

Queries can answer anything from simple questions (e.g., “*Which users haven’t reset their passwords in 180 days?*”), to complex identity attack path problems (e.g., “*Which low-privileged users can compromise computers hosting a gMSA with unconstrained delegation?*”).

The library gives you practical examples for learning Cypher and can be combined with the following resources:
The library gives you practical examples for learning Cypher and can be combined with these resources:
- [BloodHound documentation: Searching with Cypher](https://support.bloodhoundenterprise.io/hc/en-us/articles/16721164740251)
- [openCypher resources](https://opencypher.org/resources/)
- [Neo4j Cypher Cheat Sheet](https://opencypher.org/resources/)
- [Neo4j Cypher Cheat Sheet](https://neo4j.com/docs/cypher-cheat-sheet/current/lists/)

You can also learn with the communty by joining the #cypher_queries channel in the [BloodHound community Slack](https://support.bloodhoundenterprise.io/hc/en-us/articles/16730536907547).

Expand Down
18 changes: 18 additions & 0 deletions queries/ACEs across trusts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: ACEs across trusts
guid: c902d3b4-1a75-4335-acd7-28246dab746d
prebuilt: false
platform: Active Directory
category: Domain Information
description: ACEs granted across a trust, the ACEs are set on trusting objects and the rights are granted to objects from trusted domains.
query: |-
MATCH p=(trustedDomainPrincipal:Base)-[r]->(trustingDomainPrincipal:Base)
WHERE trustedDomainPrincipal.domainsid <> trustingDomainPrincipal.domainsid
AND r.isacl
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgement:
acknowledgements: Martin Sohn Christensen, @martinsohndk

16 changes: 16 additions & 0 deletions queries/AS-REP Roastable Tier Zero users (DontReqPreAuth).yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: AS-REP Roastable Tier Zero users (DontReqPreAuth)
guid: 6d51e4dc-e1ad-477a-b6c6-324f18f03120
prebuilt: false
platform: Active Directory
category: Active Directory Hygiene
description:
query: |-
MATCH (n:Base)
WHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')
AND n.dontreqpreauth = true
RETURN n
note:
revision: 1
resources: https://attack.mitre.org/techniques/T1558/004/
acknowledgements: Martin Sohn Christensen, @martinsohndk

17 changes: 17 additions & 0 deletions queries/AS-REP Roastable users (DontReqPreAuth).yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: AS-REP Roastable users (DontReqPreAuth)
guid: 2570e359-dec1-419d-b0dc-a204bd64ee42
prebuilt: true
platform: Active Directory
category: Kerberos Interaction
description:
query: |-
MATCH (u:User)
WHERE u.dontreqpreauth = true
AND u.enabled = true
RETURN u
LIMIT 100
note:
revision: 1
resources: https://attack.mitre.org/techniques/T1558/004/
acknowledgements:

17 changes: 17 additions & 0 deletions queries/Accounts with SID History to a non-existent domain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Accounts with SID History to a non-existent domain
guid: 2710401a-c4c2-4d2c-9edb-d7625045f2e8
prebuilt: false
platform: Active Directory
category: Active Directory Hygiene
description:
query: |-
MATCH (d:Domain)
WITH collect(d.objectid) AS domainSIDs
MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)
WHERE NOT n.domainsid IN domainSIDs
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

15 changes: 15 additions & 0 deletions queries/Accounts with SID History to a same-domain account.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Accounts with SID History to a same-domain account
guid: 275d2d58-0cad-4cad-8103-e0874cece666
prebuilt: false
platform: Active Directory
category: Dangerous Privileges
description:
query: |-
MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)
WHERE n.domainsid = m.domainsid
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

14 changes: 14 additions & 0 deletions queries/Accounts with SID History.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Accounts with SID History
guid: 8172d52c-a975-49bd-9180-5b6efc59c9ab
prebuilt: false
platform: Active Directory
category: Active Directory Hygiene
description:
query: |-
MATCH p=(:Base)-[:HasSIDHistory]->(:Base)
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

18 changes: 18 additions & 0 deletions queries/Accounts with clear-text password attributes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Accounts with clear-text password attributes
guid: e303498f-e3d4-489d-8a34-b68e187bc4e7
prebuilt: false
platform: Active Directory
category: Active Directory Hygiene
description:
query: |-
MATCH (n:Base)
WHERE n.userpassword IS NOT NULL
OR n.unixpassword IS NOT NULL
OR n.unicodepwd IS NOT NULL
OR n.msSFU30Password IS NOT NULL
RETURN n
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
name: AdminSDHolder protected Accounts and Groups
guid: 5ee2f40e-a55c-4140-ab8a-91746ba3752b
prebuilt: false
platform: Active Directory
category: Domain Information
description: Objects whose permissions are set by SDProp to the template AdminSDHolder object as per MS-ADTS 3.1.1.6.1.2 Protected Objects. Does not exclude objects if specified in dSHeuristics dwAdminSDExMask
query: |-
MATCH (n:Base)-[:MemberOf*0..]->(m:Group)
WHERE (
n.objectid =~ ".*-(S-1-5-32-544|S-1-5-32-548|S-1-5-32-549|S-1-5-32-550|S-1-5-32-551|S-1-5-32-552|518|512|519)" // Groups
OR m.objectid =~ ".*-(S-1-5-32-544|S-1-5-32-548|S-1-5-32-549|S-1-5-32-550|S-1-5-32-551|S-1-5-32-552|518|512|519)" // Members of groups
OR n.objectid =~ ".*-(500|502|516|521)" // Direct objects
n.objectid =~ ".*-(S-1-5-32-544|S-1-5-32-548|S-1-5-32-549|S-1-5-32-550|S-1-5-32-551|S-1-5-32-552|518|512|519)$" // Groups
OR m.objectid =~ ".*-(S-1-5-32-544|S-1-5-32-548|S-1-5-32-549|S-1-5-32-550|S-1-5-32-551|S-1-5-32-552|518|512|519)$" // Members of groups
OR n.objectid =~ ".*-(500|502|516|521)$" // Direct objects
)
RETURN n
note:
Expand All @@ -17,4 +18,5 @@ resources:
- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a0d0b4fa-2895-4c64-b182-ba64ad0f84b8
- https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory
acknowledgement:
acknowledgements: Martin Sohn Christensen, @martinsohndk

20 changes: 20 additions & 0 deletions queries/All ADCS ESC privilege escalation edges.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: All ADCS ESC privilege escalation edges
guid: 49db8edc-8421-438f-b97b-23c042959bef
prebuilt: false
platform: Active Directory
category: Active Directory Certificate Services
description:
query: |-
MATCH p=(:Base)-[:ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|GoldenCert|CoerceAndRelayNTLMToADCS]->(:Base)
RETURN p
note:
revision: 1
resources:
- https://posts.specterops.io/certified-pre-owned-d95910965cd2
- https://posts.specterops.io/adcs-attack-paths-in-bloodhound-part-1-799f3d3b03cf
- https://posts.specterops.io/adcs-attack-paths-in-bloodhound-part-2-ac7f925d1547
- https://posts.specterops.io/adcs-attack-paths-in-bloodhound-part-3-33efb00856ac
- https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53
- https://specterops.io/blog/2025/04/08/the-renaissance-of-ntlm-relay-attacks-everything-you-need-to-know/#:~:text=Introducing%20the%20CoerceAndRelayNTLMToADCS%20Edge
acknowledgements: Jonas Bülow Knudsen, @Jonas_B_K

15 changes: 15 additions & 0 deletions queries/All DNSAdmins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: All DNSAdmins
guid: 183fb320-f3ae-4ab3-a090-3f9a7db692e1
prebuilt: false
platform: Active Directory
category: Domain Information
description:
query: |-
MATCH p=(n:Base)-[:MemberOf]->(g:Group)
WHERE n.name STARTS WITH "DNSADMINS@"
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

16 changes: 16 additions & 0 deletions queries/All Domain Admins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: All Domain Admins
guid: 0596dba7-9180-49a0-aa54-00243240037c
prebuilt: true
platform: Active Directory
category: Domain Information
description:
query: |-
MATCH p = (t:Group)<-[:MemberOf*1..]-(a)
WHERE (a:User or a:Computer) and t.objectid ENDS WITH '-512'
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgements:

15 changes: 15 additions & 0 deletions queries/All Global Administrators.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: All Global Administrators
guid: 94d7d765-6837-4eb8-aa33-e1c9ef262cdc
prebuilt: true
platform: Azure
category: General
description:
query: |-
MATCH p = (:AZBase)-[:AZGlobalAdmin*1..]->(:AZTenant)
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgements:

20 changes: 20 additions & 0 deletions queries/All Kerberoastable users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: All Kerberoastable users
guid: 14ab4eaa-b73b-49c4-b2d1-1e020757c995
prebuilt: true
platform: Active Directory
category: Kerberos Interaction
description:
query: |-
MATCH (u:User)
WHERE u.hasspn=true
AND u.enabled = true
AND NOT u.objectid ENDS WITH '-502'
AND NOT COALESCE(u.gmsa, false) = true
AND NOT COALESCE(u.msa, false) = true
RETURN u
LIMIT 100
note:
revision: 1
resources: https://attack.mitre.org/techniques/T1558/003/
acknowledgements:

23 changes: 23 additions & 0 deletions queries/All Operator groups.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: All Operators
guid: 3dfd0843-1ff9-4c21-aa67-feae08d109de
prebuilt: false
platform: Active Directory
category: Domain Information
description:
query: |-
MATCH p=(:Base)-[:MemberOf]->(n:Group)
WHERE (
n.objectid ENDS WITH 'S-1-5-32-551' OR // Backup Operators
n.objectid ENDS WITH 'S-1-5-32-556' OR // Network Configuration Operators
n.objectid ENDS WITH 'S-1-5-32-549' OR // Server Operators
n.objectid ENDS WITH 'S-1-5-32-579' OR // Access Control Assistance Operators
n.objectid ENDS WITH 'S-1-5-32-548' OR // Account Operators
n.objectid ENDS WITH 'S-1-5-32-569' OR // Cryptographic Operators
n.objectid ENDS WITH 'S-1-5-32-550' // Print Operators
)
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

16 changes: 16 additions & 0 deletions queries/All Schema Admins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: All Schema Admins
guid: 76d8e61d-7a86-40ff-8a85-fd37f1e2563f
prebuilt: false
platform: Active Directory
category: Domain Information
description:
query: |-
MATCH p=(n:Base)-[:MemberOf*1..]->(m:Group)
WHERE (n:User OR n:Computer)
AND m.objectid ENDS WITH "-518" // Schema Admins
RETURN p
note:
revision: 1
resources:
acknowledgements: Martin Sohn Christensen, @martinsohndk

14 changes: 14 additions & 0 deletions queries/All coerce and NTLM relay edges.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: All coerce and NTLM relay edges
guid: 15c5ff3b-856c-44d1-a731-a8cb72512dd1
prebuilt: true
platform: Active Directory
category: NTLM Relay Attacks
description:
query: |-
MATCH p = (n:Base)-[:CoerceAndRelayNTLMToLDAP|CoerceAndRelayNTLMToLDAPS|CoerceAndRelayNTLMToADCS|CoerceAndRelayNTLMToSMB]->(:Base)
RETURN p LIMIT 500
note:
revision: 1
resources: https://specterops.io/blog/2025/04/08/the-renaissance-of-ntlm-relay-attacks-everything-you-need-to-know/
acknowledgements:

18 changes: 18 additions & 0 deletions queries/All incoming and local paths for a specific computer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: All incoming and local paths for a specific computer
guid: 1f67e538-19d4-4020-89c8-5b39b31571bd
prebuilt: false
platform: Active Directory
category: Domain Information
description: All incoming and local paths for a specific computer; incoming from domain objects and paths local inside the computer.
query: |-
// Replace 'HOSTNAME' with the computer's shortname eg. 'SRV01', not FQDN
MATCH p=(n:Base)-[:RemoteInteractiveLogonPrivilege|AdminTo|CanRDP|LocalToComputer|MemberOfLocalGroup]-(m:Base)
WHERE m.name CONTAINS 'HOSTNAME'
AND m.name CONTAINS '.' // Only see computer-related objects (eg. not AD Groups)
RETURN p
note:
revision: 1
resources:
acknowledgement:
acknowledgements: Martin Sohn Christensen, @martinsohndk

16 changes: 16 additions & 0 deletions queries/All members of high privileged roles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: All members of high privileged roles
guid: 3df24d92-dd12-4125-811b-e696b098f60e
prebuilt: true
platform: Azure
category: General
description:
query: |-
MATCH p=(t:AZRole)<-[:AZHasRole|AZMemberOf*1..2]-(:AZBase)
WHERE t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator'
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgements:

20 changes: 20 additions & 0 deletions queries/All paths crossing a specific trust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: All paths crossing a specific trust
guid: 251fc893-7a6b-4a0a-8650-9d5408d38c3c
prebuilt: false
platform: Active Directory
category: Domain Information
description: All paths crossing a specific trust from a trusted to a trusting domain.
query: |-
// Replace the TRUSTED domain SID
// Replace the TRUSTING domain SID
MATCH p=(Trusted:Base)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|MemberOf|ForceChangePassword|AllExtendedRights|AddMember|HasSession|GPLink|AllowedToDelegate|CoerceToTGT|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteGPLink|GoldenCert|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|SyncedToEntraUser|CoerceAndRelayNTLMToSMB|CoerceAndRelayNTLMToADCS|WriteOwnerLimitedRights|OwnsLimitedRights|CoerceAndRelayNTLMToLDAP|CoerceAndRelayNTLMToLDAPS|Contains|DCFor|SameForestTrust|SpoofSIDHistory|AbuseTGTDelegation]->(Trusting:Base)
WHERE Trusted.domainsid = 'S-1-5-21-1111111111-1111111111-1111111111'
AND Trusting.domainsid = 'S-1-5-21-2222222222-2222222222-2222222222'
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgement:
acknowledgements: Martin Sohn Christensen, @martinsohndk

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: All service principals with Microsoft Graph App Role assignments
guid: 74440269-eb41-476b-8dec-b4095569b029
prebuilt: true
platform: Azure
category: Microsoft Graph
description:
query: |-
MATCH p=(:AZServicePrincipal)-[:AZMGAppRoleAssignment_ReadWrite_All|AZMGApplication_ReadWrite_All|AZMGDirectory_ReadWrite_All|AZMGGroupMember_ReadWrite_All|AZMGGroup_ReadWrite_All|AZMGRoleManagement_ReadWrite_Directory|AZMGServicePrincipalEndpoint_ReadWrite_All]->(:AZServicePrincipal)
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgements:

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: All service principals with Microsoft Graph privilege to grant arbitrary App Roles
guid: e6d6b5da-89da-4514-a409-2d6e368397da
prebuilt: true
platform: Azure
category: Microsoft Graph
description:
query: |-
MATCH p=(:AZServicePrincipal)-[:AZMGGrantAppRoles]->(:AZTenant)
RETURN p
LIMIT 1000
note:
revision: 1
resources:
acknowledgements:

Loading