解密铬饼干

时间:2014-04-18 11:26:02

标签: python c++ google-chrome cookies chromium

我尝试在Python中使用Chromium Cookie,因为Chromium使用AES(使用CBC)对其Cookie进行加密,我需要将其反转。

我可以从OS X的Keychain中恢复AES密钥(它存储在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())'

以下是我的代码,我所缺少的只是解密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

我用pyCrypto's AES module尝试了很多东西,但是:

  1. 我没有初始化向量(IV)
  2. enc_val不是长度为16的倍数
  3. 以下是一些看似有用的链接:

    你能帮我搞清楚吗?

2 个答案:

答案 0 :(得分:21)

你走在正确的轨道上!我已经为此工作了几天,终于弄明白了。 (非常感谢OP提供了有关Chromium源的有用链接。)

我已经提出了post更多细节和工作脚本,但这是基本想法:

#! /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 :(得分:1)

@n8henrie's回答对我有用,但在我使用Ubuntu的环境中,Chrome不再使用'花生'作为密码,而不是它存储在gnome密钥环中。我设法使用secretstorage包来获取解密密码,如下所示:

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