Encrypted cookies in Chrome

前端 未结 6 1990
挽巷
挽巷 2020-11-27 15:36

I am currently working on a C# forms application that needs to access a specific cookie on my computer, which I can do perfectly fine. Here\'s the issue:

Google stor

相关标签:
6条回答
  • 2020-11-27 16:01

    So I wanted to do this without writing to a tempfile every time but also without implementing a separate class as per jasper's solution. Like jasper, I found it easier and quicker to access the System.Data.SQLite.dll available here. It's not as elegant as a separate class, but it's what worked best for me:

    Add-Type -AssemblyName System.Security
    Add-Type -Path 'C:\Program Files\System.Data.SQLite\2015\bin\x64\System.Data.SQLite.dll'
    
    Function Get-Last-Cookie {
        Param(
            [Parameter(Mandatory=$True)] $valueName,
            [Parameter(Mandatory=$True)] $hostKey,
            [Parameter(Mandatory=$True)] $dbDataSource
        )
    
        $conn = New-Object -TypeName System.Data.SQLite.SQLiteConnection
        $conn.ConnectionString = "Data Source=$dbDataSource"
        $conn.Open()
    
        $command = $conn.CreateCommand()
        $query = "SELECT encrypted_value FROM cookies WHERE name='$valueName' `
                  AND host_key='$hostKey' ORDER BY creation_utc DESC LIMIT 1"
        $command.CommandText = $query
        $adapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter $command
        $dataset = New-Object System.Data.DataSet
        [void]$adapter.Fill($dataset)
        $command.Dispose();
        $conn.Close();
        $cookieAsEncryptedBytes = $dataset.Tables[0].Rows[0].ItemArray[0]
        $cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
        return [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
    }
    
    $localAppDataPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)
    $cookieDbPath = 'Google\Chrome\User Data\Default\Cookies'
    $dbDataSource = Join-Path -Path $localAppDataPath -ChildPath $cookieDbPath
    
    $plainCookie = Get-Last-Cookie 'acct' '.stackoverflow.com' $dbDataSource
    Write-Host $plainCookie
    

    I also found the Add-SqliteAssembly function by halr9000 to be very helpful when it came time to schedule my script in the windows task scheduler and realized that the task scheduler runs the x86 version of PowerShell and thus SQLite rather than the x64 I was using in the console.

    0 讨论(0)
  • 2020-11-27 16:02
        # this powershell scripts exports your cookies to a format curl and wget understand
        # Obs ! Each profile has its own cookes file , replace me (ysg ;o) with your win usr name
        # aka wget -x --load-cookies cookies.txt http://stackoverflow.com/questions/22532870/encrypted-cookies-in-chrome
    
        $cookieLocation = 'C:\Users\ysg\AppData\Local\Google\Chrome\User Data\Profile 1\Cookies'
        $curl_cookies_file="C:\var\ygeo.reports.app.futurice.com.cookies.doc-pub-host.txt"
        $tempFileName1 = [System.IO.Path]::GetTempFileName()
        $tempFileName2 = [System.IO.Path]::GetTempFileName()
    
        # adjust your filter in the where clause ...
        "select writefile('$tempFileName1', encrypted_value) from cookies where host_key = '.futurice.com' ;" | sqlite3.exe "$cookieLocation"
        $cookieAsEncryptedBytes = Get-Content -Encoding Byte "$tempFileName1"
        Remove-Item "$tempFileName1"
    
    
        Add-Type -AssemblyName System.Security
        $cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
        $cookie = [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
        $unquoted_cookie=$cookie -replace '"', ""
    
        # adjust your filter in the where clause ...
        "
        select  
            host_key
         , CASE WHEN httponly=0 THEN 'FALSE' ELSE 'TRUE' END
         , path
         , CASE WHEN secure=0 THEN 'FALSE' ELSE 'TRUE' END
         , expires_utc
         , name 
         , '$unquoted_cookie'
        from cookies where host_key = '.futurice.com' ;" | sqlite3.exe -separator " " "$cookieLocation" > $curl_cookies_file
    
        Get-ChildItem *.txt | ForEach-Object { (Get-Content $_) | Out-File -Encoding ASCII $_ }
    
        # check the meta data table
        #"PRAGMA table_info([cookies]);" | sqlite3.exe "$cookieLocation"
    
        # src: https://github.com/daftano/cookies.txt/blob/master/src/popup.js
        #content += escapeForPre(cookie.domain);
        #content += "\t";
        #content += escapeForPre((!cookie.hostOnly).toString().toUpperCase());
        #content += "\t";     
        #content += escapeForPre(cookie.path); 
        #content += "\t";     
        #content += escapeForPre(cookie.secure.toString().toUpperCase());
        #content += "\t";     
        #content += escapeForPre(cookie.expirationDate ? Math.round(cookie.expirationDate) : "0");
        #content += "\t";     
        #content += escapeForPre(cookie.name);
        #content += "\t";     
        #content += escapeForPre(cookie.value);
        #content += "\n";
        #
        #0|creation_utc|INTEGER|1||1
        #1|host_key|TEXT|1||0
        #2|name|TEXT|1||0
        #3|value|TEXT|1||0
        #4|path|TEXT|1||0
        #5|expires_utc|INTEGER|1||0
        #6|secure|INTEGER|1||0
        #7|httponly|INTEGER|1||0
        #8|last_access_utc|INTEGER|1||0
        #9|has_expires|INTEGER|1|1|0
        #10|persistent|INTEGER|1|1|0
        #11|priority|INTEGER|1|1|0
        #12|encrypted_value|BLOB|0|''|0
        #13|firstpartyonly|INTEGER|1|0|0
    
    0 讨论(0)
  • 2020-11-27 16:07

    Like Jasper's answer, in a PowerShell script (of course, customize the SQL query to your needs, and the path to your cookies location):

    $cookieLocation = 'C:\Users\John\AppData\Local\Google\Chrome\User Data\Default\cookies'
    $tempFileName = [System.IO.Path]::GetTempFileName()
    
    "select writefile('$tempFileName', encrypted_value) from cookies where host_key = 'localhost' and path = '/api' and name = 'sessionId';" | sqlite3.exe "$cookieLocation"
    $cookieAsEncryptedBytes = Get-Content -Encoding Byte "$tempFileName"
    Remove-Item "$tempFileName"
    
    Add-Type -AssemblyName System.Security
    $cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
    $cookie = [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
    $cookie
    
    0 讨论(0)
  • 2020-11-27 16:07

    Just set "value" to the cookie you want, "encrypted_value" to NULL and "priority" to 0

    0 讨论(0)
  • 2020-11-27 16:11

    I've run into this same problem, and the code below provides a working example for anyone who is interested. All credit to Scherling, as the DPAPI was spot on.

    public class ChromeCookieReader
    {
        public IEnumerable<Tuple<string,string>> ReadCookies(string hostName)
        {
            if (hostName == null) throw new ArgumentNullException("hostName");
    
            var dbPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Google\Chrome\User Data\Default\Cookies";
            if (!System.IO.File.Exists(dbPath)) throw new System.IO.FileNotFoundException("Cant find cookie store",dbPath); // race condition, but i'll risk it
    
            var connectionString = "Data Source=" + dbPath + ";pooling=false";
    
            using (var conn = new System.Data.SQLite.SQLiteConnection(connectionString))
            using (var cmd = conn.CreateCommand())
            {
                var prm = cmd.CreateParameter();
                prm.ParameterName = "hostName";
                prm.Value = hostName;
                cmd.Parameters.Add(prm);
    
                cmd.CommandText = "SELECT name,encrypted_value FROM cookies WHERE host_key = @hostName";
    
                conn.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var encryptedData = (byte[]) reader[1];
                        var decodedData = System.Security.Cryptography.ProtectedData.Unprotect(encryptedData, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);
                        var plainText = Encoding.ASCII.GetString(decodedData); // Looks like ASCII
    
                        yield return Tuple.Create(reader.GetString(0), plainText);
                    }
                }
                conn.Close();
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 16:13

    Alright, so in case anyone is interested, I found a solution to this problem after alot of trial, error and googling.

    Google Chrome cookies DB has 2 columns for storing values: "value" and "encrypted_value", the latter being used when the cookie stored was requested to be encrypted - often the case with certain confidential information and long-time session keys.

    After figuring this out, I then needed to find a way to access this key, stored as a Blob value. I found several guides on how to do this, but the one that ended up paying of was: http://www.codeproject.com/Questions/56109/Reading-BLOB-in-Sqlite-using-C-NET-CF-PPC

    Simply reading the value is not enough, as it is encrypted. - Google Chrome uses triple DES encryption with the current users password as seed on windows machines. In order to decrypt this in C#, one should use Windows Data Protection API (DPAPI), there are a few guides out there on how to make use of it.

    0 讨论(0)
提交回复
热议问题