From 7ec9d428cb81bfee41628962838c94c6f5d5787c Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 27 Apr 2020 23:43:11 -0400 Subject: [PATCH 1/3] [Auditbeat] Add system module login dataset ECS categorization fields --- x-pack/auditbeat/module/system/login/login.go | 17 ++++++++++---- .../module/system/login/login_test.go | 22 ++++++++++--------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/x-pack/auditbeat/module/system/login/login.go b/x-pack/auditbeat/module/system/login/login.go index 8dc01b95e687..e0d6f62a91af 100644 --- a/x-pack/auditbeat/module/system/login/login.go +++ b/x-pack/auditbeat/module/system/login/login.go @@ -202,13 +202,22 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { switch loginRecord.Type { case userLoginRecord: - event.RootFields.Put("event.category", "authentication") + event.RootFields.Put("event.category", []string{"authentication"}) event.RootFields.Put("event.outcome", "success") - event.RootFields.Put("event.type", "authentication_success") + event.RootFields.Put("event.type", []string{"start", "authentication_success"}) case userLoginFailedRecord: - event.RootFields.Put("event.category", "authentication") + event.RootFields.Put("event.category", []string{"authentication"}) event.RootFields.Put("event.outcome", "failure") - event.RootFields.Put("event.type", "authentication_failure") + event.RootFields.Put("event.type", []string{"start", "authentication_failure"}) + case userLogoutRecord: + event.RootFields.Put("event.category", []string{"authentication"}) + event.RootFields.Put("event.type", []string{"end"}) + case bootRecord: + event.RootFields.Put("event.category", []string{"host"}) + event.RootFields.Put("event.type", []string{"start"}) + case shutdownRecord: + event.RootFields.Put("event.category", []string{"host"}) + event.RootFields.Put("event.type", []string{"end"}) } return event diff --git a/x-pack/auditbeat/module/system/login/login_test.go b/x-pack/auditbeat/module/system/login/login_test.go index 8c1bccc7753b..ea26ce6ccf42 100644 --- a/x-pack/auditbeat/module/system/login/login_test.go +++ b/x-pack/auditbeat/module/system/login/login_test.go @@ -84,10 +84,10 @@ func TestWtmp(t *testing.T) { // utmpdump: [7] [14962] [ts/2] [vagrant ] [pts/2 ] [10.0.2.2 ] [10.0.2.2 ] [2019-01-24T09:51:51,367964+00:00] checkFieldValue(t, events[0].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_success"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_login") checkFieldValue(t, events[0].RootFields, "event.outcome", "success") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_success") checkFieldValue(t, events[0].RootFields, "process.pid", 14962) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[0].RootFields, "user.name", "vagrant") @@ -123,6 +123,8 @@ func TestWtmp(t *testing.T) { } checkFieldValue(t, events[0].RootFields, "event.kind", "event") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"end"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_logout") checkFieldValue(t, events[0].RootFields, "process.pid", 14962) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") @@ -156,10 +158,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [6] [03307] [ ] [root ] [ssh:notty ] [10.0.2.2 ] [10.0.2.2 ] [2019-02-20T17:42:26,000000+0000] checkFieldValue(t, events[0].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_login") checkFieldValue(t, events[0].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[0].RootFields, "process.pid", 3307) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[0].RootFields, "user.id", 0) @@ -171,10 +173,10 @@ func TestBtmp(t *testing.T) { // The second UTMP entry in the btmp test file is a duplicate of the first, this is what Ubuntu 18.04 generates. // utmpdump: [6] [03307] [ ] [root ] [ssh:notty ] [10.0.2.2 ] [10.0.2.2 ] [2019-02-20T17:42:26,000000+0000] checkFieldValue(t, events[1].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[1].RootFields, "event.action", "user_login") checkFieldValue(t, events[1].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[1].RootFields, "process.pid", 3307) checkFieldValue(t, events[1].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[1].RootFields, "user.id", 0) @@ -185,10 +187,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [7] [03788] [/0 ] [elastic ] [pts/0 ] [ ] [0.0.0.0 ] [2019-02-20T17:45:08,447344+0000] checkFieldValue(t, events[2].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[2].RootFields, "event.action", "user_login") checkFieldValue(t, events[2].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[2].RootFields, "process.pid", 3788) checkFieldValue(t, events[2].RootFields, "source.ip", "0.0.0.0") checkFieldValue(t, events[2].RootFields, "user.name", "elastic") @@ -198,10 +200,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [7] [03788] [/0 ] [UNKNOWN ] [pts/0 ] [ ] [0.0.0.0 ] [2019-02-20T17:45:15,765318+0000] checkFieldValue(t, events[3].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[3].RootFields, "event.action", "user_login") checkFieldValue(t, events[3].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[3].RootFields, "process.pid", 3788) checkFieldValue(t, events[3].RootFields, "source.ip", "0.0.0.0") contains, err := events[3].RootFields.HasKey("user.id") From b8ffc99406d5e11be5ff0628ba48993661d41b5b Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 27 Apr 2020 23:45:22 -0400 Subject: [PATCH 2/3] add changelog entry --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b1f70eea9491..52d67f4f3108 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -210,6 +210,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Log to stderr when running using reference kubernetes manifests. {pull}17443[174443] - Fix syscall kprobe arguments for 32-bit systems in socket module. {pull}17500[17500] - Fix memory leak on when we miss socket close kprobe events. {pull}17500[17500] +- Add system module login dataset ECS categorization fields. {pull}18034[18034] *Filebeat* From 21354058b8fa841ddbb8023734c94cdbe3a8935d Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Tue, 5 May 2020 00:06:46 -0400 Subject: [PATCH 3/3] Add related.user and related.ip --- x-pack/auditbeat/module/system/login/login.go | 3 ++- x-pack/auditbeat/module/system/login/login_test.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/auditbeat/module/system/login/login.go b/x-pack/auditbeat/module/system/login/login.go index e0d6f62a91af..01e96e4dbc15 100644 --- a/x-pack/auditbeat/module/system/login/login.go +++ b/x-pack/auditbeat/module/system/login/login.go @@ -178,7 +178,7 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { if loginRecord.Username != "" { event.RootFields.Put("user.name", loginRecord.Username) - + event.RootFields.Put("related.user", []string{loginRecord.Username}) if loginRecord.UID != -1 { event.RootFields.Put("user.id", loginRecord.UID) } @@ -194,6 +194,7 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { if loginRecord.IP != nil { event.RootFields.Put("source.ip", loginRecord.IP) + event.RootFields.Put("related.ip", []string{loginRecord.IP.String()}) } if loginRecord.Hostname != "" && loginRecord.Hostname != loginRecord.IP.String() { diff --git a/x-pack/auditbeat/module/system/login/login_test.go b/x-pack/auditbeat/module/system/login/login_test.go index ea26ce6ccf42..818ad18314e3 100644 --- a/x-pack/auditbeat/module/system/login/login_test.go +++ b/x-pack/auditbeat/module/system/login/login_test.go @@ -128,7 +128,9 @@ func TestWtmp(t *testing.T) { checkFieldValue(t, events[0].RootFields, "event.action", "user_logout") checkFieldValue(t, events[0].RootFields, "process.pid", 14962) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") + checkFieldValue(t, events[0].RootFields, "related.ip", []string{"10.0.2.2"}) checkFieldValue(t, events[0].RootFields, "user.name", "vagrant") + checkFieldValue(t, events[0].RootFields, "related.user", []string{"vagrant"}) checkFieldValue(t, events[0].RootFields, "user.terminal", "pts/2") }