├── 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 | 
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 |
--------------------------------------------------------------------------------