Chrome

Let us place all of our trust in a password manager. - by hadrian3689


A solution without being reliant on a Windows VM.

Analyzing The Contents of PCAP-NG

When looking through the PCAP-NG file using Wireshark, the exfiltration of data via SMB is very noticeable. We often see the transfer of transfer.exe. To get an overview of what has been successfully transferred, we use the Wireshark feature Export via File → Export Objects → SMB and see all successful transfers.

In addition to transfer.exe, encrypted_files stands out with a size of 75MB. This could be interesting for the course of the challenge and could contain important information.

We export them to our system to analyze them further.

The file encrypted_files seems to be really encrypted, but the methods and keys used are unknown at this point. Let's take a look at the transfer.exe. When executing the file with the help of Wine, we see that it requires a specific file. A zip file is located at C:\Users\hadri\Downloads\files.zip.

We create an empty file with this name and execute transfer.exe. The encrypted file is then created in the same folder in which transfer.exe is located. Interesting; this could be our clue to decrypt the content of encrypted_files. The encryption used, and the key, could be extracted from the executable.

We see that it is a .NET assembly. It is possible to decompile and get the information we need via Ghirda, but I was not able to do so. Since it is a .NET binary we can make use of decompilers specific fot .NET binaries like dnSPY.exem, which allow us to do this very easily

It is probably possible to use dnSpy.exe via Wine, but this did not work properly on my Kali VM. If you still want to try it, you can do this as follows: WINEPREFIX=$HOME/.<INSERT YOUR PREFIX> wine dnSpy.exe. The executable can be obtained from the following resource:

Decompilation and Analysis

There is an alternative to running dnSpy on a Windows VM.

We can use the plugin ILSpy which is not only available on Visual Studio but also on Visual Studio Code to decompile .NET binaries.

If you have not setup Visual Studio Code yet checkout the following resource:

We are using the ILSpy extension on VSCode to decompile the binary:

The ILSpy plugin can be easily installed via the marketplace.

After having the plugin installed hit CTRL+SHIFT+P and enter ILSpy: Pick assembly from file system to pick the transfer.exe.

After that reach out the the Main()-function to see what is happening.

We can determine that AES was used to encrypt the zip file, and the key and IV can be extracted. We can also conclude that the CBC mode is used by the use of an IV and not by setting an Mode.

The Aes.Create() method is called to create an instance of the AES algorithm. By default, if no mode is specified, AES operates in ECB mode. However, in this code, after creating the AES instance, the initialization vector (IV) is explicitly set using the line aes.IV = bytes2;.

To undo the process of encryption, we can write a small Python script ourselves or generate it from ChatGPT and set key, IV and modes. After opening the script, we should have a zip file again, which we can now unpack and inspect.

decrypt.py
from Crypto.Cipher import AES
import os

def decrypt_file(input_file, output_file, key, iv):
    chunk_size = 64 * 1024
    aes = AES.new(key, AES.MODE_CBC, iv)
    with open(input_file, 'rb') as in_file:
        with open(output_file, 'wb') as out_file:
            while True:
                chunk = in_file.read(chunk_size)
                if len(chunk) == 0:
                    break
                out_file.write(aes.decrypt(chunk))

def main():
    key = b'REDACTED'
    iv = b'REDACTED'
    encrypted_file = "encrypted_files"
    decrypted_file = "decrypted_files.zip"
    decrypt_file(encrypted_file, decrypted_file, key, iv)
    print("File decrypted and saved successfully.")

if __name__ == "__main__":
    main()

Inspect Decrypted ZIP File

The zip file contains the AppData folder of a Windows user. Under AppData/Local/Google/Chrome/ we find the user data for Google Chrome. Our current goal, as the title of the challenge suggests.

The Login Data of Google Chrome is a local SQLite database that typically includes usernames, passwords, and possibly other authentication information that users have saved or allowed Chrome to remember for various websites and services.

Since the challenge for websites and passwords asks for indications of a password manager, we will investigate this further here.

We can use the command line or a tool of our choice to open up the database. We select the logins table and see two entries, storing encrypted passwords for two sites. At this point, we could defang the URLs using CyberChef and provide the answer to tasks two and four. But we continue. We are not finished here yet; 'unfortunately', the passwords are encrypted.

Retrieving Credentials in Chrome Password Manager

To gain access to Chrome's password manager, we follow the steps in the following blog post. But instead of making use of Mimikatz, we rely on tools to stay on our beloved Unix system. In addition, the key used to encrypt the entries in Login Data is protected by a users' password which we first have to retrieve.

The credentials at Login Data are encrypted using the AES algorithm, and the key used is encrypted with the Windows Data Protection API (DPAPI). DPAPI is primarily used to encrypt and decrypt data, protecting sensitive information such as passwords, keys, and other confidential data.

The passwords in AppData/Local/Google/Chrome/User Date/Default/Login Data are encrypted with a key stored in the AppData/Local/Google/Chrome/User Data/Local State file.

This Local State Key is encrypted with DPAPI using a master key. This master key is also protected by the users' password, so we have to retrieve it first.

Steps we take now:

  1. Get Users' Credentials

  2. Get Master Key in AppData\Roaming\Microsoft\Protect<SID>

  3. Decode and Decrypt the encrypted_key stored in User User Data/Local State using the Master Key

  4. Decrypt the passwords in Login User Data/Default/LoginData using the Local State Key

Used Tools

We use dpapi.py to retrieve the master key and avoid using Mimikatz.

We use the Windows DPAPI-NG lab to decrypt the blob instead of using Mimikatz.

We use the dcp.py tool by palmenas who originally wrote the blog post Forensic Recovery of Chrome Based Browser Passwords, to retrieve the entries of logins using the decrypted Data/Local State key.

Credentials Of The Windows User Account

Fortunately, we have the entire AppData folder of the user. In AppData\Roaming\Microsoft\Protect<SID> we find the user's master key file, which contains the encrypted user password. The SID is the security identifier of the user.

We create a hash of the masterkey file using DPAPImk2john.

┌──(0xb0b㉿kali)-[~/…/Roaming/Microsoft/Protect/S-1-5-21-3854677062-280096443-3674533662-1001]
└─$ python /usr/share/john/DPAPImk2john.py --sid="S-1-5-21-3854677062-280096443-3674533662-1001" --masterkey="8c6b6187-8eaa-48bd-be16-98212a441580" --context="local" > hash.txt

And use john to crack the hash. We have the users password.

This answers the first question of the challenge.

Retrieve The Master Key

Next, we have to extract the masterkey itself; for this, we use dpapi.py, as already mentioned. We enter the location of the masterkey, the SID, add the user password, and receive the decrypted masterkey. To not spoil too much, a lot is blurred. But the key ends with 9840, and the preceding 0x is not to be used.

┌──(0xb0b㉿kali)-[~/Documents/tryhackme/chrome/decrypted_files]
└─$ dpapi.py masterkey -file "AppData/Roaming/Microsoft/Protect/S-1-5-21-3854677062-280096443-3674533662-1001/8c6b6187-8eaa-48bd-be16-98212a441580" -sid S-1-5-21-3854677062-280096443-3674533662-1001 -password REDACTED

Decode the Encrypted Key of Local State

We now have the master key; now we can decrypt the key from AppData/Local/Google/Chrome/User Data/Local State, but we have to bring it back to its original binary form as an intermediate step. For this, we could use CyberChef or this script and storing the content to enc_key.dat.

decode-encrypted_key.py
import json
import base64

fh = open('decrypted_files/AppData/Local/Google/Chrome/User Data/Local State', 'rb')
encrypted_key = json.load(fh)

encrypted_key = encrypted_key['os_crypt']['encrypted_key']

decoded_key = base64.b64decode(encrypted_key)

open("enc_key.dat",'wb').write(decoded_key[5:])

Decrypt the Encrypted Key of Local State

Via blobdec-with-masterkey.py, we decrypt the decoded key using the encrypted master key. We get two outputs in different formats and use the first one. The decrypted key ends with 192c.

blobdec-with-masterkey.py --masterkey REDACTED-9840 enc_key.dat

Retrieve the Passwords in Login Data

With the decrypted Local State key, we can use the script from palmenas to retrieve the stored entries, and we are able to answer all remaining questions.

┌──(0xb0b㉿kali)-[~/Documents/tryhackme/chrome/dcp]
└─$ python dcp.py -S 'REDACTED-9840' -P ../decrypted_files/AppData/Local/Google/Chrome/User\ Data/Default/Login\ Data 

Last updated