srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/proxy/intrude.go
AgeCommit message (Collapse)AuthorFilesLines
2026-06-11Intruder: Battering ram, Pitchfork, and Cluster bomb attack modessrdusr1-48/+185
Generalizes Intrude beyond Sniper to all four of Burp's attack modes (proxy.AttackMode). Sniper and Battering ram only ever need one shared payload set; Pitchfork and Cluster bomb are inherently per-position, so they take one payload set per §marked§ position instead. Request-set generation (intrudeValues) is pure and side-effect free, so the total request count is validated against the existing 1000 cap before anything is dispatched - Cluster bomb's product is checked incrementally, one payload set at a time, so a pathological product bails out before ever trying to enumerate it. This also makes the combinatorics unit-testable without a live target. IntrudeResultMsg now reports Values (one substitution per marked position, in order) instead of a single Position/Payload pair, since three of the four modes touch multiple positions per request. TUI: `a` cycles the attack mode. Pitchfork/Cluster bomb reuse the existing single Payloads pane rather than a new multi-widget editor - sets are separated by a `---` delimiter line, in position order. Verified live against a real daemon: all four modes produce the expected substitution values and request counts, and pitchfork correctly rejects a payload-set count that doesn't match the template's marked positions.
2026-04-16Fix Intruder silently hanging on body-parameter fuzzingsrdusr1-0/+55
internal/proxy/intrude.go's buildRequest substitutes marker text but never recalculated Content-Length. A payload's length routinely differs from the base value it replaces, so any body-parameter fuzzing attack left a stale Content-Length from the original captured request in every substituted request. When the declared length is larger than the actual body sent, the target server blocks waiting for bytes that never arrive, and each such request eats the full 60s upstreamTimeout before failing - silently, with no error or warning anywhere. Since body- parameter fuzzing is one of the most common Intruder use cases and payload lengths vary within essentially every real attack, this made most real body-fuzzing attacks take payloads×60s for no visible reason. Found by a live audit that timed identical attacks: URL-only marker fuzzing (no body length change) completed in single-digit milliseconds per payload; the same attack with the marker in a body parameter took 60s per payload. fixContentLength recalculates an existing Content-Length header to match the actual body length after substitution, called right after buildRequest in the Intrude loop. Deliberately narrow: only touches a request with exactly one Content-Length header and a clean header/body boundary. Zero found means nothing to fix (unchanged). More than one is left alone too - a request smuggling test's own deliberately ambiguous framing, where guessing which one to "fix" would be worse than leaving both as the user built them. This is Intruder-specific, not a change to Repeater: what the user types into Repeater still goes on the wire completely unmodified, no auto-fixed Content-Length there, same as always. A fuzzed value's length is a side effect of automated substitution Intruder performs on the user's behalf, not a deliberate edit the way a Repeater request is. internal/proxy/intrude_test.go: TestFixContentLength covers recalculating a stale length, case-insensitive header matching, no-header and no-boundary no-ops, and the two-headers-left-alone case. Verified live against a real HTTP target and a real daemon (JSON over the control socket, not the TUI, for precise timing): a template with Content-Length declared far larger than any actual substituted body - the exact hang-triggering direction - completed all 4 payloads in 0.01s total, and the recorded history entries carry exactly the correct recalculated Content-Length for each (10/19/11/14, byte-for-byte matching each actual body). go build/vet/gofmt/test/mod tidy all clean.
2026-02-03Intruder-equivalent: Sniper attacks with § markerssrdusr1-0/+124
Implements build-order step 7, the last (optional) item. Scoped to Sniper only - one payload set, one §-marked position fuzzed at a time, others held at their base value - since that covers most real Intruder usage; battering ram / pitchfork / cluster bomb aren't implemented. Sequential sending, capped at 1000 generated requests as a fixed safety limit. internal/proxy: repeat.go's Repeat() is refactored into a shared sendRaw(..., source) primitive so Intrude can reuse the exact same raw-byte send/record path with source="intruder" instead of duplicating it. intrude.go adds ParseMarkers/buildRequest (marker parsing and payload substitution, covered by intrude_test.go - this is fiddly byte-splicing logic, worth locking down with real tests rather than trusting it by inspection) and Intrude(), which walks positions × payloads calling sendRaw and streaming each result through a callback. internal/ipc gains a dedicated streaming "intrude" connection (same shape as Subscribe, but blocking sends rather than drop-on-slow- consumer - each result is the attack's actual data, not a notification). cmd/mitmux gains an Intruder view: editable request template (ctrl+p inserts a § marker at the cursor - typing § directly also works, ctrl+p just doesn't require a keyboard layout that can produce it), editable payload list, and a live results table wired to the existing detail view (selecting a row and hitting enter opens the full request/response for that specific attack request). Verified live against real external traffic: a Sniper attack against httpbin.org/status/§200§ with payloads 200/404/500 produced exactly the three corresponding real status codes back (not a canned/local result), confirmed the three requests landed in history tagged source="intruder" with the § markers correctly stripped from what was actually sent, and confirmed opening a result row's full detail from the results table. This closes out the full build order from PLAN.md (steps 1-7).