srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ipc')
-rw-r--r--internal/ipc/ipc.go48
-rw-r--r--internal/ipc/server.go14
2 files changed, 37 insertions, 25 deletions
diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go
index 89a8343..d581313 100644
--- a/internal/ipc/ipc.go
+++ b/internal/ipc/ipc.go
@@ -12,6 +12,7 @@ import (
"sync"
"time"
+ "mitmux/internal/proxy"
"mitmux/internal/rules"
"mitmux/internal/scope"
"mitmux/internal/store"
@@ -35,9 +36,13 @@ type Request struct {
Host string `json:"host,omitempty"`
Raw []byte `json:"raw,omitempty"`
- // For "intrude": the payload set, applied to each marked position in
- // turn (Sniper-style - see proxy.Intrude).
- Payloads []string `json:"payloads,omitempty"`
+ // For "intrude": the attack mode (proxy.Sniper and so on - empty
+ // defaults to Sniper) and its payload sets. Sniper and BatteringRam
+ // only ever use PayloadSets[0] (one shared set); Pitchfork and
+ // ClusterBomb require exactly one set per §marked§ position, in
+ // order - see proxy.Intrude.
+ Mode proxy.AttackMode `json:"mode,omitempty"`
+ PayloadSets [][]string `json:"payload_sets,omitempty"`
// For "intrude": optional Go regexps evaluated against each result's
// response bytes. GrepMatch flags whether it matched at all;
@@ -118,10 +123,14 @@ type StatusMsg struct {
HistoryCount int64 `json:"history_count"`
}
-// IntrudeResultMsg is one completed Intruder attack request.
+// IntrudeResultMsg is one completed Intruder attack request. Values holds
+// what was substituted into each §marked§ position for this request, in
+// position order - for Sniper, every entry but the one fuzzed position
+// equals that position's base value; for the other three modes every
+// entry is an actual payload.
type IntrudeResultMsg struct {
- Position int `json:"position"`
- Payload string `json:"payload"`
+ Iteration int `json:"iteration"`
+ Values []string `json:"values"`
EntryID int64 `json:"entry_id"`
StatusCode int `json:"status_code"`
RespSize int `json:"resp_size"`
@@ -468,23 +477,24 @@ func Subscribe(path string) (<-chan store.Summary, func() error, error) {
return ch, conn.Close, nil
}
-// Intrude starts a Sniper attack (see proxy.Intrude): template must
-// contain at least one §marked§ position, fuzzed in turn through
-// payloads. grepMatch/grepExtract are optional Go regexps evaluated
-// server-side against each result's response bytes (empty string
-// disables either check) - see IntrudeResultMsg. Unlike Subscribe's live
-// feed, no result is ever dropped for a slow consumer - each one is the
-// attack's actual data, not a notification with the real thing
-// recoverable elsewhere. A setup error (bad markers, empty payload set,
-// too many requests, an unparseable grep regexp) is returned directly
-// rather than through the channel. The returned channel closes when the
-// attack finishes or the connection is closed early.
-func Intrude(path, scheme, host string, template []byte, payloads []string, grepMatch, grepExtract string) (<-chan IntrudeResultMsg, func() error, error) {
+// Intrude starts an attack (see proxy.Intrude and proxy.AttackMode):
+// template must contain at least one §marked§ position. mode selects how
+// payloadSets combine across positions; "" defaults to Sniper.
+// grepMatch/grepExtract are optional Go regexps evaluated server-side
+// against each result's response bytes (empty string disables either
+// check) - see IntrudeResultMsg. Unlike Subscribe's live feed, no result
+// is ever dropped for a slow consumer - each one is the attack's actual
+// data, not a notification with the real thing recoverable elsewhere. A
+// setup error (bad markers, empty payload set, too many requests, an
+// unparseable grep regexp) is returned directly rather than through the
+// channel. The returned channel closes when the attack finishes or the
+// connection is closed early.
+func Intrude(path, scheme, host string, template []byte, mode proxy.AttackMode, payloadSets [][]string, grepMatch, grepExtract string) (<-chan IntrudeResultMsg, func() error, error) {
conn, err := net.Dial("unix", path)
if err != nil {
return nil, nil, fmt.Errorf("dial %s: %w", path, err)
}
- req := Request{Type: "intrude", Scheme: scheme, Host: host, Raw: template, Payloads: payloads, GrepMatch: grepMatch, GrepExtract: grepExtract}
+ req := Request{Type: "intrude", Scheme: scheme, Host: host, Raw: template, Mode: mode, PayloadSets: payloadSets, GrepMatch: grepMatch, GrepExtract: grepExtract}
if err := json.NewEncoder(conn).Encode(req); err != nil {
conn.Close()
return nil, nil, err
diff --git a/internal/ipc/server.go b/internal/ipc/server.go
index c83254e..c890a54 100644
--- a/internal/ipc/server.go
+++ b/internal/ipc/server.go
@@ -9,6 +9,7 @@ import (
"regexp"
"sync"
+ "mitmux/internal/proxy"
"mitmux/internal/rules"
"mitmux/internal/scope"
"mitmux/internal/store"
@@ -20,11 +21,12 @@ type Repeater interface {
Repeat(ctx context.Context, scheme, host string, raw []byte) (*store.Entry, error)
}
-// Intruder runs a Sniper attack over a §marked§ request template -
+// Intruder runs an attack (Sniper, Battering ram, Pitchfork, or Cluster
+// bomb - see proxy.AttackMode) over a §marked§ request template -
// implemented by *proxy.Server.
type Intruder interface {
- Intrude(ctx context.Context, scheme, host string, template []byte, payloads []string,
- onResult func(position int, payload string, entry *store.Entry, sendErr error) bool) error
+ Intrude(ctx context.Context, scheme, host string, template []byte, mode proxy.AttackMode, payloadSets [][]string,
+ onResult func(iteration int, values []string, entry *store.Entry, sendErr error) bool) error
}
// Hub fans out newly captured history entries to subscribed clients.
@@ -174,9 +176,9 @@ func (s *Server) handleConn(conn net.Conn) {
}
grepExtractRe = re
}
- err := s.intruder.Intrude(context.Background(), req.Scheme, req.Host, req.Raw, req.Payloads,
- func(position int, payload string, entry *store.Entry, sendErr error) bool {
- r := IntrudeResultMsg{Position: position, Payload: payload}
+ err := s.intruder.Intrude(context.Background(), req.Scheme, req.Host, req.Raw, req.Mode, req.PayloadSets,
+ func(iteration int, values []string, entry *store.Entry, sendErr error) bool {
+ r := IntrudeResultMsg{Iteration: iteration, Values: values}
if sendErr != nil {
r.Error = sendErr.Error()
}