Explore Kerberoastable Users with BloodHound


Importing Libraries

Pre-requisites:

  • pip install py2neo

from py2neo import Graph

Count Users with Service Principal Name Set

When sharphound finds a user with a Service Principal Name set, it property named hasspn in the User node to True. Therefore, if we want to count the number users with that property set, we just need to query for users with hasspn = True.

g = Graph(password=("wardog"))
g
<Graph database=<Database uri='bolt://localhost:7687' secure=False user_agent='py2neo/4.3.0 neobolt/1.7.17 Python/3.7.3-final-0 (linux)'> name='data'>
users_hasspn_count = g.run("""
MATCH (u:User {hasspn:true})
RETURN COUNT(u)
""").to_data_frame()
users_hasspn_count
COUNT(u)
0 2
g.run("""
MATCH (u:User {hasspn:true})
RETURN u.name
""").to_data_frame()
u.name
0 KRBTGT@CONTOSO.LOCAL
1 SQL2014@CONTOSO.LOCAL

Retrieve Kerberoastable Users with Path to DA

We can limit our results and return only Kereberoastable users with paths to DA. We can find Kerberoastable users with a path to DA and also see the length of the path to see which one is the closest.

krb_users_path_to_DA = g.run("""
MATCH (u:User {hasspn:true})
MATCH (g:Group {name:'DOMAIN ADMINS@CONTOSO.LOCAL'})
MATCH p = shortestPath(
  (u)-[*1..]->(g)
)
RETURN u.name,LENGTH(p)
ORDER BY LENGTH(p) ASC
""").to_data_frame()
krb_users_path_to_DA
u.name LENGTH(p)
0 KRBTGT@CONTOSO.LOCAL 3
1 SQL2014@CONTOSO.LOCAL 3

Return Most Privileged Kerberoastable users

What if we do not have kerberoastable users with a path to DA? We can still look for most privileged Kerberoastable users based on how many computers they have local admins rights on.

privileged_kerberoastable_users = g.run("""
MATCH (u:User {hasspn:true})
OPTIONAL MATCH (u)-[:AdminTo]->(c1:Computer)
OPTIONAL MATCH (u)-[:MemberOf*1..]->(:Group)-[:AdminTo]->(c2:Computer)
WITH u,COLLECT(c1) + COLLECT(c2) AS tempVar
UNWIND tempVar AS comps
RETURN u.name,COUNT(DISTINCT(comps))
ORDER BY COUNT(DISTINCT(comps)) DESC
""").to_data_frame()
privileged_kerberoastable_users
u.name COUNT(DISTINCT(comps))
0 KRBTGT@CONTOSO.LOCAL 1
1 SQL2014@CONTOSO.LOCAL 1