From 24bcea1e76b241f13be1ea66f35078fbbc1749b2 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Thu, 21 Aug 2025 11:55:53 +0200 Subject: [PATCH 1/2] Fix issue 23 to properly match correct dsheuristics --- queries/Domains not mitigating CVE-2021-42291.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/Domains not mitigating CVE-2021-42291.yml b/queries/Domains not mitigating CVE-2021-42291.yml index 4b858ff..c523ce8 100644 --- a/queries/Domains not mitigating CVE-2021-42291.yml +++ b/queries/Domains not mitigating CVE-2021-42291.yml @@ -6,7 +6,7 @@ category: Active Directory Hygiene description: Checks the AttributeAuthorizationOnLDAPAdd flag of dSHeuristics. query: |- MATCH (n:Domain) - WHERE n.dsheuristics =~ ".{27}[^1].*" + WHERE n.dsheuristics =~ "^(.{0,27}|.{27}[^1].*)$" RETURN n revision: 1 resources: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5 From eb99f9201c761e1025bb5f54772847b10a3d7033 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 21 Aug 2025 09:57:51 +0000 Subject: [PATCH 2/2] Update combined queries --- Queries.json | 2202 +++++++++++++++++++++++++------------------------- 1 file changed, 1101 insertions(+), 1101 deletions(-) diff --git a/Queries.json b/Queries.json index 429f14a..577aa8e 100644 --- a/Queries.json +++ b/Queries.json @@ -1,104 +1,141 @@ [ { - "name": "Domain controllers with weak certificate binding enabled", - "guid": "a2444d99-10b5-412d-8fea-4b063cfddd2c", - "prebuilt": true, + "name": "Tier Zero users not member of Protected Users", + "guid": "543eb01d-9fa3-4b8f-a936-b46bbfdaa2ae", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (s:Computer)-[:DCFor]->(:Domain)\nWHERE s.strongcertificatebindingenforcementraw = 0 OR s.strongcertificatebindingenforcementraw = 1\nRETURN p\nLIMIT 1000", + "query": "MATCH (m:User)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nOPTIONAL MATCH (g:Group)<-[:MemberOf*1..]-(n:Base)\nWHERE g.objectid ENDS WITH '-525'\nWITH m, COLLECT(n) AS matchingNs\nWHERE NONE(n IN matchingNs WHERE n.objectid = m.objectid)\nRETURN m", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Kerberos-enabled service accounts without AES encryption support", - "guid": "cb8cf96e-21c9-422b-9439-390a13446ca6", + "name": "Users with logon scripts stored in a trusted domain", + "guid": "8d94d3f3-3d53-4939-a206-3c0a4dd3f646", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Accounts without Kerberos AES encryption support, or passwords set before the existence of Windows Server 2008 Domain Controller which therefore lack AES encryption keys.", - "query": "MATCH (n:Base)\nWHERE n.hasspn = true\nAND ((\n n.supportedencryptiontypes <> ['Not defined']\n OR n.supportedencryptiontypes <> []\n OR NONE(type IN n.supportedencryptiontypes WHERE type CONTAINS 'AES128' OR type CONTAINS 'AES256')\n)\nOR (n.pwdlastset < 1204070400 // Password Last Set before Windows Server 2008\nAND NOT n.pwdlastset IN [-1.0, 0.0]\n))\nRETURN n\nLIMIT 100", - "revision": 2, + "description": null, + "query": "MATCH (n:User)\nWHERE n.logonscript IS NOT NULL\nMATCH (d:Domain)-[:TrustedBy]->(:Domain)-[:Contains*1..]->(n)\nWITH n,last(split(d.name, '@')) AS domain\nWHERE toUpper(n.logonscript) STARTS WITH (\"\\\\\\\\\" + domain + \"\\\\\")\nRETURN n", + "revision": 1, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Large default groups with outbound control of OUs", - "guid": "310b3626-f8e6-4ab0-832c-72df6048597f", - "prebuilt": false, + "name": "Kerberoastable members of Tier Zero / High Value groups", + "guid": "e6da7800-ae06-41cb-80a6-d5421ab2143a", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Kerberos Interaction", "description": null, - "query": "MATCH p=(n:Group)-[]->(:OU)\nWHERE n.objectid ENDS WITH \"-513\" // DOMAIN USERS\nOR n.objectid ENDS WITH \"-515\" // DOMAIN COMPUTERS\nOR n.objectid ENDS WITH \"-S-1-5-11\" // AUTHENTICATED USERS\nOR n.objectid ENDS WITH \"-S-1-1-0\" // EVERYONE\nOR n.objectid ENDS WITH \"S-1-5-32-545\" // USERS\nOR n.objectid ENDS WITH \"S-1-5-32-546\" // GUESTS\nOR n.objectid ENDS WITH \"S-1-5-7\" // ANONYMOUS\nRETURN p", + "query": "MATCH (u:User)\nWHERE (u:Tag_Tier_Zero) AND u.hasspn=true\nAND u.enabled = true\nAND NOT u.objectid ENDS WITH '-502'\nAND NOT COALESCE(u.gmsa, false) = true\nAND NOT COALESCE(u.msa, false) = true \nRETURN u\nLIMIT 100", + "revision": 1, + "resources": [ + "https://attack.mitre.org/techniques/T1558/003/" + ], + "acknowledgements": [] + }, + { + "name": "Enrollment rights on published certificate templates with no security extension", + "guid": "0677b70c-4e04-4e89-a6a2-f5764604a6a7", + "prebuilt": true, + "platforms": [ + "Active Directory" + ], + "category": "Active Directory Certificate Services", + "description": null, + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE ct.nosecurityextension = true\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Non-Tier Zero accounts with SID History of Tier Zero accounts", - "guid": "59744dfe-9411-4daf-b342-1203dc62acd4", + "name": "Domains with a minimum default password policy length less than 15 characters", + "guid": "7d258d2d-a43d-4a90-85d7-71c946ae5fd7", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "query": "MATCH (n:Domain)\nWHERE n.minpwdlength < 15\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://pages.nist.gov/800-63-3/sp800-63b.html" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Users with passwords not rotated in over 1 year", - "guid": "be70d1bd-b7eb-40b0-971c-eefc50eca032", + "name": "All service principals with Microsoft Graph privilege to grant arbitrary App Roles", + "guid": "e6d6b5da-89da-4514-a409-2d6e368397da", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", + "category": "Microsoft Graph", "description": null, - "query": "WITH 365 as days_since_change\nMATCH (u:User)\nWHERE u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u\nLIMIT 100", + "query": "MATCH p=(:AZServicePrincipal)-[:AZMGGrantAppRoles]->(:AZTenant)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Computers with the outgoing NTLM setting set to Deny all", - "guid": "a9ddca74-feeb-4dbf-8b0f-de08b3cfa8a6", + "name": "On-Prem Users synced to Entra Users with Entra Group Membership", + "guid": "edb575df-2048-4ef0-a0e4-168544a496e9", "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "NTLM Relay Attacks", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH (c:Computer)\nWHERE c.restrictoutboundntlm = True\nRETURN c LIMIT 1000", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Accounts with SID History", - "guid": "8172d52c-a975-49bd-9180-5b6efc59c9ab", + "name": "Non-Tier Zero principals with BadSuccessor rights (no prerequisites check)", + "guid": "2b9fb71e-73ad-4061-a2df-40c7132b044d", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Dangerous Privileges", + "description": "Finds non-Tier Zero principals with BadSuccessor rights with no prerequisites check (DC2025 & KDC key).", + "query": "// Find OU control\nMATCH p = (ou:OU)<-[:WriteDacl|Owns|GenericAll|WriteOwner]-(n:Base)\n// Exclude Tier Zero\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p LIMIT 1000", + "revision": 1, + "resources": [ + "https://bsky.app/profile/specterops.io/post/3lpua65qeu22l" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] + }, + { + "name": "All Schema Admins", + "guid": "76d8e61d-7a86-40ff-8a85-fd37f1e2563f", + "prebuilt": false, + "platforms": [ + "Active Directory" + ], + "category": "Domain Information", "description": null, - "query": "MATCH p=(:Base)-[:HasSIDHistory]->(:Base)\nRETURN p", + "query": "MATCH p=(n:Base)-[:MemberOf*1..]->(m:Group)\nWHERE (n:User OR n:Computer)\nAND m.objectid ENDS WITH \"-518\" // Schema Admins\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -106,105 +143,106 @@ ] }, { - "name": "Tier Zero computers not owned by Tier Zero", - "guid": "99d29ded-223a-442b-a0e0-f8b5694c6441", + "name": "Enabled users inactive for 180 days", + "guid": "71972f3c-b32d-4023-a841-5cc8cc1c1867", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=(n:Base)-[:Owns]->(:Computer)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", - "revision": 2, + "query": "WITH 180 as inactive_days\nMATCH (n:User)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nRETURN n\nLIMIT 1000", + "revision": 1, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Principals with DCSync privileges", - "guid": "6e9beb8a-ad14-43de-bda1-644d174a5906", + "name": "Shortest paths to Domain Admins from Kerberoastable users", + "guid": "bd163361-1e05-47c7-908b-962aef251535", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Shortest Paths", "description": null, - "query": "MATCH p=(:Base)-[:DCSync|AllExtendedRights|GenericAll]->(:Domain)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=shortestPath((s:User)-[: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*1..]->(t:Group))\nWHERE s.hasspn=true\nAND s.enabled = true\nAND NOT s.objectid ENDS WITH '-502'\nAND NOT COALESCE(s.gmsa, false) = true\nAND NOT COALESCE(s.msa, false) = true\nAND t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Domains with a minimum default password policy length less than 15 characters", - "guid": "7d258d2d-a43d-4a90-85d7-71c946ae5fd7", + "name": "Direct Principal Rights Assignment", + "guid": "1d9c6ae3-38fc-4089-b5ad-fc3be0fa8eec", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:Domain)\nWHERE n.minpwdlength < 15\nRETURN n", + "description": "This query identifies rights assigned directly to users or computers instead of groups. Active Directory best practice requires granting rights to groups, then adding users as group members. This role-based access control (RBAC) approach ensures permissions are easily auditable and manageable. Results include inherited rights, which must be modified at the parent container level.", + "query": "MATCH p=(n:Base)-[r:GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteGPLink|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)\nWHERE (n:User OR n:Computer) \nRETURN p\nLIMIT 1000", "revision": 1, "resources": [ - "https://pages.nist.gov/800-63-3/sp800-63b.html" + "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Enrollment rights on published certificate templates with no security extension", - "guid": "0677b70c-4e04-4e89-a6a2-f5764604a6a7", + "name": "Domains with smart card accounts where smart account passwords do not expire", + "guid": "97e05e67-5961-4aba-a8e7-fe5f92334035", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE ct.nosecurityextension = true\nRETURN p\nLIMIT 1000", + "query": "MATCH (s:Domain)-[:Contains*1..]->(t:Base)\nWHERE s.expirepasswordsonsmartcardonlyaccounts = false\nAND t.enabled = true\nAND t.smartcardrequired = true\nRETURN s", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Servers where Domain Users can RDP", - "guid": "b9a330ae-1d89-44d4-8f74-9ca18e93eb92", + "name": "On-Prem Users synced to Entra Users that Own Entra Objects", + "guid": "4baf1026-e64c-4e31-afeb-2090b8090130", "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Dangerous Privileges", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH p=(s:Group)-[:CanRDP]->(t:Computer)\nWHERE s.objectid ENDS WITH '-513' AND toUpper(t.operatingsystem) CONTAINS 'SERVER'\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZOwns]->(:AZBase)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "All Global Administrators", - "guid": "94d7d765-6837-4eb8-aa33-e1c9ef262cdc", + "name": "Tier Zero / High Value users with non-expiring passwords", + "guid": "4eca1b69-00a2-48a0-abb3-b94ea647cf6b", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "General", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:AZBase)-[:AZGlobalAdmin*1..]->(:AZTenant)\nRETURN p\nLIMIT 1000", + "query": "MATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0') AND u.enabled = true\nAND u.pwdneverexpires = true\nRETURN u\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Computer owners who can obtain LAPS passwords", - "guid": "92aa81d6-b08e-4abb-ae39-ecbe5735a74c", + "name": "Accounts with SID History to a non-existent domain", + "guid": "2710401a-c4c2-4d2c-9edb-d7625045f2e8", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": "Creators of computer objects get abusable rights on the computer object. If the owner is not explicitly granted ReadLAPSPassword they can still compromise the computer with the abusable owner rights.", - "query": "MATCH p = (c:Computer)<-[:GenericAll|Owns|WriteDacl|WriteOwner|AllExtendedRights]-(n:User)\nWHERE c.haslaps = true AND c.ownersid = n.objectid\nRETURN p", + "category": "Active Directory Hygiene", + "description": null, + "query": "MATCH (d:Domain)\nWITH collect(d.objectid) AS domainSIDs\nMATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE NOT n.domainsid IN domainSIDs\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -212,15 +250,15 @@ ] }, { - "name": "Tier Zero computers with the WebClient running", - "guid": "27a6f917-8ed4-4e2e-9b38-41a4b6de1b14", + "name": "All Operators", + "guid": "3dfd0843-1ff9-4c21-aa67-feae08d109de", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Domain Information", "description": null, - "query": "MATCH (c:Computer)\nWHERE c.webclientrunning = True\nAND ((c:Tag_Tier_Zero) OR COALESCE(c.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN c LIMIT 1000", + "query": "MATCH p=(:Base)-[:MemberOf]->(n:Group)\nWHERE (\n n.objectid ENDS WITH 'S-1-5-32-551' OR // Backup Operators\n n.objectid ENDS WITH 'S-1-5-32-556' OR // Network Configuration Operators\n n.objectid ENDS WITH 'S-1-5-32-549' OR // Server Operators\n n.objectid ENDS WITH 'S-1-5-32-579' OR // Access Control Assistance Operators\n n.objectid ENDS WITH 'S-1-5-32-548' OR // Account Operators\n n.objectid ENDS WITH 'S-1-5-32-569' OR // Cryptographic Operators\n n.objectid ENDS WITH 'S-1-5-32-550' // Print Operators\n)\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -228,46 +266,49 @@ ] }, { - "name": "ACEs across trusts", - "guid": "c902d3b4-1a75-4335-acd7-28246dab746d", + "name": "Non-Tier Zero account with 'Admin Count' flag", + "guid": "e7f703b3-5dba-4aef-8346-4d589be2c828", "prebuilt": false, "platforms": [ "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)\nWHERE trustedDomainPrincipal.domainsid <> trustingDomainPrincipal.domainsid\nAND r.isacl\nRETURN p\nLIMIT 1000", + "category": "Active Directory Hygiene", + "description": "Users who were a member of one of AD's built-in administrative groups but are not currently Tier Zero.", + "query": "MATCH (n:User)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.admincount = true\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/windows/win32/adschema/a-admincount" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "On-Prem Users synced to Entra Users with Azure RM Roles (group delegated)", - "guid": "e4f2eada-8a89-4ba9-89eb-abbee4efbc7a", + "name": "AS-REP Roastable users (DontReqPreAuth)", + "guid": "2570e359-dec1-419d-b0dc-a204bd64ee42", "prebuilt": true, "platforms": [ - "Active Directory", - "Azure" + "Active Directory" ], - "category": "Cross Platform Attack Paths", + "category": "Kerberos Interaction", "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)-[:AZOwner|AZUserAccessAdministrator|AZGetCertificates|AZGetKeys|AZGetSecrets|AZAvereContributor|AZKeyVaultContributor|AZContributor|AZVMAdminLogin|AZVMContributor|AZAKSContributor|AZAutomationContributor|AZLogicAppContributor|AZWebsiteContributor]->(:AZBase)\nRETURN p\nLIMIT 1000", + "query": "MATCH (u:User)\nWHERE u.dontreqpreauth = true\nAND u.enabled = true\nRETURN u\nLIMIT 100", "revision": 1, - "resources": [], + "resources": [ + "https://attack.mitre.org/techniques/T1558/004/" + ], "acknowledgements": [] }, { - "name": "Tier Zero computers at risk of constrained delegation", - "guid": "8641e593-f2f2-48ba-bd45-fbc86e9f632a", + "name": "Enabled computers inactive for 180 days", + "guid": "0768e810-1e1e-4319-a216-76d9c2058644", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (n:Computer)<-[:AllowedToDelegate]-(:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "query": "WITH 180 as inactive_days\nMATCH (n:Computer)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.name STARTS WITH 'AZUREADKERBEROS.' // Removes false positive, Azure KRBTGT\nAND NOT n.name STARTS WITH 'AZUREADSSOACC.' // Removes false positive, Entra Seamless SSO\nRETURN n\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [ @@ -275,161 +316,184 @@ ] }, { - "name": "Members of Allowed RODC Password Replication Group", - "guid": "19fc5acd-e30a-4038-a5b5-2e0494f93373", + "name": "Shortest paths to Tier Zero / High Value targets", + "guid": "237aac58-8641-4703-a9f7-001d69546fd8", + "prebuilt": true, + "platforms": [ + "Active Directory" + ], + "category": "Shortest Paths", + "description": null, + "query": "MATCH p=shortestPath((s)-[: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*1..]->(t:Tag_Tier_Zero))\nWHERE s<>t\nRETURN p\nLIMIT 1000", + "revision": 1, + "resources": [], + "acknowledgements": [] + }, + { + "name": "Enabled built-in guest user accounts", + "guid": "bb0f620d-6a55-4413-ac74-4c82905e8598", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=(:Base)-[:MemberOf*1..]->(m:Group)\nWHERE m.objectid ENDS WITH \"-571\"\nRETURN p", - "revision": 2, + "query": "MATCH (n:User)\nWHERE n.objectid ENDS WITH \"-501\"\nAND n.enabled = true\nRETURN n", + "revision": 1, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Non-default permissions on IssuancePolicy nodes", - "guid": "b2280665-c91b-448c-8c0f-97d1f38b6f59", + "name": "Servers where Domain Users can RDP", + "guid": "b9a330ae-1d89-44d4-8f74-9ca18e93eb92", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH p = (s:Base)-[:GenericAll|GenericWrite|Owns|WriteOwner|WriteDacl]->(:IssuancePolicy)\nWHERE NOT s.objectid ENDS WITH '-512' AND NOT s.objectid ENDS WITH '-519'\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(s:Group)-[:CanRDP]->(t:Computer)\nWHERE s.objectid ENDS WITH '-513' AND toUpper(t.operatingsystem) CONTAINS 'SERVER'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Trace ACE inheritance", - "guid": "8c5454df-3ae8-412c-b271-3c4c55df7141", - "prebuilt": false, + "name": "Disabled Tier Zero / High Value principals", + "guid": "d65a801f-d3ef-4b7e-8030-99ebfd6dad12", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": "When BloodHound shows that an inherited ACE applies to an object it does not show the source/where it is inherited from from (OU, Container, Domain root) - the source is where it should be remediated. This query can sometimes find the source of an inherited ACE, but only works if the ACE is set to also apply to the source itself.", - "query": "// Replace INSERT_OBJECT_ID with the affected principal\n// Replace 'GenericAll' with the specific edge you're tracing\nWITH \"INSERT_OBJECT_ID\" as OID\nMATCH p=()-[:GenericAll {isacl:true,isinherited:false}]->()-[:Contains*1..]->(:Base{objectid:OID})\nWHERE NONE(ou in NODES(p) WHERE ou:OU AND ou.isaclprotected IS NOT NULL)\nRETURN p", + "category": "Active Directory Hygiene", + "description": null, + "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = false\nAND NOT n.objectid ENDS WITH '-502' // Removes false positive, KRBTGT\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nRETURN n\nLIMIT 100", "revision": 1, "resources": [], - "acknowledgements": [ - "Walter.Legowski, @SadProcessor" - ] + "acknowledgements": [] }, { - "name": "Tier Zero accounts not members of Denied RODC Password Replication Group", - "guid": "e9613406-e346-410b-a033-690a6cf0c708", + "name": "Entra ID SSO accounts not rolling Kerberos decryption key", + "guid": "1867abf8-08e3-4ea8-8f65-8366079d35c4", "prebuilt": false, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND (n:User or n:Computer)\nWITH n\nOPTIONAL MATCH (n)-[:MemberOf*1..]->(m:Group)\nWHERE m.objectid ENDS WITH '-519'\nWITH n, m\nWHERE m IS NULL\nRETURN n", + "category": "Configuration Weakness", + "description": "Microsoft highly recommends that you roll over the Entra ID SSO Kerberos decryption key at least every 30 days.", + "query": "MATCH (n:Computer)\nWHERE n.name STARTS WITH \"AZUREADSSOACC.\"\nAND n.pwdlastset < (datetime().epochseconds - (30 * 86400))\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-sso-faq#how-can-i-roll-over-the-kerberos-decryption-key-of-the--azureadsso--computer-account-" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Users with logon scripts stored in a trusted domain", - "guid": "8d94d3f3-3d53-4939-a206-3c0a4dd3f646", + "name": "Tier Zero computers not owned by Tier Zero", + "guid": "99d29ded-223a-442b-a0e0-f8b5694c6441", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH (n:User)\nWHERE n.logonscript IS NOT NULL\nMATCH (d:Domain)-[:TrustedBy]->(:Domain)-[:Contains*1..]->(n)\nWITH n,last(split(d.name, '@')) AS domain\nWHERE toUpper(n.logonscript) STARTS WITH (\"\\\\\\\\\" + domain + \"\\\\\")\nRETURN n", - "revision": 1, + "query": "MATCH p=(n:Base)-[:Owns]->(:Computer)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "revision": 2, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domains not verifying UPN and SPN uniqueness", - "guid": "cb0b1591-5c3e-45f1-afb7-984e5ad865d0", + "name": "All ADCS ESC privilege escalation edges", + "guid": "49db8edc-8421-438f-b97b-23c042959bef", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "Checks the DoNotVerifyUPNAndOrSPNUniqueness flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{20}[^0].*\"\nRETURN n", + "category": "Active Directory Certificate Services", + "description": null, + "query": "MATCH p=(:Base)-[:ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|GoldenCert|CoerceAndRelayNTLMToADCS]->(:Base)\nRETURN p", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + "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": [ - "Martin Sohn Christensen, @martinsohndk" + "Jonas B\u00fclow Knudsen, @Jonas_B_K" ] }, { - "name": "Non-Tier Zero account with 'Admin Count' flag", - "guid": "e7f703b3-5dba-4aef-8346-4d589be2c828", + "name": "Members of Allowed RODC Password Replication Group", + "guid": "19fc5acd-e30a-4038-a5b5-2e0494f93373", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "Users who were a member of one of AD's built-in administrative groups but are not currently Tier Zero.", - "query": "MATCH (n:User)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.admincount = true\nRETURN n", - "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/windows/win32/adschema/a-admincount" - ], + "category": "Domain Information", + "description": null, + "query": "MATCH p=(:Base)-[:MemberOf*1..]->(m:Group)\nWHERE m.objectid ENDS WITH \"-571\"\nRETURN p", + "revision": 2, + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Tier Zero computers with unsupported operating systems", - "guid": "a87b558c-5746-4a90-9f83-c86e7b924a52", + "name": "Microsoft Entra Connect accounts with passwords not rotated in over 90 days", + "guid": "97fb1310-d15d-4d63-82a2-8788056250f1", "prebuilt": false, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*Windows.* (2000|2003|2008|2012|xp|vista|7|8|me|nt).*'\nAND ((c:Tag_Tier_Zero) OR COALESCE(c.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN c\nLIMIT 100", + "description": "Micosoft recommends to change the password of MSOL accounts every 90 days to prevent attackers from allowing use of the high privileges", + "query": "WITH 90 as days_since_change\nMATCH (u:User)\nWHERE u.name STARTS WITH \"MSOL_\"\nAND u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/defender-for-identity/rotate-password-microsoft-entra-connect" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Large default group added to computer-local group", - "guid": "dde133d2-b4d2-4de9-a656-905f3bf066f3", + "name": "Object name conflict", + "guid": "c561c4f8-ea45-453f-85a2-3fc2e20e7f8c", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": null, - "query": "MATCH p=(n:Group)-[:MemberOfLocalGroup]->(m:ADLocalGroup)-[:LocalToComputer]->(:Computer)\nWHERE n.objectid =~ \".*-(S-1-5-11|S-1-1-0|S-1-5-32-545|S-1-5-7|-513|-515)$\" // Authenticated Users, Everyone, Users, Anonymous, Domain Users, Domain Computers\nAND NOT m.objectid =~ \".*-(545|574|554)$\" // Users, Certificate Service DCOM Access, Pre-Windows 2000 Compatible Access\nRETURN p", + "category": "Active Directory Hygiene", + "description": "When two objects are created with the same Relative Distinguished Name (RDN) in the same parent Organizational Unit or container, the conflict is recognized by the system when one of the new objects replicates to another domain controller. When this happens, one of the objects is renamed with 'CNF'", + "query": "MATCH (n:Base)\nWHERE n.distinguishedname CONTAINS 'CNF:'\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/archive/technet-wiki/15435.active-directory-duplicate-object-name-resolution" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domains without Microsoft LAPS computers", - "guid": "f9b440b5-732c-4ed3-b6d2-83857db17e1a", + "name": "Tier Zero computers at risk of constrained delegation", + "guid": "8641e593-f2f2-48ba-bd45-fbc86e9f632a", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH (d:Domain)\nOPTIONAL MATCH (c:Computer)\nWHERE c.domainsid = d.objectid AND c.haslaps = true\nWITH d, COLLECT(c) AS computers\nWHERE SIZE(computers) = 0\nRETURN d", + "query": "MATCH p = (n:Computer)<-[:AllowedToDelegate]-(:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -437,61 +501,63 @@ ] }, { - "name": "Shortest paths to Azure Subscriptions", - "guid": "4785b305-c101-461c-80fc-3fb3ff67a8ce", + "name": "Map domain trusts", + "guid": "268d3d26-5bc2-4820-a6ed-09d20f3d5413", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Shortest Paths", + "category": "Domain Information", "description": null, - "query": "MATCH p=shortestPath((s:AZBase)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZSubscription))\nWHERE s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Domain)-[:SameForestTrust|CrossForestTrust]->(:Domain)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Principals with weak supported Kerberos encryption types", - "guid": "ca329573-2157-41da-ab17-4d122c54b11d", - "prebuilt": true, + "name": "Tier Zero computers with passwords older than the default maximum password age", + "guid": "b6d6d0bf-130e-4719-996b-adc29bba36e9", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (u:Base)\nWHERE 'DES-CBC-CRC' IN u.supportedencryptiontypes\nOR 'DES-CBC-MD5' IN u.supportedencryptiontypes\nOR 'RC4-HMAC-MD5' IN u.supportedencryptiontypes\nRETURN u", - "revision": 1, + "query": "MATCH (n:Computer)\nWHERE n.enabled = true\nAND n.whencreated < (datetime().epochseconds - (60 * 3 * 86400))\nAND n.pwdlastset < (datetime().epochseconds - (60 * 3 * 86400))\nAND ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", + "revision": 2, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Enabled computers inactive for 180 days - MSSQL Failover Cluster", - "guid": "d263e621-7f1b-4efb-ad25-098fc7d4fb72", + "name": "Foreign Service Principals With any Abusable MS Graph App Role Assignment", + "guid": "d7a180c8-5624-4fc1-a407-deeb2ad3054c", "prebuilt": false, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "WITH 180 as inactive_days\nMATCH (n:Computer)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND ANY(type IN n.serviceprincipalnames WHERE \n toLower(type) CONTAINS 'mssqlservercluster' OR \n toLower(type) CONTAINS 'mssqlserverclustermgmtapi' OR \n toLower(type) CONTAINS 'msclustervirtualserver')\nRETURN n\nLIMIT 1000", + "category": "Dangerous Privileges", + "description": "MS Graph app role assignments provide significant power within an Entra ID tenant, similar to an Admin role.", + "query": "MATCH p = (sp1:AZServicePrincipal)-[r:AZMGGroupMember_ReadWrite_All|AZMGServicePrincipalEndpoint_ReadWrite_All|AZMGAppRoleAssignment_ReadWrite_All|AZMGGroup_ReadWrite_All|AZMGDirectory_ReadWrite_All|AZMGRoleManagement_ReadWrite_Directory]->(sp2:AZServicePrincipal)\nWHERE toUpper(sp1.appownerorganizationid) <> toUpper(sp1.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp1.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/troubleshoot/windows-server/high-availability/troubleshoot-issues-accounts-used-failover-clusters#troubleshoot-password-issues-with-the-cluster-name-account" + "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" ], "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" + "Stephen Hinck" ] }, { - "name": "Users with non-default Primary Group membership", - "guid": "93890f88-df2c-4167-a945-a53961d08d00", + "name": "Usage of built-in domain Administrator account", + "guid": "35b1206f-871b-44aa-a601-c5258060dfcf", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH p=(n:User)-[r:MemberOf]->(g:Group)\nWHERE NOT g.objectid ENDS WITH \"-513\" // Domain Users\nAND r.isprimarygroup = true\nAND NOT n.objectid ENDS WITH \"-501\" // Guests account, as it has primaryGroup to Guests\nAND (n.gmsa IS NULL OR n.gmsa = false) // Not gMSA, as it has primaryGroup to Domain Computers\nAND (n.msa IS NULL OR n.msa = false) // Not MSA, as it has primaryGroup to Domain Computers\nRETURN p", + "description": "Usage of Active Directory's built-in Administrator account is a sign that the account is not only used for break-glass purposes.", + "query": "MATCH (n:User)\nWHERE n.objectid ENDS WITH \"-500\"\nAND (\n n.lastlogontimestamp > (datetime().epochseconds - (60 * 86400)) OR\n n.lastlogon > (datetime().epochseconds - (60 * 86400))\n)\nAND NOT n.whencreated > (datetime().epochseconds - (60 * 86400))\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -499,126 +565,129 @@ ] }, { - "name": "Large default groups with outbound control", - "guid": "a334f21a-3d7f-448e-b7ea-1465a3127bce", - "prebuilt": false, + "name": "Kerberoastable users with most admin privileges", + "guid": "9907b208-494c-4ba6-846d-485e6de14e17", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Kerberos Interaction", "description": null, - "query": "MATCH p=(n:Group)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|GoldenCert|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC5|ADCSESC6a|ADCSESC6b|ADCSESC7|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)\nWHERE n.objectid ENDS WITH \"-513\" // DOMAIN USERS\nOR n.objectid ENDS WITH \"-515\" // DOMAIN COMPUTERS\nOR n.objectid ENDS WITH \"-S-1-5-11\" // AUTHENTICATED USERS\nOR n.objectid ENDS WITH \"-S-1-1-0\" // EVERYONE\nOR n.objectid ENDS WITH \"S-1-5-32-545\" // USERS\nOR n.objectid ENDS WITH \"S-1-5-32-546\" // GUESTS\nOR n.objectid ENDS WITH \"S-1-5-7\" // ANONYMOUS\nRETURN p", + "query": "MATCH (u:User)\nWHERE u.hasspn = true\n AND u.enabled = true\n AND NOT u.objectid ENDS WITH '-502'\n AND NOT COALESCE(u.gmsa, false) = true\n AND NOT COALESCE(u.msa, false) = true\nMATCH (u)-[:MemberOf|AdminTo*1..]->(c:Computer)\nWITH DISTINCT u, COUNT(c) AS adminCount\nRETURN u\nORDER BY adminCount DESC\nLIMIT 100", "revision": 1, - "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "resources": [ + "https://attack.mitre.org/techniques/T1558/003/" + ], + "acknowledgements": [] }, { - "name": "Tier Zero users not member of Protected Users", - "guid": "543eb01d-9fa3-4b8f-a936-b46bbfdaa2ae", + "name": "AdminSDHolder protected Accounts and Groups", + "guid": "5ee2f40e-a55c-4140-ab8a-91746ba3752b", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (m:User)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nOPTIONAL MATCH (g:Group)<-[:MemberOf*1..]-(n:Base)\nWHERE g.objectid ENDS WITH '-525'\nWITH m, COLLECT(n) AS matchingNs\nWHERE NONE(n IN matchingNs WHERE n.objectid = m.objectid)\nRETURN m", + "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)\nWHERE (\n 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\n 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\n OR n.objectid =~ \".*-(500|502|516|521)$\" // Direct objects\n)\nRETURN n", "revision": 1, - "resources": [], + "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" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Disabled Tier Zero / High Value principals", - "guid": "d65a801f-d3ef-4b7e-8030-99ebfd6dad12", + "name": "Enrollment rights on certificate templates published to Enterprise CA with User Specified SAN enabled", + "guid": "96e70597-2d74-4503-a624-f1e30b642894", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = false\nAND NOT n.objectid ENDS WITH '-502' // Removes false positive, KRBTGT\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nRETURN n\nLIMIT 100", + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(eca:EnterpriseCA)\nWHERE eca.isuserspecifiessanenabled = True\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Shortest paths to Domain Admins", - "guid": "f40cb34b-5ec7-44bc-9aa8-a200a4a41f22", + "name": "On-Prem Users synced to Entra Users with Azure RM Roles (group delegated)", + "guid": "e4f2eada-8a89-4ba9-89eb-abbee4efbc7a", "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Shortest Paths", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH p=shortestPath((t:Group)<-[: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*1..]-(s:Base))\nWHERE t.objectid ENDS WITH '-512' AND s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)-[:AZOwner|AZUserAccessAdministrator|AZGetCertificates|AZGetKeys|AZGetSecrets|AZAvereContributor|AZKeyVaultContributor|AZContributor|AZVMAdminLogin|AZVMContributor|AZAKSContributor|AZAutomationContributor|AZLogicAppContributor|AZWebsiteContributor]->(:AZBase)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Non-Tier Zero principals with control of AdminSDHolder", - "guid": "4c1e0137-5b7f-48d8-bd09-9db7674bca61", - "prebuilt": false, + "name": "Principals with foreign domain group membership", + "guid": "8fb3214a-5a75-4ecd-b293-c121abd94b4b", + "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Dangerous Privileges", "description": null, - "query": "MATCH p=(n:Group)-[r:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|CoerceToTGT|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteOwnerLimitedRights|OwnsLimitedRights]->(m:Container)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND m.name STARTS WITH \"ADMINSDHOLDER@\"\nRETURN p", + "query": "MATCH p=(s:Base)-[:MemberOf]->(t:Group)\nWHERE s.domainsid<>t.domainsid\nRETURN p\nLIMIT 1000", "revision": 1, + "resources": [], + "acknowledgements": [] + }, + { + "name": "Accounts with weak password storage encryption", + "guid": "8bd6fcf2-3f3c-414c-857a-4caf28e49def", + "prebuilt": true, + "platforms": [ + "Active Directory" + ], + "category": "Active Directory Hygiene", + "description": "Accounts with passwords set before the existence of Windows Server 2008 Domain Controller which therefore lack AES encryption keys.", + "query": "MATCH (n:Base)\nWHERE n.pwdlastset < 1204070400 // Password Last Set before Windows Server 2008 release\nRETURN n\nLIMIT 100", + "revision": 2, "resources": [ - "https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory#adminsdholder" + "https://techcommunity.microsoft.com/blog/coreinfrastructureandsecurityblog/decrypting-the-selection-of-supported-kerberos-encryption-types/1628797" ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Shortest paths from Domain Users to Tier Zero / High Value targets", - "guid": "469dc0f3-71b8-41b0-a03b-b4af7874665d", - "prebuilt": true, + "name": "Computers without Windows LAPS", + "guid": "7c50f724-c467-4005-8e3f-9a6ce1461db0", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=shortestPath((s:Group)-[: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*1..]->(t:Base))\nWHERE s.objectid ENDS WITH '-513' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", - "revision": 1, - "resources": [], - "acknowledgements": [] - }, - { - "name": "Microsoft Entra Connect accounts with passwords not rotated in over 90 days", - "guid": "97fb1310-d15d-4d63-82a2-8788056250f1", - "prebuilt": false, - "platforms": [ - "Active Directory", - "Azure" - ], - "category": "Active Directory Hygiene", - "description": "Micosoft recommends to change the password of MSOL accounts every 90 days to prevent attackers from allowing use of the high privileges", - "query": "WITH 90 as days_since_change\nMATCH (u:User)\nWHERE u.name STARTS WITH \"MSOL_\"\nAND u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u", + "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*WINDOWS (SERVER)? ?(10|11|2019|2022|2025).*'\nAND c.haslaps = false\nAND c.enabled = true\nRETURN c\nLIMIT 100", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/defender-for-identity/rotate-password-microsoft-entra-connect" + "https://learn.microsoft.com/en-us/windows-server/identity/laps/laps-overview" ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domain Controllers allowing NTLMv1 or LM authentication", - "guid": "4b42513c-f89d-47ff-8d98-908af49d2b48", + "name": "Domains affected by AdPrep privilege escalation risk", + "guid": "815ff190-f6f3-4757-a516-2f4bf589b705", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH (dc:Computer)\nWHERE dc.isdc = true\nAND (dc.lmcompatibilitylevel IS NOT NULL AND NOT dc.lmcompatibilitylevel = 5)\nRETURN dc", + "query": "MATCH p=(n:Group)-[r:GenericAll]->(m:Domain)\nWHERE n.objectid ENDS WITH \"-527\" // Enterprise Key Admins\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -626,43 +695,33 @@ ] }, { - "name": "Enabled Tier Zero / High Value principals inactive for 60 days", - "guid": "72550bcb-3c4f-463d-8973-91a49163dc5a", - "prebuilt": true, + "name": "Enabled computers inactive for 180 days - MSSQL Failover Cluster", + "guid": "d263e621-7f1b-4efb-ad25-098fc7d4fb72", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "WITH 60 as inactive_days\nMATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.name STARTS WITH 'AZUREADKERBEROS.' // Removes false positive, Azure KRBTGT\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nAND NOT n.name STARTS WITH 'AZUREADSSOACC.' // Removes false positive, Entra Seamless SSO\nRETURN n", + "query": "WITH 180 as inactive_days\nMATCH (n:Computer)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND ANY(type IN n.serviceprincipalnames WHERE \n toLower(type) CONTAINS 'mssqlservercluster' OR \n toLower(type) CONTAINS 'mssqlserverclustermgmtapi' OR \n toLower(type) CONTAINS 'msclustervirtualserver')\nRETURN n\nLIMIT 1000", "revision": 1, - "resources": [], - "acknowledgements": [] - }, - { - "name": "Tier Zero / High Value external Entra ID users", - "guid": "20e07417-d286-4dca-a962-568f2b262f65", - "prebuilt": true, - "platforms": [ - "Azure" + "resources": [ + "https://learn.microsoft.com/en-us/troubleshoot/windows-server/high-availability/troubleshoot-issues-accounts-used-failover-clusters#troubleshoot-password-issues-with-the-cluster-name-account" ], - "category": "Azure Hygiene", - "description": null, - "query": "MATCH (n:AZUser)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.name CONTAINS '#EXT#@'\nRETURN n\nLIMIT 100", - "revision": 1, - "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Enabled users inactive for 180 days", - "guid": "71972f3c-b32d-4023-a841-5cc8cc1c1867", + "name": "All incoming and local paths for a specific computer", + "guid": "1f67e538-19d4-4020-89c8-5b39b31571bd", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "WITH 180 as inactive_days\nMATCH (n:User)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nRETURN n\nLIMIT 1000", + "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\nMATCH p=(n:Base)-[:RemoteInteractiveLogonPrivilege|AdminTo|CanRDP|LocalToComputer|MemberOfLocalGroup]-(m:Base)\nWHERE m.name CONTAINS 'HOSTNAME'\nAND m.name CONTAINS '.' // Only see computer-related objects (eg. not AD Groups)\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -670,203 +729,201 @@ ] }, { - "name": "Domains with a single-point-of-failure Domain Controller", - "guid": "3359a295-7cfd-491f-976b-c5a68647431c", - "prebuilt": false, + "name": "Shortest paths from Domain Users to Tier Zero / High Value targets", + "guid": "469dc0f3-71b8-41b0-a03b-b4af7874665d", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Shortest Paths", "description": null, - "query": "MATCH (n:Group)<-[:MemberOf]-(:Computer)\nWHERE n.objectid ENDS WITH '-516'\nWITH n, COUNT(n) AS dcCount\nWHERE dcCount = 1\nRETURN n", + "query": "MATCH p=shortestPath((s:Group)-[: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*1..]->(t:Base))\nWHERE s.objectid ENDS WITH '-513' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Principal with SPN keyword", - "guid": "38a9c4c9-3d70-453f-a017-cbfd35ed9917", + "name": "Map Azure Management structure", + "guid": "c1bb109e-e6a4-4c91-864f-f78e1e42615e", "prebuilt": false, "platforms": [ - "Active Directory" + "Azure" ], "category": "Kerberos Interaction", - "description": "Finds service accounts used with a specific Kerberos-enabled service or all service accounts running on a Kerberos-enabled service on a specific server.", - "query": "// Replace keyword with a service type or server name (not FQDN)\nWITH \"KEYWORD\" as SPNKeyword\nMATCH (n:User)\nWHERE ANY(keyword IN n.serviceprincipalnames WHERE toUpper(keyword) CONTAINS toUpper(SPNKeyword))\nRETURN n", + "description": "Maps the structure of Azure Management", + "query": "MATCH p = (:AZTenant)-[:AZContains*1..]->(:AZResourceGroup)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [ - "https://adsecurity.org/?page_id=183" + "https://learn.microsoft.com/en-us/azure/governance/management-groups/overview" ], "acknowledgements": [ - "Ryan, @haus3c" + "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domains allowing authenticated domain enumeration", - "guid": "1e1e6fdd-6973-4547-906c-a494b5fbdcba", - "prebuilt": false, + "name": "Principals with DCSync privileges", + "guid": "6e9beb8a-ad14-43de-bda1-644d174a5906", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE n.objectid ENDS WITH \"S-1-5-11\" // Authenticated Users\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", + "query": "MATCH p=(:Base)-[:DCSync|AllExtendedRights|GenericAll]->(:Domain)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Public Key Services container", - "guid": "07e94492-71aa-4665-ab8c-e7aec25906cd", + "name": "Principals with passwords stored using reversible encryption", + "guid": "ab900835-b2b8-4674-87b4-8b5141e80439", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (c:Container)-[:Contains*..]->(:Base)\nWHERE c.distinguishedname starts with 'CN=PUBLIC KEY SERVICES,CN=SERVICES,CN=CONFIGURATION,DC='\nRETURN p\nLIMIT 1000", + "query": "MATCH (n:Base)\nWHERE n.encryptedtextpwdallowed = true\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "All service principals with Microsoft Graph App Role assignments", - "guid": "74440269-eb41-476b-8dec-b4095569b029", + "name": "Nested groups within Tier Zero / High Value", + "guid": "8e541e75-df1d-423f-b429-4bbf0403a338", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Microsoft Graph", + "category": "Active Directory Hygiene", "description": null, - "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)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(t:Group)<-[:MemberOf*..]-(s:Group)\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT s.objectid ENDS WITH '-512' // Domain Admins\nAND NOT s.objectid ENDS WITH '-519' // Enterprise Admins\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Direct Principal Rights Assignment", - "guid": "1d9c6ae3-38fc-4089-b5ad-fc3be0fa8eec", + "name": "Tier Zero computers with the WebClient running", + "guid": "27a6f917-8ed4-4e2e-9b38-41a4b6de1b14", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "This query identifies rights assigned directly to users or computers instead of groups. Active Directory best practice requires granting rights to groups, then adding users as group members. This role-based access control (RBAC) approach ensures permissions are easily auditable and manageable. Results include inherited rights, which must be modified at the parent container level.", - "query": "MATCH p=(n:Base)-[r:GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteGPLink|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)\nWHERE (n:User OR n:Computer) \nRETURN p\nLIMIT 1000", + "description": null, + "query": "MATCH (c:Computer)\nWHERE c.webclientrunning = True\nAND ((c:Tag_Tier_Zero) OR COALESCE(c.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN c LIMIT 1000", "revision": 1, - "resources": [ - "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Enrollment rights on certificate templates published to Enterprise CA with User Specified SAN enabled", - "guid": "96e70597-2d74-4503-a624-f1e30b642894", - "prebuilt": true, + "name": "Non-default members in Pre-Windows 2000 Compatible Access", + "guid": "091995b9-7254-473a-996f-6b8368d20431", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(eca:EnterpriseCA)\nWHERE eca.isuserspecifiessanenabled = True\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE NOT n.objectid ENDS WITH \"S-1-5-11\" // Authenticated Users\nAND NOT (n.objectid ENDS WITH \"S-1-5-7\" // Anonymous\nAND NOT n.objectid ENDS WITH \"S-1-1-0\") // Everyone\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "All Kerberoastable users", - "guid": "14ab4eaa-b73b-49c4-b2d1-1e020757c995", + "name": "Shortest paths to Domain Admins", + "guid": "f40cb34b-5ec7-44bc-9aa8-a200a4a41f22", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Kerberos Interaction", + "category": "Shortest Paths", "description": null, - "query": "MATCH (u:User)\nWHERE u.hasspn=true\nAND u.enabled = true\nAND NOT u.objectid ENDS WITH '-502'\nAND NOT COALESCE(u.gmsa, false) = true\nAND NOT COALESCE(u.msa, false) = true\nRETURN u\nLIMIT 100", + "query": "MATCH p=shortestPath((t:Group)<-[: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*1..]-(s:Base))\nWHERE t.objectid ENDS WITH '-512' AND s<>t\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://attack.mitre.org/techniques/T1558/003/" - ], + "resources": [], "acknowledgements": [] }, { - "name": "Domains allowing unauthenticated rootDSE searches and binds", - "guid": "ebc79aa4-e816-4be8-93fe-a0b30dbc771d", + "name": "Domains with a single-point-of-failure Domain Controller", + "guid": "3359a295-7cfd-491f-976b-c5a68647431c", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Checks the fLDAPBlockAnonOps flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{6}[^2].*\"\nRETURN n", + "description": null, + "query": "MATCH (n:Group)<-[:MemberOf]-(:Computer)\nWHERE n.objectid ENDS WITH '-516'\nWITH n, COUNT(n) AS dcCount\nWHERE dcCount = 1\nRETURN n", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "All Domain Admins", - "guid": "0596dba7-9180-49a0-aa54-00243240037c", - "prebuilt": true, + "name": "Non-Tier Zero principals with BadSuccessor rights (with prerequisites check)", + "guid": "74daaebe-6040-4f7a-9c9a-416faf73dcc3", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": null, - "query": "MATCH p = (t:Group)<-[:MemberOf*1..]-(a)\nWHERE (a:User or a:Computer) and t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", + "category": "Dangerous Privileges", + "description": "Finds non-Tier Zero principals with BadSuccessor rights after checking prerequisites check (DC2025 & KDC key).", + "query": "// Find 2025 DCs\nMATCH (dc:Computer)\nWHERE dc.isdc = true AND dc.operatingsystem CONTAINS '2025'\n// Find gMSAs\nMATCH (m:User)\nWHERE m.gmsa = true\n// Find OU control\nMATCH p = (ou:OU)<-[:WriteDacl|Owns|GenericAll|WriteOwner]-(n:Base)\n// Confirm domain has a 2025 DC\nWHERE ou.domain = dc.domain\n// Confirm domain KDC key\nAND ou.domain = m.domain\n// Exclude Tier Zero\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p LIMIT 1000", "revision": 1, - "resources": [], - "acknowledgements": [] + "resources": [ + "https://bsky.app/profile/specterops.io/post/3lpua65qeu22l" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Non-default delegation on MicrosoftDNS container", - "guid": "008792c0-4458-46a1-a10d-50cdaf95af1e", + "name": "Collection health of DC Registry Data", + "guid": "3f0fa2f3-fbdf-42c0-9e7d-97e689009161", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH p=(n:Base)-[r]->(m:Container)\nWHERE m.distinguishedname STARTS WITH \"CN=MICROSOFTDNS,CN=SYSTEM,DC=\"\nAND NOT n.name STARTS WITH \"DNSADMINS@\"\nAND NOT n.objectid =~ \"-(512|544|519|9)$\"\nAND r.isacl\nRETURN p", + "category": "Domain Information", + "description": "BloodHound's ADCS analysis requires collecting CA registry data to increase accuracy/enable more edges. Collection by default requires SharpHound has Administrators membership. Requires SharpHound v2.3.5 or above. It only requires one misconfigured DC to potentially a full forest compromise by any principal. DCs returned by this query have not been collected.", + "query": "MATCH p=(:Domain)<-[:DCFor]-(c:Computer)\nWHERE c.strongcertificatebindingenforcementraw IS NULL\n// Exclude inactive DCs\nAND c.enabled = true\nAND c.lastlogontimestamp > (datetime().epochseconds - (30 * 86400))\nRETURN p", "revision": 1, - "resources": [], + "resources": [ + "https://bloodhound.specterops.io/collect-data/enterprise-collection/permissions#dc-registry" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Computers with unsupported operating systems", - "guid": "d06d3b14-0318-4fa9-9639-4b79ccaf3c2c", + "name": "Enrollment rights on published enrollment agent certificate templates", + "guid": "8483bf5b-89f1-4723-abb2-c48295f6393e", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*Windows.* (2000|2003|2008|2012|xp|vista|7|8|me|nt).*'\nRETURN c\nLIMIT 100", + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE '1.3.6.1.4.1.311.20.2.1' IN ct.effectiveekus\nOR '2.5.29.37.0' IN ct.effectiveekus\nOR SIZE(ct.effectiveekus) = 0\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Non-default members in Pre-Windows 2000 Compatible Access", - "guid": "091995b9-7254-473a-996f-6b8368d20431", + "name": "Sessions across trusts", + "guid": "aea7ac64-1f51-407b-b0ee-19fd30075794", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE NOT n.objectid ENDS WITH \"S-1-5-11\" // Authenticated Users\nAND NOT (n.objectid ENDS WITH \"S-1-5-7\" // Anonymous\nAND NOT n.objectid ENDS WITH \"S-1-1-0\") // Everyone\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", + "category": "Domain Information", + "description": "Users logging on across a trust, the users originate from trusted domains.", + "query": "MATCH p=(trustedDomainPrincipal:Computer)-[r:HasSession]->(trustingDomainPrincipal:User)\nWHERE trustedDomainPrincipal.domainsid <> trustingDomainPrincipal.domainsid\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [ @@ -874,33 +931,31 @@ ] }, { - "name": "Domains with List Object mode enabled", - "guid": "05e2a94b-5ee6-47ec-b715-3982f30af01b", + "name": "Accounts with SID History to a same-domain account", + "guid": "275d2d58-0cad-4cad-8103-e0874cece666", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": "Checks the fDoListObject flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{2}[^0].*\"\nRETURN n", + "category": "Dangerous Privileges", + "description": null, + "query": "MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE n.domainsid = m.domainsid\nRETURN p", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Accounts with clear-text password attributes", - "guid": "e303498f-e3d4-489d-8a34-b68e187bc4e7", + "name": "Tier Zero users with email", + "guid": "9654c0d4-f1e8-4393-a2d1-53a5554a9de8", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:Base)\nWHERE n.userpassword IS NOT NULL\nOR n.unixpassword IS NOT NULL\nOR n.unicodepwd IS NOT NULL\nOR n.msSFU30Password IS NOT NULL\nRETURN n", + "description": "Tier Zero accounts with email access have an increased attack surface.", + "query": "MATCH (n)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.email <> \"\"\nAND n.enabled = true\nAND NOT toUpper(n.email) ENDS WITH \".ONMICROSOFT.COM\"\nAND NOT (\n (toUpper(n.email) STARTS WITH \"HEALTHMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHDISCOVERYMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHDISCOVERY\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHAPPROVAL\"\n OR toUpper(n.email) STARTS WITH \"FEDERATEDEMAIL\"\n OR toUpper(n.email) STARTS WITH \"SYSTEMMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MIGRATION.\")\n AND\n (n.name STARTS WITH \"SM_\"\n OR n.name STARTS WITH \"HEALTHMAILBOX\")\n)\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -908,265 +963,290 @@ ] }, { - "name": "Collection health of CA Registry Data", - "guid": "c8dd3479-8063-450a-9456-557bc5f39e10", + "name": "Domains without Microsoft LAPS computers", + "guid": "f9b440b5-732c-4ed3-b6d2-83857db17e1a", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Domain Information", - "description": "BloodHound's ADCS analysis requires collecting CA registry data to increase accuracy/enable more edges. Collection by default requires SharpHound has Administrators membership. Requires SharpHound v2.3.5 or above. It only requires one misconfigured CA to potentially a full forest compromise by any principal. CAs returned by this query have not been collected.", - "query": "MATCH p=(eca:EnterpriseCA)<-[:HostsCAService]-(c:Computer)\nWHERE (\n eca.isuserspecifiessanenabledcollected = false\n OR eca.casecuritycollected = false\n OR eca.enrollmentagentrestrictionscollected = false\n OR eca.roleseparationenabledcollected = false\n)\n// Exclude inactive CAs\nAND c.enabled = true\nAND c.lastlogontimestamp > (datetime().epochseconds - (30 * 86400))\nRETURN p", + "description": null, + "query": "MATCH (d:Domain)\nOPTIONAL MATCH (c:Computer)\nWHERE c.domainsid = d.objectid AND c.haslaps = true\nWITH d, COLLECT(c) AS computers\nWHERE SIZE(computers) = 0\nRETURN d", "revision": 1, - "resources": [ - "https://bloodhound.specterops.io/collect-data/enterprise-collection/permissions#ca-registry" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Kerberos-enabled service account member of built-in Admins groups", - "guid": "42a856fc-257a-4142-9592-ca95fd49e579", - "prebuilt": false, + "name": "Circular AD group memberships", + "guid": "fcaa5ffc-3d22-481f-a2a2-18a4eec30058", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH p=(n:Base)-[:MemberOf*1..]->(g:Group)\nWHERE (\n g.objectid ENDS WITH '-512' // Domain Admins\n OR g.objectid ENDS WITH '-519' // Enterprise Admins\n OR g.objectid ENDS WITH '-518' // Schema Admins\n)\nAND n.hasspn = true\nRETURN p", + "description": "Detects circular group membership chains where groups are members of themselves through one or more intermediate groups. This causes an administrative complexity.", + "query": "MATCH p=(x:Group)-[:MemberOf*2..]->(y:Group)\nWHERE x.objectid=y.objectid\nRETURN p\nLIMIT 100", "revision": 1, - "resources": [], + "resources": [ + "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "PKI hierarchy", - "guid": "928acc23-ee4c-40a5-bde7-64c05cc1491d", + "name": "Locations of Tier Zero / High Value objects", + "guid": "18a83a17-b451-4343-acfe-7620516e2968", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Domain Information", "description": null, - "query": "MATCH p=()-[:HostsCAService|IssuedSignedBy|EnterpriseCAFor|RootCAFor|TrustedForNTAuth|NTAuthStoreFor*..]->(:Domain)\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (t:Base)<-[:Contains*1..]-(:Domain)\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Foreign Service Principals With any Abusable MS Graph App Role Assignment", - "guid": "d7a180c8-5624-4fc1-a407-deeb2ad3054c", + "name": "Non-default delegation on MicrosoftDNS container", + "guid": "008792c0-4458-46a1-a10d-50cdaf95af1e", "prebuilt": false, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Dangerous Privileges", - "description": "MS Graph app role assignments provide significant power within an Entra ID tenant, similar to an Admin role.", - "query": "MATCH p = (sp1:AZServicePrincipal)-[r:AZMGGroupMember_ReadWrite_All|AZMGServicePrincipalEndpoint_ReadWrite_All|AZMGAppRoleAssignment_ReadWrite_All|AZMGGroup_ReadWrite_All|AZMGDirectory_ReadWrite_All|AZMGRoleManagement_ReadWrite_Directory]->(sp2:AZServicePrincipal)\nWHERE toUpper(sp1.appownerorganizationid) <> toUpper(sp1.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp1.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", + "category": "Active Directory Hygiene", + "description": null, + "query": "MATCH p=(n:Base)-[r]->(m:Container)\nWHERE m.distinguishedname STARTS WITH \"CN=MICROSOFTDNS,CN=SYSTEM,DC=\"\nAND NOT n.name STARTS WITH \"DNSADMINS@\"\nAND NOT n.objectid =~ \"-(512|544|519|9)$\"\nAND r.isacl\nRETURN p", "revision": 1, - "resources": [ - "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" - ], + "resources": [], "acknowledgements": [ - "Stephen Hinck" + "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Computers with membership in Protected Users", - "guid": "a26372f4-2e92-49f6-8993-6657fbc1569a", + "name": "DCs vulnerable to NTLM relay to LDAP attacks", + "guid": "3f87e0b0-fc06-4986-a94c-e08781253dc8", "prebuilt": true, "platforms": [ "Active Directory" ], "category": "NTLM Relay Attacks", "description": null, - "query": "MATCH p = (:Base)-[:MemberOf*1..]->(g:Group)\nWHERE g.objectid ENDS WITH \"-525\"\nRETURN p LIMIT 1000", + "query": "MATCH p = (dc:Computer)-[:DCFor]->(:Domain)\nWHERE (dc.ldapavailable = True AND dc.ldapsigning = False)\nOR (dc.ldapsavailable = True AND dc.ldapsepa = False)\nOR (dc.ldapavailable = True AND dc.ldapsavailable = True AND dc.ldapsigning = False and dc.ldapsepa = True)\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Kerberoastable members of Tier Zero / High Value groups", - "guid": "e6da7800-ae06-41cb-80a6-d5421ab2143a", + "name": "Entra Users synced from On-Prem Users added to Domain Admins group", + "guid": "62722d5f-bd93-4d11-beeb-9be261827e4e", "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Kerberos Interaction", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH (u:User)\nWHERE (u:Tag_Tier_Zero) AND u.hasspn=true\nAND u.enabled = true\nAND NOT u.objectid ENDS WITH '-502'\nAND NOT COALESCE(u.gmsa, false) = true\nAND NOT COALESCE(u.msa, false) = true \nRETURN u\nLIMIT 100", + "query": "MATCH p = (:AZUser)-[:SyncedToADUser]->(:User)-[:MemberOf]->(t:Group)\nWHERE t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://attack.mitre.org/techniques/T1558/003/" - ], + "resources": [], "acknowledgements": [] }, { - "name": "Computers not requiring inbound SMB signing", - "guid": "6b1fcfb6-b010-41a2-9d31-f9872fe994ff", - "prebuilt": true, + "name": "AS-REP Roastable Tier Zero users (DontReqPreAuth)", + "guid": "6d51e4dc-e1ad-477a-b6c6-324f18f03120", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:Computer)\nWHERE n.smbsigning = False\nRETURN n", + "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.dontreqpreauth = true\nRETURN n", "revision": 1, - "resources": [], - "acknowledgements": [] + "resources": [ + "https://attack.mitre.org/techniques/T1558/004/" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Unresolved SID with outbound control", - "guid": "4e8429f9-cba2-41e9-bac6-0c42f96b2c57", + "name": "Computers with passwords older than the default maximum password age", + "guid": "185c5010-8d4f-4f9b-b24e-831707dddfca", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH p=(n:Base)-[r]->(:Base)\nWHERE r.isacl\nAND n.name CONTAINS \"S-1-5-21-\" // Unresolved SID\nRETURN p\nLIMIT 1000", + "description": "Machine account passwords are regularly changed for security purposes. Starting with Windows 2000-based computers, the machine account password automatically changes every 30 days.", + "query": "WITH 60 as rotation_period\nMATCH (n:Computer)\nWHERE n.pwdlastset < (datetime().epochseconds - (rotation_period * 86400)) // password not rotated\nAND n.enabled = true // enabled computers\nAND n.whencreated < (datetime().epochseconds - (rotation_period * 86400)) // exclude recently created computers\nAND n.lastlogontimestamp > (datetime().epochseconds - (rotation_period * 86400)) // active computers (Replicated value)\nAND n.lastlogon > (datetime().epochseconds - (rotation_period * 86400)) // active computers (Non-replicated value)\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/disable-machine-account-password" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Principals with passwords stored using reversible encryption", - "guid": "ab900835-b2b8-4674-87b4-8b5141e80439", - "prebuilt": true, + "name": "Domains not verifying UPN and SPN uniqueness", + "guid": "cb0b1591-5c3e-45f1-afb7-984e5ad865d0", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:Base)\nWHERE n.encryptedtextpwdallowed = true\nRETURN n", + "description": "Checks the DoNotVerifyUPNAndOrSPNUniqueness flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{20}[^0].*\"\nRETURN n", "revision": 1, - "resources": [], - "acknowledgements": [] + "resources": [ + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Domains without Protected Users group", - "guid": "8c3e0811-a31b-45b4-a29d-1dce80fa2c5f", + "name": "Overprivileged Microsoft Entra Connect accounts", + "guid": "9e6e75b4-9ecc-45d4-a39b-b6427b813f0a", "prebuilt": false, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Domain Information", - "description": null, - "query": "MATCH (n:Domain)\nWHERE n.collected = true\nOPTIONAL MATCH (m:Group)\nWHERE m.name ENDS WITH n.name\nAND m.objectid ENDS WITH '-525'\nWITH n, m\nWHERE m IS NULL\nRETURN n", + "category": "Active Directory Hygiene", + "description": "Legacy MSOL accounts were by default deployed with Domain Admins or Enterprise Admins membership.", + "query": "MATCH p=(n:User)-[:MemberOf*1..]->(g:Group)\nWHERE n.name STARTS WITH \"MSOL_\"\nAND (g.objectid ENDS WITH \"-512\" // Domain Admins\nOR g.objectid ENDS WITH \"-519\") // Entterprise Admins\nRETURN p", "revision": 1, + "resources": [ + "https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/reference-connect-accounts-permissions" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] + }, + { + "name": "Potential GPO 'Apply' misconfiguration", + "guid": "f5f2455e-afdc-4708-9a34-98f539ce52d8", + "prebuilt": true, + "platforms": [ + "Active Directory" + ], + "category": "Dangerous Privileges", + "description": "In Active Directory, GPO's are applied to objects in the Group Policy Management Console by ticking \"Allow - Apply group policy\", but administrators can mistakenly tick \"Allow - Write\" or \"Allow - Full Control\" resulting in a misconfigured GPO that allows a principal to compromise other principals the GPO also applies to. Results are potential risks and must be audited for for correctness.", + "query": "MATCH p=(n:Base)-[:GenericAll|GenericWrite]->(g:GPO)\n\n// Exclude Enterprise Admins and Domain Admins\nWHERE NOT n.objectid =~ \"-(519|512)$\"\n\n// Exclude unresolved SIDs\nAND NOT (n.distinguishedname IS NULL)\n\n// Asset description may reveal if it's a delegation group (false-positive) or a filter group (true-positive)\n//AND n.description is not null\n//AND n.description =~ \"(?i)apply\"\n\nRETURN p\nLIMIT 1000", + "revision": 2, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Tier Zero AD principals synchronized with Entra ID", - "guid": "a8b6ec67-21aa-4dd2-8906-47bb81bf5262", + "name": "ESC8-vulnerable Enterprise CAs", + "guid": "60881923-296c-4702-adf7-a4f059dc9bb8", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Azure Hygiene", + "category": "NTLM Relay Attacks", "description": null, - "query": "MATCH (ENTRA:AZBase)\nMATCH (AD:Base)\nWHERE ((AD:Tag_Tier_Zero) OR COALESCE(AD.system_tags, '') CONTAINS 'admin_tier_0')\nAND ENTRA.onpremsyncenabled = true\nAND ENTRA.onpremid = AD.objectid\nRETURN ENTRA\n// Replace 'RETURN ENTRA' with 'RETURN AD' to see the corresponding AD principals\nLIMIT 100", + "query": "MATCH (n:EnterpriseCA)\nWHERE n.hasvulnerableendpoint=true\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Enrollment rights on published certificate templates", - "guid": "a4ae2e54-aad3-4bfd-a12d-90cb8a9cbc86", + "name": "Domains where any user can join a computer to the domain", + "guid": "421921fa-bc0f-4659-9680-b7481adcb132", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nRETURN p\nLIMIT 1000", + "query": "MATCH (n:Domain)\nWHERE n.machineaccountquota > 0\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/default-workstation-numbers-join-domain", + "https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/add-workstations-to-domain" + ], "acknowledgements": [] }, { - "name": "Collection health of DC Registry Data", - "guid": "3f0fa2f3-fbdf-42c0-9e7d-97e689009161", + "name": "Users with non-default Primary Group membership", + "guid": "93890f88-df2c-4167-a945-a53961d08d00", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": "BloodHound's ADCS analysis requires collecting CA registry data to increase accuracy/enable more edges. Collection by default requires SharpHound has Administrators membership. Requires SharpHound v2.3.5 or above. It only requires one misconfigured DC to potentially a full forest compromise by any principal. DCs returned by this query have not been collected.", - "query": "MATCH p=(:Domain)<-[:DCFor]-(c:Computer)\nWHERE c.strongcertificatebindingenforcementraw IS NULL\n// Exclude inactive DCs\nAND c.enabled = true\nAND c.lastlogontimestamp > (datetime().epochseconds - (30 * 86400))\nRETURN p", + "category": "Active Directory Hygiene", + "description": null, + "query": "MATCH p=(n:User)-[r:MemberOf]->(g:Group)\nWHERE NOT g.objectid ENDS WITH \"-513\" // Domain Users\nAND r.isprimarygroup = true\nAND NOT n.objectid ENDS WITH \"-501\" // Guests account, as it has primaryGroup to Guests\nAND (n.gmsa IS NULL OR n.gmsa = false) // Not gMSA, as it has primaryGroup to Domain Computers\nAND (n.msa IS NULL OR n.msa = false) // Not MSA, as it has primaryGroup to Domain Computers\nRETURN p", "revision": 1, - "resources": [ - "https://bloodhound.specterops.io/collect-data/enterprise-collection/permissions#dc-registry" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Kerberoastable users with most admin privileges", - "guid": "9907b208-494c-4ba6-846d-485e6de14e17", + "name": "Cross-forest trusts with abusable configuration", + "guid": "5cf1f354-80d4-420e-bc4b-424fabc21a56", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Kerberos Interaction", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (u:User)\nWHERE u.hasspn = true\n AND u.enabled = true\n AND NOT u.objectid ENDS WITH '-502'\n AND NOT COALESCE(u.gmsa, false) = true\n AND NOT COALESCE(u.msa, false) = true\nMATCH (u)-[:MemberOf|AdminTo*1..]->(c:Computer)\nWITH DISTINCT u, COUNT(c) AS adminCount\nRETURN u\nORDER BY adminCount DESC\nLIMIT 100", + "query": "MATCH p=(n:Domain)-[:CrossForestTrust|SpoofSIDHistory|AbuseTGTDelegation]-(m:Domain)\nWHERE (n)-[:SpoofSIDHistory|AbuseTGTDelegation]-(m)\nRETURN p", "revision": 1, - "resources": [ - "https://attack.mitre.org/techniques/T1558/003/" - ], + "resources": [], "acknowledgements": [] }, { - "name": "Enrollment rights on published ESC2 certificate templates", - "guid": "ebc77984-1ceb-4ed2-a395-ce1067847941", + "name": "Principals with weak supported Kerberos encryption types", + "guid": "ca329573-2157-41da-ab17-4d122c54b11d", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(c:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE c.requiresmanagerapproval = false\nAND (c.effectiveekus = [''] OR '2.5.29.37.0' IN c.effectiveekus)\nAND (c.authorizedsignatures = 0 OR c.schemaversion = 1)\nRETURN p\nLIMIT 1000", + "query": "MATCH (u:Base)\nWHERE 'DES-CBC-CRC' IN u.supportedencryptiontypes\nOR 'DES-CBC-MD5' IN u.supportedencryptiontypes\nOR 'RC4-HMAC-MD5' IN u.supportedencryptiontypes\nRETURN u", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "AS-REP Roastable Tier Zero users (DontReqPreAuth)", - "guid": "6d51e4dc-e1ad-477a-b6c6-324f18f03120", + "name": "Domains allowing unauthenticated NSPI RPC binds", + "guid": "a950fdab-5934-4c69-a88b-e2e0e3da9d52", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.dontreqpreauth = true\nRETURN n", + "description": "Checks the fAllowAnonNSPI flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{7}[^0].*\"\nRETURN n", "revision": 1, "resources": [ - "https://attack.mitre.org/techniques/T1558/004/" + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Tier Zero computers not requiring inbound SMB signing", - "guid": "13485477-f026-4b1f-906d-4f2e37364ba4", + "name": "Users with non-expiring passwords", + "guid": "212c2a98-53d9-4dfa-b177-42c601452dd1", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:Computer)\nWHERE n.smbsigning = False\nAND ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", + "query": "MATCH (u:User)\nWHERE u.enabled = true\nAND u.pwdneverexpires = true\nRETURN u\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [ @@ -1174,122 +1254,87 @@ ] }, { - "name": "All members of high privileged roles", - "guid": "3df24d92-dd12-4125-811b-e696b098f60e", + "name": "Enrollment rights on published ESC1 certificate templates", + "guid": "2af855bc-f48f-4b22-9839-627d8231e425", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "General", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p=(t:AZRole)<-[:AZHasRole|AZMemberOf*1..2]-(:AZBase)\nWHERE t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator'\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE ct.enrolleesuppliessubject = True\nAND ct.authenticationenabled = True\nAND ct.requiresmanagerapproval = False\nAND (ct.authorizedsignatures = 0 OR ct.schemaversion = 1)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Disabled Tier Zero / High Value principals", - "guid": "860d5c2d-84fe-4c85-80de-e0a9badbd0e7", + "name": "Public Key Services container", + "guid": "07e94492-71aa-4665-ab8c-e7aec25906cd", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Azure Hygiene", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH (n:AZBase)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = false\nRETURN n\nLIMIT 100", + "query": "MATCH p = (c:Container)-[:Contains*..]->(:Base)\nWHERE c.distinguishedname starts with 'CN=PUBLIC KEY SERVICES,CN=SERVICES,CN=CONFIGURATION,DC='\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "AS-REP Roastable users (DontReqPreAuth)", - "guid": "2570e359-dec1-419d-b0dc-a204bd64ee42", + "name": "All service principals with Microsoft Graph App Role assignments", + "guid": "74440269-eb41-476b-8dec-b4095569b029", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Kerberos Interaction", + "category": "Microsoft Graph", "description": null, - "query": "MATCH (u:User)\nWHERE u.dontreqpreauth = true\nAND u.enabled = true\nRETURN u\nLIMIT 100", + "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)\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://attack.mitre.org/techniques/T1558/004/" - ], + "resources": [], "acknowledgements": [] }, { - "name": "Potential GPO 'Apply' misconfiguration", - "guid": "f5f2455e-afdc-4708-9a34-98f539ce52d8", - "prebuilt": true, + "name": "Accounts with SID History", + "guid": "8172d52c-a975-49bd-9180-5b6efc59c9ab", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": "In Active Directory, GPO's are applied to objects in the Group Policy Management Console by ticking \"Allow - Apply group policy\", but administrators can mistakenly tick \"Allow - Write\" or \"Allow - Full Control\" resulting in a misconfigured GPO that allows a principal to compromise other principals the GPO also applies to. Results are potential risks and must be audited for for correctness.", - "query": "MATCH p=(n:Base)-[:GenericAll|GenericWrite]->(g:GPO)\n\n// Exclude Enterprise Admins and Domain Admins\nWHERE NOT n.objectid =~ \"-(519|512)$\"\n\n// Exclude unresolved SIDs\nAND NOT (n.distinguishedname IS NULL)\n\n// Asset description may reveal if it's a delegation group (false-positive) or a filter group (true-positive)\n//AND n.description is not null\n//AND n.description =~ \"(?i)apply\"\n\nRETURN p\nLIMIT 1000", - "revision": 2, - "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] - }, - { - "name": "Enrollment rights on published ESC1 certificate templates", - "guid": "2af855bc-f48f-4b22-9839-627d8231e425", - "prebuilt": true, - "platforms": [ - "Active Directory" - ], - "category": "Active Directory Certificate Services", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE ct.enrolleesuppliessubject = True\nAND ct.authenticationenabled = True\nAND ct.requiresmanagerapproval = False\nAND (ct.authorizedsignatures = 0 OR ct.schemaversion = 1)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(:Base)-[:HasSIDHistory]->(:Base)\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] - }, - { - "name": "Entra ID SSO accounts not rolling Kerberos decryption key", - "guid": "1867abf8-08e3-4ea8-8f65-8366079d35c4", - "prebuilt": false, - "platforms": [ - "Active Directory", - "Azure" - ], - "category": "Configuration Weakness", - "description": "Microsoft highly recommends that you roll over the Entra ID SSO Kerberos decryption key at least every 30 days.", - "query": "MATCH (n:Computer)\nWHERE n.name STARTS WITH \"AZUREADSSOACC.\"\nAND n.pwdlastset < (datetime().epochseconds - (30 * 86400))\nRETURN n", - "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-sso-faq#how-can-i-roll-over-the-kerberos-decryption-key-of-the--azureadsso--computer-account-" - ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "DCs vulnerable to NTLM relay to LDAP attacks", - "guid": "3f87e0b0-fc06-4986-a94c-e08781253dc8", + "name": "Computers with unsupported operating systems", + "guid": "d06d3b14-0318-4fa9-9639-4b79ccaf3c2c", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (dc:Computer)-[:DCFor]->(:Domain)\nWHERE (dc.ldapavailable = True AND dc.ldapsigning = False)\nOR (dc.ldapsavailable = True AND dc.ldapsepa = False)\nOR (dc.ldapavailable = True AND dc.ldapsavailable = True AND dc.ldapsigning = False and dc.ldapsepa = True)\nRETURN p", + "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*Windows.* (2000|2003|2008|2012|xp|vista|7|8|me|nt).*'\nRETURN c\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Domains with functional level not the latest version", - "guid": "3da9d14a-f1cb-4df7-b3da-8d73ff5c401b", + "name": "Domains allowing authenticated domain enumeration", + "guid": "1e1e6fdd-6973-4547-906c-a494b5fbdcba", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:Domain)\nWHERE toString(n.functionallevel) IN ['2008','2003','2003 Interim','2000 Mixed/Native']\nRETURN n", + "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE n.objectid ENDS WITH \"S-1-5-11\" // Authenticated Users\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -1297,50 +1342,50 @@ ] }, { - "name": "Tier Zero computers at risk of resource-based constrained delegation", - "guid": "4dc97cf4-3c03-4fe6-8a8b-4f665c67e1e5", + "name": "Domains not mitigating CVE-2021-42291", + "guid": "02202726-d86d-46c2-891c-9770c635f76f", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": null, - "query": "MATCH p = (n:Computer)<-[:AllowedToAct]-(:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "category": "Active Directory Hygiene", + "description": "Checks the AttributeAuthorizationOnLDAPAdd flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \"^(.{0,27}|.{27}[^1].*)$\"\nRETURN n", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Tier Zero / High Value users with non-expiring passwords", - "guid": "4eca1b69-00a2-48a0-abb3-b94ea647cf6b", + "name": "Tier Zero / High Value enabled users not requiring smart card authentication", + "guid": "867f9f17-c149-4c4b-ad84-9a807622ff8c", "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0') AND u.enabled = true\nAND u.pwdneverexpires = true\nRETURN u\nLIMIT 100", + "query": "MATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0')\nAND u.enabled = true\nAND u.smartcardrequired = false\nAND NOT u.name STARTS WITH 'MSOL_' // Removes false positive, Entra sync\nAND NOT u.name STARTS WITH 'PROVAGENTGMSA' // Removes false positive, Entra sync\nAND NOT u.name STARTS WITH 'ADSYNCMSA_' // Removes false positive, Entra sync\nRETURN u", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Tier Zero users with passwords not rotated in over 1 year", - "guid": "5e0d69b1-37d1-43ae-ac5d-f297f312fab5", - "prebuilt": false, + "name": "Computers with the WebClient running", + "guid": "51107ad1-f0bc-43d3-a561-5cee471ca196", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "NTLM Relay Attacks", "description": null, - "query": "WITH 365 as days_since_change\nMATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0')\nAND u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u\nLIMIT 100", + "query": "MATCH (c:Computer)\nWHERE c.webclientrunning = True\nRETURN c LIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { "name": "Workstations where Domain Users can RDP", @@ -1357,164 +1402,137 @@ "acknowledgements": [] }, { - "name": "Domain Admins logons to non-Domain Controllers", - "guid": "e2f3fd0a-1df2-4089-b0a4-272ad6e369a9", - "prebuilt": true, + "name": "Domains allowing unauthenticated rootDSE searches and binds", + "guid": "ebc79aa4-e816-4be8-93fe-a0b30dbc771d", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": null, - "query": "MATCH (s)-[:MemberOf*0..]->(g:Group)\nWHERE g.objectid ENDS WITH '-516'\nWITH COLLECT(s) AS exclude\nMATCH p = (c:Computer)-[:HasSession]->(:User)-[:MemberOf*1..]->(g:Group)\nWHERE g.objectid ENDS WITH '-512' AND NOT c IN exclude\nRETURN p\nLIMIT 1000", + "category": "Active Directory Hygiene", + "description": "Checks the fLDAPBlockAnonOps flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{6}[^2].*\"\nRETURN n", "revision": 1, - "resources": [], - "acknowledgements": [] + "resources": [ + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "All ADCS ESC privilege escalation edges", - "guid": "49db8edc-8421-438f-b97b-23c042959bef", - "prebuilt": false, + "name": "Shortest paths from Owned objects to Tier Zero", + "guid": "dfaa8e8f-2c79-4e92-a291-b1347f6e83b0", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Shortest Paths", "description": null, - "query": "MATCH p=(:Base)-[:ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|GoldenCert|CoerceAndRelayNTLMToADCS]->(:Base)\nRETURN p", + "query": "// MANY TO MANY SHORTEST PATH QUERIES USE EXCESSIVE SYSTEM RESOURCES AND TYPICALLY WILL NOT COMPLETE\nMATCH p=shortestPath((s:Tag_Owned)-[: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*1..]->(t:Base))\nWHERE s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", "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\u00fclow Knudsen, @Jonas_B_K" - ] + "resources": [], + "acknowledgements": [] }, { - "name": "On-Prem Users synced to Entra Users with Entra Admin Roles (direct)", - "guid": "de717635-d31f-4fbd-930b-b4dac0f22118", + "name": "PKI hierarchy", + "guid": "928acc23-ee4c-40a5-bde7-64c05cc1491d", "prebuilt": true, "platforms": [ - "Active Directory", - "Azure" + "Active Directory" ], - "category": "Cross Platform Attack Paths", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZHasRole]->(:AZRole)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=()-[:HostsCAService|IssuedSignedBy|EnterpriseCAFor|RootCAFor|TrustedForNTAuth|NTAuthStoreFor*..]->(:Domain)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Map Azure Management structure", - "guid": "c1bb109e-e6a4-4c91-864f-f78e1e42615e", - "prebuilt": false, + "name": "Shortest paths from Entra Users to Tier Zero / High Value targets", + "guid": "58089b28-54e0-4fd2-bf66-3db480b00e2f", + "prebuilt": true, "platforms": [ "Azure" ], - "category": "Kerberos Interaction", - "description": "Maps the structure of Azure Management", - "query": "MATCH p = (:AZTenant)-[:AZContains*1..]->(:AZResourceGroup)\nRETURN p\nLIMIT 1000", + "category": "Shortest Paths", + "description": null, + "query": "MATCH p=shortestPath((s:AZUser)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZBase))\nWHERE (t:AZBase) AND t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/azure/governance/management-groups/overview" - ], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "resources": [], + "acknowledgements": [] }, { - "name": "Computers with passwords older than the default maximum password age", - "guid": "185c5010-8d4f-4f9b-b24e-831707dddfca", + "name": "Computers with non-default Primary Group membership", + "guid": "5862dc4e-6f6f-4321-9474-d838968495ed", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Machine account passwords are regularly changed for security purposes. Starting with Windows 2000-based computers, the machine account password automatically changes every 30 days.", - "query": "WITH 60 as rotation_period\nMATCH (n:Computer)\nWHERE n.pwdlastset < (datetime().epochseconds - (rotation_period * 86400)) // password not rotated\nAND n.enabled = true // enabled computers\nAND n.whencreated < (datetime().epochseconds - (rotation_period * 86400)) // exclude recently created computers\nAND n.lastlogontimestamp > (datetime().epochseconds - (rotation_period * 86400)) // active computers (Replicated value)\nAND n.lastlogon > (datetime().epochseconds - (rotation_period * 86400)) // active computers (Non-replicated value)\nRETURN n", + "description": null, + "query": "MATCH p=(n:Computer)-[r:MemberOf]->(g:Group)\nWHERE NOT g.objectid ENDS WITH \"-515\" // Domain Computers\nAND NOT g.objectid ENDS WITH \"-516\" // Domain Controllers\nAND NOT g.objectid ENDS WITH \"-521\" // Read-Only Domain Controllers\nAND r.isprimarygroup = true\nRETURN p", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/disable-machine-account-password" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "CA administrators and CA managers", - "guid": "fd35e3d8-0c74-4b5a-a847-c0dd1f1c9f19", - "prebuilt": true, - "platforms": [ - "Active Directory" - ], - "category": "Active Directory Certificate Services", - "description": null, - "query": "MATCH p = (:Base)-[:ManageCertificates|ManageCA]->(:EnterpriseCA)\nRETURN p\nLIMIT 1000", - "revision": 1, - "resources": [], - "acknowledgements": [] - }, - { - "name": "Tier Zero / High Value enabled users not requiring smart card authentication", - "guid": "867f9f17-c149-4c4b-ad84-9a807622ff8c", + "name": "Users with passwords not rotated in over 1 year", + "guid": "be70d1bd-b7eb-40b0-971c-eefc50eca032", "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0')\nAND u.enabled = true\nAND u.smartcardrequired = false\nAND NOT u.name STARTS WITH 'MSOL_' // Removes false positive, Entra sync\nAND NOT u.name STARTS WITH 'PROVAGENTGMSA' // Removes false positive, Entra sync\nAND NOT u.name STARTS WITH 'ADSYNCMSA_' // Removes false positive, Entra sync\nRETURN u", + "query": "WITH 365 as days_since_change\nMATCH (u:User)\nWHERE u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "On-Prem Users synced to Entra Users that Own Entra Objects", - "guid": "4baf1026-e64c-4e31-afeb-2090b8090130", - "prebuilt": true, + "name": "Collection health of specific computer", + "guid": "bb95c9c5-984c-4057-a430-000d684c069a", + "prebuilt": false, "platforms": [ - "Active Directory", - "Azure" + "Active Directory" ], - "category": "Cross Platform Attack Paths", - "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZOwns]->(:AZBase)\nRETURN p\nLIMIT 1000", + "category": "Domain Information", + "description": "Returns Local groups and their members, and Principals with privileges", + "query": "MATCH p=(m:Base)-[:RemoteInteractiveLogonRight|AdminTo|CanRDP|LocalToComputer|MemberOfLocalGroup]-(n:Base)\n\n// Insert computer FQDN\nWHERE m.name ENDS WITH \"HOSTNAME.DOMAIN.LOCAL\"\n\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Circular AD group memberships", - "guid": "fcaa5ffc-3d22-481f-a2a2-18a4eec30058", + "name": "Domains with more than 50 Tier Zero accounts", + "guid": "f046e95a-5f84-4e83-bcda-6e83f3d8e21a", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Detects circular group membership chains where groups are members of themselves through one or more intermediate groups. This causes an administrative complexity.", - "query": "MATCH p=(x:Group)-[:MemberOf*2..]->(y:Group)\nWHERE x.objectid=y.objectid\nRETURN p\nLIMIT 100", + "description": null, + "query": "MATCH (d:Domain)-[:Contains*1..]->(n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nWITH d, COUNT(n) AS adminCount\nWHERE adminCount > 50\nRETURN d", "revision": 1, - "resources": [ - "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Smart card accounts with passwords not rotated in over 1 year", - "guid": "7e56f2e7-79c3-4f0d-aa3e-14cf3de7ab73", + "name": "Domains without Protected Users group", + "guid": "8c3e0811-a31b-45b4-a29d-1dce80fa2c5f", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Domain Information", "description": null, - "query": "MATCH (n:Base)\nWHERE n.pwdlastset < (datetime().epochseconds - (365 * 86400))\nAND n.enabled = true\nAND n.smartcardrequired = true\nRETURN n", + "query": "MATCH (n:Domain)\nWHERE n.collected = true\nOPTIONAL MATCH (m:Group)\nWHERE m.name ENDS WITH n.name\nAND m.objectid ENDS WITH '-525'\nWITH n, m\nWHERE m IS NULL\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -1522,101 +1540,130 @@ ] }, { - "name": "Domains exempting privileged groups from AdminSDHolder protections", - "guid": "79f8d8f9-8291-4bf7-a13a-15989018075f", + "name": "Uncommon permission on containers", + "guid": "018c2b45-e30f-47d8-a751-22419c3d0736", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Checks the dwAdminSDExMask flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{15}[^0].*\"\nRETURN n", + "description": "BloodHound typically identifies risk on Active Directory objects stored in OUs, however behind the scenes; Active Directory has a hieracy of containers e.g. CN=SYSTEM and CN=CONFIGURATION, on which control can lead to risk. Results are prone to false-positives but can assist auditing containers permissions.", + "query": "MATCH p=(:Domain)-[:Contains*1..]->(c:Container)<-[r]-(n:Base)\n\n// Exclude Tier Zero\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\n\n// Scope edges to ACLs\nAND r.isacl\n\n// Exclude CN=Users and CN=Computers containers\nAND NOT c.distinguishedname STARTS WITH \"CN=COMPUTERS,DC=\"\nAND NOT c.distinguishedname STARTS WITH \"CN=USERS,DC=\"\n\n// Exclude same-domain unresolved SIDs\nAND NOT (n.distinguishedname IS NULL AND n.domainsid = c.domainsid)\n\n// Exclude default: Cert Publishers\nAND NOT (c.distinguishedname CONTAINS \",CN=PUBLIC KEY SERVICES,CN=SERVICES,CN=CONFIGURATION,DC=\" AND n.objectid ENDS WITH \"-517\")\n\n// Exclude default: RAS and IAS Servers\nAND NOT (c.distinguishedname CONTAINS \"CN=RAS AND IAS SERVERS ACCESS CHECK,CN=SYSTEM,DC=\" AND n.objectid ENDS WITH \"-553\")\n\n// Exclude default: DNS\nAND NOT (c.distinguishedname CONTAINS \"CN=MICROSOFTDNS,CN=SYSTEM,DC=\" AND n.name STARTS WITH \"DNSADMINS@\")\n\n// Exclude default: ConfigMgr\nAND NOT (c.distinguishedname STARTS WITH \"CN=SYSTEM MANAGEMENT,CN=SYSTEM,DC=\" AND n.samaccountname ENDS WITH \"$\")\n\n// Exclude default: Exchange pt1\nAND NOT (c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\" AND (n.name STARTS WITH \"EXCHANGE TRUSTED SUBSYSTEM@\" OR n.name STARTS WITH \"ORGANIZATION MANAGEMENT@\" OR n.name STARTS WITH \"EXCHANGE SERVICES@\"))\n\n// Exclude default: Exchange pt2\nAND NOT ((c.distinguishedname CONTAINS \"CN=MONITORING MAILBOXES,CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\" OR c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\") AND n.name STARTS WITH \"EXCHANGE ENTERPRISE SERVERS@\")\n\n// Exclude default: Exchange pt3\nAND NOT ((c.distinguishedname CONTAINS \"CN=ACTIVE DIRECTORY CONNECTIONS,CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\" OR c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\" OR c.distinguishedname =~ \"CN=RECIPIENT UPDATE SERVICES,CN=ADDRESS LISTS CONTAINER,CN=.*,CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\") AND n.name STARTS WITH \"EXCHANGE DOMAIN SERVERS@\")\n\nRETURN p\nLIMIT 2000", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Shortest paths from Azure Applications to Tier Zero / High Value targets", - "guid": "60ff7c58-a98e-4bc1-9e32-8378d2db0c43", + "name": "Computers with the outgoing NTLM setting set to Deny all", + "guid": "a9ddca74-feeb-4dbf-8b0f-de08b3cfa8a6", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Shortest Paths", + "category": "NTLM Relay Attacks", "description": null, - "query": "MATCH p=shortestPath((s:AZApp)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZBase))\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0') AND s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH (c:Computer)\nWHERE c.restrictoutboundntlm = True\nRETURN c LIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Computers where Domain Users can read LAPS passwords", - "guid": "aa4bfa95-e7b9-4d56-8f35-f34f04d7b6f4", + "name": "CA administrators and CA managers", + "guid": "fd35e3d8-0c74-4b5a-a847-c0dd1f1c9f19", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p=(s:Group)-[:AllExtendedRights|ReadLAPSPassword]->(:Computer)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Base)-[:ManageCertificates|ManageCA]->(:EnterpriseCA)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Non-Tier Zero principals with BadSuccessor rights (with prerequisites check)", - "guid": "74daaebe-6040-4f7a-9c9a-416faf73dcc3", - "prebuilt": false, + "name": "Computers where Domain Users are local administrators", + "guid": "d43a7bdc-33c6-4a39-a3bb-24115749e595", + "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Dangerous Privileges", - "description": "Finds non-Tier Zero principals with BadSuccessor rights after checking prerequisites check (DC2025 & KDC key).", - "query": "// Find 2025 DCs\nMATCH (dc:Computer)\nWHERE dc.isdc = true AND dc.operatingsystem CONTAINS '2025'\n// Find gMSAs\nMATCH (m:User)\nWHERE m.gmsa = true\n// Find OU control\nMATCH p = (ou:OU)<-[:WriteDacl|Owns|GenericAll|WriteOwner]-(n:Base)\n// Confirm domain has a 2025 DC\nWHERE ou.domain = dc.domain\n// Confirm domain KDC key\nAND ou.domain = m.domain\n// Exclude Tier Zero\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p LIMIT 1000", + "description": null, + "query": "MATCH p=(s:Group)-[:AdminTo]->(:Computer)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://bsky.app/profile/specterops.io/post/3lpua65qeu22l" + "resources": [], + "acknowledgements": [] + }, + { + "name": "Non-Tier Zero account with unconstrained delegation", + "guid": "e7e9a927-3f34-42c7-b921-d8bcf626011e", + "prebuilt": false, + "platforms": [ + "Active Directory" ], + "category": "Dangerous Privileges", + "description": null, + "query": "MATCH (n:Base)\nWHERE n.unconstraineddelegation = true\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", + "revision": 1, + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Entra Users synced from On-Prem Users added to Domain Admins group", - "guid": "62722d5f-bd93-4d11-beeb-9be261827e4e", - "prebuilt": true, + "name": "All DNSAdmins", + "guid": "183fb320-f3ae-4ab3-a090-3f9a7db692e1", + "prebuilt": false, "platforms": [ - "Active Directory", - "Azure" + "Active Directory" ], - "category": "Cross Platform Attack Paths", + "category": "Domain Information", "description": null, - "query": "MATCH p = (:AZUser)-[:SyncedToADUser]->(:User)-[:MemberOf]->(t:Group)\nWHERE t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(n:Base)-[:MemberOf]->(g:Group) \nWHERE n.name STARTS WITH \"DNSADMINS@\"\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Foreign principals in Tier Zero / High Value targets", - "guid": "95bec736-86ef-4017-8465-9b9b66548b17", + "name": "Domains exempting privileged groups from AdminSDHolder protections", + "guid": "79f8d8f9-8291-4bf7-a13a-15989018075f", + "prebuilt": false, + "platforms": [ + "Active Directory" + ], + "category": "Active Directory Hygiene", + "description": "Checks the dwAdminSDExMask flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{15}[^0].*\"\nRETURN n", + "revision": 1, + "resources": [ + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] + }, + { + "name": "Computers where Domain Users can read LAPS passwords", + "guid": "aa4bfa95-e7b9-4d56-8f35-f34f04d7b6f4", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Azure Hygiene", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH (n:AZServicePrincipal)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT toUpper(n.appownerorganizationid) = toUpper(n.tenantid)\nAND n.appownerorganizationid CONTAINS '-'\nRETURN n\nLIMIT 100", + "query": "MATCH p=(s:Group)-[:AllExtendedRights|ReadLAPSPassword]->(:Computer)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "On-Prem Users synced to Entra Users with Azure RM Roles (direct)", - "guid": "8569113b-e42e-49b0-a968-53bcf0ccd970", + "name": "On-Prem Users synced to Entra Users with Entra Admin Roles (direct)", + "guid": "de717635-d31f-4fbd-930b-b4dac0f22118", "prebuilt": true, "platforms": [ "Active Directory", @@ -1624,108 +1671,123 @@ ], "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZOwner|AZUserAccessAdministrator|AZGetCertificates|AZGetKeys|AZGetSecrets|AZAvereContributor|AZKeyVaultContributor|AZContributor|AZVMAdminLogin|AZVMContributor|AZAKSContributor|AZAutomationContributor|AZLogicAppContributor|AZWebsiteContributor]->(:AZBase)\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZHasRole]->(:AZRole)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Dangerous privileges for Domain Users groups", - "guid": "9b8b9c18-f8c6-4c54-a20f-de0f7a7edbe0", - "prebuilt": true, + "name": "Tier Zero computers not requiring inbound SMB signing", + "guid": "13485477-f026-4b1f-906d-4f2e37364ba4", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "NTLM Relay Attacks", "description": null, - "query": "MATCH p=(s:Group)-[: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]->(:Base)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", + "query": "MATCH (n:Computer)\nWHERE n.smbsigning = False\nAND ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "On-Prem Users synced to Entra Users with Entra Admin Roles (group delegated)", - "guid": "609d648f-7fb8-42d3-ad99-626f9ce1f121", + "name": "All members of high privileged roles", + "guid": "3df24d92-dd12-4125-811b-e696b098f60e", "prebuilt": true, "platforms": [ - "Active Directory", "Azure" ], - "category": "Cross Platform Attack Paths", + "category": "General", "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)-[:AZHasRole]->(:AZRole)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(t:AZRole)<-[:AZHasRole|AZMemberOf*1..2]-(:AZBase)\nWHERE t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Cross-forest trusts with abusable configuration", - "guid": "5cf1f354-80d4-420e-bc4b-424fabc21a56", + "name": "Tier Zero AD principals synchronized with Entra ID", + "guid": "a8b6ec67-21aa-4dd2-8906-47bb81bf5262", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", + "category": "Azure Hygiene", "description": null, - "query": "MATCH p=(n:Domain)-[:CrossForestTrust|SpoofSIDHistory|AbuseTGTDelegation]-(m:Domain)\nWHERE (n)-[:SpoofSIDHistory|AbuseTGTDelegation]-(m)\nRETURN p", + "query": "MATCH (ENTRA:AZBase)\nMATCH (AD:Base)\nWHERE ((AD:Tag_Tier_Zero) OR COALESCE(AD.system_tags, '') CONTAINS 'admin_tier_0')\nAND ENTRA.onpremsyncenabled = true\nAND ENTRA.onpremid = AD.objectid\nRETURN ENTRA\n// Replace 'RETURN ENTRA' with 'RETURN AD' to see the corresponding AD principals\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "KRBTGT accounts with passwords not rotated in over 1 year", - "guid": "1b3ae310-ffa7-4ce5-a37f-6111aef600c8", + "name": "Non-Tier Zero account with excessive control", + "guid": "944cecfe-519b-4318-b226-e8520161b454", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (n:User)\nWHERE (n.objectid ENDS WITH '-502'\nOR n.name STARTS WITH 'AZUREADKERBEROS.'\nOR n.name STARTS WITH 'KRBTGT_AZUREAD@')\nAND n.pwdlastset < (datetime().epochseconds - (365 * 86400))\nRETURN n", - "revision": 1, + "category": "Dangerous Privileges", + "description": "Returns non-Tier Zero principals with >= 1000 direct rights to other principals. This does not include rights from group memberships.", + "query": "MATCH (n:Base)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|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]->(m:Base)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nWITH n, COLLECT(DISTINCT(m)) AS endNodes\nWHERE SIZE(endNodes) >= 1000\nRETURN n", + "revision": 2, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Locations of Tier Zero / High Value objects", - "guid": "18a83a17-b451-4343-acfe-7620516e2968", + "name": "Shortest paths to privileged roles", + "guid": "3dc73dd8-4873-4aeb-a88f-56a58c77f512", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Domain Information", + "category": "Shortest Paths", "description": null, - "query": "MATCH p = (t:Base)<-[:Contains*1..]-(:Domain)\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", + "query": "MATCH p=shortestPath((s:AZBase)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZRole))\nWHERE t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator' AND s<>t\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Shortest paths to systems trusted for unconstrained delegation", - "guid": "16a9e47b-45f8-4514-b409-771bb5186142", + "name": "Devices with unsupported operating systems", + "guid": "e3f2b53a-7ce6-4e52-9c74-68b69338288b", + "prebuilt": true, + "platforms": [ + "Azure" + ], + "category": "Azure Hygiene", + "description": null, + "query": "MATCH (n:AZDevice)\nWHERE n.operatingsystem CONTAINS 'WINDOWS'\nAND n.operatingsystemversion =~ '(10.0.19044|10.0.22000|10.0.19043|10.0.19042|10.0.19041|10.0.18363|10.0.18362|10.0.17763|10.0.17134|10.0.16299|10.0.15063|10.0.14393|10.0.10586|10.0.10240|6.3.9600|6.2.9200|6.1.7601|6.0.6200|5.1.2600|6.0.6003|5.2.3790|5.0.2195).?.*'\nRETURN n\nLIMIT 100", + "revision": 1, + "resources": [], + "acknowledgements": [] + }, + { + "name": "Enabled Tier Zero / High Value principals inactive for 60 days", + "guid": "72550bcb-3c4f-463d-8973-91a49163dc5a", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=shortestPath((s)-[: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*1..]->(t:Computer))\nWHERE t.unconstraineddelegation = true AND s<>t\nRETURN p\nLIMIT 1000", + "query": "WITH 60 as inactive_days\nMATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.name STARTS WITH 'AZUREADKERBEROS.' // Removes false positive, Azure KRBTGT\nAND NOT n.objectid ENDS WITH '-500' // Removes false positive, built-in Administrator\nAND NOT n.name STARTS WITH 'AZUREADSSOACC.' // Removes false positive, Entra Seamless SSO\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Accounts with SID History to a non-existent domain", - "guid": "2710401a-c4c2-4d2c-9edb-d7625045f2e8", + "name": "Tier Zero users with passwords not rotated in over 1 year", + "guid": "5e0d69b1-37d1-43ae-ac5d-f297f312fab5", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (d:Domain)\nWITH collect(d.objectid) AS domainSIDs\nMATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE NOT n.domainsid IN domainSIDs\nRETURN p", + "query": "WITH 365 as days_since_change\nMATCH (u:User)\nWHERE ((u:Tag_Tier_Zero) OR COALESCE(u.system_tags, '') CONTAINS 'admin_tier_0')\nAND u.pwdlastset < (datetime().epochseconds - (days_since_change * 86400))\nAND NOT u.pwdlastset IN [-1.0, 0.0]\nRETURN u\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [ @@ -1733,15 +1795,33 @@ ] }, { - "name": "Uncommon permission on containers", - "guid": "018c2b45-e30f-47d8-a751-22419c3d0736", + "name": "Principal with SPN keyword", + "guid": "38a9c4c9-3d70-453f-a017-cbfd35ed9917", + "prebuilt": false, + "platforms": [ + "Active Directory" + ], + "category": "Kerberos Interaction", + "description": "Finds service accounts used with a specific Kerberos-enabled service or all service accounts running on a Kerberos-enabled service on a specific server.", + "query": "// Replace keyword with a service type or server name (not FQDN)\nWITH \"KEYWORD\" as SPNKeyword\nMATCH (n:User)\nWHERE ANY(keyword IN n.serviceprincipalnames WHERE toUpper(keyword) CONTAINS toUpper(SPNKeyword))\nRETURN n", + "revision": 1, + "resources": [ + "https://adsecurity.org/?page_id=183" + ], + "acknowledgements": [ + "Ryan, @haus3c" + ] + }, + { + "name": "Domains with functional level not the latest version", + "guid": "3da9d14a-f1cb-4df7-b3da-8d73ff5c401b", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "BloodHound typically identifies risk on Active Directory objects stored in OUs, however behind the scenes; Active Directory has a hieracy of containers e.g. CN=SYSTEM and CN=CONFIGURATION, on which control can lead to risk. Results are prone to false-positives but can assist auditing containers permissions.", - "query": "MATCH p=(:Domain)-[:Contains*1..]->(c:Container)<-[r]-(n:Base)\n\n// Exclude Tier Zero\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\n\n// Scope edges to ACLs\nAND r.isacl\n\n// Exclude CN=Users and CN=Computers containers\nAND NOT c.distinguishedname STARTS WITH \"CN=COMPUTERS,DC=\"\nAND NOT c.distinguishedname STARTS WITH \"CN=USERS,DC=\"\n\n// Exclude same-domain unresolved SIDs\nAND NOT (n.distinguishedname IS NULL AND n.domainsid = c.domainsid)\n\n// Exclude default: Cert Publishers\nAND NOT (c.distinguishedname CONTAINS \",CN=PUBLIC KEY SERVICES,CN=SERVICES,CN=CONFIGURATION,DC=\" AND n.objectid ENDS WITH \"-517\")\n\n// Exclude default: RAS and IAS Servers\nAND NOT (c.distinguishedname CONTAINS \"CN=RAS AND IAS SERVERS ACCESS CHECK,CN=SYSTEM,DC=\" AND n.objectid ENDS WITH \"-553\")\n\n// Exclude default: DNS\nAND NOT (c.distinguishedname CONTAINS \"CN=MICROSOFTDNS,CN=SYSTEM,DC=\" AND n.name STARTS WITH \"DNSADMINS@\")\n\n// Exclude default: ConfigMgr\nAND NOT (c.distinguishedname STARTS WITH \"CN=SYSTEM MANAGEMENT,CN=SYSTEM,DC=\" AND n.samaccountname ENDS WITH \"$\")\n\n// Exclude default: Exchange pt1\nAND NOT (c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\" AND (n.name STARTS WITH \"EXCHANGE TRUSTED SUBSYSTEM@\" OR n.name STARTS WITH \"ORGANIZATION MANAGEMENT@\" OR n.name STARTS WITH \"EXCHANGE SERVICES@\"))\n\n// Exclude default: Exchange pt2\nAND NOT ((c.distinguishedname CONTAINS \"CN=MONITORING MAILBOXES,CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\" OR c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\") AND n.name STARTS WITH \"EXCHANGE ENTERPRISE SERVERS@\")\n\n// Exclude default: Exchange pt3\nAND NOT ((c.distinguishedname CONTAINS \"CN=ACTIVE DIRECTORY CONNECTIONS,CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\" OR c.distinguishedname CONTAINS \"CN=MICROSOFT EXCHANGE SYSTEM OBJECTS,DC=\" OR c.distinguishedname =~ \"CN=RECIPIENT UPDATE SERVICES,CN=ADDRESS LISTS CONTAINER,CN=.*,CN=MICROSOFT EXCHANGE,CN=SERVICES,CN=CONFIGURATION,DC=\") AND n.name STARTS WITH \"EXCHANGE DOMAIN SERVERS@\")\n\nRETURN p\nLIMIT 2000", + "description": null, + "query": "MATCH (n:Domain)\nWHERE toString(n.functionallevel) IN ['2008','2003','2003 Interim','2000 Mixed/Native']\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -1749,47 +1829,47 @@ ] }, { - "name": "Object name conflict", - "guid": "c561c4f8-ea45-453f-85a2-3fc2e20e7f8c", + "name": "Trace ACE inheritance", + "guid": "8c5454df-3ae8-412c-b271-3c4c55df7141", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "When two objects are created with the same Relative Distinguished Name (RDN) in the same parent Organizational Unit or container, the conflict is recognized by the system when one of the new objects replicates to another domain controller. When this happens, one of the objects is renamed with 'CNF'", - "query": "MATCH (n:Base)\nWHERE n.distinguishedname CONTAINS 'CNF:'\nRETURN n", + "category": "Domain Information", + "description": "When BloodHound shows that an inherited ACE applies to an object it does not show the source/where it is inherited from from (OU, Container, Domain root) - the source is where it should be remediated. This query can sometimes find the source of an inherited ACE, but only works if the ACE is set to also apply to the source itself.", + "query": "// Replace INSERT_OBJECT_ID with the affected principal\n// Replace 'GenericAll' with the specific edge you're tracing\nWITH \"INSERT_OBJECT_ID\" as OID\nMATCH p=()-[:GenericAll {isacl:true,isinherited:false}]->()-[:Contains*1..]->(:Base{objectid:OID})\nWHERE NONE(ou in NODES(p) WHERE ou:OU AND ou.isaclprotected IS NOT NULL)\nRETURN p", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/archive/technet-wiki/15435.active-directory-duplicate-object-name-resolution" - ], + "resources": [], "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" + "Walter.Legowski, @SadProcessor" ] }, { - "name": "Shortest paths from Entra Users to Tier Zero / High Value targets", - "guid": "58089b28-54e0-4fd2-bf66-3db480b00e2f", + "name": "All Kerberoastable users", + "guid": "14ab4eaa-b73b-49c4-b2d1-1e020757c995", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Shortest Paths", + "category": "Kerberos Interaction", "description": null, - "query": "MATCH p=shortestPath((s:AZUser)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZBase))\nWHERE (t:AZBase) AND t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", + "query": "MATCH (u:User)\nWHERE u.hasspn=true\nAND u.enabled = true\nAND NOT u.objectid ENDS WITH '-502'\nAND NOT COALESCE(u.gmsa, false) = true\nAND NOT COALESCE(u.msa, false) = true\nRETURN u\nLIMIT 100", "revision": 1, - "resources": [], + "resources": [ + "https://attack.mitre.org/techniques/T1558/003/" + ], "acknowledgements": [] }, { - "name": "All Operators", - "guid": "3dfd0843-1ff9-4c21-aa67-feae08d109de", + "name": "Domain migration groups", + "guid": "f39c4953-ae92-4d67-bb50-eb1a161d4d3f", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Domain Information", "description": null, - "query": "MATCH p=(:Base)-[:MemberOf]->(n:Group)\nWHERE (\n n.objectid ENDS WITH 'S-1-5-32-551' OR // Backup Operators\n n.objectid ENDS WITH 'S-1-5-32-556' OR // Network Configuration Operators\n n.objectid ENDS WITH 'S-1-5-32-549' OR // Server Operators\n n.objectid ENDS WITH 'S-1-5-32-579' OR // Access Control Assistance Operators\n n.objectid ENDS WITH 'S-1-5-32-548' OR // Account Operators\n n.objectid ENDS WITH 'S-1-5-32-569' OR // Cryptographic Operators\n n.objectid ENDS WITH 'S-1-5-32-550' // Print Operators\n)\nRETURN p", + "query": "MATCH (n:Group)\nWHERE n.name CONTAINS \"$$$@\"\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -1797,154 +1877,131 @@ ] }, { - "name": "Shortest paths from Owned objects to Tier Zero", - "guid": "dfaa8e8f-2c79-4e92-a291-b1347f6e83b0", + "name": "All coerce and NTLM relay edges", + "guid": "15c5ff3b-856c-44d1-a731-a8cb72512dd1", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "NTLM Relay Attacks", "description": null, - "query": "// MANY TO MANY SHORTEST PATH QUERIES USE EXCESSIVE SYSTEM RESOURCES AND TYPICALLY WILL NOT COMPLETE\nMATCH p=shortestPath((s:Tag_Owned)-[: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*1..]->(t:Base))\nWHERE s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (n:Base)-[:CoerceAndRelayNTLMToLDAP|CoerceAndRelayNTLMToLDAPS|CoerceAndRelayNTLMToADCS|CoerceAndRelayNTLMToSMB]->(:Base)\nRETURN p LIMIT 500", "revision": 1, - "resources": [], + "resources": [ + "https://specterops.io/blog/2025/04/08/the-renaissance-of-ntlm-relay-attacks-everything-you-need-to-know/" + ], "acknowledgements": [] }, { - "name": "Enrollment rights on CertTemplates with OIDGroupLink", - "guid": "140a68eb-d21c-4b75-971f-309225fb2d75", + "name": "All Global Administrators", + "guid": "94d7d765-6837-4eb8-aa33-e1c9ef262cdc", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Certificate Services", + "category": "General", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(:CertTemplate)-[:ExtendedByPolicy]->(:IssuancePolicy)-[:OIDGroupLink]->(:Group)\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:AZBase)-[:AZGlobalAdmin*1..]->(:AZTenant)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Accounts with SID History to a same-domain account", - "guid": "275d2d58-0cad-4cad-8103-e0874cece666", - "prebuilt": false, + "name": "Dangerous privileges for Domain Users groups", + "guid": "9b8b9c18-f8c6-4c54-a20f-de0f7a7edbe0", + "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Dangerous Privileges", "description": null, - "query": "MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE n.domainsid = m.domainsid\nRETURN p", + "query": "MATCH p=(s:Group)-[: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]->(:Base)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Users with non-expiring passwords", - "guid": "212c2a98-53d9-4dfa-b177-42c601452dd1", - "prebuilt": false, + "name": "On-Prem Users synced to Entra Users with Entra Admin Roles (group delegated)", + "guid": "609d648f-7fb8-42d3-ad99-626f9ce1f121", + "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Active Directory Hygiene", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH (u:User)\nWHERE u.enabled = true\nAND u.pwdneverexpires = true\nRETURN u\nLIMIT 100", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)-[:AZHasRole]->(:AZRole)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Computers with non-default Primary Group membership", - "guid": "5862dc4e-6f6f-4321-9474-d838968495ed", - "prebuilt": false, + "name": "All Domain Admins", + "guid": "0596dba7-9180-49a0-aa54-00243240037c", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Domain Information", "description": null, - "query": "MATCH p=(n:Computer)-[r:MemberOf]->(g:Group)\nWHERE NOT g.objectid ENDS WITH \"-515\" // Domain Computers\nAND NOT g.objectid ENDS WITH \"-516\" // Domain Controllers\nAND NOT g.objectid ENDS WITH \"-521\" // Read-Only Domain Controllers\nAND r.isprimarygroup = true\nRETURN p", + "query": "MATCH p = (t:Group)<-[:MemberOf*1..]-(a)\nWHERE (a:User or a:Computer) and t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Domains allowing unauthenticated domain enumeration", - "guid": "41a08d76-f8a5-4296-ad19-464c4c5c69fe", - "prebuilt": false, + "name": "On-Prem Users synced to Entra Users with Azure RM Roles (direct)", + "guid": "8569113b-e42e-49b0-a968-53bcf0ccd970", + "prebuilt": true, "platforms": [ - "Active Directory" + "Active Directory", + "Azure" ], - "category": "Active Directory Hygiene", + "category": "Cross Platform Attack Paths", "description": null, - "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE (n.objectid ENDS WITH \"S-1-5-7\" // Anonymous\nOR n.objectid ENDS WITH \"S-1-1-0\") // Everyone\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", + "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZOwner|AZUserAccessAdministrator|AZGetCertificates|AZGetKeys|AZGetSecrets|AZAvereContributor|AZKeyVaultContributor|AZContributor|AZVMAdminLogin|AZVMContributor|AZAKSContributor|AZAutomationContributor|AZLogicAppContributor|AZWebsiteContributor]->(:AZBase)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] - }, - { - "name": "Enrollment rights on published ESC15 certificate templates", - "guid": "78d59fe1-e1a0-4813-adc9-c3c96ac08b66", - "prebuilt": false, - "platforms": [ - "Active Directory" - ], - "category": "Active Directory Certificate Services", - "description": "Enrollment rights on certificate templates that meet the requirements for the ADCS ESC15 (EKUwu) attack.", - "query": "MATCH p=(:Base)-[:Enroll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)-[:TrustedForNTAuth]->(:NTAuthStore)-[:NTAuthStoreFor]->(:Domain)\nWHERE ct.enrolleesuppliessubject = True\nAND ct.authenticationenabled = False\nAND ct.requiresmanagerapproval = False\nAND ct.schemaversion = 1\nRETURN p", - "revision": 1, - "resources": [ - "https://x.com/SpecterOps/status/1844800558151901639", - "https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2024-49019" - ], - "acknowledgements": [ - "Jonas B\u00fclow Knudsen, @Jonas_B_K" - ] + "acknowledgements": [] }, { - "name": "Shortest paths to Domain Admins from Kerberoastable users", - "guid": "bd163361-1e05-47c7-908b-962aef251535", + "name": "Non-default permissions on IssuancePolicy nodes", + "guid": "b2280665-c91b-448c-8c0f-97d1f38b6f59", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p=shortestPath((s:User)-[: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*1..]->(t:Group))\nWHERE s.hasspn=true\nAND s.enabled = true\nAND NOT s.objectid ENDS WITH '-502'\nAND NOT COALESCE(s.gmsa, false) = true\nAND NOT COALESCE(s.msa, false) = true\nAND t.objectid ENDS WITH '-512'\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (s:Base)-[:GenericAll|GenericWrite|Owns|WriteOwner|WriteDacl]->(:IssuancePolicy)\nWHERE NOT s.objectid ENDS WITH '-512' AND NOT s.objectid ENDS WITH '-519'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "All service principals with Microsoft Graph privilege to grant arbitrary App Roles", - "guid": "e6d6b5da-89da-4514-a409-2d6e368397da", + "name": "Shortest paths to Azure Subscriptions", + "guid": "4785b305-c101-461c-80fc-3fb3ff67a8ce", "prebuilt": true, "platforms": [ "Azure" ], - "category": "Microsoft Graph", + "category": "Shortest Paths", "description": null, - "query": "MATCH p=(:AZServicePrincipal)-[:AZMGGrantAppRoles]->(:AZTenant)\nRETURN p\nLIMIT 1000", + "query": "MATCH p=shortestPath((s:AZBase)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZSubscription))\nWHERE s<>t\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Domains with more than 50 Tier Zero accounts", - "guid": "f046e95a-5f84-4e83-bcda-6e83f3d8e21a", + "name": "Computer owners who can obtain LAPS passwords", + "guid": "92aa81d6-b08e-4abb-ae39-ecbe5735a74c", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (d:Domain)-[:Contains*1..]->(n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nWITH d, COUNT(n) AS adminCount\nWHERE adminCount > 50\nRETURN d", + "category": "Dangerous Privileges", + "description": "Creators of computer objects get abusable rights on the computer object. If the owner is not explicitly granted ReadLAPSPassword they can still compromise the computer with the abusable owner rights.", + "query": "MATCH p = (c:Computer)<-[:GenericAll|Owns|WriteDacl|WriteOwner|AllExtendedRights]-(n:User)\nWHERE c.haslaps = true AND c.ownersid = n.objectid\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -1952,57 +2009,57 @@ ] }, { - "name": "Computers where Domain Users are local administrators", - "guid": "d43a7bdc-33c6-4a39-a3bb-24115749e595", + "name": "Shortest paths from Azure Applications to Tier Zero / High Value targets", + "guid": "60ff7c58-a98e-4bc1-9e32-8378d2db0c43", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Dangerous Privileges", + "category": "Shortest Paths", "description": null, - "query": "MATCH p=(s:Group)-[:AdminTo]->(:Computer)\nWHERE s.objectid ENDS WITH '-513'\nRETURN p\nLIMIT 1000", + "query": "MATCH p=shortestPath((s:AZApp)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZBase))\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0') AND s<>t\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Nested groups within Tier Zero / High Value", - "guid": "8e541e75-df1d-423f-b429-4bbf0403a338", + "name": "Map OU structure", + "guid": "8f14084b-5065-43d8-865a-a6ac52da25d1", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Domain Information", "description": null, - "query": "MATCH p=(t:Group)<-[:MemberOf*..]-(s:Group)\nWHERE ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT s.objectid ENDS WITH '-512' // Domain Admins\nAND NOT s.objectid ENDS WITH '-519' // Enterprise Admins\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Domain)-[:Contains*1..]->(:OU)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Devices with unsupported operating systems", - "guid": "e3f2b53a-7ce6-4e52-9c74-68b69338288b", + "name": "Domain Admins logons to non-Domain Controllers", + "guid": "e2f3fd0a-1df2-4089-b0a4-272ad6e369a9", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], - "category": "Azure Hygiene", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH (n:AZDevice)\nWHERE n.operatingsystem CONTAINS 'WINDOWS'\nAND n.operatingsystemversion =~ '(10.0.19044|10.0.22000|10.0.19043|10.0.19042|10.0.19041|10.0.18363|10.0.18362|10.0.17763|10.0.17134|10.0.16299|10.0.15063|10.0.14393|10.0.10586|10.0.10240|6.3.9600|6.2.9200|6.1.7601|6.0.6200|5.1.2600|6.0.6003|5.2.3790|5.0.2195).?.*'\nRETURN n\nLIMIT 100", + "query": "MATCH (s)-[:MemberOf*0..]->(g:Group)\nWHERE g.objectid ENDS WITH '-516'\nWITH COLLECT(s) AS exclude\nMATCH p = (c:Computer)-[:HasSession]->(:User)-[:MemberOf*1..]->(g:Group)\nWHERE g.objectid ENDS WITH '-512' AND NOT c IN exclude\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Domains affected by Exchange privilege escalation risk", - "guid": "f2d09c94-b6f2-4901-9a2d-f8bacd61edc7", + "name": "Unresolved SID with outbound control", + "guid": "4e8429f9-cba2-41e9-bac6-0c42f96b2c57", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=(n:Group)-[r:WriteDacl|ForceChangePassword|AddMember]->(m:Base)\nWHERE n.name STARTS WITH \"EXCHANGE \"\nAND ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "query": "MATCH p=(n:Base)-[r]->(:Base)\nWHERE r.isacl\nAND n.name CONTAINS \"S-1-5-21-\" // Unresolved SID\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [ @@ -2010,33 +2067,15 @@ ] }, { - "name": "Foreign Service Principals With Group Memberships", - "guid": "327ef6a5-bfa8-4c92-b35a-d3df85264a24", - "prebuilt": false, - "platforms": [ - "Azure" - ], - "category": "Azure Hygiene", - "description": "Review each to validate whether their presence is expected and whether the assigned group memberships are appropriate for the foreign service principal.", - "query": "MATCH p = (sp:AZServicePrincipal)-[:AZMemberOf]->(g:AZGroup)\nWHERE toUpper(sp.appownerorganizationid) <> toUpper(g.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", - "revision": 1, - "resources": [ - "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" - ], - "acknowledgements": [ - "Stephen Hinck" - ] - }, - { - "name": "All Schema Admins", - "guid": "76d8e61d-7a86-40ff-8a85-fd37f1e2563f", + "name": "Non-Tier Zero accounts with SID History of Tier Zero accounts", + "guid": "59744dfe-9411-4daf-b342-1203dc62acd4", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH p=(n:Base)-[:MemberOf*1..]->(m:Group)\nWHERE (n:User OR n:Computer)\nAND m.objectid ENDS WITH \"-518\" // Schema Admins\nRETURN p", + "query": "MATCH p=(n:Base)-[:HasSIDHistory]->(m:Base)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -2044,63 +2083,64 @@ ] }, { - "name": "Collection health of specific computer", - "guid": "bb95c9c5-984c-4057-a430-000d684c069a", + "name": "Enrollment rights on published ESC15 certificate templates", + "guid": "78d59fe1-e1a0-4813-adc9-c3c96ac08b66", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": "Returns Local groups and their members, and Principals with privileges", - "query": "MATCH p=(m:Base)-[:RemoteInteractiveLogonRight|AdminTo|CanRDP|LocalToComputer|MemberOfLocalGroup]-(n:Base)\n\n// Insert computer FQDN\nWHERE m.name ENDS WITH \"HOSTNAME.DOMAIN.LOCAL\"\n\nRETURN p", + "category": "Active Directory Certificate Services", + "description": "Enrollment rights on certificate templates that meet the requirements for the ADCS ESC15 (EKUwu) attack.", + "query": "MATCH p=(:Base)-[:Enroll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)-[:TrustedForNTAuth]->(:NTAuthStore)-[:NTAuthStoreFor]->(:Domain)\nWHERE ct.enrolleesuppliessubject = True\nAND ct.authenticationenabled = False\nAND ct.requiresmanagerapproval = False\nAND ct.schemaversion = 1\nRETURN p", "revision": 1, - "resources": [], + "resources": [ + "https://x.com/SpecterOps/status/1844800558151901639", + "https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2024-49019" + ], "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" + "Jonas B\u00fclow Knudsen, @Jonas_B_K" ] }, { - "name": "All paths crossing a specific trust", - "guid": "251fc893-7a6b-4a0a-8650-9d5408d38c3c", - "prebuilt": false, + "name": "Computers not requiring inbound SMB signing", + "guid": "6b1fcfb6-b010-41a2-9d31-f9872fe994ff", + "prebuilt": true, "platforms": [ "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\n// Replace the TRUSTING domain SID\nMATCH 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)\nWHERE Trusted.domainsid = 'S-1-5-21-1111111111-1111111111-1111111111'\nAND Trusting.domainsid = 'S-1-5-21-2222222222-2222222222-2222222222'\nRETURN p\nLIMIT 1000", + "category": "NTLM Relay Attacks", + "description": null, + "query": "MATCH (n:Computer)\nWHERE n.smbsigning = False\nRETURN n", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Non-Tier Zero account with excessive control", - "guid": "944cecfe-519b-4318-b226-e8520161b454", + "name": "Tier Zero accounts that can be delegated", + "guid": "4316eaf1-6af0-4879-8f55-ac2633a711c3", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": "Returns non-Tier Zero principals with >= 1000 direct rights to other principals. This does not include rights from group memberships.", - "query": "MATCH (n:Base)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|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]->(m:Base)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nWITH n, COLLECT(DISTINCT(m)) AS endNodes\nWHERE SIZE(endNodes) >= 1000\nRETURN n", - "revision": 2, + "category": "Kerberos Interaction", + "description": null, + "query": "MATCH (m:Base)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nAND m.enabled = true\nAND m.sensitive = false\nOPTIONAL MATCH (g:Group)<-[:MemberOf*1..]-(n:Base)\nWHERE g.objectid ENDS WITH '-525'\nWITH m, COLLECT(n) AS matchingNs\nWHERE NONE(n IN matchingNs WHERE n.objectid = m.objectid)\nRETURN m", + "revision": 1, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Tier Zero accounts that can be delegated", - "guid": "4316eaf1-6af0-4879-8f55-ac2633a711c3", + "name": "Accounts with clear-text password attributes", + "guid": "e303498f-e3d4-489d-8a34-b68e187bc4e7", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Kerberos Interaction", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (m:Base)\nWHERE ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nAND m.enabled = true\nAND m.sensitive = false\nOPTIONAL MATCH (g:Group)<-[:MemberOf*1..]-(n:Base)\nWHERE g.objectid ENDS WITH '-525'\nWITH m, COLLECT(n) AS matchingNs\nWHERE NONE(n IN matchingNs WHERE n.objectid = m.objectid)\nRETURN m", + "query": "MATCH (n:Base)\nWHERE n.userpassword IS NOT NULL\nOR n.unixpassword IS NOT NULL\nOR n.unicodepwd IS NOT NULL\nOR n.msSFU30Password IS NOT NULL\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -2108,15 +2148,15 @@ ] }, { - "name": "Non-Tier Zero account with unconstrained delegation", - "guid": "e7e9a927-3f34-42c7-b921-d8bcf626011e", + "name": "Large default groups with outbound control of OUs", + "guid": "310b3626-f8e6-4ab0-832c-72df6048597f", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Dangerous Privileges", "description": null, - "query": "MATCH (n:Base)\nWHERE n.unconstraineddelegation = true\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", + "query": "MATCH p=(n:Group)-[]->(:OU)\nWHERE n.objectid ENDS WITH \"-513\" // DOMAIN USERS\nOR n.objectid ENDS WITH \"-515\" // DOMAIN COMPUTERS\nOR n.objectid ENDS WITH \"-S-1-5-11\" // AUTHENTICATED USERS\nOR n.objectid ENDS WITH \"-S-1-1-0\" // EVERYONE\nOR n.objectid ENDS WITH \"S-1-5-32-545\" // USERS\nOR n.objectid ENDS WITH \"S-1-5-32-546\" // GUESTS\nOR n.objectid ENDS WITH \"S-1-5-7\" // ANONYMOUS\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -2124,237 +2164,193 @@ ] }, { - "name": "Computers with the WebClient running", - "guid": "51107ad1-f0bc-43d3-a561-5cee471ca196", + "name": "Tier Zero / High Value external Entra ID users", + "guid": "20e07417-d286-4dca-a962-568f2b262f65", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "NTLM Relay Attacks", + "category": "Azure Hygiene", "description": null, - "query": "MATCH (c:Computer)\nWHERE c.webclientrunning = True\nRETURN c LIMIT 1000", + "query": "MATCH (n:AZUser)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.name CONTAINS '#EXT#@'\nRETURN n\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Computers without Windows LAPS", - "guid": "7c50f724-c467-4005-8e3f-9a6ce1461db0", + "name": "Foreign Service Principals With Group Memberships", + "guid": "327ef6a5-bfa8-4c92-b35a-d3df85264a24", "prebuilt": false, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*WINDOWS (SERVER)? ?(10|11|2019|2022|2025).*'\nAND c.haslaps = false\nAND c.enabled = true\nRETURN c\nLIMIT 100", + "category": "Azure Hygiene", + "description": "Review each to validate whether their presence is expected and whether the assigned group memberships are appropriate for the foreign service principal.", + "query": "MATCH p = (sp:AZServicePrincipal)-[:AZMemberOf]->(g:AZGroup)\nWHERE toUpper(sp.appownerorganizationid) <> toUpper(g.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/windows-server/identity/laps/laps-overview" + "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" ], "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" + "Stephen Hinck" ] }, { - "name": "Map domain trusts", - "guid": "268d3d26-5bc2-4820-a6ed-09d20f3d5413", - "prebuilt": true, + "name": "Domains with List Object mode enabled", + "guid": "05e2a94b-5ee6-47ec-b715-3982f30af01b", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Domain Information", - "description": null, - "query": "MATCH p = (:Domain)-[:SameForestTrust|CrossForestTrust]->(:Domain)\nRETURN p\nLIMIT 1000", - "revision": 1, - "resources": [], - "acknowledgements": [] - }, - { - "name": "Overprivileged Microsoft Entra Connect accounts", - "guid": "9e6e75b4-9ecc-45d4-a39b-b6427b813f0a", - "prebuilt": false, - "platforms": [ - "Active Directory", - "Azure" - ], - "category": "Active Directory Hygiene", - "description": "Legacy MSOL accounts were by default deployed with Domain Admins or Enterprise Admins membership.", - "query": "MATCH p=(n:User)-[:MemberOf*1..]->(g:Group)\nWHERE n.name STARTS WITH \"MSOL_\"\nAND (g.objectid ENDS WITH \"-512\" // Domain Admins\nOR g.objectid ENDS WITH \"-519\") // Entterprise Admins\nRETURN p", + "description": "Checks the fDoListObject flag of dSHeuristics.", + "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{2}[^0].*\"\nRETURN n", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/reference-connect-accounts-permissions" + "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domains allowing unauthenticated NSPI RPC binds", - "guid": "a950fdab-5934-4c69-a88b-e2e0e3da9d52", + "name": "Foreign Service Principals With an EntraID Admin Role", + "guid": "b6235820-4e0d-4dfa-af5b-729b5644feb5", "prebuilt": false, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", - "description": "Checks the fAllowAnonNSPI flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{7}[^0].*\"\nRETURN n", + "category": "Dangerous Privileges", + "description": "Entra ID admin roles grant significant control over a tenant environment, even if the role is not a default Tier Zero / High Value role", + "query": "MATCH p = (sp:AZServicePrincipal)-[:AZHasRole]->(r:AZRole)\nWHERE toUpper(sp.appownerorganizationid) <> toUpper(sp.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" + "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" ], "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" + "Stephen Hinck" ] }, { - "name": "ESC8-vulnerable Enterprise CAs", - "guid": "60881923-296c-4702-adf7-a4f059dc9bb8", - "prebuilt": true, + "name": "Domains allowing unauthenticated domain enumeration", + "guid": "41a08d76-f8a5-4296-ad19-464c4c5c69fe", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:EnterpriseCA)\nWHERE n.hasvulnerableendpoint=true\nRETURN n", + "query": "MATCH p=(n:Group)-[:MemberOf]->(m:Group)\nWHERE (n.objectid ENDS WITH \"S-1-5-7\" // Anonymous\nOR n.objectid ENDS WITH \"S-1-1-0\") // Everyone\nAND m.objectid ENDS WITH \"S-1-5-32-554\" // Pre-Windows 2000 Compatible Access\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] - }, - { - "name": "Circular AZ group memberships", - "guid": "b005669c-d8af-47ae-a0f1-4f36cd5334ab", - "prebuilt": false, - "platforms": [ - "Azure" - ], - "category": "Azure Hygiene", - "description": "Detects circular group membership chains where groups are members of themselves through one or more intermediate groups. This causes an administrative complexity.", - "query": "MATCH p=(x:AZGroup)-[:AZMemberOf*2..]->(y:AZGroup)\nWHERE x.objectid=y.objectid\nRETURN p\nLIMIT 100", - "revision": 1, - "resources": [ - "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" - ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Enabled computers inactive for 180 days", - "guid": "0768e810-1e1e-4319-a216-76d9c2058644", + "name": "Non-Tier Zero principals with control of AdminSDHolder", + "guid": "4c1e0137-5b7f-48d8-bd09-9db7674bca61", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", + "category": "Dangerous Privileges", "description": null, - "query": "WITH 180 as inactive_days\nMATCH (n:Computer)\nWHERE n.enabled = true\nAND n.lastlogontimestamp < (datetime().epochseconds - (inactive_days * 86400)) // Replicated value\nAND n.lastlogon < (datetime().epochseconds - (inactive_days * 86400)) // Non-replicated value\nAND n.whencreated < (datetime().epochseconds - (inactive_days * 86400)) // Exclude recently created principals\nAND NOT n.name STARTS WITH 'AZUREADKERBEROS.' // Removes false positive, Azure KRBTGT\nAND NOT n.name STARTS WITH 'AZUREADSSOACC.' // Removes false positive, Entra Seamless SSO\nRETURN n\nLIMIT 1000", + "query": "MATCH p=(n:Group)-[r:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|CoerceToTGT|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteOwnerLimitedRights|OwnsLimitedRights]->(m:Container)\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND m.name STARTS WITH \"ADMINSDHOLDER@\"\nRETURN p", "revision": 1, - "resources": [], + "resources": [ + "https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory#adminsdholder" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Enrollment rights on published enrollment agent certificate templates", - "guid": "8483bf5b-89f1-4723-abb2-c48295f6393e", - "prebuilt": true, + "name": "Large default groups with outbound control", + "guid": "a334f21a-3d7f-448e-b7ea-1465a3127bce", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Certificate Services", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE '1.3.6.1.4.1.311.20.2.1' IN ct.effectiveekus\nOR '2.5.29.37.0' IN ct.effectiveekus\nOR SIZE(ct.effectiveekus) = 0\nRETURN p\nLIMIT 1000", + "query": "MATCH p=(n:Group)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|GoldenCert|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC5|ADCSESC6a|ADCSESC6b|ADCSESC7|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)\nWHERE n.objectid ENDS WITH \"-513\" // DOMAIN USERS\nOR n.objectid ENDS WITH \"-515\" // DOMAIN COMPUTERS\nOR n.objectid ENDS WITH \"-S-1-5-11\" // AUTHENTICATED USERS\nOR n.objectid ENDS WITH \"-S-1-1-0\" // EVERYONE\nOR n.objectid ENDS WITH \"S-1-5-32-545\" // USERS\nOR n.objectid ENDS WITH \"S-1-5-32-546\" // GUESTS\nOR n.objectid ENDS WITH \"S-1-5-7\" // ANONYMOUS\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] - }, - { - "name": "AdminSDHolder protected Accounts and Groups", - "guid": "5ee2f40e-a55c-4140-ab8a-91746ba3752b", - "prebuilt": false, - "platforms": [ - "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)\nWHERE (\n 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\n 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\n OR n.objectid =~ \".*-(500|502|516|521)$\" // Direct objects\n)\nRETURN n", - "revision": 1, - "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" - ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "All DNSAdmins", - "guid": "183fb320-f3ae-4ab3-a090-3f9a7db692e1", + "name": "Collection health of CA Registry Data", + "guid": "c8dd3479-8063-450a-9456-557bc5f39e10", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Domain Information", - "description": null, - "query": "MATCH p=(n:Base)-[:MemberOf]->(g:Group) \nWHERE n.name STARTS WITH \"DNSADMINS@\"\nRETURN p", + "description": "BloodHound's ADCS analysis requires collecting CA registry data to increase accuracy/enable more edges. Collection by default requires SharpHound has Administrators membership. Requires SharpHound v2.3.5 or above. It only requires one misconfigured CA to potentially a full forest compromise by any principal. CAs returned by this query have not been collected.", + "query": "MATCH p=(eca:EnterpriseCA)<-[:HostsCAService]-(c:Computer)\nWHERE (\n eca.isuserspecifiessanenabledcollected = false\n OR eca.casecuritycollected = false\n OR eca.enrollmentagentrestrictionscollected = false\n OR eca.roleseparationenabledcollected = false\n)\n// Exclude inactive CAs\nAND c.enabled = true\nAND c.lastlogontimestamp > (datetime().epochseconds - (30 * 86400))\nRETURN p", "revision": 1, - "resources": [], + "resources": [ + "https://bloodhound.specterops.io/collect-data/enterprise-collection/permissions#ca-registry" + ], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Map OU structure", - "guid": "8f14084b-5065-43d8-865a-a6ac52da25d1", + "name": "Enrollment rights on published ESC2 certificate templates", + "guid": "ebc77984-1ceb-4ed2-a395-ce1067847941", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Domain Information", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p = (:Domain)-[:Contains*1..]->(:OU)\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(c:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nWHERE c.requiresmanagerapproval = false\nAND (c.effectiveekus = [''] OR '2.5.29.37.0' IN c.effectiveekus)\nAND (c.authorizedsignatures = 0 OR c.schemaversion = 1)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Principals with foreign domain group membership", - "guid": "8fb3214a-5a75-4ecd-b293-c121abd94b4b", + "name": "Users which do not require password to authenticate", + "guid": "23bdc2ad-6739-4b2b-85d3-258e3f424eb2", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p=(s:Base)-[:MemberOf]->(t:Group)\nWHERE s.domainsid<>t.domainsid\nRETURN p\nLIMIT 1000", + "query": "MATCH (u:User)\nWHERE u.passwordnotreqd = true\nRETURN u\nLIMIT 100", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Paths from Domain Users to Tier Zero / High Value targets", - "guid": "977bec40-565c-40b8-90c8-e3e122c291cd", + "name": "Computers with membership in Protected Users", + "guid": "a26372f4-2e92-49f6-8993-6657fbc1569a", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "NTLM Relay Attacks", "description": null, - "query": "MATCH p=shortestPath((s:Group)-[: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*1..]->(t:Base))\nWHERE s.objectid ENDS WITH '-513' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Base)-[:MemberOf*1..]->(g:Group)\nWHERE g.objectid ENDS WITH \"-525\"\nRETURN p LIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Enabled built-in guest user accounts", - "guid": "bb0f620d-6a55-4413-ac74-4c82905e8598", + "name": "KRBTGT accounts with passwords not rotated in over 1 year", + "guid": "1b3ae310-ffa7-4ce5-a37f-6111aef600c8", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:User)\nWHERE n.objectid ENDS WITH \"-501\"\nAND n.enabled = true\nRETURN n", + "query": "MATCH (n:User)\nWHERE (n.objectid ENDS WITH '-502'\nOR n.name STARTS WITH 'AZUREADKERBEROS.'\nOR n.name STARTS WITH 'KRBTGT_AZUREAD@')\nAND n.pwdlastset < (datetime().epochseconds - (365 * 86400))\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [ @@ -2381,33 +2377,29 @@ ] }, { - "name": "Non-Tier Zero principals with BadSuccessor rights (no prerequisites check)", - "guid": "2b9fb71e-73ad-4061-a2df-40c7132b044d", - "prebuilt": false, + "name": "Enrollment rights on published certificate templates", + "guid": "a4ae2e54-aad3-4bfd-a12d-90cb8a9cbc86", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", - "description": "Finds non-Tier Zero principals with BadSuccessor rights with no prerequisites check (DC2025 & KDC key).", - "query": "// Find OU control\nMATCH p = (ou:OU)<-[:WriteDacl|Owns|GenericAll|WriteOwner]-(n:Base)\n// Exclude Tier Zero\nWHERE NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p LIMIT 1000", + "category": "Active Directory Certificate Services", + "description": null, + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)\nRETURN p\nLIMIT 1000", "revision": 1, - "resources": [ - "https://bsky.app/profile/specterops.io/post/3lpua65qeu22l" - ], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "resources": [], + "acknowledgements": [] }, { - "name": "Tier Zero users with email", - "guid": "9654c0d4-f1e8-4393-a2d1-53a5554a9de8", + "name": "Tier Zero computers at risk of resource-based constrained delegation", + "guid": "4dc97cf4-3c03-4fe6-8a8b-4f665c67e1e5", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "Tier Zero accounts with email access have an increased attack surface.", - "query": "MATCH (n)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.email <> \"\"\nAND n.enabled = true\nAND NOT toUpper(n.email) ENDS WITH \".ONMICROSOFT.COM\"\nAND NOT (\n (toUpper(n.email) STARTS WITH \"HEALTHMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHDISCOVERYMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHDISCOVERY\"\n OR toUpper(n.email) STARTS WITH \"MSEXCHAPPROVAL\"\n OR toUpper(n.email) STARTS WITH \"FEDERATEDEMAIL\"\n OR toUpper(n.email) STARTS WITH \"SYSTEMMAILBOX\"\n OR toUpper(n.email) STARTS WITH \"MIGRATION.\")\n AND\n (n.name STARTS WITH \"SM_\"\n OR n.name STARTS WITH \"HEALTHMAILBOX\")\n)\nRETURN n", + "category": "Dangerous Privileges", + "description": null, + "query": "MATCH p = (n:Computer)<-[:AllowedToAct]-(:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -2415,121 +2407,119 @@ ] }, { - "name": "Domain migration groups", - "guid": "f39c4953-ae92-4d67-bb50-eb1a161d4d3f", + "name": "Kerberos-enabled service accounts without AES encryption support", + "guid": "cb8cf96e-21c9-422b-9439-390a13446ca6", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": null, - "query": "MATCH (n:Group)\nWHERE n.name CONTAINS \"$$$@\"\nRETURN n", - "revision": 1, + "category": "Active Directory Hygiene", + "description": "Accounts without Kerberos AES encryption support, or passwords set before the existence of Windows Server 2008 Domain Controller which therefore lack AES encryption keys.", + "query": "MATCH (n:Base)\nWHERE n.hasspn = true\nAND ((\n n.supportedencryptiontypes <> ['Not defined']\n OR n.supportedencryptiontypes <> []\n OR NONE(type IN n.supportedencryptiontypes WHERE type CONTAINS 'AES128' OR type CONTAINS 'AES256')\n)\nOR (n.pwdlastset < 1204070400 // Password Last Set before Windows Server 2008\nAND NOT n.pwdlastset IN [-1.0, 0.0]\n))\nRETURN n\nLIMIT 100", + "revision": 2, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Shortest paths from Owned objects", - "guid": "e370a01d-c129-4f19-b88d-9479cbe00028", + "name": "Enrollment rights on CertTemplates with OIDGroupLink", + "guid": "140a68eb-d21c-4b75-971f-309225fb2d75", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p=shortestPath((s: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*1..]->(t:Base))\nWHERE (s:Tag_Owned)\nAND s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->(:CertTemplate)-[:ExtendedByPolicy]->(:IssuancePolicy)-[:OIDGroupLink]->(:Group)\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Domains with smart card accounts where smart account passwords do not expire", - "guid": "97e05e67-5961-4aba-a8e7-fe5f92334035", - "prebuilt": true, + "name": "All paths crossing a specific trust", + "guid": "251fc893-7a6b-4a0a-8650-9d5408d38c3c", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": null, - "query": "MATCH (s:Domain)-[:Contains*1..]->(t:Base)\nWHERE s.expirepasswordsonsmartcardonlyaccounts = false\nAND t.enabled = true\nAND t.smartcardrequired = true\nRETURN s", + "category": "Domain Information", + "description": "All paths crossing a specific trust from a trusted to a trusting domain.", + "query": "// Replace the TRUSTED domain SID\n// Replace the TRUSTING domain SID\nMATCH 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)\nWHERE Trusted.domainsid = 'S-1-5-21-1111111111-1111111111-1111111111'\nAND Trusting.domainsid = 'S-1-5-21-2222222222-2222222222-2222222222'\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Foreign Service Principals With an EntraID Admin Role", - "guid": "b6235820-4e0d-4dfa-af5b-729b5644feb5", - "prebuilt": false, + "name": "Foreign principals in Tier Zero / High Value targets", + "guid": "95bec736-86ef-4017-8465-9b9b66548b17", + "prebuilt": true, "platforms": [ "Azure" ], - "category": "Dangerous Privileges", - "description": "Entra ID admin roles grant significant control over a tenant environment, even if the role is not a default Tier Zero / High Value role", - "query": "MATCH p = (sp:AZServicePrincipal)-[:AZHasRole]->(r:AZRole)\nWHERE toUpper(sp.appownerorganizationid) <> toUpper(sp.tenantid)\n// Ensure AZServicePrincipal has a valid appownerorganizationid\nAND sp.appownerorganizationid CONTAINS \"-\"\nRETURN p\nLIMIT 1000", + "category": "Azure Hygiene", + "description": null, + "query": "MATCH (n:AZServicePrincipal)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND NOT toUpper(n.appownerorganizationid) = toUpper(n.tenantid)\nAND n.appownerorganizationid CONTAINS '-'\nRETURN n\nLIMIT 100", "revision": 1, - "resources": [ - "https://posts.specterops.io/microsoft-breach-how-can-i-see-this-in-bloodhound-33c92dca4c65" - ], - "acknowledgements": [ - "Stephen Hinck" - ] + "resources": [], + "acknowledgements": [] }, { - "name": "All coerce and NTLM relay edges", - "guid": "15c5ff3b-856c-44d1-a731-a8cb72512dd1", - "prebuilt": true, + "name": "Domains affected by Exchange privilege escalation risk", + "guid": "f2d09c94-b6f2-4901-9a2d-f8bacd61edc7", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "NTLM Relay Attacks", + "category": "Dangerous Privileges", "description": null, - "query": "MATCH p = (n:Base)-[:CoerceAndRelayNTLMToLDAP|CoerceAndRelayNTLMToLDAPS|CoerceAndRelayNTLMToADCS|CoerceAndRelayNTLMToSMB]->(:Base)\nRETURN p LIMIT 500", + "query": "MATCH p=(n:Group)-[r:WriteDacl|ForceChangePassword|AddMember]->(m:Base)\nWHERE n.name STARTS WITH \"EXCHANGE \"\nAND ((m:Tag_Tier_Zero) OR COALESCE(m.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", "revision": 1, - "resources": [ - "https://specterops.io/blog/2025/04/08/the-renaissance-of-ntlm-relay-attacks-everything-you-need-to-know/" - ], - "acknowledgements": [] + "resources": [], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Users which do not require password to authenticate", - "guid": "23bdc2ad-6739-4b2b-85d3-258e3f424eb2", + "name": "Principals with DES-only Kerberos authentication", + "guid": "d03ea1ef-70f0-439b-b1ef-d7f94ceb2af3", "prebuilt": true, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (u:User)\nWHERE u.passwordnotreqd = true\nRETURN u\nLIMIT 100", + "query": "MATCH (n:Base)\nWHERE n.enabled = true\nAND n.usedeskeyonly = true\nRETURN n", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Shortest paths to Tier Zero / High Value targets", - "guid": "237aac58-8641-4703-a9f7-001d69546fd8", + "name": "Domain controllers with weak certificate binding enabled", + "guid": "a2444d99-10b5-412d-8fea-4b063cfddd2c", "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Shortest Paths", + "category": "Active Directory Certificate Services", "description": null, - "query": "MATCH p=shortestPath((s)-[: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*1..]->(t:Tag_Tier_Zero))\nWHERE s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH p = (s:Computer)-[:DCFor]->(:Domain)\nWHERE s.strongcertificatebindingenforcementraw = 0 OR s.strongcertificatebindingenforcementraw = 1\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "All incoming and local paths for a specific computer", - "guid": "1f67e538-19d4-4020-89c8-5b39b31571bd", + "name": "Large default group added to computer-local group", + "guid": "dde133d2-b4d2-4de9-a656-905f3bf066f3", "prebuilt": false, "platforms": [ "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\nMATCH p=(n:Base)-[:RemoteInteractiveLogonPrivilege|AdminTo|CanRDP|LocalToComputer|MemberOfLocalGroup]-(m:Base)\nWHERE m.name CONTAINS 'HOSTNAME'\nAND m.name CONTAINS '.' // Only see computer-related objects (eg. not AD Groups)\nRETURN p", + "category": "Dangerous Privileges", + "description": null, + "query": "MATCH p=(n:Group)-[:MemberOfLocalGroup]->(m:ADLocalGroup)-[:LocalToComputer]->(:Computer)\nWHERE n.objectid =~ \".*-(S-1-5-11|S-1-1-0|S-1-5-32-545|S-1-5-7|-513|-515)$\" // Authenticated Users, Everyone, Users, Anonymous, Domain Users, Domain Computers\nAND NOT m.objectid =~ \".*-(545|574|554)$\" // Users, Certificate Service DCOM Access, Pre-Windows 2000 Compatible Access\nRETURN p", "revision": 1, "resources": [], "acknowledgements": [ @@ -2537,131 +2527,121 @@ ] }, { - "name": "Accounts with weak password storage encryption", - "guid": "8bd6fcf2-3f3c-414c-857a-4caf28e49def", - "prebuilt": true, + "name": "Domain Controllers allowing NTLMv1 or LM authentication", + "guid": "4b42513c-f89d-47ff-8d98-908af49d2b48", + "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "Accounts with passwords set before the existence of Windows Server 2008 Domain Controller which therefore lack AES encryption keys.", - "query": "MATCH (n:Base)\nWHERE n.pwdlastset < 1204070400 // Password Last Set before Windows Server 2008 release\nRETURN n\nLIMIT 100", - "revision": 2, - "resources": [ - "https://techcommunity.microsoft.com/blog/coreinfrastructureandsecurityblog/decrypting-the-selection-of-supported-kerberos-encryption-types/1628797" - ], + "category": "NTLM Relay Attacks", + "description": null, + "query": "MATCH (dc:Computer)\nWHERE dc.isdc = true\nAND (dc.lmcompatibilitylevel IS NOT NULL AND NOT dc.lmcompatibilitylevel = 5)\nRETURN dc", + "revision": 1, + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Sessions across trusts", - "guid": "aea7ac64-1f51-407b-b0ee-19fd30075794", - "prebuilt": false, + "name": "Paths from Domain Users to Tier Zero / High Value targets", + "guid": "977bec40-565c-40b8-90c8-e3e122c291cd", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Domain Information", - "description": "Users logging on across a trust, the users originate from trusted domains.", - "query": "MATCH p=(trustedDomainPrincipal:Computer)-[r:HasSession]->(trustingDomainPrincipal:User)\nWHERE trustedDomainPrincipal.domainsid <> trustingDomainPrincipal.domainsid\nRETURN p\nLIMIT 1000", + "category": "Dangerous Privileges", + "description": null, + "query": "MATCH p=shortestPath((s:Group)-[: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*1..]->(t:Base))\nWHERE s.objectid ENDS WITH '-513' AND s<>t\nAND ((t:Tag_Tier_Zero) OR COALESCE(t.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Domains not mitigating CVE-2021-42291", - "guid": "02202726-d86d-46c2-891c-9770c635f76f", + "name": "Tier Zero computers with unsupported operating systems", + "guid": "a87b558c-5746-4a90-9f83-c86e7b924a52", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", - "description": "Checks the AttributeAuthorizationOnLDAPAdd flag of dSHeuristics.", - "query": "MATCH (n:Domain)\nWHERE n.dsheuristics =~ \".{27}[^1].*\"\nRETURN n", + "description": null, + "query": "MATCH (c:Computer)\nWHERE c.operatingsystem =~ '(?i).*Windows.* (2000|2003|2008|2012|xp|vista|7|8|me|nt).*'\nAND ((c:Tag_Tier_Zero) OR COALESCE(c.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN c\nLIMIT 100", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e5899be4-862e-496f-9a38-33950617d2c5" - ], + "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "Domains affected by AdPrep privilege escalation risk", - "guid": "815ff190-f6f3-4757-a516-2f4bf589b705", - "prebuilt": false, + "name": "Shortest paths from Owned objects", + "guid": "e370a01d-c129-4f19-b88d-9479cbe00028", + "prebuilt": true, "platforms": [ "Active Directory" ], - "category": "Dangerous Privileges", + "category": "Shortest Paths", "description": null, - "query": "MATCH p=(n:Group)-[r:GenericAll]->(m:Domain)\nWHERE n.objectid ENDS WITH \"-527\" // Enterprise Key Admins\nAND NOT ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN p", + "query": "MATCH p=shortestPath((s: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*1..]->(t:Base))\nWHERE (s:Tag_Owned)\nAND s<>t\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], - "acknowledgements": [ - "Martin Sohn Christensen, @martinsohndk" - ] + "acknowledgements": [] }, { - "name": "Tier Zero computers with passwords older than the default maximum password age", - "guid": "b6d6d0bf-130e-4719-996b-adc29bba36e9", + "name": "Smart card accounts with passwords not rotated in over 1 year", + "guid": "7e56f2e7-79c3-4f0d-aa3e-14cf3de7ab73", "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:Computer)\nWHERE n.enabled = true\nAND n.whencreated < (datetime().epochseconds - (60 * 3 * 86400))\nAND n.pwdlastset < (datetime().epochseconds - (60 * 3 * 86400))\nAND ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nRETURN n", - "revision": 2, + "query": "MATCH (n:Base)\nWHERE n.pwdlastset < (datetime().epochseconds - (365 * 86400))\nAND n.enabled = true\nAND n.smartcardrequired = true\nRETURN n", + "revision": 1, "resources": [], "acknowledgements": [ "Martin Sohn Christensen, @martinsohndk" ] }, { - "name": "On-Prem Users synced to Entra Users with Entra Group Membership", - "guid": "edb575df-2048-4ef0-a0e4-168544a496e9", - "prebuilt": true, + "name": "Tier Zero accounts not members of Denied RODC Password Replication Group", + "guid": "e9613406-e346-410b-a033-690a6cf0c708", + "prebuilt": false, "platforms": [ - "Active Directory", - "Azure" + "Active Directory" ], - "category": "Cross Platform Attack Paths", + "category": "Active Directory Hygiene", "description": null, - "query": "MATCH p = (:User)-[:SyncedToEntraUser]->(:AZUser)-[:AZMemberOf]->(:AZGroup)\nRETURN p\nLIMIT 1000", + "query": "MATCH (n:Base)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND (n:User or n:Computer)\nWITH n\nOPTIONAL MATCH (n)-[:MemberOf*1..]->(m:Group)\nWHERE m.objectid ENDS WITH '-519'\nWITH n, m\nWHERE m IS NULL\nRETURN n", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] }, { - "name": "Domains where any user can join a computer to the domain", - "guid": "421921fa-bc0f-4659-9680-b7481adcb132", + "name": "Disabled Tier Zero / High Value principals", + "guid": "860d5c2d-84fe-4c85-80de-e0a9badbd0e7", "prebuilt": true, "platforms": [ - "Active Directory" + "Azure" ], - "category": "Active Directory Hygiene", + "category": "Azure Hygiene", "description": null, - "query": "MATCH (n:Domain)\nWHERE n.machineaccountquota > 0\nRETURN n", + "query": "MATCH (n:AZBase)\nWHERE ((n:Tag_Tier_Zero) OR COALESCE(n.system_tags, '') CONTAINS 'admin_tier_0')\nAND n.enabled = false\nRETURN n\nLIMIT 100", "revision": 1, - "resources": [ - "https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/default-workstation-numbers-join-domain", - "https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/add-workstations-to-domain" - ], + "resources": [], "acknowledgements": [] }, { - "name": "Usage of built-in domain Administrator account", - "guid": "35b1206f-871b-44aa-a601-c5258060dfcf", + "name": "ACEs across trusts", + "guid": "c902d3b4-1a75-4335-acd7-28246dab746d", "prebuilt": false, "platforms": [ "Active Directory" ], - "category": "Active Directory Hygiene", - "description": "Usage of Active Directory's built-in Administrator account is a sign that the account is not only used for break-glass purposes.", - "query": "MATCH (n:User)\nWHERE n.objectid ENDS WITH \"-500\"\nAND (\n n.lastlogontimestamp > (datetime().epochseconds - (60 * 86400)) OR\n n.lastlogon > (datetime().epochseconds - (60 * 86400))\n)\nAND NOT n.whencreated > (datetime().epochseconds - (60 * 86400))\nRETURN n", + "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)\nWHERE trustedDomainPrincipal.domainsid <> trustingDomainPrincipal.domainsid\nAND r.isacl\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [ @@ -2669,31 +2649,51 @@ ] }, { - "name": "Shortest paths to privileged roles", - "guid": "3dc73dd8-4873-4aeb-a88f-56a58c77f512", + "name": "Shortest paths to systems trusted for unconstrained delegation", + "guid": "16a9e47b-45f8-4514-b409-771bb5186142", "prebuilt": true, "platforms": [ - "Azure" + "Active Directory" ], "category": "Shortest Paths", "description": null, - "query": "MATCH p=shortestPath((s:AZBase)-[:AZAvereContributor|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZHasRole|AZMemberOf|AZOwner|AZRunsAs|AZVMContributor|AZAutomationContributor|AZKeyVaultContributor|AZVMAdminLogin|AZAddMembers|AZAddSecret|AZExecuteCommand|AZGlobalAdmin|AZPrivilegedAuthAdmin|AZGrant|AZGrantSelf|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZOwns|AZCloudAppAdmin|AZAppAdmin|AZAddOwner|AZManagedIdentity|AZAKSContributor|AZNodeResourceGroup|AZWebsiteContributor|AZLogicAppContributor|AZMGAddMember|AZMGAddOwner|AZMGAddSecret|AZMGGrantAppRoles|AZMGGrantRole|SyncedToADUser|AZRoleEligible|AZContains*1..]->(t:AZRole))\nWHERE t.name =~ '(?i)Global Administrator|User Administrator|Cloud Application Administrator|Authentication Policy Administrator|Exchange Administrator|Helpdesk Administrator|Privileged Authentication Administrator' AND s<>t\nRETURN p\nLIMIT 1000", + "query": "MATCH p=shortestPath((s)-[: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*1..]->(t:Computer))\nWHERE t.unconstraineddelegation = true AND s<>t\nRETURN p\nLIMIT 1000", "revision": 1, "resources": [], "acknowledgements": [] }, { - "name": "Principals with DES-only Kerberos authentication", - "guid": "d03ea1ef-70f0-439b-b1ef-d7f94ceb2af3", - "prebuilt": true, + "name": "Kerberos-enabled service account member of built-in Admins groups", + "guid": "42a856fc-257a-4142-9592-ca95fd49e579", + "prebuilt": false, "platforms": [ "Active Directory" ], "category": "Active Directory Hygiene", "description": null, - "query": "MATCH (n:Base)\nWHERE n.enabled = true\nAND n.usedeskeyonly = true\nRETURN n", + "query": "MATCH p=(n:Base)-[:MemberOf*1..]->(g:Group)\nWHERE (\n g.objectid ENDS WITH '-512' // Domain Admins\n OR g.objectid ENDS WITH '-519' // Enterprise Admins\n OR g.objectid ENDS WITH '-518' // Schema Admins\n)\nAND n.hasspn = true\nRETURN p", "revision": 1, "resources": [], - "acknowledgements": [] + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] + }, + { + "name": "Circular AZ group memberships", + "guid": "b005669c-d8af-47ae-a0f1-4f36cd5334ab", + "prebuilt": false, + "platforms": [ + "Azure" + ], + "category": "Azure Hygiene", + "description": "Detects circular group membership chains where groups are members of themselves through one or more intermediate groups. This causes an administrative complexity.", + "query": "MATCH p=(x:AZGroup)-[:AZMemberOf*2..]->(y:AZGroup)\nWHERE x.objectid=y.objectid\nRETURN p\nLIMIT 100", + "revision": 1, + "resources": [ + "https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references" + ], + "acknowledgements": [ + "Martin Sohn Christensen, @martinsohndk" + ] } ] \ No newline at end of file