Of course, the list that comes back doesn't show the specific site it was compromised on, only "Collection 1". As I use different passwords for all sites, I needed to know which password was actually compromised.
HaveIBeenPwned hosts a similar service where you can throw a password into a box and it'll see if that shows up in any leaks. As I'm a pretty untrustworthy guy, I didn't want to type my passwords for banking and e-mail accounts into someone elses website. However, it hosts an API where you can throw the first part of a SHA1 hash against it, and it'll return all suffixes where there's a match. This fixed my problem of submitting cleartext passwords to a web service I don't trust.
I wrote the following Python script to parse the export of LastPass credentials (Go to your Vault -> More Options -> Advanced -> Export). It'll only send the first 5 characters of the SHA1 hash, and if there's a match, it'll print the compromised password to the screen.
''' To use: -python password_breach_checker.py -e <path to lastpassexport.csv> -python password_breach_checker.py -f <path to file, one password per line> -python password_breach_checker.py -p <single password> ''' import csv import requests import hashlib import argparse # Parses the CSV file from LastPass into a de-duped list def parseLastPassExport(path): passes = set() # use a set for unique values with open(path) as f: reader = csv.DictReader(f) data = [r for r in reader] # parse the CSV using list comprehension for p in data: # for every row in the CSV, passes.add(p['password']) # grab the password and add it to a set() return list(passes) # cast the set() to a list for ease of use def checkPassword(p): apiUrl = 'https://api.pwnedpasswords.com/range/' fullHash = hashlib.sha1(p).hexdigest().upper() #hash the whole password hashFirstFive = fullHash[:5] # pull first 5 for API call hashLast=fullHash[5:] # pull the rest for checking it against the returned values req = requests.get(apiUrl+hashFirstFive) # send the API call suffixes = req.text.split('\r\n') # split the results on newlines for suffix in suffixes: # for every suffix, if hashLast in suffix: # if the last part of the hash is in the suffix, print "Password compromised -> ", p # print it out parser = argparse.ArgumentParser(description="Check passwords against cred dumps.") parser.add_argument('-e', help="Path to LastPass data export") parser.add_argument('-f', help="Path to file with passwords, one per line") parser.add_argument('-p', help="single password to check") if __name__ == "__main__": args = parser.parse_args() if args.e: passes = parseLastPassExport(args.e) for pw in passes: checkPassword(pw) elif args.f: with open(args.f) as f: passes = f.read().split() for pw in passes: checkPassword(pw) elif args.p: checkPassword(args.p) else: print "you done goofed!"