Skip to content

Instantly share code, notes, and snippets.

@WJDigby
Last active January 3, 2019 22:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WJDigby/72baae7dd7ac03118c1b7b721b9f1615 to your computer and use it in GitHub Desktop.
Save WJDigby/72baae7dd7ac03118c1b7b721b9f1615 to your computer and use it in GitHub Desktop.
Identify correct casing of password given all-caps LM password and NTLM hash
# reconcile.py
"""Given an all-capital password (from a cracked LM hash) and an NTLM hash,
identify the correct capitalization."""
import argparse
import hashlib
import itertools
def all_cases(password):
"""Take uppercase password, return set of all possible case permutations."""
permutations = set()
cases = map(''.join, itertools.product(*zip(password.upper(), password.lower())))
for case in cases:
permutations.add(case)
return permutations
def ntlminate(password):
"""Take a password of a given case permutation, return the hash."""
hashed = hashlib.new('md4', password.encode('utf-16le')).hexdigest()
return hashed
def main():
"""Take user arguments, compare case permutations with given hash
to identify correct permutation."""
parser = argparse.ArgumentParser(description='Create a database for password analysis.')
parser.add_argument('-n', '--ntlm-hash', dest='ntlm_hash', required=True, help='NTLM hash')
parser.add_argument('-p', '--password', dest='password', required=True,
help='All-caps password.')
args = parser.parse_args()
ntlm_hash = args.ntlm_hash
password = args.password
permutations = all_cases(password)
for index, value in enumerate(permutations, 1):
hashed = ntlminate(value)
if hashed == ntlm_hash:
print(f'[+] Attempted {index} of {len(permutations)} possible combinations - '
f'the correct casing is: {value}')
break
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment