# mitmux - Intercepting Proxy TUI (Burp/Caido replacement) ## Overview Daily-driver intercepting proxy for manual pentest work, terminal-based. Prior art to read before writing code: Cruster (Rust, built on hudsucker) - same problem, worth studying even though this build is Go. ## Stack - Language: Go - memory safety on hostile input matters here more than in the other projects, since this parses attacker-adjacent traffic - TLS interception: Go's own `crypto/tls` + a CA cert generator (analogous to `rcgen`) for per-domain leaf certs - Proxy core: `net/http` + manual `CONNECT` handling, or a MITM proxy library if one fits without fighting Go's aggressive header normalization. Upstream requests are round-tripped manually (write the request, read the response off the same connection) rather than through `http.Transport` - Transport's automatic HTTP/2 dispatch keys off a literal `*tls.Conn` type assertion on the dialed connection, which a raw-byte-capturing wrapper around that connection defeats (found by testing: it silently parsed HTTP/2 framing as HTTP/1.1). - Storage: SQLite in WAL mode - blob columns for raw request/response bytes, FTS5 index for search across bodies - UI: Bubble Tea + Lipgloss (TUI), same family as the packet analyzer's Go sibling if that ever gets built ## Architecture sketch (important - don't skip this) - Split proxy engine from TUI. Headless daemon owns the listening socket and the DB; TUI is a client over a Unix socket. The proxy keeps running when the UI restarts, and a web UI or CLI scanner can be bolted on later without touching the engine. - Store raw bytes as the source of truth. Parse into a display view, never re-serialize for storage - request smuggling, header injection, and parser-differential bugs depend on the original malformed framing surviving. For Repeater specifically, write requests as raw bytes over the socket rather than through a normalizing HTTP client. ## Build order 1. Proxy + CA cert generation + plaintext HTTP passthrough 2. TLS interception (per-host cert generation, install CA) 3. History view (SQLite storage, raw bytes preserved) in the TUI 4. Repeater (raw-byte send/resend, the feature used daily) 5. Search/filter (FTS5) 6. Match-and-replace rules 7. Intruder-equivalent (last, optional) ## Open questions - HTTP/2: handle natively (decided) - full fidelity over MITM'd connections rather than downgrading to HTTP/1.1. Adds complexity to CONNECT handling, stream framing, and step 3 storage (multiplexed streams over one connection need per-stream request/response boundaries, not just per-connection ones). - CA install UX per OS (Linux/macOS/Windows trust stores) - Whether WebSocket interception is v1 or a later addition - Step 6 match-and-replace shipped headers-only. Body rules are a separate, harder problem: request-body capture currently relies on streaming the body straight from the client connection to the upstream write (that's what makes it exact, byte for byte); a body rule needs to materialize, transform, and re-send it instead, which means deciding what "exact" even means for a rule-modified request before touching that path again. Also still single-line-text-field limited in the TUI (bubbles/textinput can't hold a literal CRLF), so even with header rules, injecting a brand-new header line via the form isn't possible yet - only rewriting/removing existing ones. The underlying engine (rules.ApplyHeaders) already supports arbitrary text-block edits; it's specifically the form UI that's constrained. - Step 7 (Intruder-equivalent) shipped Sniper only: one payload set, one §marked§ position fuzzed at a time, every other marked position held at its base value - the mode that covers most real Intruder usage. Battering ram / pitchfork / cluster bomb aren't implemented. Sequential sending only (no concurrency), capped at 1000 generated requests as a fixed safety limit against an accidental huge wordlist combined with several positions. Reuses the Repeater send primitive (proxy.Server.sendRaw) directly - an attack is just that primitive run in a loop with generated bytes - and results land in the same history table tagged source="intruder", same as Repeater's source="repeater", rather than a separate results store. ## Post-build-order: Burp/ZAP/Caido parity pass Build order 1-7 is done. Researched what those three actually offer (features and basic UI/UX) and triaged the gap into "should build soon" / "worth considering" / "skip" - see commit history for the full list; tracking what's shipped vs. deferred here. Shipped: vi-modal editing for the raw request textareas (table and viewport already had vi nav by default - this was specifically about textarea/textinput, which don't); a persistent status bar and a '?' keybinding reference; display-only response JSON pretty-printing; structured search filters (status:, source:, flagged:) alongside the existing FTS5 text search; a flagged marker (★) for "revisit this" - deliberately simpler than full free-text notes/comments, which would need their own text-input overlay for comparatively modest extra value over a boolean; noted as a real follow-up, not dropped silently; a Comparer tool - mark an entry with 'c' (from history list or detail view), 'c' again on a different entry opens a unified diff (git-diff style, colored) of either side's request or response. Unified rather than Burp's side-by-side: a two-column layout fights terminal width for anything but a narrow window, and unified reuses the same scrollable- viewport pattern already used everywhere else in the TUI. CRLF is normalized to LF before diffing (display-only, same reasoning as the JSON pretty-printer) so an HTTP/1.1 exact capture doesn't show every line as changed from an invisible trailing \r. Still open from "worth considering": a standalone encoder/decoder utility, multiple concurrent Repeater tabs, Intruder payload processing (encoding/case rules) and grep-match/grep-extract on results, CA install UX per OS, multiple proxy listeners and upstream proxy chaining. None of these are started yet. Skipped deliberately (from the research, matches this tool's stated scope): active/passive vulnerability scanning, plugin marketplace, Collaborator/OAST, team collaboration, CI integration, client TLS (mutual-TLS) certs, invisible/non-proxy-aware proxying.