2014-04-18 10 views
12

Sto tentando di utilizzare i cookie di Chromium in Python, perché Chromium crittografa i suoi cookie utilizzando AES (con CBC) Ho bisogno di invertire questo.Decrittografia dei cookie di cromo

posso recuperare la chiave AES dal portachiavi di OS X (è memorizzato 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())' 

Ecco il codice che ho, tutto quello che mi manca è decifrare i cookie:

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 

ho provato un sacco di cose con pyCrypto's AES module ma:

  1. non ho alcun vettore di inizializzazione (IV)
  2. enc_val non è un multiplo di 16 di lunghezza

Ecco alcuni link che sembrano utili:

Potete aiutarmi a capirlo?

risposta

17

Sei sulla strada giusta! Ci ho lavorato per alcuni giorni e finalmente l'ho capito. (. Molte grazie per il PO per i collegamenti utili alla fonte di cromo)

ho messo un post con un po 'più in dettaglio e uno script di lavoro, ma qui è l'idea di base:

#! /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)) 
+1

Impressionante! Ho solo riscritto clean per lavorare con Python 2: 'def clean (x): return x [: - ord (x [-1])]' ([PEP8 dice no f = lambda] (http: //legacy.python. org/dev/peps/pep-0008/# programming-recommendations);)) – ThinkChaos

+0

Dolce. Modificato per riflettere questo. – n8henrie

+0

Risposta stupenda, grazie – jsj

0

@n8henrie's risposta ha funzionato per me, ma nel mio ambiente con Ubuntu, Chrome non usa più 'peanuts' come password, ma è memorizzato in gnome keyring. Sono riuscito a ottenere la password per la decodifica usando il pacchetto secretstorage in questo modo:

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!') 
+1

Corretto - se qualcuno è interessato, questo problema di portachiavi di Ubuntu/Gnome è stato discusso un po '[in questo numero] (https://github.com/n8henrie/pycookiecheat/issues/12) nel mio pacchetto pycookiecheat, che ha implementato una soluzione simile di conseguenza. – n8henrie