This program only works on Python version equal to or higher than 3.6. Credits to @Graipher for helping with the previous version. Some improvements:
- Importing the program and using it in another file is easier;
- Calling the program from the command line is easier;
- Optional debug mode greatly improves performance (up to 8 times faster);
- Multiple algorithms available (sha1, sha256, sha3_256 etc.)
- Code is more readable.
pycrack.py: (hey, I had to think of something)
import hashlib
from sys import argv
from time import time
from itertools import product
from string import ascii_lowercase, ascii_uppercase, digits
colors = {"red":"\033[91m",
"green":"\033[92m",
"none":"\033[00m"
}
def get_charset(arg_charset):
charset = ""
charsets = {"L":ascii_lowercase,
"U":ascii_uppercase,
"D":digits
}
for key in arg_charset:
# Supply charset argument as list or str if imported
# Only str accepted from command line prompt.
charset += charsets[key]
return charset
def get_algorithm(arg_algo):
algorithms = {"md5":hashlib.md5,
"sha1":hashlib.sha1,
"sha224":hashlib.sha224,
"sha256":hashlib.sha256,
"sha384":hashlib.sha384,
"sha512":hashlib.sha512,
"sha3_224":hashlib.sha3_224,
"sha3_256":hashlib.sha3_256,
"sha3_384":hashlib.sha3_384,
"sha3_512":hashlib.sha3_512,
}
return algorithms[arg_algo]
def timer(func):
def wrapper(*args, **kwargs):
timer_start = time()
timer_return = func(*args, **kwargs)
timer_diff = int(time()-timer_start)
print(f"{colors['green']}Bruteforce done{colors['none']}")
print("Statistics")
print("_________________________________________")
print("Calculation time: {}{}{} seconds".format(
colors['green'],
timer_diff,
colors['none']))
print("_________________________________________")
return timer_return
return wrapper
@timer
def bruteforce(hash_, charset, min_length, max_length, algo, debug):
for length in range(int(min_length), int(max_length) + 1):
for attempt in product(charset, repeat=length):
hashed = "".join(attempt).encode("utf-8")
# Calling this hashed because otherwise statistics would
# show - found b"<<original>>" - which is ugly
hashed = algo(hashed).hexdigest()
if hashed != hash_:
if debug:
print(f"{colors['red']}{''.join(attempt)}{colors['none']}")
else:
if debug:
print(f"{colors['green']}{''.join(attempt)}{colors['none']}")
return "".join(attempt)
def main():
hash__, charset_, min_length_, max_length_, algo_, debug_ = argv[1:7]
charset = get_charset(charset_)
algo = get_algorithm(algo_)
res = bruteforce(hash__, charset, min_length_, max_length_, algo, debug_)
if res is None:
print(f"{colors['red']}No matches found.{colors['none']}")
print(colors['none'])
if __name__ == "__main__":
print("\n"*90)
main()
And here's an example implementation in another file:
import pycrack
hash_ = "d04b98f48e8f8bcc15c6ae5ac050801cd6dcfd428fb5f9e65c4e16e7807340fa"
charset = pycrack.get_charset("LUD")
min_length = 1
max_length = 5
algo = pycrack.get_algorithm("sha256")
print("\n"*80)
r = pycrack.bruteforce(hash_, charset, min_length, max_length, algo, True)
if r is None:
print("No matches.")
else:
print(f"Match: \033[92m{r}")
print("\033[00m")
print("\n"*10)
Results (debug=False):
Bruteforce done
Statistics
_________________________________________
Calculation time: 3 seconds
_________________________________________
Hash: d04b98f48e8f8bcc15c6ae5ac050801cd6dcfd428fb5f9e65c4e16e7807340fa
Match: hash
Results (debug=True):
hasd
hase
hasf
hasg
hash
Bruteforce done
Statistics
_________________________________________
Calculation time: 24 seconds
_________________________________________
Hash: d04b98f48e8f8bcc15c6ae5ac050801cd6dcfd428fb5f9e65c4e16e7807340fa
Match: hash
Now, I still have the feeling there's a lot issues with my code.
- In the
get_algorithm()
function, if one or more of the hashing algorithms aren't available on the user's system, the program will raise an AttributeError. Is there any way to efficiently check the available algorithms and add them toalgorithms
? I tried using list comprehensions andhashlib.algorithms_available
, but couldn't figure it out. - My
main()
function looks bad, is there any way to improve that? - I'm not sure how to improve whitespace usage in the code. Is there a better way to split the logical sections of the code / a standard model to follow (apart from PEP-8 which I try to follow)?