概要
WindowsのChromeは v80以降、ブラウザcookieの暗号化にAESを使用するようになった。
(Linux、 macOSのChromeブラウザのcookieについてはここでは触れない。以下「cookie」は、Windows用 Chromeブラウザのcookieを指すものとする)
以前は、DPAPI Windows API(crypt32.dllのCryptUnprotectData)を使用して暗号化されていたが、新方式で暗号化されたcookieは旧方式では復号できない。
Windows Chromeのcookieファイルの中身を直接読み取ってWebサービスにログインするようなアプリは、今回の変更の影響を受けている。(例:ニコ生コメントビューア)
AESで暗号化されているcookieの復号手順の概要を下記に示す。
Windows ChromeのCookiesファイルの場所
デフォルトでは下記(以前と変わらない)
%userprofile%\AppData\Local\Google\Chrome\User Data\default\Cookies
(プロファイルの移動をしたり、Windowsの再インストールやgoogleアカウントの変更等をした場合は変わる)
AESで暗号化されているcookieの識別
暗号化cookieデータの先頭が「0x01 00 00 00」→ DPAPIで暗号化されたcookie
暗号化cookieデータの先頭が「v10」 → AESで暗号化されたcookie
復号に必要なもの
復号には鍵(key)だけでなく、nonceと呼ばれる値が必要になる。
nonceの位置・長さ
nonceは、各暗号化cookieデータの先頭からプレフィクス3バイト('v10')を除いた4バイト目以降12バイトをそのまま用いる。
encrypted_key(暗号化された鍵)の格納場所
デフォルトでは、keyはエンコード・暗号化されて下記のLocal State
ファイル内に格納されている。
%userprofile%\AppData\Local\Google\Chrome\User Data\Local State
Local Stateの中身はJSONフォーマットになっている。
この中の["os_crypt"]->["encrypted_key"] に暗号化された鍵データが格納されている。
keyの復号
- JSON(Local Stateファイル)から取り出したencrypted_keyの値をBASE64でデコードする。
- デコードしたデータの先頭5バイト(プレフィクス
'DPAPI'
)を除去する。 - 2のデータをさらにDPAPIで復号する。
DPAPIによる復号は旧方式と同じcrypt32.dllのCryptUnprotectDataを用いればよい。
得られたkeyの長さは256bit(32バイト)のはずである。
これで、cookieの復号に必要となるkeyが復号できた。
cookieデータの復号
暗号化されたcookieデータの最初の15バイト('v10'+nonce 12bytes)を除いた部分を、上記で得られたnonceとkeyを用いて256bit AES-GCM で復号する。
さらに、復号されたデータの末尾16バイトを取り除く。
pythonによる実装
https://github.com/taizan-hokuto/chrome_cookie
AES-GCMのためにcryptographyライブラリを使用しています。
cryptographyが入っていない場合は、pip install cryptography
を行ってください。
python 3.7.4
Chrome バージョン: 80.0.3987.87(Official Build) (64 ビット)で動作確認。
参考にしたもの
browsercookiejar (regen100)
https://github.com/regen100/browsercookiejar
AES GCM example in python and go (sumanmukherjee03)
https://gist.github.com/sumanmukherjee03/dd16d6c732a1055b6af97daba484809d
A little tool to play with Windows security (gentilkiwi)
https://github.com/gentilkiwi/mimikatz