Skip to content

Instantly share code, notes, and snippets.

@TheNaterz
Last active May 19, 2021 05:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheNaterz/aa3b6cdcc178ba2db23276dad986160b to your computer and use it in GitHub Desktop.
Save TheNaterz/aa3b6cdcc178ba2db23276dad986160b to your computer and use it in GitHub Desktop.
Simple password pattern recognition for Hashcat masks
#!/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
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment