# Chrome App-Bound Encryption (ABE) - Technical Deep Dive & Research Notes **Project:** [Chrome App-Bound Encryption Decryption](https://github.com/xaitax/Chrome-App-Bound-Encryption-Decryption/) **Author:** Alexander 'xaitax' Hagenah **Last Updated:** 12 May 2025 Based on my project's v0.7.0 analysis, incorporating insights from Google's ABE design documents, public announcements, Chromium source code, and related security research. **Table of Contents** - [1. Introduction: The Evolution of Local Data Protection in Chrome](#1-introduction-the-evolution-of-local-data-protection-in-chrome) - [1.1. Core Tenets of ABE (as per Google's Design)](#11-core-tenets-of-abe-as-per-googles-design) - [2. The ABE Mechanism: A Step-by-Step Breakdown](#2-the-abe-mechanism-a-step-by-step-breakdown) - [3. Circumventing ABE Path Validation: The `chrome-inject` Strategy](#3-circumventing-abe-path-validation-the-chrome-inject-strategy) - [3.1. The Methodology](#31-the-methodology) - [3.2. Operational Context: User-Mode, No Administrative Rights Required](#32-operational-context-user-mode-no-administrative-rights-required) - [4. Dissecting Encrypted Data Structures](#4-dissecting-encrypted-data-structures) - [4.1. `Local State` and the `app_bound_encrypted_key`](#41-local-state-and-the-app_bound_encrypted_key) - [4.2. AES-GCM Blob Format (Cookies, Passwords, Payments, etc.)](#42-aes-gcm-blob-format-cookies-passwords-payments-etc) - [4.3. Cookie Value Specifics (from `encrypted_value` in `Cookies` DB)](#43-cookie-value-specifics-from-encrypted_value-in-cookies-db) - [4.4. Passwords (from `password_value` in `Login Data` DB) & Payment Information](#44-passwords-from-password_value-in-login-data-db--payment-information) - [5. Alternative Decryption Vectors & Chrome's Evolving Defenses](#5-alternative-decryption-vectors--chromes-evolving-defenses) - [5.1. Administrator-Level Decryption (e.g., `runassu/chrome_v20_decryption` PoC)](#51-administrator-level-decryption-eg-runassuchrome_v20_decryption-poc) - [5.2. Remote Debugging Port (`--remote-debugging-port`) and Its Mitigation](#52-remote-debugging-port---remote-debugging-port-and-its-mitigation) - [5.3. Device Bound Session Credentials (DBSC)](#53-device-bound-session-credentials-dbsc) - [6. Key Insights from Google's ABE Design Document & Chromium Source Code](#6-key-insights-from-googles-abe-design-document--chromium-source-code) - [7. Operational Considerations and Limitations of this tool](#7-operational-considerations-and-limitations-of-this-tool) - [7.1. Browser Process Termination (`KillBrowserProcesses`)](#71-browser-process-termination-killbrowserprocesses) - [7.2. Multi-Profile Support](#72-multi-profile-support) - [7.3. Roaming Profiles and Enterprise Environments](#73-roaming-profiles-and-enterprise-environments) - [8. Conclusion and Future Directions for ABE Research](#8-conclusion-and-future-directions-for-abe-research) - [9. References and Further Reading](#9-references-and-further-reading) --- ## 1. Introduction: The Evolution of Local Data Protection in Chrome For years, Chromium-based browsers on Windows relied on the **Data Protection API (DPAPI)** to secure sensitive user data stored locally such as cookies, passwords, payment information, and the like. DPAPI binds data to the logged-in user's credentials, offering a solid baseline against offline attacks (e.g., a stolen hard drive) and unauthorized access by other users on the same machine. However, DPAPI's Achilles' heel has always been its permissiveness within the user's own session: _any application running as the same user, with the same privilege level as Chrome, can invoke `CryptUnprotectData` and decrypt this data._ This vulnerability has been a perennial favorite for infostealer malware. To counter this, Google introduced **App-Bound Encryption (ABE)** in Chrome (publicly announced around version 127, July 2024). ABE is a significant architectural shift designed to dramatically raise the bar for attackers. Its core principle is to ensure that the primary decryption keys for sensitive Chrome data are only accessible to legitimate Chrome processes, thereby mitigating trivial data theft by same-user, same-privilege malware. ### 1.1. Core Tenets of ABE (as per Google's Design) - **Primary Goal:** Prevent an attacker operating with the _same privilege level as Chrome_ from trivially calling DPAPI to decrypt sensitive data. - **Acknowledged Limitations (Non-Goals):** ABE does not aim to prevent attackers with _higher privileges_ (Administrator, SYSTEM, kernel drivers) or those who can successfully _inject code into Chrome_. The official Google design documents explicitly recognize code injection as a potent bypass vector, a technique this project leverages for legitimate research and data recovery demonstrations. - **Underlying Mechanism:** ABE introduces an intermediary COM service (part of Chrome's Elevation Service) that acts as a gatekeeper for the DPAPI-unwrapping of a critical session key. This service verifies the "app identity" of the caller. - **Initial Identity Verification Method:** The first iteration relies on **path validation** of the calling executable. While digital signature validation was considered, path validation was chosen for the initial rollout to "descope the complexity" (as noted in a 2024 update to Google's design document), deemed sufficient against the immediate threat model. Google's conceptual diagram provides a clear overview: ![Google's ABE Diagram](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpjkAClX2VvgsIhLi2zAmvRwVMPEeJqUhqisKHIKxbfGAwh8p8-V7Ixct5azzn_jYfJYo2izWnGcbkVh3cabbCLVQQQsJAJagvFPCFJsx4MibauJqnLVymQYdhdGGc53q3wSJSeTPQ6vyxXosJ-tJRKuaaoV7_J_E2KB9glSZ1m3NSEwEBj-duevgROHlM/s1416/Screenshot%202024-07-26%202.15.06%20PM.png) _(Image: Google's conceptual diagram of App-Bound Encryption, illustrating the privileged service gating key access.)_ ## 2. The ABE Mechanism: A Step-by-Step Breakdown ABE employs a multi-layered strategy for key management and data encryption: 1. **The `app_bound_key` (Session Key):** - A unique 32-byte AES-256 key is the target plaintext that applications like Chrome's `OSCrypt` use. - This key is what this project aims to recover for subsequent data decryption. 2. **Generation of `validation_data` and `app_bound_key` Wrapping (During Encryption by Chrome):** - When Chrome (via `OSCrypt`) needs to protect the `app_bound_key` using ABE, it calls the `IElevator::EncryptData` COM method. - **Caller Validation Data Generation:** Inside `IElevator::EncryptData`, the service first generates `validation_data`. If `ProtectionLevel::PROTECTION_PATH_VALIDATION` is specified, this involves: - Obtaining the calling process's executable path (`GetProcessExecutablePath`). - Normalizing this path using a specific routine (`MaybeTrimProcessPath`), which removes the .exe name, common temporary/application subfolders (like "Application", "Temp", version strings), and standardizes "Program Files (x86)" to "Program Files". This results in a canonical base installation path. - This normalized path string (UTF-8 encoded) becomes the core of the `validation_data`. The `ProtectionLevel` itself is also prepended to this data. - **Payload Construction:** The `validation_data` (with its length) is prepended to the plaintext `app_bound_key` (also with its length). This forms the `data_to_encrypt`. - **User-Context DPAPI Encryption:** This `data_to_encrypt` blob is then encrypted using `CryptProtectData` under the calling user's DPAPI context (achieved via `ScopedClientImpersonation`). - **System-Context DPAPI Encryption (Outer Layer):** The result from the user-context DPAPI encryption is then encrypted _again_ using `CryptProtectData`, this time under the SYSTEM DPAPI context (or the service's own context if not explicitly SYSTEM). This creates a "DPAPI-ception" or layered DPAPI protection. - This doubly DPAPI-wrapped blob is what `IElevator::EncryptData` returns as the `ciphertext` BSTR. 3. **Storage in `Local State`:** - The `ciphertext` BSTR received from `IElevator::EncryptData` is Base64-encoded. - The prefix **`APPB`** (ASCII: `0x41 0x50 0x50 0x42`) is prepended. - This final string is stored in `Local State` as `os_crypt.app_bound_encrypted_key`. 4. **The `IElevator` COM Service (The Gatekeeper for Decryption):** - When Chrome (or this project's injected DLL) needs the plaintext `app_bound_key`: - It instantiates the `IElevator` COM object using browser-specific CLSIDs/IIDs: - **Google Chrome:** CLSID: `{708860E0-F641-4611-8895-7D867DD3675B}`, IID: `{463ABECF-410D-407F-8AF5-0DF35A005CC8}` - **Brave Browser:** CLSID: `{576B31AF-6369-4B6B-8560-E4B203A97A8B}`, IID: `{F396861E-0C8E-4C71-8256-2FAE6D759C9E}` - The `APPB`-prefixed, Base64-encoded string from `Local State` is decoded and the `APPB` prefix stripped. This resulting blob (the doubly DPAPI-wrapped key) is passed to `IElevator::DecryptData`. 5. **Unwrapping and Path Validation by `IElevator::DecryptData`:** - **System-Context DPAPI Decryption:** The input blob is first decrypted using `CryptUnprotectData` under the SYSTEM DPAPI context. This removes the outer DPAPI layer. - **User-Context DPAPI Decryption:** The intermediate result is then decrypted using `CryptUnprotectData` under the _calling user's_ DPAPI context (via `ScopedClientImpersonation`). This removes the inner DPAPI layer, yielding a plaintext blob. - **Extraction of Validation Data and Plaintext Key:** This plaintext blob is structured as `[validation_data_length][validation_data][app_bound_key_length][app_bound_key]`. The service uses `PopFromStringFront` to extract the original `validation_data` and then the `app_bound_key`. - **Path Validation:** The extracted `validation_data` (containing the original encrypting process's normalized path and `ProtectionLevel`) is then validated against the _current calling process_. The service gets the current caller's path, normalizes it using the same `MaybeTrimProcessPath` logic, and compares it. - If path validation passes, `IElevator::DecryptData` returns the extracted plaintext 32-byte `app_bound_key`. 6. **Data Encryption/Decryption using the `app_bound_key`:** - Chrome's `OSCrypt` (or this project's DLL) then uses this recovered 32-byte AES key with AES-256-GCM to encrypt/decrypt actual user data (cookies, passwords), which are typically prefixed (e.g., `v20`). ## 3. Circumventing ABE Path Validation: The `chrome-inject` Strategy The `chrome_inject.exe` and `chrome_decrypt.dll` tools developed in this project effectively bypass ABE's path validation by orchestrating the sensitive COM calls to `IElevator::DecryptData` to execute _from within the legitimate browser's own process space_. This approach aligns with the "Weaknesses" section of Google's ABE design document (Page 7), which explicitly notes: _"An attacker could inject code into Chrome browser and call the IPC interface."_ This project implements such a technique, not for malicious purposes, but for security research, data recovery exploration, and, for me, as a fascinating practical learning exercise in Windows internals, COM, and process manipulation. ### 3.1. The Methodology - **Injector (`chrome_inject.exe`):** 1. **Target Process Acquisition:** Identifies a running instance of the target Chromium-based browser (Chrome, Edge, Brave). It can also auto-start the browser if specified. 2. **Architectural Consistency:** Critically ensures that the injector and target process architectures align (e.g., x64 injector for x64 Chrome, ARM64 for ARM64 Chrome). 3. **DLL Path Marshalling:** Allocates memory within the target browser process's address space (`VirtualAllocEx`) and carefully writes the full path string of `chrome_decrypt.dll` into this remote memory (`WriteProcessMemory`). 4. **Remote Thread Execution:** Creates a new thread within the target process. The entry point for this new thread is the address of `LoadLibraryA` (from `kernel32.dll`), and its sole argument is the remote memory address where the DLL path string was written. - This project offers two distinct injection methods: - `CreateRemoteThread`: The standard, well-documented WinAPI function. - `NtCreateThreadEx`: A lower-level, less commonly monitored API residing in `ntdll.dll`, potentially offering a degree of stealth against some endpoint detection and response (EDR) solutions. 5. **Synchronization:** Employs a named event (`Global\ChromeDecryptWorkDoneEvent`) to pause execution and await a signal from the injected DLL indicating that its operations have concluded. - **Injected Payload (`chrome_decrypt.dll`):** 1. **Trusted Execution Context:** When `LoadLibraryA` is invoked within the remote thread, the `DllMain` function of `chrome_decrypt.dll` (specifically, the `DLL_PROCESS_ATTACH` case) is executed. At this pivotal moment, the DLL's code is running with the full identity and, crucially, the _executable path context_ of the host browser process (e.g., `chrome.exe`). This inherently satisfies the `IElevator` path validation check. 2. **Dedicated Worker Thread:** To avoid blocking `DllMain` (which can lead to deadlocks and instability) and to allow `LoadLibraryA` to return promptly (signaling successful injection to the injector), `DllMain` spawns a new, dedicated worker thread. This worker thread undertakes all subsequent COM interactions and decryption tasks. The DLL's original module handle (`HMODULE`) is passed to this worker thread, enabling it to call `FreeLibraryAndExitThread` upon completion for a clean self-unload. 3. **COM Initialization & Security Configuration:** - The worker thread initializes the COM library for its use via `CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)`. - It then instantiates the `IElevator` COM object using `CoCreateInstance`, providing the browser-specific CLSID and IID. - To ensure correct security context propagation for the COM calls, `CoSetProxyBlanket` is invoked on the `IElevator` proxy. This project uses `RPC_C_AUTHN_LEVEL_PKT_PRIVACY`, `RPC_C_IMP_LEVEL_IMPERSONATE`, and `EOAC_DYNAMIC_CLOAKING`. 4. **Retrieving and Unwrapping the `app_bound_key`:** - The DLL reads the `Local State` JSON file from the appropriate user data directory. - It parses the JSON to locate the `os_crypt.app_bound_encrypted_key` value. - This value is Base64-decoded, and the `APPB` prefix is stripped, yielding the raw DPAPI-wrapped blob. - This blob is then passed to the `IElevator::DecryptData` method. 5. **Data Decryption and Output:** - If the `IElevator::DecryptData` call succeeds, the returned plaintext 32-byte AES key is the `app_bound_key`. - This key is then used with Windows Cryptography API: Next Generation (CNG) functions (specifically `BCrypt*` for AES-GCM) to decrypt sensitive data retrieved from the browser's SQLite databases (Cookies, Login Data, Web Data). - The decrypted data items are formatted into JSON and written to separate files in the user's `%TEMP%` directory. - For research and verification, the plaintext `app_bound_key` (in hexadecimal format) is saved to `%TEMP%\chrome_appbound_key.txt`. - A detailed operational log is also generated and saved to `%TEMP%\chrome_decrypt.log`. 6. **Signaling Completion and Resource Cleanup:** The worker thread signals the `Global\ChromeDecryptWorkDoneEvent` named event, uninitializes COM via `CoUninitialize`, and then calls `FreeLibraryAndExitThread` to unload the DLL from the browser's process space. ### 3.2. Operational Context: User-Mode, No Administrative Rights Required A key characteristic of this project's methodology is that it operates entirely in **user mode** and **does not require administrative privileges**. This is possible because: - The `IElevator` COM server, while part of an "Elevation Service," performs the decryption relevant to user data by impersonating the user and leveraging the user's DPAPI context. The "privileged" nature of the service (as depicted in Google's diagram where it runs as SYSTEM) primarily pertains to its role as a gatekeeper for DPAPI access and its ability to validate callers, not necessarily that the decryption task for user keys itself requires SYSTEM-level rights. - DLL injection into another process running as the _same user_ typically does not necessitate administrative elevation. - All file system access (for `Local State`, SQLite databases) targets locations within the user's own profile, which are accessible without elevated rights. ## 4. Dissecting Encrypted Data Structures ### 4.1. `Local State` and the `app_bound_encrypted_key` - **Typical Location:** `%LOCALAPPDATA%\\\User Data\Local State` (e.g., `Google\Chrome\User Data\Local State`). - **Relevant JSON Key:** `os_crypt.app_bound_encrypted_key`. - **Format:** A string value: `"APPB"`. ### 4.2. AES-GCM Blob Format (Cookies, Passwords, Payments, etc.) Data items encrypted with the `app_bound_key` generally adhere to a consistent format: 1. **Prefix:** A version or type prefix string. For cookies, passwords, and payment data observed thus far, this is typically **`v20`** (ASCII: `0x76 0x32 0x30`). Older data encrypted solely with DPAPI might use prefixes like `v10` or `v11`. 2. **Nonce (IV):** A 12-byte Initialization Vector, essential for the security of AES-GCM mode. 3. **Ciphertext:** The actual encrypted data, variable in length. 4. **Authentication Tag:** A 16-byte GCM authentication tag, which ensures both the integrity and authenticity of the decrypted ciphertext. **Overall Blob Structure:** `[Prefix (e.g., 3 bytes for "v20")][IV (12 bytes)][Ciphertext (variable length)][Tag (16 bytes)]` ### 4.3. Cookie Value Specifics (from `encrypted_value` in `Cookies` DB) - A notable observation during the development of this tool is that after successfully decrypting a `v20`-prefixed cookie blob using AES-GCM with the `app_bound_key`, the first **32 bytes** of the resulting plaintext appear to be some form of metadata or padding. The actual cookie value string begins after this `DECRYPTED_COOKIE_VALUE_OFFSET` of 32 bytes. ### 4.4. Passwords (from `password_value` in `Login Data` DB) & Payment Information - These data types also use `v20`-prefixed blobs. - Unlike cookies, the entire decrypted plaintext (after accounting for the `v20` prefix, IV, and tag during the AES-GCM decryption process) is generally considered to be the sensitive value itself (e.g., the password string, credit card number, or CVC). ## 5. Alternative Decryption Vectors & Chrome's Evolving Defenses ### 5.1. Administrator-Level Decryption (e.g., `runassu/chrome_v20_decryption` PoC) The proof-of-concept by `runassu` illustrates that if an attacker possesses **Administrator privileges**, the `app_bound_key` can potentially be decrypted. This aligns with ABE's stated non-goal of protecting against higher-privilege attackers. 1. The PoC's description of needing to decrypt the `app_bound_encrypted_key` from `Local State` first with SYSTEM DPAPI, then user DPAPI, **directly matches** the initial steps within the legitimate `IElevator::DecryptData` function as seen in `elevator.cc`. An administrator can perform these steps outside of the `IElevator` service. 2. After these two DPAPI unwrap steps, the result would be the `[validation_data_length][validation_data][app_bound_key_length][app_bound_key]` plaintext. An admin tool could then simply parse this structure to extract the `app_bound_key` directly, without needing to perform path validation. 3. The `runassu` PoC's claim that this result is "*not* the final `app_bound_key`" and requires a *further* AES-GCM decryption with a key hardcoded in `elevation_service.exe` is intriguing. * This additional layer is **not** part of the standard `IElevator::DecryptData` flow for returning the `app_bound_key` to `OSCrypt`, as evidenced by `elevator.cc`. The `plaintext_str` returned by `IElevator::DecryptData` *is* the application-level key. * The PoC's extra step might be attempting to decrypt data that has undergone an additional, internal transformation within Chrome, possibly related to the `PreProcessData`/`PostProcessData` functions seen in `elevator.cc` (conditionally compiled with `BUILDFLAG(GOOGLE_CHROME_BRANDING)`). These functions might apply another layer of encryption using a service-internal key for specific branded builds or key versions. * Alternatively, the PoC might be targeting a different internal key or an older/variant ABE scheme. - **Hardcoded Keys in `elevation_service.exe`:** The presence of hardcoded keys in `elevation_service.exe` (as mentioned by the PoC for ChaCha20_Poly1305 or AES-256-GCM) would most likely be for such internal service operations or specific recovery mechanisms, rather than the primary ABE flow that returns the key to `OSCrypt`. - **Stability Concerns:** Relying on such internal administrator-level method, undocumented layers and hardcoded keys is highly unstable and prone to break with Chrome updates. The method employed by this project (injecting and calling the official `IElevator::DecryptData` COM interface) is more aligned with the intended client interaction path and thus inherently more stable, despite the injection vector. ### 5.2. Remote Debugging Port (`--remote-debugging-port`) and Its Mitigation Attackers had also turned to Chrome's remote debugging capabilities as a vector to exfiltrate cookies, effectively sidestepping ABE's file-based protections. - **Chrome's Countermeasure (Chrome 136+):** As detailed in a Chrome Developers blog post, Google addressed this by changing the behavior of the `--remote-debugging-port` and `--remote-debugging-pipe` command-line switches. Starting with Chrome 136, these switches will no longer function when Chrome is launched with its default user data directory. To enable remote debugging, users must now also specify the `--user-data-dir` switch, pointing Chrome to a _non-standard, separate_ data directory. This ensures that any debugging session operates on an isolated profile, using a different encryption key, thereby safeguarding the user's primary profile data. - **Bypass Simplicity:** While this change adds a hurdle, it's worth noting that an attacker _can_ control Chrome's launch parameters (e.g., by modifying shortcuts or through malware that relaunches Chrome), they could potentially still launch Chrome with both `--remote-debugging-port` and a temporary `--user-data-dir`, then attempt to import or access data if Chrome allows such operations into a fresh, debuggable profile. The effectiveness of the debug port mitigation hinges on preventing unauthorized modification of launch parameters and on Chrome's policies regarding data access in such scenarios. ### 5.3. Device Bound Session Credentials (DBSC) As an overlapping and complementary security effort, Google has been developing **Device Bound Session Credentials (DBSC)**, available for Origin Trial in Chrome 135. DBSC aims to combat cookie theft by cryptographically binding session cookies to the device. - **Mechanism:** When a DBSC session is initiated, the browser generates a public-private key pair, storing the private key securely (ideally using hardware like a TPM). The server associates the session with the public key. Periodically, the browser proves possession of the private key to refresh the (typically short-lived) session cookie. - **Relevance to ABE:** While ABE protects data at rest on the user's device, DBSC focuses on making stolen session cookies useless if exfiltrated and used on another device. They are two distinct but synergistic layers of defense against session hijacking. An attacker bypassing ABE to get cookies might still find those cookies unusable elsewhere if they are DBSC-protected. ## 6. Key Insights from Google's ABE Design Document & Chromium Source Code Insights from Google's design documents and the Chromium source code (`elevator.h`, `elevator.cc`, `caller_validation.h`, `caller_validation.cc`) provide a comprehensive understanding: - **Original Intent vs. Implemented Reality (Path vs. Signature Validation):** The initial proposal (Page 4 of the design doc) contemplated validating the _digital signature_ of both the calling process and the `IElevator` service executable. However, an "Update (2024)" note clarifies that the project was descoped to use **path validation** for the initial implementation, primarily for simplicity, with the assessment that it offered "equivalent protection against a non-admin attacker" for the prevailing threat models at the time. - **`OSCrypt` Module Modifications:** The core `components/os_crypt` module within Chromium was slated to be augmented. Instead of making direct DPAPI calls, it would use new IPC mechanisms to communicate with the Elevation Service (Pages 2, 5). The design proposed that `OSCrypt` would iterate through a list of "key encryption delegates" - one for legacy DPAPI keys, another for ABE-protected keys via IPC - to find a delegate capable of decrypting a given key (Page 6). - **Stateless Nature of the Service:** The `IElevator` service, in its role for ABE, is designed as a largely stateless encrypt/decrypt primitive. It doesn't require its own persistent storage for ABE operations (Page 4). - **Explicit Acknowledgment of Injection as a Bypass:** Page 7 ("Weaknesses") of the design document candidly states: _"An attacker could inject code into Chrome browser and call the IPC interface. It would be hard to defeat a determined attacker using this technique..."_ This project serves as a practical validation of this assessment. - **Understanding the `IElevator` COM Interface and its Definition:** - The `IElevator` interface is a standard Windows **COM (Component Object Model)** interface. Such interfaces define a contract between a service provider (like Chrome's Elevation Service) and a client (like Chrome's `OSCrypt` module, or in this project's case, the injected `chrome_decrypt.dll`). - This contract is formally specified using **MIDL (Microsoft Interface Definition Language)**. An `.idl` file written in MIDL describes the methods, parameters, and data types. The MIDL compiler processes this `.idl` file to generate C/C++ header files (defining the interface structure for compilers) and a type library (`.tlb`) that describes the interface's binary layout. It also generates proxy/stub code that enables COM to transparently manage communication between the client and server, even if they are in different processes. - While this project's `chrome_decrypt.dll` contains a C++ stub for `IElevator` (using the `MIDL_INTERFACE` macro), this serves as a compile-time declaration of the interface's shape. The crucial elements for runtime interaction are the correct CLSID (to identify the COM component) and IID (to request the specific `IElevator` interface pointer) passed to `CoCreateInstance`. - The `IElevator` interface, as potentially defined by Chrome, would include methods like `EncryptData` and `DecryptData`. An illustrative C++ stub, similar to what's in `chrome_decrypt.cpp`, is: ```cpp // Illustrative C++ MIDL_INTERFACE definition stub from chrome_decrypt.cpp MIDL_INTERFACE("A949CB4E-C4F9-44C4-B213-6BF8AA9AC69C") IElevator : public IUnknown { public: // Method for Chrome's recovery mechanisms, not directly used for decryption by this tool. virtual HRESULT STDMETHODCALLTYPE RunRecoveryCRXElevated( const WCHAR *crx_path, const WCHAR *browser_appid, /* ...other params... */) = 0; // Method used by Chrome to initially encrypt the app_bound_key. virtual HRESULT STDMETHODCALLTYPE EncryptData( ProtectionLevel protection_level, // Specifies the type of protection to apply const BSTR plaintext, BSTR *ciphertext, DWORD *last_error) = 0; // The key method utilized by this tool to decrypt the app_bound_key. virtual HRESULT STDMETHODCALLTYPE DecryptData( const BSTR ciphertext, // DPAPI-wrapped app_bound_key blob from Local State BSTR *plaintext, // Output: raw 32-byte app_bound_key DWORD *last_error) = 0; // Propagates underlying errors (e.g., from DPAPI) }; ``` - The `EncryptData` method, though not called by this decryption tool, would likely use an enum like `ProtectionLevel` to dictate the security measures applied during the encryption of the `app_bound_key`. This project includes such an enum in `chrome_decrypt.cpp`: ```cpp // From elevation_service_idl.h (implicitly, via project's chrome_decrypt.cpp stub) enum class ProtectionLevel // As used by IElevator { PROTECTION_NONE = 0, PROTECTION_PATH_VALIDATION_OLD = 1, // An older path validation scheme PROTECTION_PATH_VALIDATION = 2, // The ABE path validation relevant to this research PROTECTION_MAX = 3 // Boundary for valid levels }; ``` - By specifying `ProtectionLevel::PROTECTION_PATH_VALIDATION` during the `EncryptData` call, Chrome instructs the `IElevator` service to enforce the path validation check when creating the `app_bound_encrypted_key`. The `DecryptData` method, subsequently used by this tool, implicitly respects the protection level that was originally applied during encryption. - The `IElevator::EncryptData` method, when called by Chrome with `ProtectionLevel::PROTECTION_PATH_VALIDATION`, generates caller-specific `validation_data` (based on the normalized path of Chrome itself), prepends this to the actual `app_bound_key`, and then encrypts this combined payload twice with DPAPI (first user-context, then system-context). - The `IElevator::DecryptData` method reverses this: decrypts twice with DPAPI (first system-context, then user-context), extracts the `validation_data` and the `app_bound_key`, performs path validation using the extracted `validation_data` against the current caller, and returns the `app_bound_key` if valid. This project's tool correctly utilizes this returned key. - **Path Normalization (`MaybeTrimProcessPath` in `caller_validation.cc`):** A critical detail for `ProtectionLevel::PROTECTION_PATH_VALIDATION` is that the validation does not use the raw executable path. Instead, `MaybeTrimProcessPath` normalizes it by: 1. Removing the executable filename (e.g., `chrome.exe`). 2. Conditionally removing trailing directory components if they match "Temp", "Application", or a version string (e.g., `127.0.0.0`). 3. Standardizing `Program Files (x86)` to `Program Files`. This ensures that different Chrome versions or temporary unpack locations within the same sanctioned base installation directory can still validate successfully. ## 7. Operational Considerations and Limitations of this tool ### 7.1. Browser Process Termination (`KillBrowserProcesses`) The `chrome_decrypt.dll` currently includes logic to terminate existing browser processes of the target type before proceeding. - **Rationale:** This is primarily to ensure that SQLite database files (`Cookies`, `Login Data`, `Web Data`) are not locked by live browser instances and that the `IElevator` COM server can initialize in a clean state, potentially avoiding conflicts or issues if existing browser instances have the service in an unusual state. - **User Impact:** This is a disruptive action. Future enhancements to this tool could explore less intrusive methods, such as attempting to copy the database files to a temporary location and operating on those copies, or implementing a more conditional termination strategy (e.g., only if initial COM instantiation or DB access fails). ### 7.2. Multi-Profile Support Currently, this tool primarily targets the `Default` user profile within the browser's user data directory. Comprehensive support for environments with multiple Chrome profiles would involve: 1. Enumerating all active profile directories (e.g., `Profile 1`, `Profile 2`, etc.) within the main `User Data` folder. 2. Applying the (likely single, shared per `User Data` instance) `app_bound_key` to decrypt data from each profile's respective SQLite databases, as the key is tied to the overall user data directory, not individual sub-profiles. ### 7.3. Roaming Profiles and Enterprise Environments Google's public communications on ABE explicitly state that it "will not function correctly in environments where Chrome profiles roam between multiple machines." This is because the underlying DPAPI protection for the `app_bound_key` is inherently machine-bound (and user-bound). If an enterprise requires support for roaming profiles, they are encouraged to follow existing best practices. For scenarios where ABE might cause incompatibility, Chrome provides the `ApplicationBoundEncryptionEnabled` enterprise policy to configure or disable this feature. ## 8. Conclusion and Future Directions for ABE Research App-Bound Encryption marks a commendable and significant enhancement in securing locally stored Chrome data on the Windows platform. By fundamentally tying decryption capabilities to a path-validated COM service, Google has effectively "moved the goalposts" for attackers, compelling them to resort to either privilege escalation or code injection into Chrome itself - both of which are generally "noisier" and more readily detectable actions than straightforward, unprivileged DPAPI calls. This project, through its implementation of a user-mode DLL injection technique, serves multiple purposes: 1. It provides a practical, working demonstration of the bypass vector that Google's own design documents acknowledged. 2. It functions as a valuable tool for legitimate data recovery scenarios and for security researchers aiming to understand ABE's intricacies. 3. It stands as a reference implementation for interacting with the ABE system from within the trusted browser context. The ongoing evolution of Chrome and its security mechanisms means that ABE research will remain a dynamic field. Future areas of focus will likely include: - **Monitoring the `IElevator` service:** Tracking any changes to its CLSIDs, IIDs, interface methods, or the core validation logic (e.g., a potential future shift from path validation to digital signature validation, as originally contemplated). - **Deep Analysis of Undocumented Structures:** Further reverse engineering efforts to understand elements like the 32-byte prefix observed in decrypted cookie plaintext. - **Chrome's Detection and Mitigation of Injection Techniques:** As Google and security vendors work to make code injection "more detectable," understanding these evolving detection strategies and their impact will be crucial. - **Impact of Further OS-Level Hardening:** Investigating how improvements in Windows process integrity, application isolation primitives, or EDR technologies might affect ABE and bypass techniques. The landscape of browser security is one of constant flux. App-Bound Encryption is a critical new defensive layer, and the continued efforts of the research community will be essential for a comprehensive understanding of its strengths, its limitations, and its trajectory in the face of ever-adapting threats. ## 9. References and Further Reading - **Google Security Blog:** [Improving the security of Chrome cookies on Windows](https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html) (July 30, 2024) - **Google Design Document:** [Chrome app-bound encryption Service (formerly: Chrome Elevated Data Service)](https://drive.google.com/file/d/1xMXmA0UJifXoTHjHWtVir2rb94OsxXAI/view) (Original: Jan 25, 2021, with later updates) - **Chrome Developers Blog (Remote Debugging):** [Changes to remote debugging switches to improve security](https://developer.chrome.com/blog/remote-debugging-port) (Example: March 17, 2025) - **Chrome Developers Blog (DBSC):** [Origin trial: Device Bound Session Credentials in Chrome](https://developer.chrome.com/blog/dbsc-origin-trial) - **runassu's PoC (Admin-level decryption):** [chrome_v20_decryption](https://github.com/runassu/chrome_v20_decryption) - **Related Research/Tools:** - [snovvcrash's X/Twitter Profile (Security Researcher)](https://x.com/snovvcrash) - [SilentDev33's ChromeAppBound-key-injection (Similar PoC)](https://github.com/SilentDev33/ChromeAppBound-key-injection)