Hello folks,

Christmas approaches and raises my will to open cookies jars.. :)

If I just modify the path and the table name in this program to access Chrome 107 cookies ('C:/Users/'.$ENV{UserName}.'/AppData/Local/Google/Chrome/User Data/Default/Network/Cookies'; the path and cookies the table) I get a nice screenful of... encrypted cookies.

To offer encrypted cookies is against the Halloween trick or treat policy: is both trick and treat in the same time!

I read here:

> Since Chrome version 80 and higher, cookies are encrypted using AES-256 in GCM mode. The applied key is encrypted using DPAPI. (...) The encrypted key starts with the ASCII encoding of DPAPI (i.e. 0x4450415049) and is Base64 encoded, i.e. the key must first be Base64 decoded and the first 5 bytes must be removed. Afterwards a decryption with win32crypt.CryptUnprotectData is possible. The decryption returns a tuple whose second value contains the decrypted key:

From what I understand there is key and this key is used to enrypt the encrypted_value inside the cookies DB. Too much for me..

So again on metacpan for HTTP::Cookies::Chrome that installs fine under windows. The load_cookies.t sounds promising but fails, because guess_password method is unimplemented for Windows. Meh!

This perl gist (probably by PerlRob)

#!/usr/bin/perl -w use File::Copy qw(copy); use DBI; use Win32::API; use strict; use warnings; print ("Decrypting cookies...\n") && &fix_cookies && print ("Cookies d +ecrypted!\n"); sub fix_cookies { #Chrome has been encrypting cookie values since Chrome..33? #We need to decrypt the value before we can use it. my $chrome_cookie_file = 'C:/Users/'.$ENV{"USERNAME"}.'/AppData/Lo +cal/Google/Chrome/User Data/Default/Cookies'; copy($chrome_cookie_file, 'Cookies') || die "Failed to move files: + $!";; my $dbc = DBI->connect("dbi:SQLite:dbname=Cookies", '', '', { Rais +eError => 1, AutoCommit => 0}); my @rows = @{$dbc->selectall_arrayref("SELECT host_key, name, valu +e, encrypted_value FROM cookies")}; foreach my $row (@rows){ my ($host_key, $name, $value, $encrypted_value) = @{$row}; my $new_value = decryptData($encrypted_value) || $value || '0' +; #This is optional, but it allows us to use any session cookies + that may exist at the time of running this. #This is assuming that you will be generating a new decrypted +session file whenever you run your script. my $sth = $dbc->prepare(qq{ UPDATE cookies SET value = ?, has_expires = 1, expires_utc + = 99999999999999999, is_persistent = 1 WHERE host_key = ? AND name = ? }); $sth->execute($new_value, $host_key, $name); } $dbc->commit(); #SQLite is slow at excuting one row at a time. SEE +: http://stackoverflow.com/a/8882184 $dbc->disconnect(); } sub decryptData { #Cleaned up version of http://www.perlmonks.org/?node_id=776481 my $encryptedData = shift; if($encryptedData eq ''){ return undef; } #avoid errors... my $pDataIn = pack('LL', length($encryptedData)+1, unpack('L!', pa +ck('P', $encryptedData))); my $DataOut; my $pDataOut = pack('LL', 0, 0); my $CryptUnprotectData = Win32::API->new('Crypt32', 'CryptUnprotec +tData', ['P', 'P', 'P', 'P', 'P', 'N', 'P'], 'N'); if($CryptUnprotectData->Call($pDataIn, pack('L', 0), 0, pack('L', +0), pack('L4', 16, 0, 0, unpack('L!', pack('P', 0))), 0, $pDataOut)){ my($len, $ptr) = unpack('LL', $pDataOut); $DataOut = unpack('P'.$len, pack('L!', $ptr)); return $DataOut; }else{ return undef; } }

seems to be the solution, calling the native Windows CryptUnprotectData API but fails with Win32::API::Call: parameter 7 had a buffer overflow

Porting to Perl the code presented here or here and then patching the HTTP::Cookies::Chrome module?

Why this? I'm not so gluttonous, but I suppose that accessing a real cookie is key point in web automation: if I'm able to present the right session cookie my program is me.

Thanks for reading!

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

In reply to Access and decrypt Chrome cookies on Windows by Discipulus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.