TL;DR
import json, sqlite3
from base64 import b64decode
from os.path import expandvars
from win32.win32crypt import CryptUnprotectData # pip install pywin32
from Cryptodome.Cipher.AES import new, MODE_GCM # pip install pycryptodomex
db = expandvars('%LOCALAPPDATA%/Google/Chrome/User Data/Default/Cookies')
key = CryptUnprotectData(b64decode(json.load(open(f'{db}/../../Local State'))['os_crypt']['encrypted_key'])[5:])[1]
conn = sqlite3.connect(db)
conn.create_function('decrypt', 1, lambda v: new(key, MODE_GCM, v[3:15]).decrypt(v[15:-16]).decode())
print(dict(conn.execute("SELECT name, decrypt(encrypted_value) FROM cookies")))
出力
{'NID': '219=SQ2s60nIXcSZo3sE==', 'freeform': 'cookieFooVal', 'key': 'value'}
復号に必要なキーを取得する
%LOCALAPPDATA%/Google/Chrome/User Data/Local State のencrypted_keyからキーを復号します。
先頭5バイト('DPAPI')は、除去します。
key = CryptUnprotectData(b64decode(json.load(open(f'{db}/../../Local State'))['os_crypt']['encrypted_key'])[5:])[1]
nonceで暗号化された値を復号する
encrypted_value カラムの先頭3バイト('v10')を除去し、15バイト目までをnonceとします。
後ろの16バイトは、検証用タグなので取り除き複合します。
conn.create_function('decrypt', 1, lambda v: new(key, MODE_GCM, v[3:15]).decrypt(v[15:-16]).decode())
使いやすく、関数にまとめました。
https://gist.github.com/GitHub30/427b0474008234d449acefb216a4a833
SQLにWHEREを追加をすることで任意のCookieを絞り込めます。
print(dict(conn.execute("SELECT name, decrypt(encrypted_value) FROM cookies")))
参考