26 November 2024
Claudio Contin
Introduction
Last January we released a post on the DPAPI. Since the end of July 2024, Chromium based browsers such as Google Chrome, Microsoft Edge, Brave, etc. have implemented significant changes around the way they handle the encryption of the cookies. In the future, there is also a plan to expand this protection to "passwords, payment data, and other persistent authentication tokens".
Encryption prior to Chrome version 127
Prior to this release, Chromium based browsers used to use a State Key
to encrypt the cookies. The State Key
itself was encrypted with the DPAPI Master Key
of the account running the browser.
In the event of an attacker gaining access to the victim's host, they could have simply decrypted the State Key by operating in the context of the victim and obtain access to their cookies. This is what info stealers, which is malware used to collect sensitive information, used to abuse. With these new changes, info stealers are now moving towards different abuse paths, such as starting the browser with the remote debug interface enabled, or extracting cookies and other secret data from the browser process memory with tools like ChromeKatz.
COM-based IElevator service
The recent changes introduced a privileged COM object that runs with SYSTEM privileges. This component is the one responsible for encryption and decryption of cookies. Let's inspect the Chromium source code to determine how this new Elevation Service
works.
The snippet below has been extracted from the elevator.cc
file of the Chromium project on GitHub (https://github.com/chromium/chromium/blob/225f82f8025e4f93981310fd33daa71dc972bfa9/chrome/elevation_service/elevation_service.cc) and contains the definition of the EncryptData
function as of the time of writing this post.
We can determine from the code that the ProtectionLevel::PROTECTION_MAX
has not been implemented yet. This means that in the future, further checks might be added to the new validation logic of this service. The default protection level is PROTECTION_PATH_VALIDATION
.
The EncryptData
function accepts four parameters, including the plaintext
string that needs encryption. The function obtains the full image path of the caller process. In the case of Chrome, on Windows 10 or 11, the path is: C:\Program Files\Google\Chrome\Application\chrome.exe
. This path is added to the plaintext data to encrypt.
Finally, the function calls the DPAPI CryptProtectData
is performed twice. One in the context of the calling process, which runs in the context of the user, and once in the context of the SYSTEM account. This indicates that by simply having access to the user DPAPI master keys is not sufficient any more, as the data is now also encrypted using the SYSTEM account master keys.
Let's now examine how the decryption of the data is performed, and how the requesting process is validated before the decrypted information is returned back to the calling process.
The following is the content extracted from the same elevator.cc
file mentioned above.
The function takes the encrypted data as one of the parameters, and calls the DPAPI CryptUnprotectData
twice, once using the SYSTEM master keys, and once using the caller process account context (user). As described, the encrypted data also contains the full image path of the process that invoked they COM object interface. This data, together with the caller process information are passed to the ValidateData(process, data, &log_message);
function, which is defined in the caller_validation.cc
file (https://github.com/chromium/chromium/blob/225f82f8025e4f93981310fd33daa71dc972bfa9/chrome/elevation_service/caller_validation.cc). The ValidateData
simply invokes the ValidatePath
function, passing the same arguments.
The snippet below has been extracted from the caller_validation.cc
file of the Chromium project on GitHub and contains the definition of the ValidatePath
function as of the time of writing this post.
The function receives the COM interface caller process information, as well as the original full image path of the process that encrypted the specific data that the COM object has been requested to decrypt. The function then retrieves the full image path of the caller process, and compares it with the full image path of the process that originally requested the encryption. If the two paths match, the function returns S_OK
(success). If not, the functions returns a validation error and logs a Warning event (257) in the Windows Application logs, as shown below.
Conclusion
The analysis clearly shows that having code execution access as the victim on their Windows host is no longer possible to obtain the cleartext version of their browser cookies by simply using the DPAPI user master keys. It is still possible of course to attempt obtaining the cookies via the browser's process memory dump or while injecting malicious code into the browser process, or by restarting the browser process with the remote debugging interface enabled. If an EDR is present on the victim's host, both these alternative options are more likely to trigger alerts.
The image path validation appears to be an effective security in-depth solution implemented by the Chromium developers.
Note that in case local administrator privileges are obtained, it is possible to work around the path restriction. Anything installed under C:\Program Files
is by default not writeable by non-administrator accounts. With administrator access, it is possible to save an executable under the Chrome default installation directory C:\Program Files\Google\Chrome\
and communicate directly with the COM interface. This is exactly what the tool https://github.com/xaitax/Chrome-App-Bound-Encryption-Decryption uses to decrypt the cookies, which was released at the end of October. The executable full image path will match what the COM interface expects as the legitimate path of the caller process.
Chromium developers are also working on a new specification (Device Bound Session Credentials) that is currently being developed. This new specification aims to render cookies stolen on a device unusable on another device, forcing an attacker to operate from the victim's device.