Skip to content

Instantly share code, notes, and snippets.

@kosh04
Last active November 21, 2024 06:03
Show Gist options
  • Save kosh04/36cf6023fb75b516451ce933b9db2207 to your computer and use it in GitHub Desktop.
Save kosh04/36cf6023fb75b516451ce933b9db2207 to your computer and use it in GitHub Desktop.
Chrome Cookies Decrypter

Chrome Cookies Decrypter

Chrome の Cookies を Netscape 形式で出力するスクリプト

今のところ macOS 専用

Usage

$ python3 ./chrome_cookies_decrypt.py > cookie.txt
$ curl --cookie cookie.txt URL

参考リンク

-- http://www.forensicswiki.org/wiki/Google_Chrome
SELECT datetime(((cookies.creation_utc/1000000)-11644473600), "unixepoch"),
cookies.host_key,
cookies.name,
cookies.value,
cookies.path,
datetime(((cookies.expires_utc/1000000)-11644473600), "unixepoch"),
cookies.secure,
cookies.httponly,
datetime(((cookies.last_access_utc/1000000)-11644473600), "unixepoch"),
cookies.has_expires,
cookies.persistent,
cookies.priority FROM cookies;
#!/usr/bin/env python3
# Usage:
# $ ./chrome_cookies_decrypt.py > cookie.txt
import os
import sqlite3
import keyring
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
class AESCipher:
def __init__(self, key):
self.key = key
def decrypt(self, text):
cipher = AES.new(self.key, AES.MODE_CBC, IV=(' ' * 16))
return self._unpad(cipher.decrypt(text))
def _unpad(self, s):
return s[:-ord(s[len(s) - 1:])]
passwd = keyring.get_password('Chrome Safe Storage', 'Chrome')
passwd = passwd.encode()
salt = b'saltysalt'
length = 16
iterations = 1003
key = PBKDF2(passwd, salt, length, iterations)
cipher = AESCipher(key)
cookie_file = os.path.expanduser(
'~/Library/Application Support/Google/Chrome/Default/Cookies')
conn = sqlite3.connect(cookie_file)
# NOTE: Chrome uses Win32_FILETIME format
# NOTE: 11644473600 == strftime('%s', '1601-01-01')
sql = 'SELECT host_key,path,is_secure,name,value,encrypted_value,((expires_utc/1000000)-11644473600) FROM cookies'
if __name__ == '__main__':
for host_key, path, is_secure, name, _value, encrypted_value, _exptime in conn.execute(sql):
value = _value
if encrypted_value[:3] == b'v10':
encrypted_value = encrypted_value[3:] # Trim prefix 'v10'
value = cipher.decrypt(encrypted_value)
value = value.decode()
exptime = max(_exptime, 0)
secure = str(bool(is_secure)).upper()
print(host_key, 'TRUE', path, secure, exptime, name, value, sep='\t')
conn.rollback()
#!/bin/bash
set -eu
DIR=$(dirname $0)
COOKIE=$DIR/cookie.txt
python3 "$DIR/chrome_cookies_decrypt.py" > "$COOKIE"
head "$COOKIE"
echo update...done
@sagiwei
Copy link

sagiwei commented Jun 1, 2023

Awesome! Help me so much, now I convert it to a swift version which using in a Raycast extension.
chrome_cookies_decrypt.swift

@Ret2lib
Copy link

Ret2lib commented Nov 20, 2024

Recent changes to how chrome saves cookies.. They added 32bytes of random data that can't be utf-8 decoded.

import os
import sqlite3
import keyring
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2


class AESCipher:

    def __init__(self, key):
        self.key = key

    def decrypt(self, text):
        cipher = AES.new(self.key, AES.MODE_CBC, IV=(b' ' * 16))
        return self._unpad(cipher.decrypt(text))

    def _unpad(self, s):
        padding_length = s[-1]
        return s[:-padding_length]


passwd = keyring.get_password('Chrome Safe Storage', 'Chrome')
passwd = passwd.encode()

salt = b'saltysalt'
length = 16
iterations = 1003
key = PBKDF2(passwd, salt, length, iterations)

cipher = AESCipher(key)

cookie_file = os.path.expanduser(
    '~/Library/Application Support/Google/Chrome/Default/Cookies')

conn = sqlite3.connect(cookie_file)
conn.text_factory = bytes
sql = 'SELECT host_key,path,is_secure,name,value,encrypted_value,((expires_utc/1000000)-11644473600) FROM cookies'

if __name__ == '__main__':

    for host_key, path, is_secure, name, _value, encrypted_value, _exptime in conn.execute(sql):

        value = _value
        if encrypted_value[:3] == b'v10':
            encrypted_value = encrypted_value[3:]
            value = cipher.decrypt(encrypted_value)
            value = value[32:].decode('utf-8')

        exptime = max(_exptime, 0)
        secure = str(bool(is_secure)).upper()

        print(host_key, 'TRUE', path, secure, exptime, name, value, sep='\t')

    conn.rollback()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment