Bloodhound
Ingestors (offical collectors)
SharpHound requires .NET > 3.5, but can be ran from a non domain joined computer.
. .\SharpHound.ps1
Invoke-BloodHound -collectionmethod all [-jsonfolder c:\windows\temp]
SharpHound.exe -c all,GPOLocalGroup --NoSaveCache [-jsonfolder c:\windows\temp] [-EncryptZip]
Running the collector from a non domain-joined computer
Use the standard collection procedure with the runas /netonly
trick.
runas /netonly /user:domain\username cmd.exe
Non official collectors
These collectors do not include all features correctly such as delegations and sessions. It is recommended to use a non domain-joined VM (see above).
bloodhound --collectionmethod all
pip install ldap3 dnspython ldapdomaindump
ldapdomaindump -u "DOMAIN\user" <ip>
BloodHound GUI
Custom queries
Download customqueries.json and put it under the following path /root/.config/bloodhound/customqueries.json
.
List of current custom queries:
- ALL Path from DOMAIN USERS to High Value Targets
- Find Servers where DOMAIN USERS can RDP To
- Top Ten Computers with Most Admins
- All Shortest Path - Owned to HighValue
- Find all other Rights DOMAIN USERS shouldn’t have
Shortcuts
- Ctrl: Change node labels (Hide, Default threshold, Show all)
- Space: Search amongst the currently displayed nodes
- Ctrl+R: Restart Bloodhound (in case of a crash)
Cypher Queries
These commands cannot be run in bloodhound as they query directly the db, prefer the neo4j api or web browser http://localhost:7474.
Find potential vulnerable systems
MATCH (H:Computer) WHERE H.operatingsystem =~ '(?i).*(2000|2003|2008|xp|vista|me).*' RETURN H
Find users with reversible encryption password
MATCH (u:User) WHERE NOT u.userpassword IS null RETURN u.name,u.userpassword
Find Shortest path with a condition on start, end and middle nodes
MATCH (a) WHERE <CONDITION on a which is the start node>
MATCH (b) WHERE <CONDITION on b which is the end node>
MATCH p=allShortestsPaths((a)-r[:MemberOf|GenericalAll|<ANY OTHER RELATION>*1..]->(b))
WITH p, nodes(p)[1..-1] as nodeslist
WHERE ALL( n in nodeslist[1..] WHERE <CONDITION on intermediate nodes>)
RETURN p
AD Metrics
Very heavy query
Percentage User to Target group + Distance/Cost/ComputerTouched.
MATCH (tx:User),
p = shortestPath((x:User)-[r*1..]->(g:Group {name:'<DOMAIN [email protected]>'})) WITH g.name as G,
COUNT(DISTINCT(tx)) as TX,
COUNT(DISTINCT(x)) as X, ROUND(100*AVG(LENGTH(RELATIONSHIPS(p))))/100 as H,
ROUND(100*AVG(length(filter(z in extract(r in relationships(p)| type(r)) where z<>'MemberOf'))))/100 as C,
ROUND(100*AVG(length(filter(y in extract(n in nodes(p)|LABELS(n)[0]) WHERE y='Computer'))))/100 AS T
WITH G,TX,X,H,C,T,
ROUND(100*(100.0*X/TX))/100 as P
RETURN {
TotalCount: TX,
PathCount: X,
Percent: P,
HopAvg: H,
CostAvg: C,
TouchAvg: T
}
Set node as owned from file (for examples hashes cracked with Hashcat)
The following script sets the user nodes provided as Owned and write the password in the Notes field
The Hash file MUST have one user:password
per line
It is preferable to close Bloodhound GUI when running the script
CURRENTLY, IT WILL OVERRIDE ANY NOTE SAVED FOR AN OWNED USER
pip3 install py2neo
export NEO4J_USER=<neo4j>
export NEO4J_PASSWORD=<CHANGEME>
python3 bloodypasswords.py <DOMAIN FQDN FOR EX: CORP.LOCAL> <USER_HASH_FILE>