Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decrypting Chromium cookies

I'm trying to use Chromium cookies in Python, because Chromium encrypts its cookies using AES (with CBC) I need to reverse this.

I can recover the AES key from OS X's Keychain (it's stored in Base 64):

security find-generic-password -w -a Chrome -s Chrome Safe Storage
# From Python:
python -c 'from subprocess import PIPE, Popen; print(Popen(['security', 'find-generic-password', '-w', '-a', 'Chrome', '-s', 'Chrome Safe Storage'], stdout=PIPE).stdout.read().strip())'

Here's the code I have, all I'm missing is decrypting the cookies:

from subprocess import PIPE, Popen
from sqlite3 import dbapi2

def get_encryption_key():
  cmd = ['security', 'find-generic-password', '-w', '-a', 'Chrome', '-s', 'Chrome Safe Storage']
  return Popen(cmd, stdout=PIPE).stdout.read().strip().decode('base-64')

def get_cookies(database):
  key = get_encryption_key()
  with dbapi2.connect(database) as conn:
    conn.rollback()
    rows = conn.cursor().execute('SELECT name, encrypted_value FROM cookies WHERE host_key like ".example.com"')

  cookies = {}
  for name, enc_val in rows:
    val = decrypt(enc_val, key) # magic missing
    cookies[name] = val

  return cookies

I tried a bunch of things with pyCrypto's AES module but:

  1. I have no Initialization Vector (IV)
  2. enc_val is not a multiple of 16 in length

Here are some links that seem useful:

  • the commit that started it all
  • components/encryptor/keychain_password_mac.mm
  • AES key generation (not used in OS X but could help someone else)
  • cookie insertion function

Can you help me figure this out?

like image 860
ThinkChaos Avatar asked Apr 18 '14 11:04

ThinkChaos


People also ask

How do you decrypt cookies?

Decrypt the cookie and check the digest: Decrypt de key of the cookie: do Base64 decoding, then decrypt it using your institution's private RSA key. Decrypt the data using the decrypted AES key. Check the digest using secutix public certificate. The following example in java will show you how to proceed.

Are Chrome cookies encrypted?

A recent change to Chromium has the consequence that all desktop versions of Google Chrome will encrypt stored cookies in the near future (while Chrome OS and Android use fully encrypted profiles already). This only affects new cookies saved to the system after Chrome is updated with the new implementation.


2 Answers

You're on the right track! I've been working on this for a few days and finally figured it out. (Many thanks to the OP for the helpful links to the Chromium source.)

I've put up a post with a little more detail and a working script, but here is the basic idea:

#! /usr/bin/env python3

from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2

# Function to get rid of padding
def clean(x): 
    return x[:-x[-1]].decode('utf8')

# replace with your encrypted_value from sqlite3
encrypted_value = ENCRYPTED_VALUE 

# Trim off the 'v10' that Chrome/ium prepends
encrypted_value = encrypted_value[3:]

# Default values used by both Chrome and Chromium in OSX and Linux
salt = b'saltysalt'
iv = b' ' * 16
length = 16

# On Mac, replace MY_PASS with your password from Keychain
# On Linux, replace MY_PASS with 'peanuts'
my_pass = MY_PASS
my_pass = my_pass.encode('utf8')

# 1003 on Mac, 1 on Linux
iterations = 1003

key = PBKDF2(my_pass, salt, length, iterations)
cipher = AES.new(key, AES.MODE_CBC, IV=iv)

decrypted = cipher.decrypt(encrypted_value)
print(clean(decrypted))
like image 88
n8henrie Avatar answered Sep 23 '22 10:09

n8henrie


@n8henrie's answer worked for me, but in my environment with Ubuntu, Chrome no longer use 'peanuts' as password, instead it's stored in gnome keyring. I managed to get the password for decryption using secretstorage package like this:

import secretstorage

bus = secretstorage.dbus_init()
collection = secretstorage.get_default_collection(bus)
for item in collection.get_all_items():
    if item.get_label() == 'Chrome Safe Storage':
        MY_PASS = item.get_secret()
        break
else:
    raise Exception('Chrome password not found!')
like image 25
Ski Avatar answered Sep 20 '22 10:09

Ski