## BloodHound Cypher Cheatsheet 1. [Find edges](#find-edges) - [Find all edges for specific user](#find-all-edges-for-specific-user) - [Find all edges for specific Group](#find-all-edges-for-specific-group) - [Find all user edges for specific Group](#find-all-user-edges-for-specific-group) - [Find all user edges for specific User](#find-all-user-edges-for-specific-user) - [Find all computer edges for specific Group](#find-all-computer-edges-for-specific-group) - [Shortest paths to Domain](#shortest-paths-to-domain) - [Shortest paths to Domain Admins group from all domain groups](#shortest-paths-to-domain-admins-group-from-all-domain-groups) - [Shortest paths to Domain Admins group from computers](#shortest-paths-to-domain-admins-group-from-computers) - [List all High Valued Targets](#list-all-high-valued-targets) - [Shortest Paths from Kerberoastable Users to High Value Targets](#shortest-paths-from-kerberoastable-users-to-high-value-targets) 2. [Users](#users) - [Find users created in the last 30 days](#find-users-created-in-the-last-30-days) - [Find users credentials in description fields](#find-users-credentials-in-description-fields) - [Users never logged on and account still active](#users-never-logged-on-and-account-still-active) - [Users logged in the last 90 days](#users-logged-in-the-last-90-days) - [Users with passwords last set in the last 90 days](#users-with-passwords-last-set-in-the-last-90-days) - [Find users that belong to high value groups](#find-users-that-belong-to-high-value-groups) - [Find users that can RDP into something](#find-users-that-can-rdp-into-something) - [Users with most local admin rights](#users-with-most-local-admin-rights) - [Find if unprivileged users have rights to add members into groups](#find-if-unprivileged-users-have-rights-to-add-members-into-groups) - [Search for key words in users title](#search-for-key-words-in-users-title) - [Find users that have never logged on and account is still active](#find-users-that-have-never-logged-on-and-account-is-still-active) - [Find users with blank passwords that are enabled](#find-users-with-blank-passwords-that-are-enabled) - [Find if unprivileged users have rights to add members into groups](#find-if-unprivileged-users-have-rights-to-add-members-into-groups) - [All Users with a homedirectory](#all-users-with-a-homedirectory) - [Find constrained delegation](#find-constrained-delegation) 3. [Groups](#groups) - [Find all other Rights Domain Users shouldn't have](#find-all-other-rights-domain-users-shouldnt-have) - [Find what groups can RDP](#find-what-groups-can-rdp) - [Groups that contain the word 'admin'](#groups-that-contain-the-word-admin) - [Groups of High Value Targets](#groups-of-high-value-targets) - [Non Admin Groups with High Value Privileges](#non-admin-groups-with-high-value-privileges) - [Groups that can reset passwords (Warning: Heavy)](#groups-that-can-reset-passwords-warning-heavy) - [Groups that have local admin rights (Warning: Heavy)](#groups-that-have-local-admin-rights-warning-heavy) - [Find groups that can reset passwords (Warning: Heavy)](#find-groups-that-can-reset-passwords-warning-heavy) - [Find groups that have local admin rights (Warning: Heavy)](#find-groups-that-have-local-admin-rights-warning-heavy) - [Show all high value target groups](#show-all-high-value-target-groups) 4. [Kerberos](#kerberos) - [Find All Users with an SPN](#find-all-users-with-an-spn-find-all-kerberoastable-users) - [Find All Users with an SPN with passwords last set > 5 years ago ](#find-all-users-with-an-spn-with-passwords-last-set-more-then-5-years-ago) - [Kerberoastable Users with a path to DA ](#kerberoastable-users-with-a-path-to-da) - [Kerberoastable Admins ](#kerberoastable-admins) - [Find users that can be AS-REP roasted](#find-users-that-can-be-as-rep-roasted) - [Find Kerberoastable users who are members of high value groups](#find-kerberoastable-users-who-are-members-of-high-value-groups) 5. [Computers](#computers) - [Find Server 2000 and Enabled](#find-server-2000-and-enabled) - [Find Server 2000 with session](#find-server-2000-with-session) - [Find Server 2003 and Enabled](#find-server-2003-and-enabled) - [All computers without LAPS and the computer is enabled](#all-computers-without-laps-and-the-computer-is-enabled) - [Find computers that allow unconstrained delegation that are not domain controllers](#find-computers-that-allow-unconstrained-delegation-that-are-not-domain-controllers) - [All enabled computers with a description](#all-enabled-computers-with-a-description) - [All computers without LAPS and the computer is enabled](#all-computers-without-laps-and-the-computer-is-enabled-1) - [Computers with administrative Domain Users](#computers-with-administrative-domain-users) - [Find computers with constrained delegation permissions and the corresponding targets where they allowed to delegate](#find-computers-with-constrained-delegation-permissions-and-the-corresponding-targets-where-they-allowed-to-delegate) 6. [GPO](#gpo) - [View all GPOs](#view-all-gpos) - [Shortes path from Group to GPO](#shortes-path-from-group-to-gpo) - [Shortes path from Computer to GPO](#shortes-path-from-computer-to-gpo) - [Find Users/Groups with direct access to GPOs](#find-usersgroups-with-direct-access-to-gpos) - [Find if any domain user has interesting permissions against a GPO (Warning: Heavy)](#find-if-any-domain-user-has-interesting-permissions-against-a-gpo-warning-heavy) 7. [Session](#session) - [Find the active user sessions on all domain computers](#find-the-active-user-sessions-on-all-domain-computers) - [Find all active Domain Admin sessions](#find-all-active-domain-admin-sessions) 8. [Remove dataset from neoj4](#remove-dataset-from-neo4j) # Find edges ## Find all edges for specific user ```bash MATCH p = allShortestPaths((u:User)-[*1..3]->(a)) WHERE u.name =~ 'USER01@CORPORATE.LOCAL' AND u <> a RETURN p ``` ```bash MATCH p = allShortestPaths((u:User {name: 'USER01@CORPORATE.LOCAL'})-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..2]->(a)) WHERE u <> a RETURN p ``` ## Find all edges for specific Group ```bash MATCH p = allShortestPaths((u:Group)-[*1..3]->(a)) WHERE u.name =~ 'DOMAIN USERS@CORPORATE.LOCAL' AND u <> a RETURN p ``` ```bash MATCH p = allShortestPaths((u:User {name: 'DOMAIN USERS@CORPORATE.LOCAL'})-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..2]->(a)) WHERE u <> a RETURN p ``` ## Find all user edges for specific Group ```bash MATCH (n:User),(m:Group {name:'DOMAIN USERS@COMPANY.COM'}), p=(m)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..2]->(n) RETURN p ``` ## Find all user edges for specific User ```bash MATCH (n:User),(m:User {name:'USER@COMPANY.COM'}), p=(m)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..2]->(n) RETURN p ``` ## Find all computer edges for specific Group ```bash MATCH (n:Computer),(m:Group {name:'TEST@CORPORATE.LOCAL'}), p=(m)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..2]->(n) RETURN p ``` ## Shortest paths to Domain ```bash MATCH p = allShortestPaths((uc)-[*1..2]->(d:Domain {name: "CORPORATE.COM"})) WHERE uc:User OR uc:Computer RETURN p ``` ## Shortest paths to Domain Admins group from all domain groups ```bash MATCH (n:Group), (m:Group {name:'DOMAIN ADMINS@CORPORATE.LOCAL'}) WHERE n <> m MATCH p=shortestPath((n)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..]->(m)) RETURN p ``` ## Shortest paths to Domain Admins group from computers ```bash MATCH (n:Computer),(m:Group {name:'DOMAIN ADMINS@CORPORATE.LOCAL'}),p=shortestPath((n)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..]->(m)) RETURN p ``` ## List all High Valued Targets ```bash MATCH (m) WHERE m.highvalue=TRUE RETURN m ``` ## Shortest Paths from Kerberoastable Users to High Value Targets ```bash MATCH p = allShortestPaths((u:User)-[*1..]->(h)) WHERE u.hasspn = true AND h.highvalue = true RETURN p ``` # Users ## Find users created in the last 30 days ```bash MATCH (u:User) where u.enabled=TRUE and u.whencreated > (datetime().epochseconds - (30 * 86400)) RETURN u ``` ## Find users credentials in description fields ```bash MATCH (m:User) WHERE m.description CONTAINS 'password' RETURN m.name, m.description ``` ## Users never logged on and account still active ```bash MATCH (n:User) WHERE n.lastlogontimestamp=-1.0 AND n.enabled=TRUE RETURN n ``` ## Users logged in the last 90 days ```bash MATCH (u:User) WHERE u.lastlogon < (datetime().epochseconds - (90 * 86400)) and NOT u.lastlogon IN [-1.0, 0.0] RETURN u ``` ## Users with passwords last set in the last 90 days ```bash MATCH (u:User) WHERE u.pwdlastset < (datetime().epochseconds - (90 * 86400)) and NOT u.pwdlastset IN [-1.0, 0.0] RETURN u ``` ## Find users that belong to high value groups ```bash match (u1:User) WHERE u1.plaintext=True MATCH p=(u1:User)-[r:MemberOf*1..]->(m:Group {highvalue:true}) RETURN u1 ``` ## Find users that can RDP into something ```bash match (u1:User) WHERE u1.plaintext=True MATCH p1=(u1)-[:CanRDP*1..]->(c:Computer) RETURN u1 ``` ## Users with most local admin rights ```bash MATCH (U:User)-[r:MemberOf|AdminTo*1..]->(C:Computer) WITH U.name as n, COUNT(DISTINCT(C)) AS c RETURN n,c ORDER BY c DESC LIMIT 5 ``` ## Find if unprivileged users have rights to add members into groups ```bash MATCH (n:User {admincount:False}) MATCH p=allShortestPaths((n)-[r:AddMember*1..]->(m:Group)) RETURN p ``` ## Search for key words in users title ```bash MATCH p = (d:Domain)-[r:Contains*1..]->(u:User) WHERE u.title =~ '(?i).*scientist*' AND u.enabled = true RETURN p ``` ## Find users that have never logged on and account is still active ```bash MATCH (n:User) WHERE n.lastlogontimestamp=-1.0 AND n.enabled=TRUE RETURN n ``` ## Find users with blank passwords that are enabled ```bash MATCH (u:User) WHERE NOT u.userpassword IS null AND u.enabled = TRUE RETURN u.name,u.userpassword ``` ## Find if unprivileged users have rights to add members into groups ```bash MATCH (n:User {admincount:False}) MATCH p=allShortestPaths((n)-[r:AddMember*1..]->(m:Group)) RETURN p ``` ## All Users with a homedirectory ```bash MATCH p = (d:Domain)-[r:Contains*1..]->(u:User) WHERE u.homedirectory =~ '(?i).*.*' RETURN p ``` ## Find constrained delegation ```bash MATCH p=(u:User)-[:AllowedToDelegate]->(c:Computer) RETURN p ``` # Groups ## Find all other Rights Domain Users shouldn't have ```bash MATCH p=(m:Group)-[r:Owns|WriteDacl|GenericAll|WriteOwner|ExecuteDCOM|GenericWrite|AllowedToDelegate|ForceChangePassword]->(n:Computer) WHERE m.objectid ENDS WITH '-513' OR m.objectsid ENDS WITH '-515' OR m.objectsid ENDS WITH 'S-1-5-11' OR m.objectsid ENDS WITH 'S-1-1-0' RETURN p ``` ## Find what groups can RDP ```bash MATCH p=(m:Group)-[r:CanRDP]->(n:Computer) RETURN p ``` ## Groups that contain the word 'admin' ```bash Match (n:Group) WHERE n.name CONTAINS 'ADMIN' RETURN n ``` ## Groups of High Value Targets ```bash MATCH p=(n:User)-[r:MemberOf*1..]->(m:Group {highvalue:true}) RETURN p ``` ## Non Admin Groups with High Value Privileges ```bash MATCH p=(g:Group)-[r:Owns|:WriteDacl|:GenericAll|:WriteOwner|:ExecuteDCOM|:GenericWrite|:AllowedToDelegate|:ForceChangePassword]->(n:Computer) WHERE NOT g.name CONTAINS 'ADMIN' RETURN p ``` ## Groups that can reset passwords (Warning: Heavy) ```bash MATCH p=(m:Group)-[r:ForceChangePassword]->(n:User) RETURN p ``` ## Groups that have local admin rights (Warning: Heavy) ```bash MATCH p=(m:Group)-[r:AdminTo]->(n:Computer) RETURN p ``` ## Find groups that can reset passwords (Warning: Heavy) ```bash MATCH p=(m:Group)-[r:ForceChangePassword]->(n:User) RETURN p ``` ## Find groups that have local admin rights (Warning: Heavy) ```bash MATCH p=(m:Group)-[r:AdminTo]->(n:Computer) RETURN p ``` ## Show all high value target groups ```bash MATCH p=(n:User)-[r:MemberOf*1..]->(m:Group {highvalue:true}) RETURN p ``` # Kerberos ## Find All Users with an SPN: ```bash MATCH (n:User)WHERE n.hasspn=true RETURN n ``` ## Find All Users with an SPN with passwords last set more then 5 years ago: ```bash MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (1825 * 86400)) AND NOT u.pwdlastset IN [-1.0, 0.0] RETURN u.name, u.pwdlastset order by u.pwdlastset ``` ## Kerberoastable Users with a path to DA: ```bash MATCH (u:User {hasspn:true}) MATCH (g:Group) WHERE g.name CONTAINS 'DOMAIN ADMINS' MATCH p = shortestPath( (u)-[*1..]->(g) ) RETURN p ``` ## Kerberoastable Admins ```bash MATCH (n:Group) WHERE n.objectsid =~ $sid WITH n MATCH p=(n)<-[MemberOf*1..]-(m {hasspn: true}) RETURN p ``` ## Find users that can be AS REP roasted ```bash MATCH (u:User {dontreqpreauth: true}) RETURN u ``` ## Find Kerberoastable users who are members of high value groups ```bash MATCH (u:User)-[r:MemberOf*1..]->(g:Group) WHERE g.highvalue=true AND u.hasspn=true RETURN u ``` # Computers ## Find Server 2000 and Enabled ```bash MATCH (H:Computer) WHERE H.operatingsystem =~ '(?i).*(2000).*' AND H.enabled = TRUE RETURN H ``` ## Find Server 2000 with session ```bash MATCH (H:Computer)-[:HasSession]->(y) WHERE H.operatingsystem =~ '(?i).*(2000).*' RETURN H ``` ## Find Server 2003 and Enabled ```bash MATCH (H:Computer) WHERE H.operatingsystem =~ '(?i).*(2003).*' AND H.enabled = TRUE RETURN H ``` ## All computers without LAPS and the computer is enabled ```bash MATCH p = (d:Domain)-[r:Contains*1..]->(c:Computer) WHERE c.haslaps = false AND c.enabled = true RETURN p ``` ## Find computers that allow unconstrained delegation that are not domain controllers: ```bash MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH '-516' WITH COLLECT(c1.name) AS domainControllers MATCH (c2:Computer {unconstraineddelegation:true}) WHERE NOT c2.name IN domainControllers RETURN c2 ``` ## All enabled computers with a description ```bash MATCH p = (d:Domain)-[r:Contains*1..]->(c:Computer) WHERE c.description =~ '(?i).*.*' RETURN p ``` ## All computers without LAPS and the computer is enabled ```bash MATCH p = (d:Domain)-[r:Contains*1..]->(c:Computer) WHERE c.haslaps = false AND c.enabled = true RETURN p ``` ## Computers with administrative Domain Users ```bash MATCH p=(m:Group)-[r:AddMember|AdminTo|AllExtendedRights|AllowedToDelegate|CanRDP|Contains|ExecuteDCOM|ForceChangePassword|GenericAll|GenericWrite|GetChanges|GetChangesAll|HasSession|Owns|ReadLAPSPassword|SQLAdmin|TrustedBy|WriteDACL|WriteOwner|AddAllowedToAct|AllowedToAct]->(t) WHERE m.objectsid ENDS WITH '-513' OR m.objectsid ENDS WITH '-515' OR m.objectsid ENDS WITH 'S-1-5-11' OR m.objectsid ENDS WITH 'S-1-1-0' RETURN p ``` ## Find computers with constrained delegation permissions and the corresponding targets where they allowed to delegate ```bash MATCH (c:Computer) WHERE c.allowedtodelegate IS NOT NULL RETURN c ``` # GPO ## View all GPOs ```bash Match (n:GPO) RETURN n ``` ## Shortes path from Group to GPO ```bash MATCH (n:Group {name:'DOMAIN USERS@CORPORATE.LOCAL'}), (m:GPO) WHERE n <> m MATCH p=shortestPath((n)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..]->(m)) RETURN p ``` ## Shortes path from Computer to GPO ```bash MATCH (n:Computer {name:'DOMAIN USERS@CORPORATE.LOCAL'}), (m:GPO) WHERE n <> m MATCH p=shortestPath((n)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct*1..]->(m)) RETURN p ``` ## Find Users/Groups with direct access to GPOs ```bash MATCH p = (n)-[r:AddMember|AddSelf|WriteSPN|AddKeyCredentialLink|AllExtendedRights|ForceChangePassword|GenericAll|GenericWrite|WriteDacl|WriteOwner|Owns]->(g:GPO) RETURN p ``` ## Find if any domain user has interesting permissions against a GPO (Warning: Heavy) ```bash MATCH p=(u:User)-[r:AllExtendedRights|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|GpLink*1..]->(g:GPO) RETURN p ``` # Session ## Find the active user sessions on all domain computers ```bash MATCH (n:User),(m:Computer), (n)<-[r:HasSession]-(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH n, count(r) as rel_count ORDER BY rel_count DESC MATCH p=(m)-[r:HasSession]->(n) RETURN p ``` ## Top Ten Users with Most Sessions ```bash MATCH (n:User),(m:Computer), (n)<-[r:HasSession]-(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH n, count(r) as rel_count order by rel_count desc LIMIT 10 MATCH p=(m)-[r:HasSession]->(n) RETURN p ``` ## Find all active Domain Admin sessions ```bash MATCH (m:User)-[r:MemberOf*1..]->(n:Group) WHERE n.objectid =~ '(?i)S-1-5-.*-512' WITH m MATCH q=((m)<-[:HasSession]-(o:Computer)) RETURN q ``` ## Remove dataset from neo4j ```bash match (a) -[r] -> () delete a, r ``` ```bash match (a) delete a ```