From f7eaabe27a8eb30cd3f0f07782af13dc31ed60b0 Mon Sep 17 00:00:00 2001 From: Omar Santos Date: Sat, 28 Sep 2024 01:40:49 -0400 Subject: [PATCH] Create using_bloodhound.md --- windows/using_bloodhound.md | 167 ++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 windows/using_bloodhound.md diff --git a/windows/using_bloodhound.md b/windows/using_bloodhound.md new file mode 100644 index 0000000..3a9cec1 --- /dev/null +++ b/windows/using_bloodhound.md @@ -0,0 +1,167 @@ +# Advanced BloodHound Queries Collection + +This document contains a comprehensive collection of queries for use with BloodHound, organized by category. These queries can help you analyze Active Directory environments more effectively. + +## User and Group Analysis + +### Find all edges any owned user has on a computer +``` +MATCH p=shortestPath((m:User)-[r]->(b:Computer)) WHERE m.owned RETURN p +``` + +### Find all Kerberoastable Users +``` +MATCH (n:User) WHERE n.hasspn=true RETURN n +``` + +### Find Kerberoastable Users with passwords last set > 5 years ago +``` +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 +``` + +### Find users that logged in within the last 90 days +``` +MATCH (u:User) +WHERE u.lastlogon < (datetime().epochseconds - (90 * 86400)) + AND NOT u.lastlogon IN [-1.0, 0.0] +RETURN u.name, u.lastlogon +ORDER BY u.lastlogon +``` + +### List users and their login times + password last set times in human-readable format +``` +MATCH (n:User) +WHERE n.enabled = TRUE +RETURN n.name, + datetime({epochSeconds: toInteger(n.pwdlastset)}) as PwdLastSet, + datetime({epochSeconds: toInteger(n.lastlogon)}) as LastLogon +ORDER BY n.pwdlastset +``` + +### Find users that have never logged on and account is still active +``` +MATCH (n:User) +WHERE n.lastlogontimestamp=-1.0 AND n.enabled=TRUE +RETURN n.name +ORDER BY n.name +``` + +## Computer and Session Analysis + +### Find computers with unconstrained delegation that AREN'T domain controllers +``` +MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) +WHERE g.objectsid ENDS WITH '-516' +WITH COLLECT(c1.name) AS domainControllers +MATCH (c2:Computer {unconstraineddelegation:true}) +WHERE NOT c2.name IN domainControllers +RETURN c2.name, c2.operatingsystem +ORDER BY c2.name ASC +``` + +### Find active Domain Admin sessions +``` +MATCH (n:User)-[:MemberOf*1..]->(g:Group) +WHERE g.objectid ENDS WITH '-512' +MATCH p = (c:Computer)-[:HasSession]->(n) +RETURN p +``` + +### Find computers with descriptions +``` +MATCH (c:Computer) +WHERE c.description IS NOT NULL +RETURN c.name, c.description +``` + +## Domain and Forest Analysis + +### Find connections between different domains/forests +``` +MATCH (n)-[r]->(m) +WHERE NOT n.domain = m.domain +RETURN LABELS(n)[0], n.name, TYPE(r), LABELS(m)[0], m.name +``` + +## Privilege and Access Analysis + +### Find the percentage of computers with a path to Domain Admins +``` +MATCH (totalComputers:Computer {domain:'DOMAIN.GR'}) +MATCH p=shortestPath((ComputersWithPath:Computer {domain:'DOMAIN.GR'})-[r*1..]->(g:Group {name:'DOMAIN ADMINS@DOMAIN.GR'})) +WITH COUNT(DISTINCT(totalComputers)) as totalComputers, COUNT(DISTINCT(ComputersWithPath)) as ComputersWithPath +RETURN 100.0 * ComputersWithPath / totalComputers AS percentComputersToDA +``` + +### Find the most privileged groups on the domain +``` +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, COUNT(DISTINCT(computers)) AS AdminRightCount +ORDER BY AdminRightCount DESC +``` + +## Kerberos and Delegation Analysis + +### Find users with constrained delegation permissions +``` +MATCH (u:User) +WHERE u.allowedtodelegate IS NOT NULL +RETURN u.name, u.allowedtodelegate +``` + +### Find computers with constrained delegation permissions +``` +MATCH (c:Computer) +WHERE c.allowedtodelegate IS NOT NULL +RETURN c.name, c.allowedtodelegate +``` + +## GPO and OU Analysis + +### View OUs based on member count +``` +MATCH (o:OU)-[:Contains]->(c:Computer) +RETURN o.name, o.guid, COUNT(c) +ORDER BY COUNT(c) DESC +``` + +### Find if any domain user has interesting permissions against a GPO +``` +MATCH p=(u:User)-[r:AllExtendedRights|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|GpLink*1..]->(g:GPO) +RETURN p +LIMIT 25 +``` + +## ACL and Permission Analysis + +### Find what permissions Everyone/Authenticated Users/Domain Users/Domain Computers have +``` +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 m.name, TYPE(r), t.name, t.enabled +``` + +## Miscellaneous Queries + +### Adjust Query to Local Timezone (Change timezone parameter) +``` +MATCH (u:User) +WHERE NOT u.lastlogon IN [-1.0, 0.0] +RETURN u.name, datetime({epochSeconds:toInteger(u.lastlogon), timezone: '+10:00'}) as LastLogon +``` + +### Find users that are part of the VPN group +``` +MATCH (u:User)-[:MemberOf]->(g:Group) +WHERE g.name CONTAINS "VPN" +RETURN u.name, g.name +``` +