Skip to content

Commit

Permalink
infer LogType based on events we want to match
Browse files Browse the repository at this point in the history
Signed-off-by: Quentin JEROME <[email protected]>
  • Loading branch information
qjerome committed Oct 15, 2023
1 parent 02c34cb commit 54d3070
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 15 deletions.
12 changes: 7 additions & 5 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ type Engine struct {
// default actions
defaultActions map[int][]string
// log formats
logFormats map[string]*LogType
logTypes map[string]*LogType

// engine statistics
Stats Stats
Expand All @@ -141,14 +141,16 @@ func NewEngine() (e *Engine) {
e.ruleExtensions = DefaultRuleExtensions
e.tplExtensions = DefaultTplExtensions
e.defaultActions = make(map[int][]string)
e.logFormats = make(map[string]*LogType)
e.AddLogFormat("winevt", &TypeWinevt)
e.AddLogFormat("kunai", &TypeKunai)
e.logTypes = make(map[string]*LogType)
// we set all known logTypes
for n, t := range logTypes {
e.logTypes[n] = t
}
return
}

func (e *Engine) AddLogFormat(name string, format *LogType) {
e.logFormats[name] = format
e.logTypes[name] = format
}

// addRule adds a rule to the current engine
Expand Down
5 changes: 5 additions & 0 deletions engine/log_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const (

var (
ErrUnkNameConv = fmt.Errorf("unknown name convension")

logTypes = map[string]*LogType{
"kunai": &TypeKunai,
"winevt": &TypeWinevt,
}
)

// NameConv defines a custom type for identifying
Expand Down
14 changes: 7 additions & 7 deletions engine/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func TestLoadRule(t *testing.T) {
"Condition": "$c and $a and (!$b)"
}`

er, err := LoadRule([]byte(ruleStr), nil, &TypeWinevt)
er, err := LoadRule([]byte(ruleStr), nil)
tt.CheckErr(err)

tt.Assert(er.Match(winevtEvent))
Expand Down Expand Up @@ -231,7 +231,7 @@ func TestBlacklist(t *testing.T) {
// bogus value in whitelist, we don't care what's in it
containers.AddStringToContainer("whitelist", "turbo fish")

er, err := LoadRule([]byte(ruleStr), containers, &TypeWinevt)
er, err := LoadRule([]byte(ruleStr), containers)

tt.CheckErr(err)
tt.Assert(er.Match(winevtEvent))
Expand All @@ -257,7 +257,7 @@ func TestIndirectMatch(t *testing.T) {
"Condition": "$dummyIndirect and $abs and !$fail"
}`

er, err := LoadRule([]byte(ruleStr), nil, &TypeWinevt)
er, err := LoadRule([]byte(ruleStr), nil)

tt.CheckErr(err)

Expand All @@ -279,7 +279,7 @@ func TestMatchEvent(t *testing.T) {
}
}`

er, err := LoadRule([]byte(ruleStr), nil, &TypeWinevt)
er, err := LoadRule([]byte(ruleStr), nil)
tt.CheckErr(err)
tt.Assert(!er.EventFilter.IsEmpty(), "filter should not be empty")

Expand All @@ -301,7 +301,7 @@ func TestMatchOS(t *testing.T) {
}
}`

er, err := LoadRule([]byte(ruleStr), nil, nil)
er, err := LoadRule([]byte(ruleStr), nil)
tt.CheckErr(err)
tt.Assert(er.OSs.Len() == 3)

Expand All @@ -320,7 +320,7 @@ func TestMatchOS(t *testing.T) {
"Meta": {
"OSs": ["invalid_os"]
}
}`), nil, nil)
}`), nil)

tt.ExpectErr(err, ErrInvalidOS)
}
Expand All @@ -343,6 +343,6 @@ func TestAuthorsComments(t *testing.T) {
}
}`

_, err := LoadRule([]byte(ruleStr), nil, nil)
_, err := LoadRule([]byte(ruleStr), nil)
tt.CheckErr(err)
}
34 changes: 31 additions & 3 deletions engine/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,38 @@ func (jr *Rule) JSON() (string, error) {
return string(b), err
}

func (jr *Rule) resolveLogType(logTypes map[string]*LogType) *LogType {
// the logtype specified in rule takes precedence
if len(jr.Meta.LogType) > 0 {
return logTypes[jr.Meta.LogType]
}

// if we wanna match ONLY kunai events
if _, ok := jr.Meta.Events["kunai"]; ok && len(jr.Meta.Events) == 1 {
return logTypes["kunai"]
}

// based on windows channels frequently matched
winMatch := 0
for c := range jr.Meta.Events {
if c == "Security" ||
strings.HasPrefix(c, "Microsoft") {
winMatch += 1
}
}

// we are sure ONLY all we want to match are windows channels
if winMatch == len(jr.Meta.Events) {
return logTypes["winevt"]
}

return nil
}

// Compile a Rule
func (jr *Rule) Compile(e *Engine) (*CompiledRule, error) {
if e != nil {
return jr.compile(e.containers, e.logFormats[jr.Meta.LogType])
return jr.compile(e.containers, jr.resolveLogType(e.logTypes))
}
return jr.compile(nil, nil)
}
Expand Down Expand Up @@ -338,13 +366,13 @@ func (jr *Rule) compile(containers *ContainerDB, format *LogType) (*CompiledRule
}

// LoadRule loads (unmarshal and compile) a rule
func LoadRule(b []byte, containers *ContainerDB, format *LogType) (*CompiledRule, error) {
func LoadRule(b []byte, containers *ContainerDB) (*CompiledRule, error) {
var jr Rule

dec := NewRuleDecoder(bytes.NewBuffer(b))
err := dec.Decode(&jr)
if err != nil {
return nil, err
}
return jr.compile(containers, format)
return jr.compile(containers, jr.resolveLogType(logTypes))
}

0 comments on commit 54d3070

Please sign in to comment.