BloodHound Cypher Queries

The purpose of this page is to share cypher queries to assist in Active Directory assessments.

This page contains BloodHound queries to:

#1 List owned users

MATCH (u:User {owned:true}) RETURN u.name

Usefull when owned accounts have been flagged on BloodHound (‘Mark node as owned’)

#2 List owned computers

MATCH (c:Computer {owned:true}) RETURN c.name,c.operatingsystem

Same as above

#3 List enabled machines with unsupported operating system

MATCH (c:Computer {enabled:true}) WHERE c.operatingsystem =~ ‘(?i).*(2000|2003|2008|xp|vista|7|me).*’ RETURN c.name,c.operatingsystem

When network ranges are not provided, a quick list of potential targets is the hosts with unsupported operating systems. Prioritize these hosts for vulnerability scanning - for example Nessus scans.

#4 List description of enabled machines

MATCH (c:Computer {enabled:true}) WHERE c.description IS NOT NULL return c.name,c.description

List computer accounts that have a description. Usefull to get an understanding of the role of the reviewed host.

#5 List description of enabled users

MATCH (u:User {enabled:true}) WHERE u.description IS NOT NULL return u.name,u.description

List enabled user accounts that have a description. Usefull to get an understanding of the role of the reviewed account.

#6 List user accounts that contain the word “PASS” in their description

MATCH (u:User {enabled:true}) WHERE toupper(u.description) CONTAINS ‘PASS’ RETURN u.name,u.description

This query looks for account that may contain a password in the description

#7 List computer accounts that contain the word ‘TOMCAT’ in the description

MATCH (c:Computer {enabled:true}) WHERE toupper(c.description) CONTAINS ‘TOMCAT’ RETURN c.name,c.description

Identify server that may be running Tomcat

#8 List hosts where an owned user can RDP to

MATCH (u:User {owned:true}) MATCH (c:Computer {enabled:true}) MATCH p=(u)-[:MemberOf|CanRDP*1..]->(c) WHERE NOT u=c return p

To which hosts a user can RDP by investigating group membership

#9 List enabled user accounts that have a blank password

MATCH (u:User {enabled:true,passwordnotreqd:true}) RETURN u.name,u.displayname

#10 List enabled computer accounts that allow unconstrained delegation

MATCH (c:Computer {enabled:true,unconstraineddelegation:true}) return c.name,c.description

Returns hosts configured with unconstrained delegation. If a computer configured with unconstrained delegation is compromised and additionally the attacker has elevated privileges on that host, a privileged account can be forced to authenticate to the compromised host and as a result extract the TGT of the privileged account from the memory of the compromised computer.

#11 Find edges an owned user has to a computer

MATCH p=shortestPath((u:User {owned:true})-[r]->(c:Computer)) RETURN p

#12 List user accounts that do not require PreAuthentication

MATCH (u:User {enabled:true,donotreqpreauth:true}) RETURN u

#13 List user accounts configured with constrained delegation

MATCH (u:User {enabled:true}) WHERE u.allowedtodelegate IS NOT NULL RETURN u.name,u.allowedtodelegate

#14 List hosts with Service Principal Names (SPN)

MATCH (c:Computer {enabled:true}) WHERE c.serviceprincipalnames IS NOT NULL RETURN c.name,c.serviceprincipalnames

Returns hosts with service principal names. Service Principal Names (SPN) reveal additional context on the role of the each host, such as the services that may be running on each host.

#15 List active accounts that have never logged in

MATCH (u:User {enabled:true}) WHERE u.lastlogon=-1 AND u.lastlogontimestamp=-1 RETURN u.name

#16 List enabled computers of a specific domain

MATCH (c:Computer {enabled:true}) WHERE c.domain=~’contoso.local’ RETURN c.name,c.description

#17 List first degree object control for enabled accounts that do not require password

MATCH (u:User {enabled:true,passwordnotreqd:true}), p=(u)-[r1]->(n) WHERE r1.isacl=true RETURN p

#18 List which domain groups are admins to what computers

MATCH (g:Group) OPTIONAL MATCH (g)-[:AdminTo]->(c1:Computer) OPTIONAL MATCH (g)-[:MemberOf*1..]->(:Group)-[:AdminTo]->(c2:Computer) WITH g, COLLECT(c1) + COLLECT(c2) AS tempVar UNWIND tempVar AS computers RETURN g.name AS GroupName, COLLECT(computers.name) AS AdminRights

#19 List home directories of users

MATCH (u:User) WHERE u.homedirectory =~ ‘^\\\\.+’ u.name,u.homedirectory

This query returns a list of user accounts with their respective home directories. From this we can identify network shares.

#20 List Kerberoastable user accounts configured with unconstrained delegation

MATCH (u:User {enabled:True}) WHERE u.hasspn = true AND NOT u.name CONTAINS ‘$’ AND u.unconstraineddelegation = true RETURN u.name,u.description

Example abuse scenario:

#21 List hosts that contain a specific string within the Service Principal Name (SPN) field

MATCH (c:Computer {enabled:true}) UWIND c.serviceprincipalnames AS spn WITH spn,c WHERE toupper(spn) =~ ‘^some_string.+’ RETURN c.name,spn

#22 List shortest paths to high value targets from owned principals

MATCH p=shortestpath((o {owned:true})-[*1..]->(hvt {highvalue:true})) WHERE o<>hvt RETURN p

#23 List the groups a user is member of

MATCH p=((n:User {name:’<username>’})-[r:MemberOf]->(g:Group)) RETURN g.name

#24 List Group Policy Objects

MATCH (g:GPO) RETURN g.name


tags: #active directory