Giter Site home page Giter Site logo

max's Introduction

Maximizing BloodHound with a simple suite of tools

Description

New Release:

  • dpat - The BloodHound Domain Password Audit Tool (DPAT)

A simple suite of tools:

  • get-info - Pull lists of information from the Neo4j database
  • mark-owned - Mark a list of objects as Owned
  • mark-hvt - Mark a list of objects as High Value Targets
  • query - Run a raw Cypher query and return output
  • export - Export all outbound controlling privileges of a domain object to a CSV file
  • del-edge - Delete an edge from the database
  • add-spns - Create HasSPNConfigured relationships, new attack primitive
  • add-spw - Create SharesPasswordWith relationships
  • dpat - The BloodHound Domain Password Audit Tool (DPAT)
  • pet-max - Dogsay, happiness for stressful engagements

This was released with screenshots & use-cases on the following blogs: Max Release, Updates & Primitives & DPAT

A new potential attack primitive was added to this tool during my research, see the add-spns section for full details.

Usage

Installation

Ideally there shouldn't be much to install, but I've included a requirements.txt file just in case. Tested on Kali Linux & Windows 10, all functionality should work for both linux and Windows operating systems.

pip3 install -r requirements.txt

Neo4j Creds

Neo4j credentials can be hardcoded at the beginning of the script, they can be provided as CLI arguments, or stored as environment variables. If either parameter is left blank, you will be prompted for the uname/password. To use environment variables, it is probably easiest to add a line (e.g., export NEO4J_USERNAME='neo4j') within ~/.bashrc or ~/.zshrc to store the username since it isn't really sensitive. The database password can be set within your shell's tab prior to running Max. Adding a space before the export command should prevent it from appearing within history.

 export NEO4J_PASSWORD='bloodhound' # Notice whitespace before 'export'
python3 max.py {module} {args}
python3 max.py -u neo4j -p neo4j {module} {args}
python3 max.py {module} {args}
Neo4j Username: neo4j
Neo4j Password:

Quick Use

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
python3 max.py get-info --users --enabled

[email protected]
[email protected]
...

Get list of objects in a target group

python3 max.py get-info --group-members "domain [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 -q "MATCH (n:User),(m:Group {name:'DOMAIN [email protected]'}) MATCH (n)-[*1..]->(m) RETURN DISTINCT(n.name)"

Delete an edge from the database

python3 max.py del-edge CanRDP

Add HasSPNConfigured relationship using the information stored within BloodHound, or with a GetUserSPNs impacket file

python3 max.py add-spns -b
python3 max.py add-spns -i getuserspns-raw-output.txt

DPAT

python3 max.py dpat -n ~/client/ntds.dit -c ~/.hashcat/hashcat.potfile -o ouputdir --html --sanitize

Pet max

python3 max.py pet-max

Object Files & Specification

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

Further work

I hope to include an analyze function to provide some sort functionality similar to PlumHound/Cypheroth. 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

Contributors

I'd like to especially thank those who have contributed their time to developing & improving this tool:

max's People

Contributors

blurbdust avatar knavesec avatar scottconrad avatar thetoddluci0 avatar tigre-bleu avatar yellow-starburst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

max's Issues

DPAT failure if password is expired

The code at line 1104 is causing max.py to fail if I am using the dpat option.
num_pass_hashes_list.append([entry['row'][0], entry['row'][1], length, entry['row'][2], datetime.datetime.fromtimestamp(entry['row'][3])], )

The datetime conversion here fails, and causes the script to exit if a user's password is expired/marked to be changed at next logon. In AD, this flag being set will set the password's last change date to a blank entry and it appears to be what's throwing the script off

I double checked that this is the case by moving each of those variables and outputting them one at a time, and it only fails once it hits an an account where that flag was set. I need to test a change or two, but I think this could quickly be fixed by checking if entry['row'][3] is blank and,if so, setting the output to a different string rather than trying to convert the timestamp.

Here's a screen capture of the output (after adding two lines to also print usernames and the timestamp without conversion)
image

It seems like expired passwords in the .ntds / .dit file are maked with a timestamp of "-1" which is fails when passed to datetime. The following change resolves it, though I'm not sure if it's the best code-wise

try:

    num_pass_hashes_list.append([entry['row'][0], entry['row'][1], length, entry['row'][2], datetime.datetime.fromtimestamp(entry['row'][3])], )

except:

    num_pass_hashes_list.append([entry['row'][0], entry['row'][1], length, entry['row'][2], ''], )

DPAT file name issue

In Windows having a > in a file name is not allowed resulting in it being )%.

The two cases where this is:
Inactive_Accounts_(Last_Used_)%_6mos_Ago)Cracked.html
Accounts_With_Passwords_Set
)%_1yr_Ago_Cracked.html

The Report.html file links to the file name with > resulting in broken links.

2022 DPAT Roadmap Ideas

Disclaimer - I by no means want to be that guy that makes a bunch of tool complaints. I have some time this month to help make these improvements.
This tool deserves recognition for how brilliant it is. Great job @knavesec !

  1. Password_Length_Stats - This has the list of the number of users with a specific number character of password. So if 10 people have a password that is 9 characters. Problem is it does not filter out the disabled users.
    Request - Filter the amount of affected users by being enabled users. Right now it combines enabled and disabled users.

DPAT query fails if both parts of the 'or' return something

Using the query option to run the command directly, we get nothing back if you run the full original command. If you split the command into sub-sections, they run fine. The end result of this in live usage is no users getting mapped for DPAT.

https://github.com/knavesec/Max/blob/master/max.py#L736

┌──(venv)─(notroot㉿devbox)-[~/git/Max]
└─$ python3 max.py query -q "MATCH (u:User) WHERE u.name='[email protected]' OR (u.name STARTS WITH 'USERNAME@' AND u.objectid ENDS WITH '-25935')  RETURN u.name,u.objectid" 
/home/notroot/git/Max/max.py:16: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.util import strtobool
                                                                                                                                                                                                                                            
┌──(venv)─(notroot㉿devbox)-[~/git/Max]
└─$ python3 max.py query -q "MATCH (u:User) WHERE u.name='[email protected]'  RETURN u.name,u.objectid" 
/home/notroot/git/Max/max.py:16: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.util import strtobool
[email protected] - S-1-5-21-1214440339-1035525444-XXXXXXXXXX-25935
                                                                                                                                                                                                                                            
┌──(venv)─(notroot㉿devbox)-[~/git/Max]
└─$ python3 max.py query -q "MATCH (u:User) WHERE u.name STARTS WITH 'USERNAME@' AND u.objectid ENDS WITH '-25935'  RETURN u.name,u.objectid" 
/home/notroot/git/Max/max.py:16: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.util import strtobool
[email protected] - S-1-5-21-1214440339-1035525444-XXXXXXXXXX-25935

Incompatibility with neo4j 5.1

I'm running on neo4j 5.1 and had to adjust a few things for Max to work again:

  • neo4j URI is now /db/neo4j/tx/commit instead of /db/data/transaction/commit
  • EXISTS(u.cracked) is not supported anymore, instead u.cracked IS NOT NULL must be used

Unfortunately I don't have time for a proper PR right now, hope this helps though

Depricated imports

Max/max.py:16: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.util import strtobool

Strange Python Error When Enumerating Known Groups

Problem: The following command:

python3 max.py -u neo4j -p pass --url http://127.0.0.1:7474 get-info --group-members "REMOTE DESKTOP USERS"

Returns the following error:

Traceback (most recent call last): File "max.py", line 650, in <module> main() File "max.py", line 622, in main get_info(args) File "max.py", line 235, in get_info query = query.format(enabled="") KeyError: 'name'

This happens regardless of the groups I try, all of which I have confirmed exist.

Thanks!

Invalid Escape Sequence

Current Version:

C:\Tools\Max\max.py:1474: SyntaxWarning: invalid escape sequence '\ ' max = """

Seems like ASCII art is throwing a warning.

Not an immediate fix, but I just wanted to give you a heads-up.

Thank you!

Max dosen't like it if you don't immediatly open his shiny new toys

Just like a real pupper, Max gets disappointed if he brings you something and you ignore it. Unlike a pupper, Max immediately dies.

[+] Writing HTML files
[+] Report has been written to the "Report.html" file in the "/client/REDACTED/dpat/" directory
[+] Would you like to open the report now? [Y/n]
n
Traceback (most recent call last):
  File "/home/notroot/git/Max/max.py", line 1666, in <module>
    main()
  File "/home/notroot/git/Max/max.py", line 1658, in main
    dpat_func(args)
  File "/home/notroot/git/Max/max.py", line 1417, in dpat_func
    elif ((reponse == 'n') or (response == "no")):
NameError: name 'reponse' is not defined. Did you mean: 'response'?

Query Module not working?

Hi,

when I run python3 max.py get-info --kerb I get a list of kerberoastable users.
However, running the pre-built BloodHound query "List all Kerberoastable Accounts" with python3 max.py query "MATCH (n:User) WHERE n.hasspn=true RETURN n" shows no results. The same holds true for all other Cypher queries I tried.

Do you have any idea why this happens?
Is there an easy way to troubleshoot this issue (error logs, etc.)?

DPAT reused password

It would be nice to have a breakout of the most common reused passwords like the original DPAT tool has.

Incomplete list of unsupported OS

max.py get-info --unsupported seems to omit some machines from the list of unsupported OS versus Bloodhound.

I had a case where bloodhound repported a machine with Windows XP Professional Service Pack 3 while max did not.

Support STDIN for mark-owned

It would be nice to be able to stream data straight from a tool into Max to have it marked as owned, without having to write a file to disk.

Add azure queries to `get-info`

Or maybe roll azure into existing queries? For some, this is already the case (like --hvt), but for some (like --users) Azure AD objects aren't included. Looking at the queries, this inconsistency seems to be more happenstance than an intentional decision.

Happy to write some queries for it, but not sure which approach is better here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.