This commit is contained in:
Sebastien Blot 2023-07-24 09:13:26 +02:00
parent 4993758b36
commit 01ced8fb99
No known key found for this signature in database
GPG key ID: DFC2902F40449F6A
4 changed files with 44 additions and 14 deletions

2
go.mod
View file

@ -204,3 +204,5 @@ require (
)
replace golang.org/x/time/rate => github.com/crowdsecurity/crowdsec/pkg/time/rate v0.0.0
replace github.com/crowdsecurity/coraza/v3 => /home/seb/taff/crowdsec/git/crowdsec-org/coraza

View file

@ -8,7 +8,6 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/pkg/waf"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
)
func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
@ -47,16 +46,17 @@ func EventFromRequest(r waf.ParsedRequest) (types.Event, error) {
}
func LogWaapEvent(evt *types.Event) {
log.WithFields(log.Fields{
/*log.WithFields(log.Fields{
"module": "waf",
"source": evt.Parsed["source_ip"],
"target_uri": evt.Parsed["target_uri"],
}).Infof("%s triggered %d rules [%+v]", evt.Parsed["source_ip"], len(evt.Waap), evt.Waap.GetRuleIDs())
}).Infof("%s triggered %d rules [%+v]", evt.Parsed["source_ip"], len(evt.Waap), evt.Waap.GetRuleIDs())*/
//log.Infof("%s", evt.Waap)
}
func (r *WafRunner) AccumulateTxToEvent(tx experimental.FullTransaction, kind string, evt *types.Event) error {
r.logger.Infof("TX %v", &tx)
//log.Infof("tx addr: %p", tx)
if tx.IsInterrupted() {
r.logger.Infof("interrupted() = %t", tx.IsInterrupted())
r.logger.Infof("interrupted.action = %s", tx.Interruption().Action)
@ -66,10 +66,15 @@ func (r *WafRunner) AccumulateTxToEvent(tx experimental.FullTransaction, kind st
evt.Parsed["interrupted"] = "true"
evt.Parsed["action"] = tx.Interruption().Action
//log.Infof("action: %s", tx.Interruption().Action)
evt.Meta["waap_interrupted"] = "1"
evt.Meta["waap_action"] = tx.Interruption().Action
}
r.logger.Infof("variables addr in AccumulateTxToEvent: %p", tx.Variables())
//log.Infof("variables: %s", spew.Sdump(tx.Variables()))
//log.Infof("tx variables: %+v", tx.Collection(variables.TX))
//log.Infof("TX %s", spew.Sdump(tx.MatchedRules()))
for _, rule := range tx.MatchedRules() {
if rule.Message() == "" {
continue

View file

@ -11,8 +11,10 @@ import (
"github.com/antonmedv/expr"
"github.com/crowdsecurity/coraza/v3"
"github.com/crowdsecurity/coraza/v3/collection"
"github.com/crowdsecurity/coraza/v3/experimental"
corazatypes "github.com/crowdsecurity/coraza/v3/types"
"github.com/crowdsecurity/coraza/v3/types/variables"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/pkg/waf"
@ -206,6 +208,7 @@ func (w *WafSource) Configure(yamlConfig []byte, logger *log.Entry) error {
}
w.InChan = make(chan waf.ParsedRequest)
w.logger.Infof("w.InChan creation: %p", w.InChan)
w.WafRunners = make([]WafRunner, w.config.WafRoutines)
for nbRoutine := 0; nbRoutine < w.config.WafRoutines; nbRoutine++ {
w.logger.Infof("Loading %d in-band rules", len(strings.Split(inBandRules, "\n")))
@ -259,10 +262,7 @@ func (w *WafSource) Configure(yamlConfig []byte, logger *log.Entry) error {
w.WafRunners[nbRoutine] = runner
}
w.logger.Infof("Loading %d out-of-band rules", len(strings.Split(outOfBandRules, "\n")))
if err != nil {
return errors.Wrap(err, "Cannot create WAF")
}
w.logger.Infof("Created %d waf runners", len(w.WafRunners))
//We don´t use the wrapper provided by coraza because we want to fully control what happens when a rule match to send the information in crowdsec
w.mux.HandleFunc(w.config.Path, w.wafHandler)
@ -296,6 +296,7 @@ func (w *WafSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) err
runner := runner
runner.outChan = out
t.Go(func() error {
defer trace.CatchPanic("crowdsec/acquis/waf/live/runner")
return runner.Run(t)
})
}
@ -370,15 +371,26 @@ func (r *WafRunner) processReqWithEngine(tx experimental.FullTransaction, parsed
in = tx.ProcessRequestHeaders()
for _, v := range tx.Collection(variables.TX).FindAll() {
log.Infof("tx variable: %s | %s", v.Key(), v.Value())
}
tx.Variables().All(func(v variables.RuleVariable, col collection.Collection) bool {
log.Infof("Collection: %s", col.Name())
log.Infof("Variable: %s", v.Name())
//collect := tx.Collection(col)
return true
})
//spew.Dump(in)
//spew.Dump(tx.MatchedRules())
for _, rule := range tx.MatchedRules() {
//r.logger.Infof("Rule %d disruptive: %t", rule.Rule().ID(), rule.Disruptive())
/*for _, rule := range tx.MatchedRules() {
log.Infof("Rule %d disruptive: %t", rule.Rule().ID(), rule.Disruptive())
if rule.Message() == "" {
continue
}
}
}*/
//if we're inband, we should stop here, but for outofband go to the end
if in != nil && wafType == InBand {
@ -393,6 +405,7 @@ func (r *WafRunner) processReqWithEngine(tx experimental.FullTransaction, parsed
}
if it != nil {
//log.Infof("blocking rule id %d", in.RuleID)
return it, nil, nil
}
// from https://github.com/corazawaf/coraza/blob/main/internal/corazawaf/transaction.go#L419
@ -413,6 +426,8 @@ func (r *WafRunner) processReqWithEngine(tx experimental.FullTransaction, parsed
return nil, nil, errors.Wrap(err, "Cannot process request body")
}
if in != nil && wafType == InBand {
//log.Infof("blocking rule id %d", in.RuleID)
return in, tx, nil
}
@ -427,6 +442,7 @@ func (r *WafRunner) Run(t *tomb.Tomb) error {
r.logger.Infof("Waf Runner is dying")
return nil
case request := <-r.inChan:
r.logger.Infof("Requests handled by runner %s", r.UUID)
var evt *types.Event
WafReqCounter.With(prometheus.Labels{"source": request.RemoteAddr}).Inc()
//measure the time spent in the WAF
@ -436,6 +452,8 @@ func (r *WafRunner) Run(t *tomb.Tomb) error {
// we use this internal transaction for the expr helpers
tx := waf.NewTransaction(expTx)
//r.logger.Infof("Processing request %s | tx: %p", request.UUID, tx)
//Run the pre_eval hooks
for _, rules := range r.RulesCollections {
if len(rules.CompiledPreEval) == 0 {
@ -482,6 +500,12 @@ func (r *WafRunner) Run(t *tomb.Tomb) error {
request.Tx = expTx
//log.Infof("-> %s", spew.Sdump(in))
//log.Infof("tx variables: %+v", expTx.Collection(variables.TX))
//foo := expTx.(plugintypes.TransactionState)
//log.Infof("from tstate: %+v", foo.Variables().TX().FindAll())
response := waf.NewResponseRequest(expTx, in, request.UUID, err)
// run the on_match hooks

View file

@ -11,7 +11,6 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/davecgh/go-spew/spew"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
)
@ -104,7 +103,7 @@ func (w *WafRuleLoader) LoadWafRules() ([]*WafRulesCollection, error) {
continue
}
spew.Dump(wafConfig)
//spew.Dump(wafConfig)
collection := &WafRulesCollection{}