Skip to content

Instantly share code, notes, and snippets.

@lboulard
Created August 6, 2017 22:16
Show Gist options
  • Save lboulard/85994a7f8bed762ae674bc4516add38b to your computer and use it in GitHub Desktop.
Save lboulard/85994a7f8bed762ae674bc4516add38b to your computer and use it in GitHub Desktop.
Find presence of password in pwned SHA1 files
#!/usr/bin/env python3
# SHA1 files can be found here: https://haveibeenpwned.com/Passwords
import sys
import os, os.path
from hashlib import sha1
import codecs
HERE=os.path.dirname(os.path.abspath(__file__))
PASSWDFILE = [
os.path.join(HERE, 'pwned-passwords-1.0.txt'),
os.path.join(HERE, 'pwned-passwords-update-1.txt'),
os.path.join(HERE, 'pwned-passwords-update-2.txt')
]
def main():
hexencode = codecs.getencoder('hex')
hexdecode = codecs.getdecoder('hex')
for passwd_string in sys.argv[1:]:
passwd, _ = codecs.utf_8_encode(passwd_string)
enc = sha1()
enc.update(passwd)
h = enc.digest()
hh, _ = hexencode(h)
print('Looking up \"%s\" with SHA1 %s' % (passwd_string, hh))
found = False
for passfile in PASSWDFILE:
fd = os.open(passfile, os.O_RDONLY)
st = os.stat(fd)
min, max, hmiddle = 0, st.st_size, ''
while (max - min) > 42 and not found:
middle = (min + max) // 2
middle -= middle % 42
os.lseek(fd, middle, os.SEEK_SET)
hmiddle = os.read(fd, 40)
if len(hmiddle) != 40:
print('bad read')
print(hmiddle)
try:
hmiddle, n = hexdecode(hmiddle)
if n != 40:
print('# n =', n)
raise Exception('SHA1 must be 20 bytes')
except Exception:
print('# Failed to decode')
print(hmiddle)
raise
if h < hmiddle:
max = middle
elif h > hmiddle:
min = middle
elif h == hmiddle:
min = max = middle
if hmiddle == h:
hh, _ = hexencode(hmiddle)
print("PWNED !!!!! Hash found in %s !" % (os.path.basename(passfile)))
found = True
os.close(fd)
if found:
break
if not found:
print('Good ! Password not found')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment