ChromElevator: ABE Bypass via Target-Context COM Injection
T1539 — Steal Web Session Cookie
T1555.003 — Credentials from Web Browsers
T1055 — Process Injection
In July 2024, Google deployed ABE to make browser credential theft impossible without admin rights. The old DPAPI approach broke overnight. The naive CDP workaround (debug port) is noisy and leaves a detectable network socket open. ChromElevator takes the opposite path: process hollowing + reflective injection + direct syscalls. The COM service validates the caller path, sees Chrome, and hands over the AES master key. No debug ports. No admin required. No disk writes. Confirmed working: Chrome 144, Brave, Edge, Avast.
What App-Bound Encryption Actually Does
Before July 2024, stealing Chrome credentials required three steps: copy the SQLite cookie database, call Windows's DPAPI decryption API, read the plaintext. Any program running as the logged-in user could do it. That's why infostealers were so effective.
Google's fix introduced a security guard. Imagine Chrome's AES master key is locked in a vault. A COM service — a separate Windows process called the Chrome Elevation Service — holds the combination. Its rule: I only open the vault for processes that can prove they are the real Chrome browser.
The proof is path validation. When a process asks the Elevation Service to decrypt the key, the service checks: "What executable file is making this request? Does its install path match Chrome?" If the path normalises to C:\Program Files\Google\Chrome\Application, the key is returned. Any other path gets rejected.
// Why DPAPI-in-DPAPI
The ABE key is actually wrapped in two layers of DPAPI encryption simultaneously: one using the calling user's credentials, one using the Windows SYSTEM account. Both layers are only unwrapped by the Elevation Service — which runs as SYSTEM and can impersonate the current user. A regular user-level process can't replicate this without cracking SYSTEM first.
Two Ways Past the Guard
Once ABE shipped, researchers found two categories of bypass:
CDP is the simpler technique and widely documented. ChromElevator is the surgical approach: no debug ports, no Chrome restart, no localhost socket. The attack surface for defenders is narrower and the COM call looks like normal browser behaviour.
ChromElevator: How It Works (Layman)
Step 1 — The Hollow Shell
ChromElevator creates a new chrome.exe process in a suspended state before any Chrome code runs. At this point Windows has already loaded the legitimate Chrome executable and set the process's identity — path, headers, everything. From Windows's perspective, this is Chrome.
The tool then unmaps Chrome's actual code from the process's memory and writes its own payload into that space. When the process resumes, it runs the payload. The process still shows as chrome.exe at the correct install path.
Step 2 — The Encrypted Payload
The DLL that performs the credential extraction is never stored on disk. It lives inside the main binary as an encrypted blob, encrypted with ChaCha20 at compile time. There are no readable strings, no recognisable API names, no patterns that signature-based detection can match against. The payload is decrypted into memory at runtime only.
Step 3 — Hell's Gate
Normal Windows programs call system functions like CreateProcess or VirtualAllocEx through Windows's official library (ntdll.dll). Security software instruments these calls to log and alert on suspicious behaviour.
ChromElevator uses a technique called Hell's Gate: instead of calling ntdll's functions by name, it reads ntdll's memory to find the actual syscall numbers, then calls the kernel directly. EDR hooks in ntdll are completely skipped. The calls are invisible to most endpoint security tools.
Step 4 — Reflective DLL Injection
The payload loads itself. Rather than using Windows's standard DLL loader (which creates filesystem traces and is monitored by security tools), the DLL contains its own mini-loader that maps it into Chrome's memory from scratch. After it runs, the DLL destroys its own PE headers in memory — so even a memory-scanning tool looking for loaded modules has less to find.
Step 5 — The COM Call
Now running inside a process that Windows identifies as chrome.exe at Chrome's real install path, the payload calls the Chrome Elevation Service's IElevator::DecryptData COM method. The Elevation Service performs path validation, normalises the caller's path, compares it — and finds Chrome. The 32-byte AES master key is returned.
With the master key, every v20-prefixed value in Chrome's databases is AES-256-GCM decryptable: session cookies, saved passwords, payment card data.
Research Output
ChromElevator extraction output — AES master key recovered, credential databases decrypted
Multi-browser run — same COM injection technique, different CLSIDs/IIDs per vendor
Process hollowing chain — suspended chrome.exe, payload mapped, COM call issued from within Chrome's address space
// Validated — October 2026
Confirmed working across all Chromium-based browsers that implement ABE:
- Google Chrome 144.0.7559.133 — IElevator2Chrome (Chrome 144+ interface)
- Brave 1.86.148 — IElevatorBrave CLSID
- Microsoft Edge 145.0.3800.36 — IEdgeElevatorFinal (extra vtable layer, different inheritance chain)
- Avast Secure Browser 143.0.33371.147 — IElevatorChrome IID (Avast uses Chrome's own interface)
No administrator privileges required on any of the above. x64 and ARM64 verified.
Chrome 144: The Guard Gets a Promotion
In November 2025, Chromium commit 49620496b8f0b7c0c63e2666a82e01180df3f4c3 landed: "Add two new interfaces on IElevator." Chrome 144 ships with a second interface family — IElevator2 alongside the original IElevator.
The original IElevator chain had six interfaces: one base, five browser-specific flavours (Chrome Stable, Beta, Dev, Canary, Chromium). Chrome 144 doubles this to twelve by adding a parallel IElevator2 tree, each member inheriting the two new methods RunIsolatedChrome and AcceptInvitation.
The important detail: DecryptData is still at the same vtable offset in IElevator2. The inheritance chain is IUnknown → IElevator → IElevator2 → IElevator2Chrome, so the first six method slots are identical to the old interface. Tools that statically hardcode the IElevatorChrome IID fail on Chrome 144 — not because the vtable layout changed, but because the registered interface has changed. Tools that dynamically resolve the CLSID and IID from the type library, or detect the Chrome 144 boundary and switch IIDs, continue to work.
The RunIsolatedChrome and AcceptInvitation methods appear to be groundwork for Mojo-based communication between elevated and non-elevated Chrome processes — a signal that future ABE hardening may involve verifying the calling process through Mojo IPC rather than path string matching alone.
Bypass Approaches Compared
| Method | Admin Required | Network Artefacts | Disk Writes | EDR Visibility |
|---|---|---|---|---|
| DPAPI direct Pre-Chrome 127 |
No | None | None | Low — API call only |
| CDP debug port Chrome 127+ |
No | TCP 9222 on loopback, WebSocket | None | High — process args, port, parent chain |
| COM injection (ChromElevator) Chrome 127–144+ |
No | None | None | Medium — process hollowing detectable if telemetry covers it |
| Admin SYSTEM DPAPI Requires elevation |
Yes | None | None | Low — standard system call |
Detection
| Detection Type | Indicator | Applies To |
|---|---|---|
| Process | chrome.exe with non-browser parent (not explorer.exe, not chrome.exe) | COM injection + CDP |
| Process | chrome.exe created with CREATE_SUSPENDED flag (Sysmon) |
COM injection |
| Memory | chrome.exe with no PE headers mapped (Sysmon Event 25) | COM injection (post-hollow) |
| COM | elevation_service.exe serving DecryptData to unusual chrome.exe instance | COM injection |
| Process | chrome.exe with --remote-debugging-port flag |
CDP only |
| Network | TCP 9222 listening on loopback | CDP only |
| Behavioral | Chrome killed → Chrome relaunched hidden → localhost WebSocket | CDP only |
What Doesn't Catch It
Signature-based AV scanning the ChromElevator binary sees only a ChaCha20-encrypted blob. No recognisable API names, no plaintext strings, no known shellcode patterns. The syscalls bypass ntdll hooks, so user-mode EDR telemetry misses the allocation and injection calls unless the EDR instruments at kernel level (minifilter or ETW kernel provider). The COM call to the Elevation Service looks identical to a legitimate Chrome startup sequence.
Defensive Recommendations
For Endpoint Security Teams
- Deploy Sysmon with rules covering Event ID 25 (ProcessTampering — image replaced) and Event ID 8 (CreateRemoteThread into chrome.exe)
- Monitor the Chrome Elevation Service (elevation_service.exe) with COM audit logging — Windows ETW
Microsoft-Windows-RPCprovider - Alert on chrome.exe processes whose parent is not explorer.exe, an existing chrome.exe, or GoogleUpdate.exe
- Enable Credential Guard — while it doesn't protect browser data, it signals the policy posture that treats credential theft as a priority
- On Chrome 127+: alert on any process launching Chrome with
--remote-debugging-portargument
For Web Application Developers
- Implement device-bound session credentials (DBSC) — Chrome's next layer beyond ABE, ties the session to a TPM-backed key that can't be extracted
- Require re-authentication from a new IP or user agent for sensitive operations
- Treat any session token presented from an unfamiliar device fingerprint as suspicious, not merely different
Related Research
- Google Security Blog: Improving the security of Chrome cookies on Windows (Jul 2024)
- xaitax / Chrome-App-Bound-Encryption-Decryption — public reference implementation
- Learn: Ch7 — Zero Writes (HWBP/VEH, direct syscalls in detection evasion context)
- Learn: Ch6 — Blinding the Sensor Array (how kernel-level defences respond)
- MITRE ATT&CK T1055 — Process Injection
- MITRE ATT&CK T1539 — Steal Web Session Cookie
Research conducted for defensive purposes. All testing on owned infrastructure. Understanding injection-based credential access enables detection engineers to build telemetry that catches the technique rather than its artefacts.