A simple suite of tools:
- Pull lists of information from the Neo4j database
- Mark a list of objects as Owned
- Mark a list of objects as High Value Targets
- Run a raw Cypher query and return output
This was released with screenshots & use-cases on the following blog: https://whynotsecurity.com/blog/max/
Ideally there shouldn't be much to install, it uses pythons standard libraries. You may have to pip3 install a library or two if you don't have it. Tested on Kali linux.
Neo4j credentials can be hardcoded at the beginning of the script OR they can be provided as CLI
Getting help in general, and module specific
python3 max.py -h
python3 max.py {module} -h
Importing owned objects into BH
python3 max.py mark-owned -f owned.txt
python3 max.py mark-owned -f owned.txt --add-note "Owned by repeated local admin"
Get list of users
python3 max.py get-info --users
[email protected]
[email protected]
...
Get a list of computers that a user has administrative rights to
python3 max.py get-info --adminto [email protected]
Get a list of owned objects with the notes for each
python3 max.py get-info --owned --get-note
Running a query - return a list of all users with a path to DA
python3 max.py query "MATCH (n:User),(m:Group {name:'DOMAIN [email protected]'}) MATCH (n)-[*1..]->(m) RETURN DISTINCT(n.name)"
Getting help in general, and module specific
python3 max.py -h
python3 max.py {module} -h
There are 4 modules: get-info, mark-owned, mark-hvt, query
python3 max.py get-info -h
usage: max.py get-info [-h] (--users | --comps | --groups | --groups-full | --das | --unconst | --npusers | --adminto UNAME | --adminsof COMP | --owned | --hvt | --desc | --admincomps) [--get-note] [-l]
optional arguments:
-h, --help show this help message and exit
--users Return a list of all domain users
--comps Return a list of all domain computers
--groups Return a list of all domain groups
--groups-full Return a list of all domain groups with all respective group members
--das Return a list of all Domain Admins
--unconst Return a list of all objects configured with Unconstrained Delegation
--npusers Return a list of all users that don't require Kerberos Pre-Auth (AS-REP roastable)
--adminto UNAME Return a list of computers that UNAME is a local administrator to
--adminsof COMP Return a list of users that are administrators to COMP
--owned Return all objects that are marked as owned
--hvt Return all objects that are marked as High Value Targets
--desc Return all users with the description field populated (also returns description)
--admincomps Return all computers with admin privileges to another computer [Comp1-AdminTo->Comp2]
--get-note Return the "notes" attribute for whatever objects are returned
-l Apply labels to the columns returned
Few things to note:
users,comps,groups,das,unconst,npusers,owned,hvtall return simple listsgroups-fullreturns all domain groups with their respective members in the format[email protected] - member_node_namedescreturns users configured with a description in the format[email protected] - descriptionadmincompsreturns computers that are configured with admin rights for another computer in the formatadmincomp.domain.local - victimcomp.domain.local. Useful for relay attacksadmintoreturns a all computersUNAMEis local admin to. Useful for offline cred spraying & dumpsadminsofreturns a list of all the users that have administrative privileges toCOMPget-notereturns the notes of each object, typically used with theadd-notefunction in themark-*modules-lapply column labels as a header. All queries withget-infodo not return column headers (like "UserName","ComputerName","Description",etc) by default with the query
python3 max.py mark-owned -h
usage: max.py mark-owned [-h] [-f FILENAME] [--add-note NOTES] [--clear]
optional arguments:
-h, --help show this help message and exit
-f FILENAME, --file FILENAME
Filename containing AD objects (must have FQDN attached)
--add-note NOTES Notes to add to all marked objects (method of compromise)
--clear Removed owned marker from all objects
Few things to note:
clearwill set the 'owned' attribute to false for every objectadd-notewill set a note on all object, it's found in the BloodHound GUI. This can also be retrieved via theget-notesflag in theget-infomoduleFILENAMEcontents must include FQDN similar to the naming style of BloodHound objects. For more info see the "Object Files & Specification" section
python3 max.py mark-hvt -h
usage: max.py mark-hvt [-h] [-f FILENAME] [--add-note NOTES] [--clear]
optional arguments:
-h, --help show this help message and exit
-f FILENAME, --file FILENAME
Filename containing AD objects (must have FQDN attached)
--add-note NOTES Notes to add to all marked objects (reason for HVT status)
--clear Remove HVT marker from all objects
Few things to note:
clearwill set the 'highvalue' attribute to false for every objectadd-notewill set a note on all object, it's found in the BloodHound GUI. This can also be retrieved via theget-notesflag in theget-infomoduleFILENAMEcontents must include FQDN similar to the naming style of BloodHound objects. For more info see the "Object Files & Specification" section
For the advanced BloodHound user, experience with Cypher queries required
python3 max.py query -h
usage: max.py query [-h] QUERY
positional arguments:
QUERY Query designation
optional arguments:
-h, --help show this help message and exit
Few things to note:
- Invalid syntax will return a syntax error and Neo4j debugging instructions
- Must return node attributes like:
n.name,n.description,n.owned, etc (there are many more) - Unlike other modules, the notes in "Object Files & Specification" do not all apply, any object name must include FQDN but also must be capitalized, just like any query run in the browser
- Main benefit is not having to copy-paste out of the Neo4j browser console
Objects in file, must contain FQDN within, capitalization does not matter. This also applies to whenever a CLI username/computer name is supplied.
[email protected] <- will be added / correct CLI input
[email protected] <- will be added / correct CLI input
computer01.domain.local <- will be added / correct CLI input
ComPutEr01.doMAIn.LOcaL <- will be added / correct CLI input
user02 <- will not be added / incorrect CLI input
computer02 <- will not be added / incorrect CLI input
I hope to include an analyze function to provide some sort functionality similar to PlumHound/Cypheroth. Additionally planning on an add-relationship style module for large scale creation of relationships within the database. Lastly, thinking about creating a Powershell version for those running Neo4j on Windows, but I'm trash at Powershell so TBD.
Any other features and improvements welcome, find me @knavesec in the BloodHoundGang Slack channel and on Twitter