4

I'm trying to read the contents of a cookie (to use for authentication in a script), but the value is stored as some sort of encrypted value in the chrome sqlite database. Is there any way to decrypt this using powershell?

Right now I can read the value out of the database using a script like this:

[string]$sqlite_library_path = "C:\Path\To\System.Data.SQLite.dll"
[string]$db_data_source = "C:\Users\$env:USERNAME\AppData\Local\Google\Chrome\User Data\Default\Cookies"
[string]$db_query = "SELECT * FROM cookies WHERE name='cookiename' AND host_key='servername'"

[void][System.Reflection.Assembly]::LoadFrom($sqlite_library_path)

$db_dataset = New-Object System.Data.DataSet

$db_data_adapter = New-Object System.Data.SQLite.SQLiteDataAdapter($db_query,"Data Source=$db_data_source")
[void]$db_data_adapter.Fill($db_dataset)
$db_dataset.Tables[0].encrypted_value

The problem is that the encryped value that is returned is unusable. How can I convert this into a usable value?

EGr
  • 2,072
  • 10
  • 41
  • 61

2 Answers2

2

Adapted to Powershell from this answer: Encrypted cookies in Chrome

# Load System.Security assembly
Add-Type -AssemblyName System.Security

# Decrypt cookie
$ByteArr = [System.Security.Cryptography.ProtectedData]::Unprotect(
                $db_dataset.Tables[0].encrypted_value,
                $null,
                [System.Security.Cryptography.DataProtectionScope]::CurrentUser
            )

# Convert to string
$DecryptedCookie = [System.Text.Encoding]::ASCII.GetString($ByteArr)

I also advise you to change the way you getting the path to the cookies DB, because it's unreliable. In fact, it doesn't works on my machine, because, I've renamed user, but profile folder still keeps it's old name. Use Environment.GetFolderPath method instead:

# Get Cookies DB path
[string]$db_data_source = Join-Path -Path [Environment]::GetFolderPath('LocalApplicationData') -ChildPath 'Google\Chrome\User Data\Default\Cookies'
Community
  • 1
  • 1
beatcracker
  • 6,714
  • 1
  • 18
  • 41
0

For those who don't have/want a SQLite assembly, you can use the sqlite command.

Here's a working 1-line example for Bash on MSYS2 (spread over multiple lines for readability).

Fill in the '' blanks in the SQL query as needed.

sqlite3 "${LOCALAPPDATA}\\Google\\Chrome\\User Data\\Default\\Cookies" \
    ".mode quote" \
    "SELECT encrypted_value FROM cookies WHERE host_key = '' AND name = '' AND path = '/'"|\
powershell -command 'function main() {
    $newline = [System.Text.Encoding]::ASCII.GetBytes(([char]10).ToString());
    $stdout = [System.Console]::OpenStandardOutput();
    try {
        for ($n = 0; ($s = [System.Console]::In.ReadLine()) -ne $null; ++$n) {
            if ($n) { $stdout.Write($newline, 0, $newline.Length); }
            $s = [System.Text.RegularExpressions.Regex]::Match($s,
                "^X" + [char]39 + "(.*)" + [char]39 + "$").Groups[1].Value;
            $b = [byte[]]::new($s.Length / 2);
            For ($i=0; $i -lt $s.Length; $i += 2) {
                $b[$i / 2] = [System.Convert]::ToByte($s.Substring($i, 2), 16);
            }
            Add-Type -AssemblyName System.Security;
            $output = [System.Security.Cryptography.ProtectedData]::Unprotect($b, $null,
                [System.Security.Cryptography.DataProtectionScope]::CurrentUser);
            $stdout.Write($output, 0, $output.Length);
        }
    } finally {
        $stdout.Close();
    }
}
main'
user541686
  • 205,094
  • 128
  • 528
  • 886