Brute-Campbell is a Python-based tool designed to brute force given binaries that have passwords made up of digits (0-9) with a maximum length of three, or a dictionary word (either ending with a single number or its leet speak version), or binaries that are vulnerable to a timing attack.
Brute-Campbell is currently only compatible with the Linux operating system. It has a basic menu system that simplifies binary selection. Its features have been separated into different files: brute_basic.py, brute_intermediate.py, brute_advanced.py, for cracking a maximum of three-digit pins, for bypassing arbitrary-length dictionary-based passwords, and for exploiting a timing attack in a vulnerable binary, respectively. The files are located in the src folder of the root directory.
To achieve the desired output, ensure to follow the installation steps below
- Linux operating system
- Python 3 Install Python for Linux
- Pip How to install Pip on Linux
Using the Makefile provided to set up the environment. Ensure you are in the brute_campbell/ directory
Create a virtual environment:
make venv
Activate the virtual environment
source brute_env/bin/activate
Install prerequisites (it is advisable to do this step in the virtual environment)
make prereqs
If the make command does not exist, install the necessary packages and run the above steps again How to install make in Linux
Without the Makefile, ignore the immediate steps below if the commands above worked
Install the virtual environment How to install Python virtual environment
pip install virtualenv
Create a virtual environment
python -m virtualenv brute_env
Activate the virtual environment
source brute_env/bin/activate
Install prerequisites (it is advisable to do this step in the virtual environment)
pip install -r requirements.txt
Download the binaries using a Bash script
chmod +x download_targets.sh # if not executable
./download_targets.sh
Alternatively: download the binaries using a Python script
python download_targets.py
If the above fails, proceed to download the binaries manually Link to binaries. The link also includes additional information on the accepted password type for each binary set. Note: when downloading manually, save all the binaries in the targets/ folder in the root directory.
After the requirements above have been met, proceed to run the program.
When brute_basic.py, brute_intermediate.py, or brute_advanced.py is run, a basic menu appears as seen in each Output below. Each related binary can be selected using its corresponding key (0, 1, or 2). After selecting, Brute-Campbell will automatically carry out the brute force, and when completed successfully it will return a success message with the determined or forced password as seen in each Corresponding result below. If unsuccessful it will return a failure message indicating that all the password attempts were unsuccessful.
Advanced Demo
This attempts to crack binaries that accept passwords made up of digits (0-9) that have a maximum length of three.
python src/brute_basic.py
Output:
Basic Binary Breaker
Which binary do you want to brute force?
0: targets/basic1
1: targets/basic2
2: targets/basic3
Enter the number of the binary to be forced: 0
Corresponding result:
0: targets/basic1 - The Guess '026' appears to be correct
1: targets/basic2 - The Guess '187' appears to be correct
2: targets/basic3 - The Guess '255' appears to be correct
This attempts to use dictionary words that are extended in the program to include modifications of each word: it's leet speak version (speak = 5p34k) and a single-digit (0-9) appended to each word (abroad0, abroad1, …) to break the given binary.
python src/brute_intermediate.py
Output:
Intermediate Binary Breaker
Which binary do you want to brute force?
0: targets/intermediate1
1: targets/intermediate2
2: targets/intermediate3
Enter the number of the binary to be forced: 0
Corresponding result:
0: targets/intermediate1 - The Guess 'c04t3d' appears to be correct
1: targets/intermediate2 - The Guess '50l4r15' appears to be correct
2: targets/intermediate3 - The Guess 'rotary7' appears to be correct
Note: To use a custom dictionary file simply replace or extend the dictionaries/base.txt file. Ensure each word starts on a new line and that the replacement file is named base.txt and stored in the dictionaries directory.
This attempts to exploit a timing attack in a vulnerable binary. More explanation is provided in the Algorithms section.
python src/brute_advanced.py
Output:
Advanced Binary Breaker
Which binary do you want to brute force?
0: targets/advanced1
1: targets/advanced2
2: targets/advanced3
Enter the number of the binary to be forced: 0
Corresponding result:
0: targets/advanced1 - The Guess 'cat' appears to be correct
1: targets/advanced2 - The Guess 'clip' appears to be correct
2: targets/advanced3 - The Guess 'yell' appears to be correct
Note:
21. alphabets = string.ascii_lowercase # This holds all lowercase alphabets
To extend the characters for the timing attack, simply modify line 21 as seen above in the brute_advanced.py file to whatever character you wish to use (Ensure they are in a List if you decide to do this manually). For example:
21. alphabets = string.printable # This holds all lowercase and upppercase alphabets, digits, and punctuation
Python String printable function
To change the target binaries for each feature (basic, intermediate, advanced) to a custom binary, simply replace each corresponding binary with your binary file. For example, to use a custom binary (e.g BinaryBasic) that accepts a three-digit PIN, replace any of the basic binaries (e.g basic1) with your binary and rename your binary to ‘basic1,’ and select its relating key in the basic menu system for breaking basic binaries.
Using the Makefile provided to run tests.
make test
Without the Makefile, ignore this step if the command above worked
pytest -v test/
Table 1: All tests performed for the Basic task
Function | Test | Expected Result |
---|---|---|
test_generate_guesses() |
Type of return | List |
test_generate_guesses_max_length() |
Length of return | 1000 |
test_generate_guesses_min_and_max_length() |
First digit is 000 Last digit is 999 Maximum length is 3 Maximum length is not 4 |
000 999 True True |
Table 2: All tests performed for the Intermediate task
Function | Test | Expected Result |
---|---|---|
test_generate_guesses_from_dict() |
Type of return | List |
test_generate_guesses_from_dict_includes_word_without_number() |
Word without number in return | True |
test_generate_guesses_from_dict_word_endswith_number() |
Word that ends with a number exists in return | True |
test_generate_guesses_from_dict_word_is_leet_speak() |
Word that has a mix of numbers and characters exists in return | True |
Table 3: All tests performed for the Advanced task
Function | Test | Expected Result |
---|---|---|
test_check_binary() |
Generates a word in return (more than one character) | True |
Tests result:
All tests are expected to pass as seen in image below.
In this project, three algorithms were developed:
- Creating a list of all possible three-digit PINs
- Creating a word list by modifying dictionary words
- Cracking a password using a timing attack
This leverages list comprehension to model a construct of the Cartesian Product for deriving a set of all possible ordered pairs with the first and last elements being 000 and 999 respectively.
- Determined the maximum PIN length: max = 3
- Created a list of possibilities: [‘0’, …, ‘9’]
- Generated a list of all possible digits ranging from 000 - 999
This algorithm accepts a dictionary file with words of arbitrary length, converts each word to its leet speak version, and also uses the Cartesian Product construct to append a single-digits to each word.
- Assigned leet speak substitute of each letter as a value to its corresponding letter as a key in a dictionary {‘o’: ‘0’, ‘i': ‘1’, …}
- Created a list of single-digit numbers to add to each word [‘0’, …, ‘9’]
- Retrieve words from the dictionary
- Extend each word by appending a single digit ranging from 0-9 to the word (‘abroad0’, ‘abroad1’, …)
- Extend each word to convert each corresponding letter in the dictionary to its leet speak version (speak = 5p34k)
This attempts to exploit timing issues in a vulnerable binary. It checks each letter of the alphabet against each position of the binaries' actual password one after the other.
- Created a dictionary to hold each letters’ average time on every looped attempt {‘a’: 0.022526912, ‘b’: 0.124225923}
- Sort and retrieve the character with the highest time on every iteration
- Append retrieved character as preceding character for the next timed attempt
- Repeat till all characters have been determined and store the guess
- Then test determined guess against the target binary for validation of the guess
- James Shuttleworth @csx239
- Olajuwon Olawale Faleke @falekeo
Fork this repository and send a pull request!