|
@@ -3,6 +3,7 @@ package csprofiles
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
"net"
|
|
"net"
|
|
|
|
+ "strings"
|
|
|
|
|
|
"github.com/antonmedv/expr"
|
|
"github.com/antonmedv/expr"
|
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
|
@@ -45,14 +46,15 @@ func GenerateDecisionFromProfile(Profile *csconfig.ProfileCfg, Alert *models.Ale
|
|
decision.Value = new(string)
|
|
decision.Value = new(string)
|
|
*decision.Value = *Alert.Source.Value
|
|
*decision.Value = *Alert.Source.Value
|
|
|
|
|
|
- if *decision.Scope == types.Ip {
|
|
|
|
|
|
+ if strings.EqualFold(*decision.Scope, types.Ip) {
|
|
srcAddr := net.ParseIP(Alert.Source.IP)
|
|
srcAddr := net.ParseIP(Alert.Source.IP)
|
|
if srcAddr == nil {
|
|
if srcAddr == nil {
|
|
return nil, fmt.Errorf("can't parse ip %s", Alert.Source.IP)
|
|
return nil, fmt.Errorf("can't parse ip %s", Alert.Source.IP)
|
|
}
|
|
}
|
|
decision.StartIP = int64(types.IP2Int(srcAddr))
|
|
decision.StartIP = int64(types.IP2Int(srcAddr))
|
|
decision.EndIP = decision.StartIP
|
|
decision.EndIP = decision.StartIP
|
|
- } else if *decision.Scope == types.Range {
|
|
|
|
|
|
+ } else if strings.EqualFold(*decision.Scope, types.Range) {
|
|
|
|
+
|
|
/*here we're asked to ban a full range. let's keep in mind that it's not always possible :
|
|
/*here we're asked to ban a full range. let's keep in mind that it's not always possible :
|
|
- the alert is about an IP, but the geolite enrichment failed
|
|
- the alert is about an IP, but the geolite enrichment failed
|
|
- the alert is about an IP, but the geolite enrichment isn't present
|
|
- the alert is about an IP, but the geolite enrichment isn't present
|
|
@@ -108,6 +110,7 @@ func EvaluateProfiles(Profiles []*csconfig.ProfileCfg, Alert *models.Alert) ([]*
|
|
}
|
|
}
|
|
PROFILE_LOOP:
|
|
PROFILE_LOOP:
|
|
for _, profile := range Profiles {
|
|
for _, profile := range Profiles {
|
|
|
|
+ matched := false
|
|
for eIdx, expression := range profile.RuntimeFilters {
|
|
for eIdx, expression := range profile.RuntimeFilters {
|
|
output, err := expr.Run(expression, exprhelpers.GetExprEnv(map[string]interface{}{"Alert": Alert}))
|
|
output, err := expr.Run(expression, exprhelpers.GetExprEnv(map[string]interface{}{"Alert": Alert}))
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -117,11 +120,13 @@ PROFILE_LOOP:
|
|
switch out := output.(type) {
|
|
switch out := output.(type) {
|
|
case bool:
|
|
case bool:
|
|
if out {
|
|
if out {
|
|
|
|
+ matched = true
|
|
/*the expression matched, create the associated decision*/
|
|
/*the expression matched, create the associated decision*/
|
|
subdecisions, err := GenerateDecisionFromProfile(profile, Alert)
|
|
subdecisions, err := GenerateDecisionFromProfile(profile, Alert)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "while generating decision from profile %s", profile.Name)
|
|
return nil, errors.Wrapf(err, "while generating decision from profile %s", profile.Name)
|
|
}
|
|
}
|
|
|
|
+
|
|
decisions = append(decisions, subdecisions...)
|
|
decisions = append(decisions, subdecisions...)
|
|
} else {
|
|
} else {
|
|
if profile.Debug != nil && *profile.Debug {
|
|
if profile.Debug != nil && *profile.Debug {
|
|
@@ -132,10 +137,14 @@ PROFILE_LOOP:
|
|
break PROFILE_LOOP
|
|
break PROFILE_LOOP
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
default:
|
|
default:
|
|
return nil, fmt.Errorf("unexpected type %t (%v) while running '%s'", output, output, profile.Filters[eIdx])
|
|
return nil, fmt.Errorf("unexpected type %t (%v) while running '%s'", output, output, profile.Filters[eIdx])
|
|
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if matched {
|
|
if profile.OnSuccess == "break" {
|
|
if profile.OnSuccess == "break" {
|
|
break PROFILE_LOOP
|
|
break PROFILE_LOOP
|
|
}
|
|
}
|