From f081e72f09475a74c586e299d5754fdb361a858e Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 30 Apr 2020 14:42:08 -0400 Subject: [PATCH 1/5] add related event generation to ancestor nodes --- .../plugins/endpoint/common/generate_data.ts | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts index e40fc3e386bc..9742725c9e1c 100644 --- a/x-pack/plugins/endpoint/common/generate_data.ts +++ b/x-pack/plugins/endpoint/common/generate_data.ts @@ -331,7 +331,11 @@ export class EndpointDocGenerator { percentNodesWithRelated?: number, percentChildrenTerminated?: number ) { - const ancestry = this.createAlertEventAncestry(alertAncestors); + const ancestry = this.createAlertEventAncestry( + alertAncestors, + relatedEventsPerNode, + percentNodesWithRelated + ); for (let i = 0; i < ancestry.length; i++) { yield ancestry[i]; } @@ -350,18 +354,44 @@ export class EndpointDocGenerator { * Creates an alert event and associated process ancestry. The alert event will always be the last event in the return array. * @param alertAncestors - number of ancestor generations to create */ - public createAlertEventAncestry(alertAncestors = 3): Event[] { + public createAlertEventAncestry( + alertAncestors = 3, + relatedEventsPerNode = 5, + pctWithRelated = 30 + ): Event[] { const events = []; const startDate = new Date().getTime(); const root = this.generateEvent({ timestamp: startDate + 1000 }); events.push(root); let ancestor = root; + // generate related alerts for root + const processDuration: number = 6 * 3600; + if (this.randomN(100) < pctWithRelated) { + for (const relatedEvent of this.relatedEventsGenerator( + ancestor, + relatedEventsPerNode, + processDuration + )) { + events.push(relatedEvent); + } + } for (let i = 0; i < alertAncestors; i++) { ancestor = this.generateEvent({ timestamp: startDate + 1000 * (i + 1), parentEntityID: ancestor.process.entity_id, }); events.push(ancestor); + + // generate related alerts for ancestor + if (this.randomN(100) < pctWithRelated) { + for (const relatedEvent of this.relatedEventsGenerator( + ancestor, + relatedEventsPerNode, + processDuration + )) { + events.push(relatedEvent); + } + } } events.push( this.generateAlert( From f964d77ee7247fbe566c9dbaf533da88228af4bb Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 30 Apr 2020 15:40:42 -0400 Subject: [PATCH 2/5] Marshall Main review: adjusting index into ancestry array --- x-pack/plugins/endpoint/common/generate_data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts index 9742725c9e1c..2e7181bf5e10 100644 --- a/x-pack/plugins/endpoint/common/generate_data.ts +++ b/x-pack/plugins/endpoint/common/generate_data.ts @@ -339,9 +339,9 @@ export class EndpointDocGenerator { for (let i = 0; i < ancestry.length; i++) { yield ancestry[i]; } - // ancestry will always have at least 2 elements, and the second to last element will be the process associated with the alert + // ancestry will always have at least 2 elements, and the last element will be the process associated with the alert yield* this.descendantsTreeGenerator( - ancestry[ancestry.length - 2], + ancestry[ancestry.length - 1], childGenerations, maxChildrenPerNode, relatedEventsPerNode, From f886b71ffd998849c9dfe4f1e8cd27fbac8e3781 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 30 Apr 2020 15:48:05 -0400 Subject: [PATCH 3/5] Marshall Main review: adjusted comment --- x-pack/plugins/endpoint/common/generate_data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts index 2e7181bf5e10..6db936e932b0 100644 --- a/x-pack/plugins/endpoint/common/generate_data.ts +++ b/x-pack/plugins/endpoint/common/generate_data.ts @@ -339,7 +339,7 @@ export class EndpointDocGenerator { for (let i = 0; i < ancestry.length; i++) { yield ancestry[i]; } - // ancestry will always have at least 2 elements, and the last element will be the process associated with the alert + // ancestry will always have at least 2 elements, and the last element will be the alert yield* this.descendantsTreeGenerator( ancestry[ancestry.length - 1], childGenerations, From 91be628738196cfe937f4bda0ad894b717ceedc2 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Tue, 5 May 2020 00:57:25 -0400 Subject: [PATCH 4/5] adjusting tests --- .../endpoint/common/generate_data.test.ts | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/endpoint/common/generate_data.test.ts b/x-pack/plugins/endpoint/common/generate_data.test.ts index 88e1c66ea3e8..8443a9c94dae 100644 --- a/x-pack/plugins/endpoint/common/generate_data.test.ts +++ b/x-pack/plugins/endpoint/common/generate_data.test.ts @@ -90,20 +90,43 @@ describe('data generator', () => { }); it('with n-1 process events', () => { - for (let i = 1; i < events.length - 1; i++) { - expect(events[i].process.parent?.entity_id).toEqual(events[i - 1].process.entity_id); - expect(events[i].event.kind).toEqual('event'); - expect(events[i].event.category).toEqual('process'); + // for (let i = 1; i < events.length - 1; i++) { + // expect(events[i].process.parent?.entity_id).toEqual(events[i - 1].process.entity_id); + // expect(events[i].event.kind).toEqual('event'); + // expect(events[i].event.category).toEqual('process'); + // } + for (let i = events.length - 1; i > 0; ) { + const parentEntityIdOfChild = events[i].process.parent?.entity_id; + for ( + ; + --i >= -1 && (events[i].event.kind !== 'event' || events[i].event.category !== 'process'); + + ) { + // related event - skip it + } + expect(i).toBeGreaterThanOrEqual(0); + expect(parentEntityIdOfChild).toEqual(events[i].process.entity_id); } }); it('with a corresponding alert at the end', () => { + let previousProcessEventIndex = events.length - 2; + for ( + ; + previousProcessEventIndex >= -1 && + (events[previousProcessEventIndex].event.kind !== 'event' || + events[previousProcessEventIndex].event.category !== 'process'); + previousProcessEventIndex-- + ) { + // related event - skip it + } + expect(previousProcessEventIndex).toBeGreaterThanOrEqual(0); // The alert should be last and have the same entity_id as the previous process event expect(events[events.length - 1].process.entity_id).toEqual( - events[events.length - 2].process.entity_id + events[previousProcessEventIndex].process.entity_id ); expect(events[events.length - 1].process.parent?.entity_id).toEqual( - events[events.length - 2].process.parent?.entity_id + events[previousProcessEventIndex].process.parent?.entity_id ); expect(events[events.length - 1].event.kind).toEqual('alert'); expect(events[events.length - 1].event.category).toEqual('malware'); From 8a678667ecb6bcb7f12268700492ca05c0df8caa Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Tue, 5 May 2020 11:15:04 -0400 Subject: [PATCH 5/5] fix tests to account for alert at n-1 --- x-pack/plugins/endpoint/common/generate_data.test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/plugins/endpoint/common/generate_data.test.ts b/x-pack/plugins/endpoint/common/generate_data.test.ts index 817e30d02e7f..f99fa5c871d8 100644 --- a/x-pack/plugins/endpoint/common/generate_data.test.ts +++ b/x-pack/plugins/endpoint/common/generate_data.test.ts @@ -101,12 +101,7 @@ describe('data generator', () => { }); it('with n-1 process events', () => { - // for (let i = 1; i < events.length - 1; i++) { - // expect(events[i].process.parent?.entity_id).toEqual(events[i - 1].process.entity_id); - // expect(events[i].event.kind).toEqual('event'); - // expect(events[i].event.category).toEqual('process'); - // } - for (let i = events.length - 1; i > 0; ) { + for (let i = events.length - 2; i > 0; ) { const parentEntityIdOfChild = events[i].process.parent?.entity_id; for ( ;