Last active
May 19, 2021 05:16
-
-
Save TheNaterz/aa3b6cdcc178ba2db23276dad986160b to your computer and use it in GitHub Desktop.
Simple password pattern recognition for Hashcat masks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import sys, subprocess | |
patterns = {} | |
# run hashcat with show to spit out cracked hash:password | |
# should be changed based off of environment | |
# arg should be file of line seperated hashes | |
p = subprocess.Popen(['/opt/hashcat/hashcat-3.30/hashcat64.bin', '-m', '1000', sys.argv[1], '--show'], stdout=subprocess.PIPE) | |
out, err = p.communicate() | |
hashes = out.decode().splitlines() | |
passwords = [] | |
for h in hashes: | |
passwords.append(h.split(':')[-1]) | |
# uniquify. comment out to include duplicates. | |
passwords = list(set(passwords)) | |
for password in passwords: | |
# some hashes might have been broken, so we're gonna HANDLE it. ugly but whatevs | |
# honestly if something is broken, fix the hash in hash file ya filthy animal | |
if "Line-length exception" in password or "failed to parse" in password: | |
continue | |
pattern = "" | |
keyspace = 1 | |
# build the mask for this password and assign a difficulty rating | |
for char in password: | |
if char.islower(): | |
pattern += "?l" | |
keyspace *= 26 | |
elif char.isupper(): | |
pattern += "?u" | |
keyspace *= 26 | |
elif char.isdigit(): | |
pattern += "?d" | |
keyspace *= 10 | |
else: | |
pattern += "?s" | |
keyspace *= 33 | |
try: | |
# pattern in map, so increment | |
patterns[pattern][0] += 1 | |
except KeyError: | |
# new pattern, add to map | |
patterns[pattern] = [1, keyspace] | |
# sort patterns based off of popularity | |
# most popular -> least popular | |
sorted_patterns = sorted(patterns.items(), key=lambda x:x[1][0], reverse=True) | |
# grab the most popular pattern. all other patterns will be judged by this ones popularity | |
maximum_pop = sorted_patterns[0][1][0] | |
# these values define upper and lower 'effort' values. | |
# these should be changed based off of crackbox setup. | |
# lower_eff ~= hashes per second | |
# upper_eff ~= hashes per hour | |
lower_eff = 2500000000 | |
upper_eff = lower_eff*3600 | |
patterns_2 = {} | |
# assign effort scores to patterns | |
for p in patterns: | |
effort = (patterns[p][1] - lower_eff)*1.0 | |
if effort < 1: | |
effort = 1 | |
elif effort > (upper_eff-lower_eff): | |
effort = 0 | |
else: | |
effort = 1-(effort / (upper_eff-lower_eff)) | |
cost = ((patterns[p][0]*1.0)/maximum_pop)*effort | |
patterns_2[p] = [cost, patterns[p][0], patterns[p][1]] | |
# now sort again. result is most popular and easy to crack -> least popular and hard to crack | |
sorted_patterns_2 = sorted(patterns_2.items(), key=lambda x:x[1], reverse=True) | |
mask_file = open('/opt/analyze/analyze.hcmask', 'w') | |
# we only use top 20, but change as desired | |
for i in range(0,20): | |
print(sorted_patterns_2[i]) | |
mask_file.write(sorted_patterns_2[i][0]+"\n") | |
mask_file.close() | |
# print simple copy pasta string. should be changed based on environment | |
print('./hashcat64.bin -w 1 -a 3 -m 1000 '+sys.argv[1]+' /opt/analyze/analyze.hcmask') |
ThanHuuTuan
commented
May 19, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment