-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ECS normalization #62
Changes from all commits
b421380
e661278
d853608
54e16a6
8ff6108
ddba1ce
c1d127f
39525d6
b6f7bcd
8c22c7a
2a64f9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,13 @@ import ( | |
// package does not have a constant defined for this. | ||
const modeBlockDevice = 060000 | ||
|
||
// ECSEvent contains ECS-specific categorization fields | ||
type ECSEvent struct { | ||
Category []string `json:"category,omitempty" yaml:"category,omitempty"` | ||
Type []string `json:"type,omitempty" yaml:"type,omitempty"` | ||
Outcome string `json:"outcome,omitempty" yaml:"outcome,omitempty"` | ||
} | ||
|
||
type Event struct { | ||
Timestamp time.Time `json:"@timestamp" yaml:"timestamp"` | ||
Sequence uint32 `json:"sequence" yaml:"sequence"` | ||
|
@@ -54,6 +61,10 @@ type Event struct { | |
Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"` | ||
Paths []map[string]string `json:"paths,omitempty" yaml:"paths,omitempty"` | ||
|
||
ECS struct { | ||
Event ECSEvent `json:"event" yaml:"event"` | ||
} `json:"ecs" yaml:"ecs"` | ||
|
||
Warnings []error `json:"-" yaml:"-"` | ||
} | ||
|
||
|
@@ -427,10 +438,17 @@ func addFieldsToEventData(msg *auparse.AuditMessage, event *Event) { | |
func applyNormalization(event *Event) { | ||
setHowDefaults(event) | ||
|
||
var syscallNorm *Normalization | ||
if syscall, ok := event.Data["syscall"]; ok { | ||
syscallNorm, ok = syscallNorms[syscall] | ||
if !ok { | ||
syscallNorm = syscallNorms["*"] // get the default to add some basic categorization | ||
} | ||
} | ||
|
||
var norm *Normalization | ||
if event.Type == auparse.AUDIT_SYSCALL { | ||
syscall := event.Data["syscall"] | ||
norm = syscallNorms[syscall] | ||
norm = syscallNorm | ||
} else { | ||
norms := recordTypeNorms[event.Type.String()] | ||
switch len(norms) { | ||
|
@@ -454,6 +472,23 @@ func applyNormalization(event *Event) { | |
return | ||
} | ||
|
||
event.ECS.Event.Category = norm.ECS.Category.Values | ||
event.ECS.Event.Type = norm.ECS.Type.Values | ||
|
||
// we check to see if the non-AUDIT_SYSCALL event has an associated syscall | ||
// from another part of the auditd message log, if it does and we have normalizations | ||
// for that syscall, we merge the ECS categorization and type information so that | ||
// the event has both enrichment for the record type itself and for the syscall it | ||
// captures | ||
hasAdditionalNormalization := syscallNorm != nil && syscallNorm != norm | ||
if hasAdditionalNormalization { | ||
andrewstucki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
event.ECS.Event.Category = append(event.ECS.Event.Category, syscallNorm.ECS.Category.Values...) | ||
event.ECS.Event.Type = append(event.ECS.Event.Type, syscallNorm.ECS.Type.Values...) | ||
if event.Result == "fail" { | ||
event.ECS.Event.Outcome = "failure" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we're only explicit if something was a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. non blocking because "failure" is one of 3 constant values, it might be nice to use a constant for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ideally this would also be in an enum in the ECS generated go structures |
||
} | ||
} | ||
|
||
event.Summary.Action = norm.Action | ||
|
||
switch norm.Object.What { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non blocking
Would event.kind be held somewhere else? or maybe the caller of the library is responsible for that?
What do you think about having something about ECS categorization in the struct type? That might provide clues to the type of fields in the struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my initial thought is that it could be in the caller--namely because I'm pretty sure we're working only with
event
kinds--but then again would "anomaly" events actually bealert
kinds? If so, or if we just want to be explicit, I can addkind
in a follow-up PR.For the second question, I'm not entirely sure I follow--do you meaning adding constant enums for the categorization values themselves? If so I'd almost prefer to do that in the ECS go generated code from the ECS repo itself (which ideally we'd be using here too--but we still need to add tags and formalize on things like
omitempty
, pointer usage, etc. before doing that).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm good with it being the callers responsibility, I just wanted to double check that we weren't missing one of the ECS categorization fields.
I was thinking the name of the type might be better as ECSCategorization or ECSCat or something like that, since it really just holds the categorization info, nothing else about ECS.
Enums would be awesome and I agree it would be good to do that work once in ECS repo.