それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Chrome(OSX)のパスワード・クッキーを取り出すコマンド作った

Mac OSX のChromeのパスワードを取り出すツールを書いた。

takuya/chrome-storage · GitHub

なぜ書いたのか

OSXChromeが、Keychains.app に同期しなくなったので、インポートするために仕方なく書きました。

いままではKeychainを見ればパスワードを回収できたのですが、OperaSafariFirefoxChromeがそれぞれ別管理になって、別々にアカウント同期でパスワードを持っていくのですが、どれが新しくてドレが古いか全くわからなくなりそうでした。

Chromeの管理からパスワード取り出せば良いのですが、chrome://settings/passwords のパスワードチェックがめんどくさい。ちょっと視認性の悪いUIですよね。

いままではローカルKeychainにパスワードつくってiCloudに移動すればよかったのに・・・Windowsの悪夢に逆戻りだ・・・

Opera/chrome のクッキーとパスワードのデコード

Chromium のパスワードは $PROFILE_PATH/Login Dataのファイルに保存されています。ファイルはSqlite3のデータベースになっています。そのファイルの中身でパスワードは暗号化されて保存されています。

暗号化されたパスワードは、Keychain.app にあるsafe storageに保存された文字列で復号化出来ます。

ダウンロード先

github.com

safe storage が幾つかある。

Opera(stable/beta) とChromeがそれぞれ使っています。

ここに保存されたパスフレーズでブラウザ中の暗号化データをデコード出来るようになっています。

f:id:takuya_1st:20151216034018p:plain:w600

暗号化・復号化処理も含めたブラウザのソースコードは公開されてるので、わたしたちはブラウザから平文でパスワードを得ることが可能になります。これからも安心して使える。ソース公開って素晴らしい

Firefoxはどうしてるんだろう・・・

パスワード・クッキーのデータベースの構造

パスワードとクッキーのデータベースは、次の通りのテーブル構造に格納されていました。

パスワードテーブル
CREATE TABLE   "logins"     (
    origin_url  VARCHAR    NOT   NULL    ,
        action_url  VARCHAR    ,
        username_element    VARCHAR    ,
        username_value  VARCHAR    ,
        password_element    VARCHAR    ,
        password_value  BLOB    ,
        submit_element  VARCHAR    ,
        signon_realm    VARCHAR    NOT   NULL    ,
    ssl_valid   INTEGER    NOT   NULL    ,
    preferred   INTEGER    NOT   NULL    ,
    date_created    INTEGER    NOT   NULL    ,
    blacklisted_by_user INTEGER    NOT   NULL    ,
    scheme  INTEGER    NOT   NULL    ,
    password_type   INTEGER    ,
    possible_usernames  BLOB    ,
    times_used  INTEGER    ,
    form_data   BLOB    ,
    date_synced INTEGER    ,
    display_name    VARCHAR    ,
    icon_url    VARCHAR    ,
    federation_url  VARCHAR    ,
    skip_zero_click INTEGER    ,
    generation_upload_status    INTEGER    ,
    UNIQUE      (
    origin_url  ,
        username_element    ,
        username_value  ,
        password_element    ,
        signon_realm    )
        )
        ;
クッキーテーブル
CREATE TABLE   cookies     (
    creation_utc    INTEGER    NOT   NULL    UNIQUE  PRIMARY KEY ,
    host_key    TEXT    NOT   NULL    ,
    name    TEXT    NOT   NULL    ,
    value   TEXT    NOT   NULL    ,
    path    TEXT    NOT   NULL    ,
    expires_utc INTEGER    NOT   NULL    ,
    secure  INTEGER    NOT   NULL    ,
    httponly    INTEGER    NOT   NULL    ,
    last_access_utc INTEGER    NOT   NULL    ,
        has_expires INTEGER    NOT   NULL    DEFAULT 1  ,
        persistent  INTEGER    NOT   NULL    DEFAULT 1  ,
    priority    INTEGER    NOT   NULL    DEFAULT 1  ,
    encrypted_value BLOB    DEFAULT '' ,
    firstpartyonly  INTEGER    NOT   NULL    DEFAULT 0  )
        ;

データベースからデータを取り出して、復号化

復号化はそんなに難しいものではなく、WEBを探したら色々出てきます。WindowsWin32を使っていて、linux/osxはキーチェンに保存したパスフレーズとhmacを使ったOpensslを使っているようだ

次の例は、ruby で復号化を試みた箇所です。 引数 passの部分は、Keychainから拾ってきます。

    def decrypt(encrypted_value, pass ) 
      iter = 1003
      key_len = 16
      salt = "saltysalt"
      iv = " " * 16

      return if encrypted_value.size < 3

      key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)

      cipher = OpenSSL::Cipher::AES.new(128,:CBC)
      cipher.decrypt
      cipher.iv = iv 
      cipher.key = key

      data = encrypted_value
      data = data[3,data.size]

      return cipher.update(data) + cipher.final
    end

取り出したID/PASSはKeychainに

security コマンド を使うことで、パスワードをKeychainに書き込むことが出来ます

 security add-internet-password -a ユーザー名 -s サーバー -w パス   -p 対象のフルURL  -U

これで、しばらくは生き延びられそうです。

関連記事

ChromeのCookieをプログラムから使う - それマグで!

chrome のCookieを取り出す。(暗号化Cookieの複合化でデコード済テキストを取り出す) - それマグで!

MechanizeでChromeのCookieを扱って面倒なログインを飛ばす - それマグで!

httpOnlyなCookieとは? - それマグで!

Chrome のパスワードがOSX Keychains に保存・同期しなくなった - それマグで!