srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/ipc/ipc.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ipc/ipc.go')
-rw-r--r--internal/ipc/ipc.go46
1 files changed, 31 insertions, 15 deletions
diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go
index 7d81473..270b8e4 100644
--- a/internal/ipc/ipc.go
+++ b/internal/ipc/ipc.go
@@ -38,6 +38,16 @@ type Request struct {
// turn (Sniper-style - see proxy.Intrude).
Payloads []string `json:"payloads,omitempty"`
+ // For "intrude": optional Go regexps evaluated against each result's
+ // response bytes. GrepMatch flags whether it matched at all;
+ // GrepExtract additionally captures text (first submatch if the
+ // pattern has a capturing group, else the whole match) into the
+ // result. Either or both may be empty to skip that check. Compiled
+ // and validated once, server-side, before the attack starts - a bad
+ // pattern fails the same way a bad marker or empty payload set does.
+ GrepMatch string `json:"grep_match,omitempty"`
+ GrepExtract string `json:"grep_extract,omitempty"`
+
// For "rules_save": add (Rule.ID == 0) or update (Rule.ID != 0) a
// match-and-replace rule. For "rules_delete"/"rules_toggle": RuleID
// (and RuleEnabled for toggle) identify the target.
@@ -72,13 +82,15 @@ type StatusMsg struct {
// IntrudeResultMsg is one completed Intruder attack request.
type IntrudeResultMsg struct {
- Position int `json:"position"`
- Payload string `json:"payload"`
- EntryID int64 `json:"entry_id"`
- StatusCode int `json:"status_code"`
- RespSize int `json:"resp_size"`
- Duration time.Duration `json:"duration"`
- Error string `json:"error,omitempty"`
+ Position int `json:"position"`
+ Payload string `json:"payload"`
+ EntryID int64 `json:"entry_id"`
+ StatusCode int `json:"status_code"`
+ RespSize int `json:"resp_size"`
+ Duration time.Duration `json:"duration"`
+ Error string `json:"error,omitempty"`
+ GrepMatch bool `json:"grep_match,omitempty"`
+ GrepExtract string `json:"grep_extract,omitempty"`
}
// EntryDetail is a full history entry, raw bytes included.
@@ -307,18 +319,22 @@ func Subscribe(path string) (<-chan store.Summary, func() error, error) {
// Intrude starts a Sniper attack (see proxy.Intrude): template must
// contain at least one §marked§ position, fuzzed in turn through
-// payloads. 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) 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) (<-chan IntrudeResultMsg, func() error, error) {
+// 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) {
conn, err := net.Dial("unix", path)
if err != nil {
return nil, nil, fmt.Errorf("dial %s: %w", path, err)
}
- if err := json.NewEncoder(conn).Encode(Request{Type: "intrude", Scheme: scheme, Host: host, Raw: template, Payloads: payloads}); err != nil {
+ req := Request{Type: "intrude", Scheme: scheme, Host: host, Raw: template, Payloads: payloads, GrepMatch: grepMatch, GrepExtract: grepExtract}
+ if err := json.NewEncoder(conn).Encode(req); err != nil {
conn.Close()
return nil, nil, err
}