From bfae89ce80d653caf1aaa30913e3477c1377ccf9 Mon Sep 17 00:00:00 2001 From: rkspx Date: Mon, 11 Apr 2022 12:34:34 +0700 Subject: [PATCH] fix inverse behaviour on text matching --- internal/pkg/dsiem/rule/rule.go | 19 ++++++++++++++++++- internal/pkg/dsiem/rule/rule_test.go | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/pkg/dsiem/rule/rule.go b/internal/pkg/dsiem/rule/rule.go index fa7bbde9..45aec1fe 100644 --- a/internal/pkg/dsiem/rule/rule.go +++ b/internal/pkg/dsiem/rule/rule.go @@ -388,11 +388,12 @@ func isNetAddrMatchCSVRule(rulesInCSV, term string) bool { // split it into slice of strings, match its value one by one, and returns if one of the value matches. // otherwose, matchText will do non case-sensitve match for the subject and term. func matchText(subject, term string) bool { + if isCSV(subject) { return isStringMatchCSVRule(subject, term) } - return strings.TrimSpace(strings.ToLower(subject)) == strings.TrimSpace(strings.ToLower(term)) + return matchTextNonSensitive(subject, term) } // isCSV determines wether the given term is a comma separated list of strings or not. @@ -402,6 +403,22 @@ func isCSV(term string) bool { return strings.Contains(term, ",") } +func matchTextNonSensitive(term1, term2 string) bool { + var inverse bool + if strings.HasPrefix(term1, "!") { + term1 = str.TrimLeftChar(term1) + inverse = true + } + + match := strings.TrimSpace(strings.ToLower(term1)) == strings.TrimSpace(strings.ToLower(term2)) + + if inverse { + return !match + } + + return match +} + func isStringMatchCSVRule(rulesInCSV string, term string) (match bool) { // s is something like stringA, stringB, !stringC, !stringD sSlice := str.CsvToSlice(rulesInCSV) diff --git a/internal/pkg/dsiem/rule/rule_test.go b/internal/pkg/dsiem/rule/rule_test.go index 29380428..aa02eeb9 100644 --- a/internal/pkg/dsiem/rule/rule_test.go +++ b/internal/pkg/dsiem/rule/rule_test.go @@ -512,6 +512,7 @@ func TestCustomDataMatch(t *testing.T) { {"Network Command Shell", "Network Command Shell", true}, {"Network Command Shell", "Network Command Login", false}, {"!Network Command Shell", "Network Command Shell", false}, + {"!Network Command Shell", "Network Command Login", true}, {"foo,bar,qux", "foo", true}, {"foo,bar,qux", "bar", true}, {"foo,bar,qux", "qux", true}, @@ -519,6 +520,8 @@ func TestCustomDataMatch(t *testing.T) { {"foo,!bar,qux", "bar", false}, {"foo,bar,!qux", "qux", false}, {"!foo,bar,qux", "foo", false}, + {"!foo, foo, bar, qux", "foo", false}, + {"foo, !foo, bar, qux", "foo", true}, } { t.Run(c.ruleCustomData, func(t *testing.T) { r := DirectiveRule{