├── requirements.txt ├── README.md ├── drpy3_various.py ├── drpy3_bruter.py └── md5bruter.py /requirements.txt: -------------------------------------------------------------------------------- 1 | colorama>=0.4.4 2 | tqdm>=4.48.0 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # MD5Bruter 4 | 5 | Bruteforce MD5 decryption written in Python 3.8. No password list needed.
6 | Working for single hashes as well as lists of hashes and combolists (userid:md5hash).
7 | All results are saved to a textfile called "logs.txt". 8 | 9 | *For educational purposes only!* 10 | 11 | ![MD5Bruter Demo with Testdata](https://i.ibb.co/bKTBCPw/MD5-Bruter-DEMO.gif) 12 | 13 | ## How to use 14 | 15 | Download code or clone the repo: 16 | 17 | git clone https://github.com/DrPython3/MD5Bruter 18 | 19 | Install requirements / dependencies: 20 | 21 | cd MD5Bruter 22 | python3 install -r requirements.txt 23 | 24 | Then start MD5Bruter: 25 | 26 | python3 md5bruter.py 27 | 28 | ... and follow the output. 29 | 30 | ## Support 31 | 32 | If you like this tool, support my work and buy me a coffee!
33 | Or send a donation to one of the following wallets: 34 | 35 | **BTC:** 19v1XuRJWoFoqqNKJ3r6wdHuRMjg2fjHji
36 | **LTC:** LbukCLWfCqUn3cu8xViQft8pDVVfDqLBZA 37 | 38 | Every donation helps! 39 | 40 |
41 | -------------------------------------------------------------------------------- /drpy3_various.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/opt/python@3.8/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | PROJECT: MD5Bruter, "Various Stuff" 6 | AUTHOR: DrPython3 @ GitHub.com 7 | DATE: 2021-04-03 8 | ''' 9 | 10 | # ********************** 11 | # *** PYTHON MODULES *** 12 | # ********************** 13 | 14 | import sys 15 | try: 16 | import os 17 | import time 18 | except: 19 | sys.exit('Error importing Python modules.\n\n') 20 | 21 | # ***************** 22 | # *** FUNCTIONS *** 23 | # ***************** 24 | 25 | def clean_screen(): 26 | ''' 27 | Provides a blank screen on purpose. 28 | 29 | :return: None 30 | ''' 31 | if os.name == 'nt': 32 | os.system('cls') 33 | else: 34 | os.system('clear') 35 | return None 36 | 37 | 38 | def writer(output): 39 | ''' 40 | Saves any output to textfile logs.txt. 41 | 42 | :param str output: any output to save 43 | :return: True/False 44 | ''' 45 | try: 46 | with open('logs.txt', 'a+') as output_file: 47 | output_file.write(output + '\n') 48 | except: 49 | return False 50 | return True 51 | 52 | 53 | def log_startstop(type): 54 | ''' 55 | Writes timestamps (start, end) to log-file. 56 | 57 | :param str type: (start/stop) 58 | :return: None 59 | ''' 60 | user_time = time.asctime( 61 | time.localtime() 62 | ) 63 | if type == 'start': 64 | log = writer(str( 65 | f'MD5Bruter startet at: {str(user_time)}\n' 66 | )) 67 | else: 68 | log = writer(str( 69 | f'\nMD5Bruter stopped at: {str(user_time)}\n' 70 | )) 71 | return None 72 | -------------------------------------------------------------------------------- /drpy3_bruter.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/opt/python@3.8/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | PROJECT: MD5Bruter, "Bruteforce Worker" 6 | AUTHOR: DrPython3 @ GitHub.com 7 | DATE: 2021-04-04 8 | ''' 9 | 10 | # ********************** 11 | # *** PYTHON MODULES *** 12 | # ********************** 13 | 14 | import sys 15 | try: 16 | import string 17 | import itertools 18 | import hashlib 19 | import colorama 20 | from tqdm import tqdm 21 | except: 22 | sys.exit('Error importing Python Modules.\n\n') 23 | 24 | colorama.init(autoreset=True) 25 | 26 | # *********************************** 27 | # *** CHARSETS FOR WORD GENERATOR *** 28 | # *********************************** 29 | 30 | charset_letterslo = list(string.ascii_lowercase) 31 | charset_lettersuplo = list(string.ascii_letters) 32 | charset_digits = list(string.digits) 33 | charset_digitsletterslo = list(string.digits) + list(string.ascii_lowercase) 34 | charset_alphanum = list(string.ascii_letters) + list(string.digits) 35 | charset_full = list(string.ascii_letters) + list(string.digits) + list(string.punctuation) 36 | 37 | # ******************* 38 | # *** BRUTEFORCER *** 39 | # ******************* 40 | 41 | def bruter(charset_name, min_length, max_length, target_hash): 42 | ''' 43 | Generates strings, calculates hashes and compares them with targeted hash. 44 | 45 | :param str charset_name: charset to use 46 | :param int min_length: min password length 47 | :param int max_length: max password length 48 | :param str target_hash: target MD5 hash 49 | :return: found_string, amount_tested 50 | ''' 51 | amount_tested = int(0) 52 | found_string = str('') 53 | if charset_name == 'charset_letterslo': 54 | charset = charset_letterslo 55 | elif charset_name == 'charset_lettersuplo': 56 | charset = charset_lettersuplo 57 | elif charset_name == 'charset_digits': 58 | charset = charset_digits 59 | elif charset_name == 'charset_alphanum': 60 | charset = charset_alphanum 61 | elif charset_name == 'charset_digitsletterslo': 62 | charset = charset_digitsletterslo 63 | else: 64 | charset = charset_full 65 | for i in range(min_length, max_length + 1): 66 | print(colorama.Fore.YELLOW + f'\nTarget: {str(target_hash)}, testing strings with {str(i)} character(s) now ...') 67 | total = int(len(charset)**i) 68 | for next_string in tqdm(itertools.product(charset, repeat=i), 69 | desc='progress', 70 | total=total, 71 | leave=False, 72 | unit=' strings', 73 | unit_scale=True): 74 | amount_tested += 1 75 | test_string = str('').join(next_string) 76 | hashed_string = hashlib.md5(test_string.encode()) 77 | test_hash = hashed_string.hexdigest() 78 | if test_hash == target_hash: 79 | print(colorama.Fore.GREEN + '... hit!') 80 | found_string = str(test_string) 81 | return found_string, str(amount_tested) 82 | else: 83 | pass 84 | print(colorama.Fore.RED + '... done!') 85 | return found_string, str(amount_tested) 86 | -------------------------------------------------------------------------------- /md5bruter.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/opt/python@3.8/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | PROJECT: MD5Bruter 6 | AUTHOR: DrPython3 @ GitHub.com 7 | DATE: 2021-04-04 8 | ------------------------------------------------------------------------------- 9 | INFO: Bruteforce tool / cracker for MD5 hashes. Processing single hashes, 10 | lists and combolists (userid:md5hash). Work still in progress. 11 | Written just to learn more about bruteforce attacks. 12 | 13 | For educational purposes only! 14 | ''' 15 | 16 | # ********************** 17 | # *** PYTHON MODULES *** 18 | # ********************** 19 | 20 | import sys 21 | try: 22 | # ... official modules: 23 | import os 24 | import colorama 25 | from time import sleep 26 | # ... custom modules: 27 | import drpy3_bruter as worker 28 | import drpy3_various as various 29 | except: 30 | sys.exit('Error importing Python modules.\n\n') 31 | 32 | # ... initialize colorama: 33 | colorama.init(autoreset=True) 34 | 35 | # *************** 36 | # *** VARIOUS *** 37 | # *************** 38 | 39 | logo_main = str(''' 40 | 41 | . : :::::::-. :::::::::::::::. :::::::.. ... :::::::::::::::.,:::::: :::::::.. 42 | ;;,. ;;; ;;, `';,`;;``''; ;;;'';;';;;;``;;;; ;; ;;;;;;;;;;;````;;;;```` ;;;;``;;;; 43 | [[[[, ,[[[[,`[[ [[ [[,_ [[[__[[\.[[[,/[[[' [[' [[[ [[ [[cccc [[[,/[[[' 44 | $$$$$$$$"$$$ $$, $$ `""*Ycc $$""""Y$$$$$$$$c $$ $$$ $$ $$"""" $$$$$$c 45 | 888 Y88" 888o888_,o8P' __,od8"_88o,,od8P888b "88bo,88 .d888 88, 888oo,__ 888b "88bo, 46 | MMM M' "MMMMMMMP"` MMP" ""YUMMMP" MMMM "W" "YmmMMMM"" MMM """"YUMMMMMMM "W" 47 | _______________________________________________________________________________________________ 48 | DrPython3 @ GitHub (C) 2021 49 | 50 | [ OPTIONS:] [1] = Brute Combolist (userid:md5hash) 51 | [2] = Brute Hashlist (1x MD5-hash/line) 52 | [3] = Brute MD5-hash (single MD5-hash) 53 | ========================================== 54 | [0] = EXIT 55 | 56 | ''') 57 | 58 | logo_exit = str(''' 59 | 8 8 88 60 | 8 8 88 61 | 8oPYo. o o .oPYo. 8oPYo. o o .oPYo. 88 62 | 8 8 8 8 8oooo8 8 8 8 8 8oooo8 88 63 | 8 8 8 8 8. 8 8 8 8 8. `' 64 | `YooP' `YooP8 `Yooo' `YooP' `YooP8 `Yooo' 88 65 | :.....::....8 :.....::::.....::....8 :.....:... 66 | :::::::::ooP'.::::::::::::::::::ooP'.:::::::::: 67 | :::::::::...::::::::::::::::::::...:::::::::::: 68 | 69 | ... and thank you for using MD5Bruter! 70 | 71 | If you like this tool, support my work, please. 72 | Buy me a coffee or send a tip to one of the 73 | following wallets: 74 | 75 | BTC: 19v1XuRJWoFoqqNKJ3r6wdHuRMjg2fjHji 76 | LTC: LbukCLWfCqUn3cu8xViQft8pDVVfDqLBZA 77 | 78 | Every donation helps! Best wishes, DrPython3 79 | ''') 80 | 81 | included_charsets = { 82 | 1:'charset_letterslo', 83 | 2:'charset_lettersuplo', 84 | 3:'charset_digits', 85 | 4:'charset_alphanum', 86 | 5:'charset_full', 87 | 6:'charset_digitsletterslo' 88 | } 89 | 90 | # ***************** 91 | # *** FUNCTIONS *** 92 | # ***************** 93 | 94 | def bruteforce(type): 95 | ''' 96 | For setup and starting / performing bruteforce attacks. 97 | 98 | :param str type: (combos / hashes / single) 99 | :return: None 100 | ''' 101 | targets = [] 102 | found = int(0) 103 | various.clean_screen() 104 | print(colorama.Fore.RED + '\n\n*** MD5Bruter *** Interactive Startup\n' + '='*37 + '\n\n') 105 | if type == 'combos' or type == 'hashes': 106 | target_input = str(input(colorama.Fore.WHITE + 'user@md5: enter filename, e.g. "input.txt" ... ' 107 | + colorama.Fore.YELLOW)) 108 | try: 109 | targets = open(target_input, 'r').read().splitlines() 110 | except: 111 | various.clean_screen() 112 | print(colorama.Fore.RED + f'\n\n[ERROR] File {target_input} not found.') 113 | input(colorama.Fore.RED + 'Press ENTER to return to main menu.\n\n') 114 | return None 115 | elif type == 'single': 116 | target_input = str(input(colorama.Fore.WHITE + 'user@md5: enter hash ... ' 117 | + colorama.Fore.YELLOW)) 118 | if target_input == '': 119 | print(colorama.Fore.YELLOW + '\n\nNothing entered, so returning to main menu ...') 120 | sleep(3.0) 121 | return None 122 | else: 123 | targets.append(target_input) 124 | else: 125 | various.clean_screen() 126 | print(colorama.Fore.RED + '\n\n[ERROR] MD5Bruter Startup failed.') 127 | input(colorama.Fore.RED + 'Press ENTER to return to main menu.\n\n') 128 | return None 129 | try: 130 | password_min = int(input(colorama.Fore.WHITE + '\n\nuser@md5: enter minimum password length, e.g. 1 ... ' 131 | + colorama.Fore.YELLOW)) 132 | password_max = int(input(colorama.Fore.WHITE + '\n\nuser@md5: enter maximum password length, e.g. 9 ... ' 133 | + colorama.Fore.YELLOW)) 134 | print(colorama.Fore.WHITE + '\n\nAvailable charsets:\n' + '='*19 + '\n' 135 | + '(1) letters (lowercase only)\n' 136 | + '(2) letters (lower- and uppercase)\n' 137 | + '(3) digits\n' 138 | + '(4) alphanumeric (letter and digits)\n' 139 | + '(5) letters, digits and symbols (full)\n' 140 | + '(6) lowercase letters and digits\n\n') 141 | charset_option = int(input(colorama.Fore.WHITE + 'user@md5: enter number of charset to use, e.g. 2 ... ' 142 | + colorama.Fore.YELLOW)) 143 | charset = str(included_charsets[charset_option]) 144 | except: 145 | print(colorama.Fore.RED + '\n\n[ERROR] Entered value not valid.\nMD5Bruter will use default values instead.\n\n') 146 | sleep(3.0) 147 | password_min = int(1) 148 | password_max = int(9) 149 | charset = str('charset_alphanum') 150 | try: 151 | bruteforce_settings = str(f'target(s): {target_input}\n' 152 | + f'total: {str(len(targets))}\n' 153 | + f'password length: {str(password_min)} - {str(password_max)}\n' 154 | + f'charset: {charset}') 155 | various.clean_screen() 156 | print(colorama.Fore.RED + '\n\n*** MD5Bruter *** Overview:\n' + '='*27) 157 | print(colorama.Fore.WHITE + bruteforce_settings) 158 | print(colorama.Fore.YELLOW + '\n\nBruteforcing started. Be patient, please (...)\n\n' + colorama.Fore.WHITE) 159 | various.log_startstop(str('start')) 160 | various.writer(bruteforce_settings + '\n') 161 | for next_target in targets: 162 | if type == 'combos': 163 | target = str(next_target).replace(';', ':').replace('|', ':') 164 | bruter_input = str(target.split(':')[1]) 165 | else: 166 | bruter_input = str(next_target) 167 | result, amount_tries = worker.bruter(charset, password_min, password_max, bruter_input) 168 | if result == '': 169 | various.writer(str(f'[NO RESULT] {str(next_target)}, tries: {str(amount_tries)}')) 170 | else: 171 | various.writer(str(f'[RESULT] {str(next_target)}, decrypted: {str(result)}, tries: {str(amount_tries)}')) 172 | found += 1 173 | various.log_startstop(str('stop')) 174 | various.clean_screen() 175 | if found > 0: 176 | print(colorama.Fore.GREEN + '\n\n*** MD5Bruter *** Result:\n' + '='*25) 177 | print(colorama.Fore.GREEN + f'Decrypted hashes: {str(found)}, see logs.txt for details.') 178 | input(colorama.Fore.GREEN + 'Press ENTER to return to main menu.\n\n') 179 | else: 180 | print(colorama.Fore.RED + '\n\n*** MD5Bruter *** Result:\n' + '='*25) 181 | input(colorama.Fore.RED + 'No decrypted hashes.\nPress ENTER to return to main menu.\n\n') 182 | except: 183 | various.clean_screen() 184 | print(colorama.Fore.RED + '\n\n[ERROR] Bruteforce attack failed or has been aborted.') 185 | input(colorama.Fore.RED + 'Press ENTER to return to main menu.\n\n') 186 | return None 187 | 188 | 189 | def md5bruter(): 190 | ''' 191 | Provides main menu for MD5Bruter. 192 | 193 | :return: None 194 | ''' 195 | various.clean_screen() 196 | print(colorama.Fore.RED + logo_main) 197 | user_option = input(colorama.Fore.WHITE + 'user@md5: enter option ... ' + colorama.Fore.YELLOW) 198 | if user_option == '0': 199 | various.clean_screen() 200 | print(colorama.Fore.RED + logo_exit) 201 | sys.exit('') 202 | elif user_option == '1': 203 | list_type = str('combos') 204 | elif user_option == '2': 205 | list_type = str('hashes') 206 | elif user_option == '3': 207 | list_type = str('single') 208 | else: 209 | various.clean_screen() 210 | print(colorama.Fore.YELLOW + '\n\n[INFO] No valid option entered.') 211 | input(colorama.Fore.YELLOW + 'Press ENTER to return to main menu.\n\n') 212 | return None 213 | try: 214 | bruteforce(list_type) 215 | except: 216 | pass 217 | return None 218 | 219 | # ... start MD5Bruter: 220 | while True: 221 | md5bruter() 222 | --------------------------------------------------------------------------------