Spoof-when-possible browser personas, Tier-2 telemetry kill + artifact wipe, UI polish
Browser: identity persona dropdown (blend Windows-Chrome / Firefox / mac-Safari / hardened / custom) + cookie policy dropdown. Blend personas relax RFP/FPI/strict-TP so the machine looks normal while still hiding behind the chain. Persona TZ applied via env var; UA / language / locale / screen via user.js. WebRTC still forced off (it leaks real IP). Privacy: Telemetry kill toggle (DiagTrack, Activity History, ad ID, Cortana, scheduled tasks) with full snapshot/restore. One-button forensic artifact wipe (TEMP, Recent, Jump Lists, Prefetch, MRU, clipboard). UI: neon palette, glow card borders, gradient header banner. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -35,6 +35,13 @@ from .firewall import (
|
||||
is_engaged as fw_is_engaged,
|
||||
request_admin_relaunch,
|
||||
)
|
||||
from .artifact_wipe import wipe_artifacts
|
||||
from .browser_identity import (
|
||||
COOKIE_LABELS,
|
||||
COOKIE_MODES,
|
||||
PERSONA_LABELS,
|
||||
PERSONAS,
|
||||
)
|
||||
from .dns_leak import check_dns_leak_hint, flush_dns_cache
|
||||
from .leak_audit import AuditReport, run_audit_sync
|
||||
from .browser_launcher import (
|
||||
@@ -80,22 +87,26 @@ class UILogHandler(logging.Handler):
|
||||
|
||||
|
||||
# ── palette ──────────────────────────────────────────────────────────────────
|
||||
BG = "#0d0d1a"
|
||||
CARD = "#12122a"
|
||||
PANEL = "#1a1a3e"
|
||||
ACCENT = "#1e3a8a"
|
||||
ACCENT2 = "#2563eb"
|
||||
GREEN = "#00e676"
|
||||
RED = "#ff1744"
|
||||
YELLOW = "#ffab00"
|
||||
ORANGE = "#ff6d00"
|
||||
PURPLE = "#bb86fc"
|
||||
BLUE = "#448aff"
|
||||
CYAN = "#00bcd4"
|
||||
DIM = "#4a5568"
|
||||
TEXT = "#e2e8f0"
|
||||
TEXT2 = "#94a3b8"
|
||||
FONT = "Segoe UI"
|
||||
# Neon "blueprint terminal" theme — same overall vibe, deeper black, sharper
|
||||
# cyan/magenta accent, glow borders rendered via 1px border_color on cards.
|
||||
BG = "#070713"
|
||||
CARD = "#0f0f24"
|
||||
PANEL = "#171738"
|
||||
ACCENT = "#3052ff" # primary action / outlines
|
||||
ACCENT2 = "#00e5ff" # secondary highlight / glow
|
||||
GREEN = "#00ff9c"
|
||||
RED = "#ff2a6d"
|
||||
YELLOW = "#ffd000"
|
||||
ORANGE = "#ff8a00"
|
||||
PURPLE = "#c77dff"
|
||||
BLUE = "#5b8bff"
|
||||
CYAN = "#00f5ff"
|
||||
MAGENTA = "#ff00d6"
|
||||
DIM = "#2a2f4a"
|
||||
TEXT = "#eaf2ff"
|
||||
TEXT2 = "#7a8aab"
|
||||
GLOW = "#0a87ff"
|
||||
FONT = "Segoe UI"
|
||||
|
||||
|
||||
def _ts() -> str:
|
||||
@@ -108,10 +119,56 @@ def main() -> None:
|
||||
|
||||
root = ctk.CTk()
|
||||
root.title("Proxy God v2")
|
||||
root.geometry("1080x740")
|
||||
root.geometry("1080x760")
|
||||
root.minsize(900, 620)
|
||||
root.configure(fg_color=BG)
|
||||
|
||||
# ── 3D-ish neon header banner (drawn on a Canvas for a true gradient) ────
|
||||
def _draw_header_banner(parent: Any) -> Any:
|
||||
import tkinter as tk
|
||||
canvas = tk.Canvas(
|
||||
parent, height=44, highlightthickness=0, bd=0, bg=BG,
|
||||
)
|
||||
canvas.pack(fill="x", side="top")
|
||||
|
||||
def _hex(rgb: tuple[int, int, int]) -> str:
|
||||
return "#" + "".join(f"{v:02x}" for v in rgb)
|
||||
|
||||
def _lerp(a: tuple[int, int, int], b: tuple[int, int, int], t: float) -> tuple[int, int, int]:
|
||||
return tuple(int(a[i] + (b[i] - a[i]) * t) for i in range(3)) # type: ignore[return-value]
|
||||
|
||||
def _repaint(_event: Any = None) -> None:
|
||||
canvas.delete("grad")
|
||||
w = canvas.winfo_width() or 1080
|
||||
h = 44
|
||||
left = (8, 32, 64) # near-black blue
|
||||
mid = (48, 82, 255) # ACCENT
|
||||
right = (0, 229, 255) # ACCENT2 cyan
|
||||
for x in range(0, w, 2):
|
||||
t = x / max(1, w - 1)
|
||||
c = _lerp(left, mid, t * 2) if t < 0.5 else _lerp(mid, right, (t - 0.5) * 2)
|
||||
canvas.create_line(x, 0, x, h, fill=_hex(c), tags="grad")
|
||||
# 1px neon underline
|
||||
canvas.create_line(0, h - 1, w, h - 1, fill=CYAN, width=1, tags="grad")
|
||||
# Title text + small subtitle
|
||||
canvas.create_text(
|
||||
18, h // 2 - 2, anchor="w",
|
||||
text="P R O X Y G O D",
|
||||
fill="#ffffff", font=(FONT, 16, "bold"),
|
||||
tags="grad",
|
||||
)
|
||||
canvas.create_text(
|
||||
190, h // 2 - 1, anchor="w",
|
||||
text="// multi-hop · anti-fingerprint · paranoid mode",
|
||||
fill="#bfeaff", font=(FONT, 9, "italic"),
|
||||
tags="grad",
|
||||
)
|
||||
|
||||
canvas.bind("<Configure>", _repaint)
|
||||
return canvas
|
||||
|
||||
_draw_header_banner(root)
|
||||
|
||||
ui_q: queue.Queue[dict[str, Any]] = queue.Queue()
|
||||
svc = ChainService(notify=lambda m: ui_q.put(m))
|
||||
s = load_settings()
|
||||
@@ -847,7 +904,10 @@ def main() -> None:
|
||||
ctk.CTkLabel(
|
||||
br_scroll, text=subtitle, font=(FONT, 10), text_color=TEXT2, wraplength=900, justify="left"
|
||||
).pack(anchor="w", padx=8, pady=(0, 4))
|
||||
f = ctk.CTkFrame(br_scroll, fg_color=CARD, corner_radius=8)
|
||||
f = ctk.CTkFrame(
|
||||
br_scroll, fg_color=CARD, corner_radius=10,
|
||||
border_width=1, border_color=GLOW,
|
||||
)
|
||||
f.pack(fill="x", padx=8, pady=(4, 8))
|
||||
return f
|
||||
|
||||
@@ -895,6 +955,78 @@ def main() -> None:
|
||||
"Browser controls",
|
||||
"These settings are applied each time you launch from this tab.",
|
||||
)
|
||||
persona_card = _section_inline(
|
||||
br_scroll,
|
||||
"Identity persona (spoof when possible, block when not)",
|
||||
"Blend-in personas mimic the most common Windows + Chrome setup so the "
|
||||
"browser looks normal. Hardened mode is the classic 'block everything' "
|
||||
"profile but stands out as anti-fingerprint.",
|
||||
) if "_section_inline" in dir() else None
|
||||
if persona_card is None:
|
||||
persona_card = ctk.CTkFrame(
|
||||
br_scroll, fg_color=CARD, corner_radius=10,
|
||||
border_width=1, border_color=GLOW,
|
||||
)
|
||||
persona_card.pack(fill="x", padx=8, pady=(2, 8))
|
||||
ctk.CTkLabel(
|
||||
persona_card,
|
||||
text="Identity persona (spoof when possible, block when not)",
|
||||
font=(FONT, 12, "bold"),
|
||||
text_color=ORANGE,
|
||||
).pack(anchor="w", padx=12, pady=(10, 0))
|
||||
ctk.CTkLabel(
|
||||
persona_card,
|
||||
text=(
|
||||
"Blend-in personas mimic the most common Windows + Chrome setup "
|
||||
"so the browser looks normal. Hardened = full anti-fingerprint."
|
||||
),
|
||||
font=(FONT, 9), text_color=TEXT2, justify="left", wraplength=820,
|
||||
).pack(anchor="w", padx=12, pady=(0, 6))
|
||||
|
||||
persona_row = ctk.CTkFrame(persona_card, fg_color="transparent")
|
||||
persona_row.pack(fill="x", padx=12, pady=(0, 6))
|
||||
ctk.CTkLabel(persona_row, text="Persona:", font=(FONT, 11), text_color=TEXT,
|
||||
width=80, anchor="w").pack(side="left")
|
||||
persona_var = ctk.StringVar(
|
||||
value=PERSONA_LABELS.get(s.browser_persona, PERSONA_LABELS["blend_windows_chrome"])
|
||||
)
|
||||
persona_menu = ctk.CTkOptionMenu(
|
||||
persona_row,
|
||||
values=[PERSONA_LABELS[k] for k in PERSONAS],
|
||||
variable=persona_var,
|
||||
fg_color=BG, button_color=ACCENT2, button_hover_color=ACCENT,
|
||||
text_color=TEXT, font=(FONT, 11), width=500,
|
||||
)
|
||||
persona_menu.pack(side="left", padx=(4, 0))
|
||||
|
||||
cookie_row = ctk.CTkFrame(persona_card, fg_color="transparent")
|
||||
cookie_row.pack(fill="x", padx=12, pady=(0, 10))
|
||||
ctk.CTkLabel(cookie_row, text="Cookies:", font=(FONT, 11), text_color=TEXT,
|
||||
width=80, anchor="w").pack(side="left")
|
||||
cookie_var = ctk.StringVar(
|
||||
value=COOKIE_LABELS.get(s.browser_cookie_mode, COOKIE_LABELS["block_third_party"])
|
||||
)
|
||||
cookie_menu = ctk.CTkOptionMenu(
|
||||
cookie_row,
|
||||
values=[COOKIE_LABELS[k] for k in COOKIE_MODES],
|
||||
variable=cookie_var,
|
||||
fg_color=BG, button_color=ACCENT2, button_hover_color=ACCENT,
|
||||
text_color=TEXT, font=(FONT, 11), width=500,
|
||||
)
|
||||
cookie_menu.pack(side="left", padx=(4, 0))
|
||||
|
||||
def _persona_key() -> str:
|
||||
for k in PERSONAS:
|
||||
if PERSONA_LABELS[k] == persona_var.get():
|
||||
return k
|
||||
return "blend_windows_chrome"
|
||||
|
||||
def _cookie_key() -> str:
|
||||
for k in COOKIE_MODES:
|
||||
if COOKIE_LABELS[k] == cookie_var.get():
|
||||
return k
|
||||
return "block_third_party"
|
||||
|
||||
br_force_proxy_var = ctk.BooleanVar(value=s.browser_force_proxy)
|
||||
br_disable_webrtc_var = ctk.BooleanVar(value=s.browser_disable_webrtc)
|
||||
br_rfp_var = ctk.BooleanVar(value=s.browser_resist_fingerprinting)
|
||||
@@ -984,6 +1116,8 @@ def main() -> None:
|
||||
first_party_isolation=bool(br_fpi_var.get()),
|
||||
strict_tracking_protection=bool(br_strict_tp_var.get()),
|
||||
timezone_utc=bool(br_tz_utc_var.get()),
|
||||
persona=_persona_key(),
|
||||
cookie_mode=_cookie_key(),
|
||||
)
|
||||
|
||||
def _refresh_browser_status() -> None:
|
||||
@@ -1043,7 +1177,10 @@ def main() -> None:
|
||||
ctk.CTkLabel(priv_scroll, text=subtitle, font=(FONT, 10),
|
||||
text_color=TEXT2, wraplength=900, justify="left").pack(
|
||||
anchor="w", padx=8, pady=(0, 4))
|
||||
f = ctk.CTkFrame(priv_scroll, fg_color=CARD, corner_radius=8)
|
||||
f = ctk.CTkFrame(
|
||||
priv_scroll, fg_color=CARD, corner_radius=10,
|
||||
border_width=1, border_color=GLOW,
|
||||
)
|
||||
f.pack(fill="x", padx=8, pady=(4, 8))
|
||||
return f
|
||||
|
||||
@@ -1090,6 +1227,7 @@ def main() -> None:
|
||||
ipv6_var = ctk.BooleanVar(value=s.disable_ipv6_while_active)
|
||||
webrtc_var = ctk.BooleanVar(value=s.harden_webrtc_enabled)
|
||||
lan_var = ctk.BooleanVar(value=s.lan_lockdown_enabled)
|
||||
telemetry_var = ctk.BooleanVar(value=s.telemetry_kill_enabled)
|
||||
|
||||
def _priv_toggle(parent: Any, text: str, var: ctk.BooleanVar, tip: str = "") -> ctk.CTkCheckBox:
|
||||
cb = ctk.CTkCheckBox(
|
||||
@@ -1132,6 +1270,13 @@ def main() -> None:
|
||||
"Stops your machine from advertising its hostname on the local network "
|
||||
"(admin required, reversible on stop).",
|
||||
)
|
||||
_priv_toggle(
|
||||
toggles_card,
|
||||
"Telemetry kill: DiagTrack, Activity History, Cortana web, ad ID",
|
||||
telemetry_var,
|
||||
"Stops Windows telemetry pipelines while chain is up. Reversible on stop "
|
||||
"(snapshot of original state taken).",
|
||||
)
|
||||
|
||||
fp_card = _priv_section(
|
||||
"Device fingerprint",
|
||||
@@ -1177,6 +1322,35 @@ def main() -> None:
|
||||
_btn(dns_btn_row, "Flush DNS now", _manual_dns_flush, w=110, h=28,
|
||||
fg_color=DIM).pack(side="left")
|
||||
|
||||
wipe_card = _priv_section(
|
||||
"Forensic artifact wipe",
|
||||
"One-button purge of common Windows breadcrumb trails. Irreversible.",
|
||||
)
|
||||
wipe_result_lbl = ctk.CTkLabel(
|
||||
wipe_card, text="Click 'Wipe now' to purge %TEMP%, Recent, Jump Lists, "
|
||||
"Prefetch (Admin), MRU lists, and the clipboard.",
|
||||
font=(FONT, 10), text_color=TEXT2, wraplength=880, justify="left",
|
||||
)
|
||||
wipe_result_lbl.pack(anchor="w", padx=12, pady=8)
|
||||
|
||||
def _do_wipe() -> None:
|
||||
wipe_result_lbl.configure(text="Wiping…", text_color=YELLOW)
|
||||
|
||||
def work() -> None:
|
||||
try:
|
||||
rep = wipe_artifacts(include_prefetch=True)
|
||||
except Exception as e:
|
||||
root.after(0, lambda: wipe_result_lbl.configure(
|
||||
text=f"Wipe failed: {e}", text_color=RED))
|
||||
return
|
||||
root.after(0, lambda: wipe_result_lbl.configure(
|
||||
text=rep.summary(), text_color=GREEN if not rep.errors else YELLOW))
|
||||
|
||||
threading.Thread(target=work, daemon=True).start()
|
||||
|
||||
_btn(wipe_card, "Wipe now", _do_wipe, w=110, h=28,
|
||||
fg_color=RED, hover_color="#8a1d1d").pack(anchor="w", padx=12, pady=(0, 10))
|
||||
|
||||
audit_card = _priv_section(
|
||||
"Leak audit (mission-critical)",
|
||||
"Probes every leak surface: IP, DNS, IPv6, WPAD, Group Policy, "
|
||||
@@ -1310,6 +1484,9 @@ def main() -> None:
|
||||
ipv6_var.set(False)
|
||||
webrtc_var.set(True)
|
||||
lan_var.set(False)
|
||||
telemetry_var.set(False)
|
||||
persona_var.set(PERSONA_LABELS["blend_windows_chrome"])
|
||||
cookie_var.set(COOKIE_LABELS["block_third_party"])
|
||||
br_force_proxy_var.set(True)
|
||||
br_disable_webrtc_var.set(True)
|
||||
br_rfp_var.set(True)
|
||||
@@ -1381,6 +1558,7 @@ def main() -> None:
|
||||
disable_ipv6_while_active=bool(ipv6_var.get()),
|
||||
harden_webrtc_enabled=bool(webrtc_var.get()),
|
||||
lan_lockdown_enabled=bool(lan_var.get()),
|
||||
telemetry_kill_enabled=bool(telemetry_var.get()),
|
||||
firefox_path=firefox_path_var.get().strip(),
|
||||
firefox_profile_dir=firefox_profile_var.get().strip(),
|
||||
browser_clear_on_close=bool(br_clear_var.get()),
|
||||
@@ -1395,6 +1573,8 @@ def main() -> None:
|
||||
browser_first_party_isolation=bool(br_fpi_var.get()),
|
||||
browser_strict_tracking_protection=bool(br_strict_tp_var.get()),
|
||||
browser_timezone_utc=bool(br_tz_utc_var.get()),
|
||||
browser_persona=_persona_key(),
|
||||
browser_cookie_mode=_cookie_key(),
|
||||
)
|
||||
if not (1 <= ns.local_port <= 65535):
|
||||
raise ValueError("Port must be 1-65535")
|
||||
|
||||
Reference in New Issue
Block a user