Skip to content

Instantly share code, notes, and snippets.

@sagiwei
Forked from kosh04/.gitignore
Last active October 7, 2024 23:31
Show Gist options
  • Save sagiwei/b3e7fe33f344cbebe2caabf77ff27826 to your computer and use it in GitHub Desktop.
Save sagiwei/b3e7fe33f344cbebe2caabf77ff27826 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()
import Foundation
import SQLite3
import CommonCrypto
import KeychainAccess
import CryptoSwift
func aes256cbcDecrypt(key: Data, data: Data) -> String? {
let keyData = key
let ivData = " ".data(using: .utf8)! // 16 个空格
let dataLength = data.count
let bufferSize = dataLength + kCCBlockSizeAES128
var buffer = [UInt8](repeating: 0, count: bufferSize)
var numBytesDecrypted: size_t = 0
let cryptStatus = keyData.withUnsafeBytes { keyBytes in
ivData.withUnsafeBytes { ivBytes in
data.withUnsafeBytes { dataBytes in
CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding),
keyBytes, keyData.count,
ivBytes,
dataBytes, dataLength,
&buffer, bufferSize,
&numBytesDecrypted)
}
}
}
if cryptStatus == kCCSuccess {
return String(bytes: buffer.prefix(Int(numBytesDecrypted)), encoding: .utf8)
} else {
return nil
}
}
let keychain = Keychain(service: "Chrome Safe Storage")
let passwd = try! keychain.getString("Chrome")
let salt = Data("saltysalt".utf8)
let length = 16
let iterations = 1003
let key = try! PKCS5.PBKDF2(password: Array(passwd!.utf8), salt: salt.bytes, iterations: iterations, keyLength: length, variant: .sha1).calculate()
let cookieFile = FileManager.default
.homeDirectoryForCurrentUser
.appendingPathComponent("Library/Application Support/Google/Chrome/Default/Cookies")
.path
var conn: OpaquePointer?
if sqlite3_open(cookieFile, &conn) != SQLITE_OK {
print("Failed to open database")
}
// NOTE: Chrome uses Win32_FILETIME format
// NOTE: 11644473600 == strftime('%s', '1601-01-01')
let sql = "SELECT host_key, path, is_secure, name, value, encrypted_value, ((expires_utc/1000000)-11644473600) FROM cookies"
var stmt: OpaquePointer?
if sqlite3_prepare_v2(conn, sql, -1, &stmt, nil) != SQLITE_OK {
print("Failed to prepare statement")
}
while sqlite3_step(stmt) == SQLITE_ROW {
let hostKey = String(cString: sqlite3_column_text(stmt, 0))
let path = String(cString: sqlite3_column_text(stmt, 1))
let isSecure = Int(sqlite3_column_int(stmt, 2)) != 0
let name = String(cString: sqlite3_column_text(stmt, 3))
let encryptedValue = sqlite3_column_blob(stmt, 5)
let encryptedValueLength = Int(sqlite3_column_bytes(stmt, 5))
let expiresUtc = sqlite3_column_double(stmt, 6)
var value = String(cString: sqlite3_column_text(stmt, 4))
if let encryptedValue = encryptedValue, encryptedValueLength >= 3,
encryptedValue.load(fromByteOffset: 0, as: UInt8.self) == 118,
encryptedValue.load(fromByteOffset: 1, as: UInt8.self) == 49,
encryptedValue.load(fromByteOffset: 2, as: UInt8.self) == 48 {
let encryptedData = Data(bytes: encryptedValue + 3, count: encryptedValueLength - 3)
let decryptedString = aes256cbcDecrypt(key: Data(key), data: encryptedData)
value = decryptedString ?? ""
}
let exptime = max(Int(expiresUtc), 0)
let secure = isSecure ? "TRUE" : "FALSE"
print("\(hostKey)\t\(secure)\t\(path)\t\(secure)\t\(exptime)\t\(name)\t\(value)")
}
sqlite3_finalize(stmt)
sqlite3_close(conn)
#!/bin/bash
set -eu
DIR=$(dirname $0)
COOKIE=$DIR/cookie.txt
python3 "$DIR/chrome_cookies_decrypt.py" > "$COOKIE"
head "$COOKIE"
echo update...done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment