diff --git a/pkg/acquisition/modules/waap/waap_runner.go b/pkg/acquisition/modules/waap/waap_runner.go index 5bf8cef63..fa80141ed 100644 --- a/pkg/acquisition/modules/waap/waap_runner.go +++ b/pkg/acquisition/modules/waap/waap_runner.go @@ -40,10 +40,11 @@ func (r *WaapRunner) Init(datadir string) error { for _, collection := range r.WaapRuntime.OutOfBandRules { outOfBandRules += collection.String() } - runnerLogger := r.logger.Dup() + inBandLogger := r.logger.Dup().WithField("band", "inband") + outBandLogger := r.logger.Dup().WithField("band", "outband") //setting up inband engine - inbandCfg := coraza.NewWAFConfig().WithDirectives(inBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(runnerLogger)) + inbandCfg := coraza.NewWAFConfig().WithDirectives(inBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(inBandLogger)) if !r.WaapRuntime.Config.InbandOptions.DisableBodyInspection { inbandCfg = inbandCfg.WithRequestBodyAccess() } else { @@ -58,7 +59,7 @@ func (r *WaapRunner) Init(datadir string) error { } //setting up outband engine - outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(runnerLogger)) + outbandCfg := coraza.NewWAFConfig().WithDirectives(outOfBandRules).WithRootFS(fs).WithDebugLogger(waf.NewCrzLogger(outBandLogger)) if !r.WaapRuntime.Config.OutOfBandOptions.DisableBodyInspection { outbandCfg = outbandCfg.WithRequestBodyAccess() } else { diff --git a/pkg/types/event.go b/pkg/types/event.go index 83e5ee76a..0e8de7f8e 100644 --- a/pkg/types/event.go +++ b/pkg/types/event.go @@ -1,9 +1,7 @@ package types import ( - "fmt" "net" - "regexp" "time" log "github.com/sirupsen/logrus" @@ -18,230 +16,6 @@ const ( WAAP ) -/* - 1. If user triggered a rule that is for a CVE, that has high confidence and that is blocking, ban - 2. If user triggered 3 distinct rules with medium confidence accross 3 different requests, ban - - -any(evt.Waf.ByTag("CVE"), {.confidence == "high" && .action == "block"}) - -len(evt.Waf.ByTagRx("*CVE*").ByConfidence("high").ByAction("block")) > 1 - -*/ - -type MatchedRules []map[string]interface{} - -type WaapEvent struct { - MatchedRules - Vars map[string]string -} -type Field string - -func (f Field) String() string { - return fmt.Sprintf("%s", f) -} - -const ( - ID Field = "id" - RuleType Field = "rule_type" - Tags Field = "tags" - File Field = "file" - Confidence Field = "confidence" - Revision Field = "revision" - SecMark Field = "secmark" - Accuracy Field = "accuracy" - Msg Field = "msg" - Severity Field = "severity" - Kind Field = "kind" -) - -func (w WaapEvent) GetVar(varName string) string { - if w.Vars == nil { - return "" - } - if val, ok := w.Vars[varName]; ok { - return val - } - log.Infof("var %s not found", varName, w.Vars) - return "" - -} - -// getters -func (w MatchedRules) GetField(field Field) []interface{} { - ret := make([]interface{}, 0) - for _, rule := range w { - ret = append(ret, rule[field.String()]) - } - return ret -} - -func (w MatchedRules) GetURI() string { - for _, rule := range w { - return rule["uri"].(string) - } - return "" -} - -func (w MatchedRules) GetHash() string { - for _, rule := range w { - //@sbl : let's fix this - return rule["hash"].(string) - } - return "" -} - -func (w MatchedRules) GetVersion() string { - for _, rule := range w { - //@sbl : let's fix this - return rule["version"].(string) - } - return "" -} - -func (w MatchedRules) GetName() string { - for _, rule := range w { - //@sbl : let's fix this - return rule["name"].(string) - } - return "" -} - -func (w MatchedRules) GetMethod() string { - for _, rule := range w { - return rule["method"].(string) - } - return "" -} - -func (w MatchedRules) GetRuleIDs() []int { - ret := make([]int, 0) - for _, rule := range w { - ret = append(ret, rule["id"].(int)) - } - return ret -} - -func (w MatchedRules) Kinds() []string { - ret := make([]string, 0) - for _, rule := range w { - exists := false - for _, val := range ret { - if val == rule["kind"] { - exists = true - break - } - } - if !exists { - ret = append(ret, rule["kind"].(string)) - } - } - return ret -} - -// filters -func (w MatchedRules) ByID(id int) MatchedRules { - waap := MatchedRules{} - - for _, rule := range w { - if rule["id"] == id { - waap = append(waap, rule) - } - } - return waap -} - -func (w MatchedRules) ByKind(kind string) MatchedRules { - waap := MatchedRules{} - for _, rule := range w { - if rule["kind"] == kind { - waap = append(waap, rule) - } - } - return waap -} - -func (w MatchedRules) ByTags(match []string) MatchedRules { - waap := MatchedRules{} - for _, rule := range w { - for _, tag := range rule["tags"].([]string) { - for _, match_tag := range match { - if tag == match_tag { - waap = append(waap, rule) - break - } - } - } - } - return waap -} - -func (w MatchedRules) ByTag(match string) MatchedRules { - waap := MatchedRules{} - for _, rule := range w { - for _, tag := range rule["tags"].([]string) { - if tag == match { - waap = append(waap, rule) - break - } - } - } - return waap -} - -func (w MatchedRules) ByTagRx(rx string) MatchedRules { - waap := MatchedRules{} - re := regexp.MustCompile(rx) - if re == nil { - return waap - } - for _, rule := range w { - for _, tag := range rule["tags"].([]string) { - log.Infof("ByTagRx: %s = %s -> %t", rx, tag, re.MatchString(tag)) - if re.MatchString(tag) { - waap = append(waap, rule) - break - } - } - } - return waap -} - -func (w MatchedRules) ByDisruptiveness(is bool) MatchedRules { - log.Infof("%s", w) - wap := MatchedRules{} - for _, rule := range w { - if rule["disruptive"] == is { - wap = append(wap, rule) - } - } - log.Infof("ByDisruptiveness(%t) -> %d", is, len(wap)) - - return wap -} - -func (w MatchedRules) BySeverity(severity string) MatchedRules { - wap := MatchedRules{} - for _, rule := range w { - if rule["severity"] == severity { - wap = append(wap, rule) - } - } - log.Infof("BySeverity(%s) -> %d", severity, len(wap)) - return wap -} - -func (w MatchedRules) ByAccuracy(accuracy string) MatchedRules { - wap := MatchedRules{} - for _, rule := range w { - if rule["accuracy"] == accuracy { - wap = append(wap, rule) - } - } - log.Infof("ByAccuracy(%s) -> %d", accuracy, len(wap)) - return wap -} - // Event is the structure representing a runtime event (log or overflow) type Event struct { /* is it a log or an overflow */ diff --git a/pkg/types/waap_event.go b/pkg/types/waap_event.go new file mode 100644 index 000000000..9b474be4d --- /dev/null +++ b/pkg/types/waap_event.go @@ -0,0 +1,231 @@ +package types + +import ( + "regexp" + + log "github.com/sirupsen/logrus" +) + +/* + 1. If user triggered a rule that is for a CVE, that has high confidence and that is blocking, ban + 2. If user triggered 3 distinct rules with medium confidence accross 3 different requests, ban + + +any(evt.Waf.ByTag("CVE"), {.confidence == "high" && .action == "block"}) + +len(evt.Waf.ByTagRx("*CVE*").ByConfidence("high").ByAction("block")) > 1 + +*/ + +type MatchedRules []map[string]interface{} + +type WaapEvent struct { + MatchedRules + Vars map[string]string +} +type Field string + +func (f Field) String() string { + return string(f) +} + +const ( + ID Field = "id" + RuleType Field = "rule_type" + Tags Field = "tags" + File Field = "file" + Confidence Field = "confidence" + Revision Field = "revision" + SecMark Field = "secmark" + Accuracy Field = "accuracy" + Msg Field = "msg" + Severity Field = "severity" + Kind Field = "kind" +) + +func (w WaapEvent) GetVar(varName string) string { + if w.Vars == nil { + return "" + } + if val, ok := w.Vars[varName]; ok { + return val + } + log.Infof("var %s not found. Available variables: %+v", varName, w.Vars) + return "" + +} + +// getters +func (w MatchedRules) GetField(field Field) []interface{} { + ret := make([]interface{}, 0) + for _, rule := range w { + ret = append(ret, rule[field.String()]) + } + return ret +} + +func (w MatchedRules) GetURI() string { + for _, rule := range w { + return rule["uri"].(string) + } + return "" +} + +func (w MatchedRules) GetHash() string { + for _, rule := range w { + //@sbl : let's fix this + return rule["hash"].(string) + } + return "" +} + +func (w MatchedRules) GetVersion() string { + for _, rule := range w { + //@sbl : let's fix this + return rule["version"].(string) + } + return "" +} + +func (w MatchedRules) GetName() string { + for _, rule := range w { + //@sbl : let's fix this + return rule["name"].(string) + } + return "" +} + +func (w MatchedRules) GetMethod() string { + for _, rule := range w { + return rule["method"].(string) + } + return "" +} + +func (w MatchedRules) GetRuleIDs() []int { + ret := make([]int, 0) + for _, rule := range w { + ret = append(ret, rule["id"].(int)) + } + return ret +} + +func (w MatchedRules) Kinds() []string { + ret := make([]string, 0) + for _, rule := range w { + exists := false + for _, val := range ret { + if val == rule["kind"] { + exists = true + break + } + } + if !exists { + ret = append(ret, rule["kind"].(string)) + } + } + return ret +} + +// filters +func (w MatchedRules) ByID(id int) MatchedRules { + waap := MatchedRules{} + + for _, rule := range w { + if rule["id"] == id { + waap = append(waap, rule) + } + } + return waap +} + +func (w MatchedRules) ByKind(kind string) MatchedRules { + waap := MatchedRules{} + for _, rule := range w { + if rule["kind"] == kind { + waap = append(waap, rule) + } + } + return waap +} + +func (w MatchedRules) ByTags(match []string) MatchedRules { + waap := MatchedRules{} + for _, rule := range w { + for _, tag := range rule["tags"].([]string) { + for _, match_tag := range match { + if tag == match_tag { + waap = append(waap, rule) + break + } + } + } + } + return waap +} + +func (w MatchedRules) ByTag(match string) MatchedRules { + waap := MatchedRules{} + for _, rule := range w { + for _, tag := range rule["tags"].([]string) { + if tag == match { + waap = append(waap, rule) + break + } + } + } + return waap +} + +func (w MatchedRules) ByTagRx(rx string) MatchedRules { + waap := MatchedRules{} + re := regexp.MustCompile(rx) + if re == nil { + return waap + } + for _, rule := range w { + for _, tag := range rule["tags"].([]string) { + log.Infof("ByTagRx: %s = %s -> %t", rx, tag, re.MatchString(tag)) + if re.MatchString(tag) { + waap = append(waap, rule) + break + } + } + } + return waap +} + +func (w MatchedRules) ByDisruptiveness(is bool) MatchedRules { + log.Infof("%s", w) + wap := MatchedRules{} + for _, rule := range w { + if rule["disruptive"] == is { + wap = append(wap, rule) + } + } + log.Infof("ByDisruptiveness(%t) -> %d", is, len(wap)) + + return wap +} + +func (w MatchedRules) BySeverity(severity string) MatchedRules { + wap := MatchedRules{} + for _, rule := range w { + if rule["severity"] == severity { + wap = append(wap, rule) + } + } + log.Infof("BySeverity(%s) -> %d", severity, len(wap)) + return wap +} + +func (w MatchedRules) ByAccuracy(accuracy string) MatchedRules { + wap := MatchedRules{} + for _, rule := range w { + if rule["accuracy"] == accuracy { + wap = append(wap, rule) + } + } + log.Infof("ByAccuracy(%s) -> %d", accuracy, len(wap)) + return wap +}