diff --git a/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts index 167fc9dd17a2..8708aa4c0760 100644 --- a/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts +++ b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts @@ -39,12 +39,12 @@ export const eventHit = { '/var/lib/jenkins/workspace/Beats_beats_PR-22624/.gvm/versions/go1.14.7.linux.amd64/bin/go', ], 'source.geo.location': [{ coordinates: [118.7778, 32.0617], type: 'Point' }], - 'threat.indicator': [ + 'threat.enrichments': [ { 'matched.field': ['matched_field', 'other_matched_field'], - first_seen: ['2021-02-22T17:29:25.195Z'], - provider: ['yourself'], - type: ['custom'], + 'indicator.first_seen': ['2021-02-22T17:29:25.195Z'], + 'indicator.provider': ['yourself'], + 'indicator.type': ['custom'], 'matched.atomic': ['matched_atomic'], lazer: [ { @@ -57,9 +57,9 @@ export const eventHit = { }, { 'matched.field': ['matched_field_2'], - first_seen: ['2021-02-22T17:29:25.195Z'], - provider: ['other_you'], - type: ['custom'], + 'indicator.first_seen': ['2021-02-22T17:29:25.195Z'], + 'indicator.provider': ['other_you'], + 'indicator.type': ['custom'], 'matched.atomic': ['matched_atomic_2'], lazer: [ { @@ -259,70 +259,70 @@ export const eventDetailsFormattedFields = [ }, { category: 'threat', - field: 'threat.indicator.matched.field', + field: 'threat.enrichments.matched.field', values: ['matched_field', 'other_matched_field', 'matched_field_2'], originalValue: ['matched_field', 'other_matched_field', 'matched_field_2'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.first_seen', + field: 'threat.enrichments.indicator.first_seen', values: ['2021-02-22T17:29:25.195Z'], originalValue: ['2021-02-22T17:29:25.195Z'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.provider', + field: 'threat.enrichments.indicator.provider', values: ['yourself', 'other_you'], originalValue: ['yourself', 'other_you'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.type', + field: 'threat.enrichments.indicator.type', values: ['custom'], originalValue: ['custom'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.matched.atomic', + field: 'threat.enrichments.matched.atomic', values: ['matched_atomic', 'matched_atomic_2'], originalValue: ['matched_atomic', 'matched_atomic_2'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.lazer.great.field', + field: 'threat.enrichments.lazer.great.field', values: ['grrrrr', 'grrrrr_2'], originalValue: ['grrrrr', 'grrrrr_2'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.lazer.great.field.wowoe.fooooo', + field: 'threat.enrichments.lazer.great.field.wowoe.fooooo', values: ['grrrrr'], originalValue: ['grrrrr'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.lazer.great.field.astring', + field: 'threat.enrichments.lazer.great.field.astring', values: ['cool'], originalValue: ['cool'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.lazer.great.field.aNumber', + field: 'threat.enrichments.lazer.great.field.aNumber', values: ['1'], originalValue: ['1'], isObjectArray: false, }, { category: 'threat', - field: 'threat.indicator.lazer.great.field.neat', + field: 'threat.enrichments.lazer.great.field.neat', values: ['true'], originalValue: ['true'], isObjectArray: false, diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index b433de5751ac..d9452a537826 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -59,9 +59,9 @@ export const SAVED_OBJECTS_MANAGEMENT_FEATURE_ID = 'Saved Objects Management'; export const DEFAULT_SPACE_ID = 'default'; // Document path where threat indicator fields are expected. Fields are used -// to enrich signals, and are copied to threat.indicator. +// to enrich signals, and are copied to threat.enrichments. export const DEFAULT_INDICATOR_SOURCE_PATH = 'threatintel.indicator'; -export const INDICATOR_DESTINATION_PATH = 'threat.indicator'; +export const ENRICHMENT_DESTINATION_PATH = 'threat.enrichments'; export const DEFAULT_THREAT_INDEX_KEY = 'securitySolution:defaultThreatIndex'; export const DEFAULT_THREAT_INDEX_VALUE = ['filebeat-*']; diff --git a/x-pack/plugins/security_solution/common/cti/constants.ts b/x-pack/plugins/security_solution/common/cti/constants.ts index feb47dbce046..2c50c8e0d12a 100644 --- a/x-pack/plugins/security_solution/common/cti/constants.ts +++ b/x-pack/plugins/security_solution/common/cti/constants.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { INDICATOR_DESTINATION_PATH } from '../constants'; +import { ENRICHMENT_DESTINATION_PATH } from '../constants'; export const MATCHED_ATOMIC = 'matched.atomic'; export const MATCHED_FIELD = 'matched.field'; @@ -13,28 +13,26 @@ export const MATCHED_ID = 'matched.id'; export const MATCHED_TYPE = 'matched.type'; export const INDICATOR_MATCH_SUBFIELDS = [MATCHED_ATOMIC, MATCHED_FIELD, MATCHED_TYPE]; -export const INDICATOR_MATCHED_ATOMIC = `${INDICATOR_DESTINATION_PATH}.${MATCHED_ATOMIC}`; -export const INDICATOR_MATCHED_FIELD = `${INDICATOR_DESTINATION_PATH}.${MATCHED_FIELD}`; -export const INDICATOR_MATCHED_TYPE = `${INDICATOR_DESTINATION_PATH}.${MATCHED_TYPE}`; +export const INDICATOR_MATCHED_ATOMIC = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_ATOMIC}`; +export const INDICATOR_MATCHED_FIELD = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_FIELD}`; +export const INDICATOR_MATCHED_TYPE = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_TYPE}`; export const EVENT_DATASET = 'event.dataset'; -export const EVENT_REFERENCE = 'event.reference'; -export const EVENT_URL = 'event.url'; -export const PROVIDER = 'provider'; -export const FIRSTSEEN = 'first_seen'; -export const INDICATOR_DATASET = `${INDICATOR_DESTINATION_PATH}.${EVENT_DATASET}`; -export const INDICATOR_EVENT_URL = `${INDICATOR_DESTINATION_PATH}.${EVENT_URL}`; -export const INDICATOR_FIRSTSEEN = `${INDICATOR_DESTINATION_PATH}.${FIRSTSEEN}`; -export const INDICATOR_LASTSEEN = `${INDICATOR_DESTINATION_PATH}.last_seen`; -export const INDICATOR_PROVIDER = `${INDICATOR_DESTINATION_PATH}.${PROVIDER}`; -export const INDICATOR_REFERENCE = `${INDICATOR_DESTINATION_PATH}.${EVENT_REFERENCE}`; +export const FIRST_SEEN = 'indicator.first_seen'; +export const LAST_SEEN = 'indicator.last_seen'; +export const PROVIDER = 'indicator.provider'; +export const REFERENCE = 'indicator.reference'; + +export const INDICATOR_FIRSTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${FIRST_SEEN}`; +export const INDICATOR_LASTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${LAST_SEEN}`; +export const INDICATOR_PROVIDER = `${ENRICHMENT_DESTINATION_PATH}.${PROVIDER}`; +export const INDICATOR_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${REFERENCE}`; export const CTI_ROW_RENDERER_FIELDS = [ INDICATOR_MATCHED_ATOMIC, INDICATOR_MATCHED_FIELD, INDICATOR_MATCHED_TYPE, - INDICATOR_DATASET, INDICATOR_REFERENCE, INDICATOR_PROVIDER, ]; diff --git a/x-pack/plugins/security_solution/common/ecs/threat/index.ts b/x-pack/plugins/security_solution/common/ecs/threat/index.ts index e5e7964c5d09..8136c5693d0e 100644 --- a/x-pack/plugins/security_solution/common/ecs/threat/index.ts +++ b/x-pack/plugins/security_solution/common/ecs/threat/index.ts @@ -6,6 +6,7 @@ */ import { EventEcs } from '../event'; +import { UrlEcs } from '../url'; interface ThreatMatchEcs { atomic?: string[]; @@ -15,13 +16,27 @@ interface ThreatMatchEcs { type?: string[]; } -export interface ThreatIndicatorEcs { +export interface LegacyThreatIndicatorEcs { + domain?: string[]; matched?: ThreatMatchEcs; event?: EventEcs & { reference?: string[] }; provider?: string[]; type?: string[]; } -export interface ThreatEcs { - indicator: ThreatIndicatorEcs[]; +export interface ThreatIndicatorEcs { + url?: UrlEcs; + provider?: string[]; + reference?: string[]; + type?: string[]; +} + +export interface ThreatEnrichmentEcs { + indicator?: ThreatIndicatorEcs; + matched?: ThreatMatchEcs; +} + +export interface ThreatEcs { + indicator?: LegacyThreatIndicatorEcs[]; + enrichments?: ThreatEnrichmentEcs[]; } diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/cti_enrichments.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/cti_enrichments.spec.ts index 8e82394da1db..6d39fcad54cf 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/cti_enrichments.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/cti_enrichments.spec.ts @@ -56,13 +56,13 @@ describe('CTI Enrichment', () => { it('Displays enrichment matched.* fields on the timeline', () => { const expectedFields = { - 'threat.indicator.matched.atomic': getNewThreatIndicatorRule().atomic, - 'threat.indicator.matched.type': 'indicator_match_rule', - 'threat.indicator.matched.field': getNewThreatIndicatorRule().indicatorMappingField, + 'threat.enrichments.matched.atomic': getNewThreatIndicatorRule().atomic, + 'threat.enrichments.matched.type': 'indicator_match_rule', + 'threat.enrichments.matched.field': getNewThreatIndicatorRule().indicatorMappingField, }; const fields = Object.keys(expectedFields) as Array; - addsFieldsToTimeline('threat.indicator.matched', fields); + addsFieldsToTimeline('threat.enrichments.matched', fields); fields.forEach((field) => { cy.get(TIMELINE_FIELD(field)).should('have.text', expectedFields[field]); @@ -75,7 +75,7 @@ describe('CTI Enrichment', () => { { line: 3, text: - ' "indicator": "{\\"first_seen\\":\\"2021-03-10T08:02:14.000Z\\",\\"file\\":{\\"size\\":80280,\\"pe\\":{},\\"type\\":\\"elf\\",\\"hash\\":{\\"sha256\\":\\"a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3\\",\\"tlsh\\":\\"6D7312E017B517CC1371A8353BED205E9128223972AE35302E97528DF957703BAB2DBE\\",\\"ssdeep\\":\\"1536:87vbq1lGAXSEYQjbChaAU2yU23M51DjZgSQAvcYkFtZTjzBht5:8D+CAXFYQChaAUk5ljnQssL\\",\\"md5\\":\\"9b6c3518a91d23ed77504b5416bfb5b3\\"}},\\"type\\":\\"file\\",\\"event\\":{\\"reference\\":\\"https://urlhaus-api.abuse.ch/v1/download/a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3/\\",\\"ingested\\":\\"2021-03-10T14:51:09.809069Z\\",\\"created\\":\\"2021-03-10T14:51:07.663Z\\",\\"kind\\":\\"enrichment\\",\\"module\\":\\"threatintel\\",\\"category\\":\\"threat\\",\\"type\\":\\"indicator\\",\\"dataset\\":\\"threatintel.abusemalware\\"},\\"matched\\":{\\"atomic\\":\\"a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3\\",\\"field\\":\\"myhash.mysha256\\",\\"id\\":\\"84cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f\\",\\"index\\":\\"filebeat-7.12.0-2021.03.10-000001\\",\\"type\\":\\"indicator_match_rule\\"}}"', + ' "enrichments": "{\\"indicator\\":{\\"first_seen\\":\\"2021-03-10T08:02:14.000Z\\",\\"file\\":{\\"size\\":80280,\\"pe\\":{},\\"type\\":\\"elf\\",\\"hash\\":{\\"sha256\\":\\"a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3\\",\\"tlsh\\":\\"6D7312E017B517CC1371A8353BED205E9128223972AE35302E97528DF957703BAB2DBE\\",\\"ssdeep\\":\\"1536:87vbq1lGAXSEYQjbChaAU2yU23M51DjZgSQAvcYkFtZTjzBht5:8D+CAXFYQChaAUk5ljnQssL\\",\\"md5\\":\\"9b6c3518a91d23ed77504b5416bfb5b3\\"}},\\"type\\":\\"file\\"},\\"matched\\":{\\"atomic\\":\\"a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3\\",\\"field\\":\\"myhash.mysha256\\",\\"id\\":\\"84cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f\\",\\"index\\":\\"filebeat-7.12.0-2021.03.10-000001\\",\\"type\\":\\"indicator_match_rule\\"}}"', }, { line: 2, text: ' }' }, ]; @@ -97,34 +97,23 @@ describe('CTI Enrichment', () => { it('Displays threat indicator details on the threat intel tab', () => { const expectedThreatIndicatorData = [ - { field: 'event.category', value: 'threat' }, - { field: 'event.created', value: '2021-03-10T14:51:07.663Z' }, - { field: 'event.dataset', value: 'threatintel.abusemalware' }, - { field: 'event.ingested', value: '2021-03-10T14:51:09.809069Z' }, - { field: 'event.kind', value: 'enrichment' }, - { field: 'event.module', value: 'threatintel' }, + { field: 'indicator.file.hash.md5', value: '9b6c3518a91d23ed77504b5416bfb5b3' }, { - field: 'event.reference', - value: - 'https://urlhaus-api.abuse.ch/v1/download/a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3/(opens in a new tab or window)', - }, - { field: 'event.type', value: 'indicator' }, - { field: 'file.hash.md5', value: '9b6c3518a91d23ed77504b5416bfb5b3' }, - { - field: 'file.hash.sha256', + field: 'indicator.file.hash.sha256', value: 'a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3', }, { - field: 'file.hash.ssdeep', + field: 'indicator.file.hash.ssdeep', value: '1536:87vbq1lGAXSEYQjbChaAU2yU23M51DjZgSQAvcYkFtZTjzBht5:8D+CAXFYQChaAUk5ljnQssL', }, { - field: 'file.hash.tlsh', + field: 'indicator.file.hash.tlsh', value: '6D7312E017B517CC1371A8353BED205E9128223972AE35302E97528DF957703BAB2DBE', }, - { field: 'file.size', value: '80280' }, - { field: 'file.type', value: 'elf' }, - { field: 'first_seen', value: '2021-03-10T08:02:14.000Z' }, + { field: 'indicator.file.size', value: '80280' }, + { field: 'indicator.file.type', value: 'elf' }, + { field: 'indicator.first_seen', value: '2021-03-10T08:02:14.000Z' }, + { field: 'indicator.type', value: 'file' }, { field: 'matched.atomic', value: 'a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3', @@ -136,7 +125,6 @@ describe('CTI Enrichment', () => { }, { field: 'matched.index', value: 'filebeat-7.12.0-2021.03.10-000001' }, { field: 'matched.type', value: 'indicator_match_rule' }, - { field: 'type', value: 'file' }, ]; expandFirstAlert(); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts index fdd30a237544..2a62accb4575 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/indicator_match_rule.spec.ts @@ -490,8 +490,6 @@ describe('indicator match', () => { it('Investigate alert in timeline', () => { const accessibilityText = `Press enter for options, or press space to begin dragging.`; - const threatIndicatorPath = - '../../../x-pack/test/security_solution_cypress/es_archives/threat_indicator/data.json'; loadPrepackagedTimelineTemplates(); @@ -506,27 +504,21 @@ describe('indicator match', () => { cy.get(PROVIDER_BADGE).should('have.length', 3); cy.get(PROVIDER_BADGE).should( 'have.text', - `threat.indicator.matched.atomic: "${ + `threat.enrichments.matched.atomic: "${ getNewThreatIndicatorRule().atomic - }"threat.indicator.matched.type: "indicator_match_rule"threat.indicator.matched.field: "${ + }"threat.enrichments.matched.type: "indicator_match_rule"threat.enrichments.matched.field: "${ getNewThreatIndicatorRule().indicatorMappingField }"` ); - cy.readFile(threatIndicatorPath).then((threatIndicator) => { - cy.get(INDICATOR_MATCH_ROW_RENDER).should( - 'have.text', - `threat.indicator.matched.field${ - getNewThreatIndicatorRule().indicatorMappingField - }${accessibilityText}matched${getNewThreatIndicatorRule().indicatorMappingField}${ - getNewThreatIndicatorRule().atomic - }${accessibilityText}threat.indicator.matched.typeindicator_match_rule${accessibilityText}fromthreat.indicator.event.dataset${ - threatIndicator.value.source.event.dataset - }${accessibilityText}:threat.indicator.event.reference${ - threatIndicator.value.source.event.reference - }(opens in a new tab or window)${accessibilityText}` - ); - }); + cy.get(INDICATOR_MATCH_ROW_RENDER).should( + 'have.text', + `threat.enrichments.matched.field${ + getNewThreatIndicatorRule().indicatorMappingField + }${accessibilityText}matched${getNewThreatIndicatorRule().indicatorMappingField}${ + getNewThreatIndicatorRule().atomic + }${accessibilityText}threat.enrichments.matched.typeindicator_match_rule${accessibilityText}` + ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts index 620c3991b0ad..9dd5a611352f 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/__mocks__/index.ts @@ -659,14 +659,14 @@ export const mockAlertDetailsData = [ }, { category: 'threat', - field: 'threat.indicator', - values: [`{"first_seen":"2021-03-25T18:17:00.000Z"}`], - originalValue: [`{"first_seen":"2021-03-25T18:17:00.000Z"}`], + field: 'threat.enrichments', + values: [`{"indicator":{"first_seen":"2021-03-25T18:17:00.000Z"}}`], + originalValue: [`{"indicator":{"first_seen":"2021-03-25T18:17:00.000Z"}}`], }, { category: 'threat', - field: 'threat.indicator.matched', - values: `["file", "url"]`, - originalValue: ['file', 'url'], + field: 'threat.enrichments.matched.field', + values: ['host.name'], + originalValue: ['host.name'], }, ]; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.test.tsx index 858962efa9e8..d02cbea717a3 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.test.tsx @@ -35,7 +35,7 @@ describe('parseExistingEnrichments', () => { const data = [ { category: 'threat', - field: 'threat.indicator', + field: 'threat.enrichments', isObjectArray: true, originalValue: ['whoops'], values: ['whoops'], @@ -48,13 +48,13 @@ describe('parseExistingEnrichments', () => { const data = [ { category: 'threat', - field: 'threat.indicator', + field: 'threat.enrichments', isObjectArray: true, originalValue: [ - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"geenensp","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"provider","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, ], values: [ - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"geenensp","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"provider","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, ], }, ]; @@ -62,88 +62,39 @@ describe('parseExistingEnrichments', () => { expect(parseExistingEnrichments(data)).toEqual([ [ { - category: 'first_seen', - field: 'first_seen', + category: 'indicator', + field: 'indicator.first_seen', isObjectArray: false, originalValue: ['2021-03-21T19:40:19.000Z'], values: ['2021-03-21T19:40:19.000Z'], }, { - category: 'provider', - field: 'provider', + category: 'indicator', + field: 'indicator.provider', isObjectArray: false, - originalValue: ['geenensp'], - values: ['geenensp'], + originalValue: ['provider'], + values: ['provider'], }, { - category: 'ip', - field: 'ip', + category: 'indicator', + field: 'indicator.reference', + isObjectArray: false, + originalValue: ['http://reference.url'], + values: ['http://reference.url'], + }, + { + category: 'indicator', + field: 'indicator.ip', isObjectArray: false, originalValue: ['192.168.1.19'], values: ['192.168.1.19'], }, { - category: 'type', - field: 'type', + category: 'indicator', + field: 'indicator.type', isObjectArray: false, - originalValue: ['url'], - values: ['url'], - }, - { - category: 'event', - field: 'event.reference', - isObjectArray: false, - originalValue: ['https://urlhaus.abuse.ch/url/1055419/'], - values: ['https://urlhaus.abuse.ch/url/1055419/'], - }, - { - category: 'event', - field: 'event.ingested', - isObjectArray: false, - originalValue: ['2021-03-08T19:40:44.213673Z'], - values: ['2021-03-08T19:40:44.213673Z'], - }, - { - category: 'event', - field: 'event.created', - isObjectArray: false, - originalValue: ['2021-03-08T19:40:43.160Z'], - values: ['2021-03-08T19:40:43.160Z'], - }, - { - category: 'event', - field: 'event.kind', - isObjectArray: false, - originalValue: ['other'], - values: ['other'], - }, - { - category: 'event', - field: 'event.module', - isObjectArray: false, - originalValue: ['threatintel'], - values: ['threatintel'], - }, - { - category: 'event', - field: 'event.category', - isObjectArray: false, - originalValue: ['threat'], - values: ['threat'], - }, - { - category: 'event', - field: 'event.type', - isObjectArray: false, - originalValue: ['indicator'], - values: ['indicator'], - }, - { - category: 'event', - field: 'event.dataset', - isObjectArray: false, - originalValue: ['threatintel.abuseurl'], - values: ['threatintel.abuseurl'], + originalValue: ['ip'], + values: ['ip'], }, { category: 'matched', @@ -177,8 +128,8 @@ describe('parseExistingEnrichments', () => { category: 'matched', field: 'matched.type', isObjectArray: false, - originalValue: ['url'], - values: ['url'], + originalValue: [ENRICHMENT_TYPES.IndicatorMatchRule], + values: [ENRICHMENT_TYPES.IndicatorMatchRule], }, ], ]); @@ -188,15 +139,15 @@ describe('parseExistingEnrichments', () => { const data = [ { category: 'threat', - field: 'threat.indicator', + field: 'threat.enrichments', isObjectArray: true, originalValue: [ - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"other","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"iiL9NHoB_Blp1Ib9yoJo","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"geenensp","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"provider","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"other","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"iiL9NHoB_Blp1Ib9yoJo","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, ], values: [ - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"other","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"iiL9NHoB_Blp1Ib9yoJo","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, - `{"first_seen":"2021-03-21T19:40:19.000Z","provider":"geenensp","ip":"192.168.1.19","type":"url","event":{"reference":"https://urlhaus.abuse.ch/url/1055419/","ingested":"2021-03-08T19:40:44.213673Z","created":"2021-03-08T19:40:43.160Z","kind":"other","module":"threatintel","category":"threat","type":"indicator","dataset":"threatintel.abuseurl"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"url"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"provider","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"0SIZMnoB_Blp1Ib9ZYHU","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, + `{"indicator":{"first_seen":"2021-03-21T19:40:19.000Z","provider":"other","reference":"http://reference.url","ip":"192.168.1.19","type":"ip"},"matched":{"atomic":"192.168.1.19","field":"host.ip","id":"iiL9NHoB_Blp1Ib9yoJo","index":"filebeat-8.0.0-2021.05.28-000001","type":"indicator_match_rule"}}`, ], }, ]; @@ -204,74 +155,111 @@ describe('parseExistingEnrichments', () => { expect(parseExistingEnrichments(data)).toEqual([ expect.arrayContaining([ { - category: 'first_seen', - field: 'first_seen', + category: 'indicator', + field: 'indicator.first_seen', isObjectArray: false, originalValue: ['2021-03-21T19:40:19.000Z'], values: ['2021-03-21T19:40:19.000Z'], }, { - category: 'provider', - field: 'provider', + category: 'indicator', + field: 'indicator.provider', isObjectArray: false, - originalValue: ['other'], - values: ['other'], + originalValue: ['provider'], + values: ['provider'], }, { - category: 'ip', - field: 'ip', + category: 'indicator', + field: 'indicator.reference', + isObjectArray: false, + originalValue: ['http://reference.url'], + values: ['http://reference.url'], + }, + { + category: 'indicator', + field: 'indicator.ip', isObjectArray: false, originalValue: ['192.168.1.19'], values: ['192.168.1.19'], }, { - category: 'type', - field: 'type', + category: 'indicator', + field: 'indicator.type', isObjectArray: false, - originalValue: ['url'], - values: ['url'], + originalValue: ['ip'], + values: ['ip'], }, { - category: 'event', - field: 'event.reference', + category: 'matched', + field: 'matched.atomic', isObjectArray: false, - originalValue: ['https://urlhaus.abuse.ch/url/1055419/'], - values: ['https://urlhaus.abuse.ch/url/1055419/'], + originalValue: ['192.168.1.19'], + values: ['192.168.1.19'], }, { - category: 'event', - field: 'event.ingested', + category: 'matched', + field: 'matched.field', isObjectArray: false, - originalValue: ['2021-03-08T19:40:44.213673Z'], - values: ['2021-03-08T19:40:44.213673Z'], + originalValue: ['host.ip'], + values: ['host.ip'], }, { - category: 'event', - field: 'event.module', + category: 'matched', + field: 'matched.id', isObjectArray: false, - originalValue: ['threatintel'], - values: ['threatintel'], + originalValue: ['0SIZMnoB_Blp1Ib9ZYHU'], + values: ['0SIZMnoB_Blp1Ib9ZYHU'], }, { - category: 'event', - field: 'event.category', + category: 'matched', + field: 'matched.index', isObjectArray: false, - originalValue: ['threat'], - values: ['threat'], + originalValue: ['filebeat-8.0.0-2021.05.28-000001'], + values: ['filebeat-8.0.0-2021.05.28-000001'], }, { - category: 'event', - field: 'event.type', + category: 'matched', + field: 'matched.type', isObjectArray: false, - originalValue: ['indicator'], - values: ['indicator'], + originalValue: [ENRICHMENT_TYPES.IndicatorMatchRule], + values: [ENRICHMENT_TYPES.IndicatorMatchRule], + }, + ]), + expect.arrayContaining([ + { + category: 'indicator', + field: 'indicator.first_seen', + isObjectArray: false, + originalValue: ['2021-03-21T19:40:19.000Z'], + values: ['2021-03-21T19:40:19.000Z'], }, { - category: 'event', - field: 'event.dataset', + category: 'indicator', + field: 'indicator.provider', isObjectArray: false, - originalValue: ['threatintel.abuseurl'], - values: ['threatintel.abuseurl'], + originalValue: ['other'], + values: ['other'], + }, + { + category: 'indicator', + field: 'indicator.reference', + isObjectArray: false, + originalValue: ['http://reference.url'], + values: ['http://reference.url'], + }, + { + category: 'indicator', + field: 'indicator.ip', + isObjectArray: false, + originalValue: ['192.168.1.19'], + values: ['192.168.1.19'], + }, + { + category: 'indicator', + field: 'indicator.type', + isObjectArray: false, + originalValue: ['ip'], + values: ['ip'], }, { category: 'matched', @@ -305,115 +293,8 @@ describe('parseExistingEnrichments', () => { category: 'matched', field: 'matched.type', isObjectArray: false, - originalValue: ['url'], - values: ['url'], - }, - ]), - expect.arrayContaining([ - { - category: 'first_seen', - field: 'first_seen', - isObjectArray: false, - originalValue: ['2021-03-21T19:40:19.000Z'], - values: ['2021-03-21T19:40:19.000Z'], - }, - { - category: 'provider', - field: 'provider', - isObjectArray: false, - originalValue: ['geenensp'], - values: ['geenensp'], - }, - { - category: 'ip', - field: 'ip', - isObjectArray: false, - originalValue: ['192.168.1.19'], - values: ['192.168.1.19'], - }, - { - category: 'type', - field: 'type', - isObjectArray: false, - originalValue: ['url'], - values: ['url'], - }, - { - category: 'event', - field: 'event.reference', - isObjectArray: false, - originalValue: ['https://urlhaus.abuse.ch/url/1055419/'], - values: ['https://urlhaus.abuse.ch/url/1055419/'], - }, - { - category: 'event', - field: 'event.ingested', - isObjectArray: false, - originalValue: ['2021-03-08T19:40:44.213673Z'], - values: ['2021-03-08T19:40:44.213673Z'], - }, - { - category: 'event', - field: 'event.module', - isObjectArray: false, - originalValue: ['threatintel'], - values: ['threatintel'], - }, - { - category: 'event', - field: 'event.category', - isObjectArray: false, - originalValue: ['threat'], - values: ['threat'], - }, - { - category: 'event', - field: 'event.type', - isObjectArray: false, - originalValue: ['indicator'], - values: ['indicator'], - }, - { - category: 'event', - field: 'event.dataset', - isObjectArray: false, - originalValue: ['threatintel.abuseurl'], - values: ['threatintel.abuseurl'], - }, - { - category: 'matched', - field: 'matched.atomic', - isObjectArray: false, - originalValue: ['192.168.1.19'], - values: ['192.168.1.19'], - }, - { - category: 'matched', - field: 'matched.field', - isObjectArray: false, - originalValue: ['host.ip'], - values: ['host.ip'], - }, - { - category: 'matched', - field: 'matched.id', - isObjectArray: false, - originalValue: ['0SIZMnoB_Blp1Ib9ZYHU'], - values: ['0SIZMnoB_Blp1Ib9ZYHU'], - }, - { - category: 'matched', - field: 'matched.index', - isObjectArray: false, - originalValue: ['filebeat-8.0.0-2021.05.28-000001'], - values: ['filebeat-8.0.0-2021.05.28-000001'], - }, - { - category: 'matched', - field: 'matched.type', - isObjectArray: false, - originalValue: ['url'], - values: ['url'], + originalValue: [ENRICHMENT_TYPES.IndicatorMatchRule], + values: [ENRICHMENT_TYPES.IndicatorMatchRule], }, ]), ]); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.tsx index b048bb076e2d..7b72b9875de1 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/helpers.tsx @@ -6,10 +6,7 @@ */ import { groupBy } from 'lodash'; -import { - DEFAULT_INDICATOR_SOURCE_PATH, - INDICATOR_DESTINATION_PATH, -} from '../../../../../common/constants'; +import { ENRICHMENT_DESTINATION_PATH } from '../../../../../common/constants'; import { ENRICHMENT_TYPES, MATCHED_ATOMIC, @@ -35,7 +32,7 @@ export const parseExistingEnrichments = ( data: TimelineEventsDetailsItem[] ): TimelineEventsDetailsItem[][] => { const threatIndicatorField = data.find( - ({ field, originalValue }) => field === INDICATOR_DESTINATION_PATH && originalValue + ({ field, originalValue }) => field === ENRICHMENT_DESTINATION_PATH && originalValue ); if (!threatIndicatorField) { return []; @@ -68,14 +65,15 @@ export const getEnrichmentValue = (enrichment: CtiEnrichment, field: string) => getFirstElement(enrichment[field]) as string | undefined; /** - * These fields (e.g. 'x') may be in one of two keys depending on whether it's - * a new enrichment ('threatintel.indicator.x') or an old indicator alert - * (simply 'x'). Once enrichment has been normalized and we support the new ECS - * fields, this value should always be 'indicator.x'; + * These fields (e.g. 'indicator.ip') may be in one of three places depending on whether it's: + * * a queried, legacy filebeat indicator ('threatintel.indicator.ip') + * * a queried, ECS 1.11 filebeat indicator ('threat.indicator.ip') + * * an existing indicator from an enriched alert ('indicator.ip') */ export const getShimmedIndicatorValue = (enrichment: CtiEnrichment, field: string) => getEnrichmentValue(enrichment, field) || - getEnrichmentValue(enrichment, `${DEFAULT_INDICATOR_SOURCE_PATH}.${field}`); + getEnrichmentValue(enrichment, `threatintel.${field}`) || + getEnrichmentValue(enrichment, `threat.${field}`); export const getEnrichmentIdentifiers = (enrichment: CtiEnrichment): CtiEnrichmentIdentifiers => ({ id: getEnrichmentValue(enrichment, MATCHED_ID), diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.test.tsx index c8c2a3a64c55..37f61c4898a0 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.test.tsx @@ -10,7 +10,6 @@ import { mount } from 'enzyme'; import { TestProviders } from '../../../mock'; import { buildEventEnrichmentMock } from '../../../../../common/search_strategy/security_solution/cti/index.mock'; -import { FIRSTSEEN } from '../../../../../common/cti/constants'; import { ThreatDetailsView } from './threat_details_view'; describe('ThreatDetailsView', () => { @@ -31,11 +30,10 @@ describe('ThreatDetailsView', () => { ); }); - it('renders anchor links for event.url and event.reference', () => { + it('renders an anchor link for indicator.reference', () => { const enrichments = [ buildEventEnrichmentMock({ - 'event.url': ['http://foo.bar'], - 'event.reference': ['http://foo.baz'], + 'threatintel.indicator.reference': ['http://foo.baz'], }), ]; const wrapper = mount( @@ -43,7 +41,7 @@ describe('ThreatDetailsView', () => { ); - expect(wrapper.find('a').length).toEqual(2); + expect(wrapper.find('a').length).toEqual(1); }); it('sorts same type of enrichments by first_seen descending', () => { @@ -52,7 +50,7 @@ describe('ThreatDetailsView', () => { // this simulates a legacy enrichment from the old indicator match rule, // where first_seen is available at the top level const existingEnrichment = buildEventEnrichmentMock({ - first_seen: [mostRecentDate], + 'indicator.first_seen': [mostRecentDate], }); delete existingEnrichment['threatintel.indicator.first_seen']; const newEnrichment = buildEventEnrichmentMock({ @@ -70,10 +68,10 @@ describe('ThreatDetailsView', () => { const firstSeenRows = wrapper .find('.euiTableRow') .hostNodes() - .filterWhere((node) => node.text().includes(FIRSTSEEN)); + .filterWhere((node) => node.text().includes('first_seen')); expect(firstSeenRows.map((node) => node.text())).toEqual([ - `first_seen${mostRecentDate}`, - `first_seen${olderDate}`, + `indicator.first_seen${mostRecentDate}`, + `indicator.first_seen${olderDate}`, ]); }); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.tsx index 67c490a33693..41827acb8116 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_details_view.tsx @@ -22,12 +22,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { StyledEuiInMemoryTable } from '../summary_view'; import { getSummaryColumns, SummaryRow, ThreatDetailsRow } from '../helpers'; -import { - FIRSTSEEN, - EVENT_URL, - EVENT_REFERENCE, - ENRICHMENT_TYPES, -} from '../../../../../common/cti/constants'; +import { FIRST_SEEN, ENRICHMENT_TYPES, REFERENCE } from '../../../../../common/cti/constants'; import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../common/constants'; import { getFirstElement } from '../../../../../common/utils/data_retrieval'; import { CtiEnrichment } from '../../../../../common/search_strategy/security_solution/cti'; @@ -42,7 +37,7 @@ import { InspectButton } from '../../inspect'; import { EnrichmentButtonContent } from './enrichment_button_content'; const getFirstSeen = (enrichment: CtiEnrichment): number => { - const firstSeenValue = getShimmedIndicatorValue(enrichment, FIRSTSEEN); + const firstSeenValue = getShimmedIndicatorValue(enrichment, FIRST_SEEN); const firstSeenDate = Date.parse(firstSeenValue ?? 'no date'); return Number.isInteger(firstSeenDate) ? firstSeenDate : new Date(-1).valueOf(); }; @@ -61,7 +56,7 @@ const ThreatDetailsDescription: React.FC = ({ fieldName, value, }) => { - const tooltipChild = [EVENT_URL, EVENT_REFERENCE].includes(fieldName) ? ( + const tooltipChild = fieldName.match(REFERENCE) ? ( {value} @@ -91,7 +86,7 @@ const buildThreatDetailsItems = (enrichment: CtiEnrichment) => .sort() .map((field) => { const displayField = field.startsWith(DEFAULT_INDICATOR_SOURCE_PATH) - ? field.replace(`${DEFAULT_INDICATOR_SOURCE_PATH}.`, '') + ? field.replace(`${DEFAULT_INDICATOR_SOURCE_PATH}`, 'indicator') : field; return { diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts b/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts index 2d93e7e0dc3a..cfa73da6368c 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts +++ b/x-pack/plugins/security_solution/public/common/mock/mock_detection_alerts.ts @@ -90,7 +90,7 @@ export const getThreatMatchDetectionAlert = (overrides: Partial = {}): Ecs }, }, threat: { - indicator: [ + enrichments: [ { matched: { atomic: ['matched.atomic'], diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts index 6a3c6468f43d..155588d1681c 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts +++ b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts @@ -1095,18 +1095,17 @@ export const mockTimelineData: TimelineItem[] = [ _id: 'BuBP4W0BOpWiDweSoYSg', timestamp: '2019-10-18T23:59:15.091Z', threat: { - indicator: [ + enrichments: [ { + indicator: { + provider: ['indicator_provider'], + reference: ['https://example.com'], + }, matched: { atomic: ['192.168.1.1'], field: ['source.ip'], type: ['ip'], }, - event: { - dataset: ['threatintel.example_dataset'], - reference: ['https://example.com'], - }, - provider: ['indicator_provider'], }, ], }, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/__snapshots__/threat_match_row.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/__snapshots__/threat_match_row.test.tsx.snap index 5e86ba25e4ba..8bbd09f9a230 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/__snapshots__/threat_match_row.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/__snapshots__/threat_match_row.test.tsx.snap @@ -23,7 +23,6 @@ exports[`ThreatMatchRowView matches the registered snapshot 1`] = ` { - const threatData = get(data, INDICATOR_DESTINATION_PATH); + const threatData = get(data, ENRICHMENT_DESTINATION_PATH); if (threatData == null) { return []; } else if (!Array.isArray(threatData)) { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/indicator_details.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/indicator_details.tsx index f2e4555147c5..68498f736c6d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/indicator_details.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/indicator_details.tsx @@ -10,7 +10,6 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { - INDICATOR_DATASET, INDICATOR_MATCHED_TYPE, INDICATOR_PROVIDER, INDICATOR_REFERENCE, @@ -22,7 +21,6 @@ import { HorizontalSpacer } from './helpers'; interface IndicatorDetailsProps { contextId: string; eventId: string; - indicatorDataset: string | undefined; indicatorProvider: string | undefined; indicatorReference: string | undefined; indicatorType: string | undefined; @@ -32,7 +30,6 @@ interface IndicatorDetailsProps { export const IndicatorDetails: React.FC = ({ contextId, eventId, - indicatorDataset, indicatorProvider, indicatorReference, indicatorType, @@ -58,28 +55,6 @@ export const IndicatorDetails: React.FC = ({ /> )} - {indicatorDataset && ( - <> - - - - - - - - - - )} {indicatorProvider && ( <> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.test.tsx index 872ca017d7f7..68b5ab36c718 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.test.tsx @@ -22,7 +22,6 @@ describe('ThreatMatchRowView', () => { { { baseProps = { contextId: 'contextId', eventId: 'eventId', - indicatorDataset: 'dataset', indicatorProvider: 'provider', indicatorReference: 'http://example.com', indicatorType: 'domain', @@ -117,29 +114,6 @@ describe('ThreatMatchRowView', () => { expect(indicatorType.exists()).toBeFalsy(); }); - it('renders the indicator dataset, if present', () => { - const wrapper = render(baseProps); - const indicatorDataset = wrapper.find( - '[data-test-subj="threat-match-indicator-details-indicator-dataset"]' - ); - expect(indicatorDataset.props()).toEqual( - expect.objectContaining({ - value: 'dataset', - }) - ); - }); - - it('does not render the indicator dataset, if absent', () => { - const wrapper = render({ - ...baseProps, - indicatorDataset: undefined, - }); - const indicatorDataset = wrapper.find( - '[data-test-subj="threat-match-indicator-details-indicator-dataset"]' - ); - expect(indicatorDataset.exists()).toBeFalsy(); - }); - it('renders the indicator provider, if present', () => { const wrapper = render(baseProps); const indicatorProvider = wrapper.find( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.tsx index 94ed19e218d7..3b0ac277d604 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_row.tsx @@ -11,12 +11,11 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Fields } from '../../../../../../../common/search_strategy'; import { - EVENT_DATASET, - EVENT_REFERENCE, MATCHED_ATOMIC, MATCHED_FIELD, MATCHED_TYPE, PROVIDER, + REFERENCE, } from '../../../../../../../common/cti/constants'; import { MatchDetails } from './match_details'; import { IndicatorDetails } from './indicator_details'; @@ -24,7 +23,6 @@ import { IndicatorDetails } from './indicator_details'; export interface ThreatMatchRowProps { contextId: string; eventId: string; - indicatorDataset: string | undefined; indicatorProvider: string | undefined; indicatorReference: string | undefined; indicatorType: string | undefined; @@ -47,8 +45,7 @@ export const ThreatMatchRow = ({ const props = { contextId, eventId, - indicatorDataset: get(data, EVENT_DATASET)[0] as string | undefined, - indicatorReference: get(data, EVENT_REFERENCE)[0] as string | undefined, + indicatorReference: get(data, REFERENCE)[0] as string | undefined, indicatorProvider: get(data, PROVIDER)[0] as string | undefined, indicatorType: get(data, MATCHED_TYPE)[0] as string | undefined, isDraggable, @@ -62,7 +59,6 @@ export const ThreatMatchRow = ({ export const ThreatMatchRowView = ({ contextId, eventId, - indicatorDataset, indicatorProvider, indicatorReference, indicatorType, @@ -90,7 +86,6 @@ export const ThreatMatchRowView = ({ { it('is false for an alert with indicator data but no match', () => { const indicatorTypeData = getThreatMatchDetectionAlert({ threat: { - indicator: [{ type: ['url'] }], + enrichments: [{ indicator: { type: ['url'] } }], }, }); expect(threatMatchRowRenderer.isInstance(indicatorTypeData)).toBe(false); @@ -40,7 +40,7 @@ describe('threatMatchRowRenderer', () => { it('is false for an alert with threat match fields but no data', () => { const emptyThreatMatchData = getThreatMatchDetectionAlert({ threat: { - indicator: [{ matched: { type: [] } }], + enrichments: [{ matched: { type: [] } }], }, }); expect(threatMatchRowRenderer.isInstance(emptyThreatMatchData)).toBe(false); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_rows.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_rows.tsx index d2c1f09d903c..8de9692a116f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_rows.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/cti/threat_match_rows.tsx @@ -10,6 +10,7 @@ import { get } from 'lodash'; import React, { Fragment } from 'react'; import styled from 'styled-components'; +import { ENRICHMENT_DESTINATION_PATH } from '../../../../../../../common/constants'; import { RowRenderer } from '../../../../../../../common'; import { Fields } from '../../../../../../../common/search_strategy'; import { ID_FIELD_NAME } from '../../../../../../common/components/event_details/event_id'; @@ -21,7 +22,7 @@ const SpacedContainer = styled.div` `; export const ThreatMatchRows: RowRenderer['renderRow'] = ({ data, isDraggable, timelineId }) => { - const indicators = get(data, 'threat.indicator') as Fields[]; + const indicators = get(data, ENRICHMENT_DESTINATION_PATH) as Fields[]; const eventId = get(data, ID_FIELD_NAME); return ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts index bf091ef2508a..3dead29d54bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts @@ -59,6 +59,23 @@ export const createMigration = async ({ ctx._source.signal._meta = [:]; } ctx._source.signal._meta.version = params.version; + + // migrate enrichments before 7.15 to ECS 1.11 + if (ctx._source.signal?.rule?.type == "threat_match" && + ctx._source.threat?.indicator instanceof List && + ctx._source.threat?.enrichments == null) { + ctx._source.threat.enrichments = []; + for (indicator in ctx._source.threat.indicator) { + def enrichment = [:]; + enrichment.indicator = indicator; + enrichment.indicator.reference = indicator.event?.reference; + enrichment.matched = indicator.matched; + enrichment.indicator.remove("matched"); + + ctx._source.threat.enrichments.add(enrichment); + } + ctx._source.threat.remove("indicator"); + } `, params: { version, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/__snapshots__/get_signals_template.test.ts.snap b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/__snapshots__/get_signals_template.test.ts.snap index f07bed9fa556..fb53550dba76 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/__snapshots__/get_signals_template.test.ts.snap +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/__snapshots__/get_signals_template.test.ts.snap @@ -14,7 +14,7 @@ Object { "mappings": Object { "_meta": Object { "aliases_version": 1, - "version": 55, + "version": 56, }, "dynamic": false, "properties": Object { @@ -3791,204 +3791,767 @@ Object { }, "threat": Object { "properties": Object { - "framework": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "indicator": Object { + "enrichments": Object { "properties": Object { - "as": Object { + "indicator": Object { "properties": Object { - "number": Object { - "type": "long", - }, - "organization": Object { + "as": Object { "properties": Object { + "number": Object { + "type": "long", + }, + "organization": Object { + "properties": Object { + "name": Object { + "fields": Object { + "text": Object { + "norms": false, + "type": "text", + }, + }, + "type": "wildcard", + }, + }, + }, + }, + }, + "confidence": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "description": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "email": Object { + "properties": Object { + "address": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "file": Object { + "properties": Object { + "accessed": Object { + "type": "date", + }, + "attributes": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "code_signature": Object { + "properties": Object { + "exists": Object { + "type": "boolean", + }, + "signing_id": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "status": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "subject_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "team_id": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "trusted": Object { + "type": "boolean", + }, + "valid": Object { + "type": "boolean", + }, + }, + }, + "created": Object { + "type": "date", + }, + "ctime": Object { + "type": "date", + }, + "device": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "directory": Object { + "type": "wildcard", + }, + "drive_letter": Object { + "ignore_above": 1, + "type": "keyword", + }, + "elf": Object { + "properties": Object { + "architecture": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "byte_order": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "cpu_type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "creation_date": Object { + "type": "date", + }, + "exports": Object { + "type": "flattened", + }, + "header": Object { + "properties": Object { + "abi_version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "class": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "data": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "entrypoint": Object { + "type": "long", + }, + "object_version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "os_abi": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "imports": Object { + "type": "flattened", + }, + "sections": Object { + "properties": Object { + "chi2": Object { + "type": "long", + }, + "entropy": Object { + "type": "long", + }, + "flags": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "physical_offset": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "physical_size": Object { + "type": "long", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "virtual_address": Object { + "type": "long", + }, + "virtual_size": Object { + "type": "long", + }, + }, + "type": "nested", + }, + "segments": Object { + "properties": Object { + "sections": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + "type": "nested", + }, + "shared_libraries": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "telfhash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "extension": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "gid": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "group": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "inode": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "mime_type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "mode": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "mtime": Object { + "type": "date", + }, "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "owner": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "path": Object { "fields": Object { "text": Object { "norms": false, "type": "text", }, }, + "type": "wildcard", + }, + "size": Object { + "type": "long", + }, + "target_path": Object { + "fields": Object { + "text": Object { + "norms": false, + "type": "text", + }, + }, + "type": "wildcard", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "uid": Object { "ignore_above": 1024, "type": "keyword", }, }, }, - }, - }, - "confidence": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "dataset": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "description": Object { - "type": "wildcard", - }, - "domain": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "email": Object { - "properties": Object { - "address": Object { - "ignore_above": 1024, - "type": "keyword", - }, - }, - }, - "event": Object { - "properties": Object { - "action": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "category": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "code": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "created": Object { + "first_seen": Object { "type": "date", }, - "dataset": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "duration": Object { - "type": "long", - }, - "end": Object { - "type": "date", + "geo": Object { + "properties": Object { + "city_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "continent_code": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "continent_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "country_iso_code": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "country_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "location": Object { + "type": "geo_point", + }, + "name": Object { + "type": "wildcard", + }, + "postal_code": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "region_iso_code": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "region_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "timezone": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, "hash": Object { - "ignore_above": 1024, - "type": "keyword", + "properties": Object { + "md5": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "sha1": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "sha256": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "sha512": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "ssdeep": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, - "id": Object { - "ignore_above": 1024, - "type": "keyword", + "ip": Object { + "type": "ip", }, - "ingested": Object { + "last_seen": Object { "type": "date", }, - "kind": Object { - "ignore_above": 1024, - "type": "keyword", + "marking": Object { + "properties": Object { + "tlp": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, - "module": Object { - "ignore_above": 1024, - "type": "keyword", + "modified_at": Object { + "type": "date", }, - "original": Object { - "doc_values": false, - "ignore_above": 1024, - "index": false, - "type": "keyword", + "pe": Object { + "properties": Object { + "architecture": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "authentihash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "company": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "compile_timestamp": Object { + "type": "date", + }, + "compiler": Object { + "properties": Object { + "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "creation_date": Object { + "type": "date", + }, + "debug": Object { + "properties": Object { + "offset": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "size": Object { + "type": "long", + }, + "timestamp": Object { + "type": "date", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + "type": "nested", + }, + "description": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "entry_point": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "exports": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "file_version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "icon": Object { + "properties": Object { + "hash": Object { + "properties": Object { + "dhash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + }, + }, + "imphash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "imports": Object { + "type": "flattened", + }, + "machine_type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "original_file_name": Object { + "type": "wildcard", + }, + "packers": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "product": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "resources": Object { + "properties": Object { + "chi2": Object { + "type": "long", + }, + "entropy": Object { + "type": "long", + }, + "filetype": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "language": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "sha256": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + "type": "nested", + }, + "rich_header": Object { + "properties": Object { + "hash": Object { + "properties": Object { + "md5": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + }, + }, + "sections": Object { + "properties": Object { + "chi2": Object { + "type": "long", + }, + "entropy": Object { + "type": "float", + }, + "flags": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "raw_size": Object { + "type": "long", + }, + "virtual_address": Object { + "type": "long", + }, + }, + "type": "nested", + }, + }, }, - "outcome": Object { - "ignore_above": 1024, - "type": "keyword", + "port": Object { + "type": "long", }, "provider": Object { "ignore_above": 1024, "type": "keyword", }, - "reason": Object { - "ignore_above": 1024, - "type": "keyword", - }, "reference": Object { "ignore_above": 1024, "type": "keyword", }, - "risk_score": Object { - "type": "float", + "registry": Object { + "properties": Object { + "data": Object { + "properties": Object { + "bytes": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "strings": Object { + "type": "wildcard", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "hive": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "key": Object { + "type": "wildcard", + }, + "path": Object { + "type": "wildcard", + }, + "value": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, - "risk_score_norm": Object { - "type": "float", - }, - "sequence": Object { + "scanner_stats": Object { "type": "long", }, - "severity": Object { + "sightings": Object { "type": "long", }, - "start": Object { - "type": "date", - }, - "timezone": Object { - "ignore_above": 1024, - "type": "keyword", - }, "type": Object { "ignore_above": 1024, "type": "keyword", }, "url": Object { - "ignore_above": 1024, - "type": "keyword", - }, - }, - }, - "first_seen": Object { - "type": "date", - }, - "geo": Object { - "properties": Object { - "city_name": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "continent_name": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "country_iso_code": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "country_name": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "location": Object { - "type": "geo_point", - }, - "name": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "region_iso_code": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "region_name": Object { - "ignore_above": 1024, - "type": "keyword", - }, - }, - }, - "ip": Object { - "type": "ip", - }, - "last_seen": Object { - "type": "date", - }, - "marking": Object { - "properties": Object { - "tlp": Object { - "ignore_above": 1024, - "type": "keyword", + "properties": Object { + "domain": Object { + "type": "wildcard", + }, + "extension": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "fragment": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "full": Object { + "fields": Object { + "text": Object { + "norms": false, + "type": "text", + }, + }, + "type": "wildcard", + }, + "original": Object { + "fields": Object { + "text": Object { + "norms": false, + "type": "text", + }, + }, + "type": "wildcard", + }, + "password": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "path": Object { + "type": "wildcard", + }, + "port": Object { + "type": "long", + }, + "query": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "registered_domain": Object { + "type": "wildcard", + }, + "scheme": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "subdomain": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "top_level_domain": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "username": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "x509": Object { + "properties": Object { + "alternative_names": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "issuer": Object { + "properties": Object { + "common_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "country": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "distinguished_name": Object { + "type": "wildcard", + }, + "locality": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "organization": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "organizational_unit": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "state_or_province": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "not_after": Object { + "type": "date", + }, + "not_before": Object { + "type": "date", + }, + "public_key_algorithm": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "public_key_curve": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "public_key_exponent": Object { + "doc_values": false, + "index": false, + "type": "long", + }, + "public_key_size": Object { + "type": "long", + }, + "serial_number": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "signature_algorithm": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "subject": Object { + "properties": Object { + "common_name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "country": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "distinguished_name": Object { + "type": "wildcard", + }, + "locality": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "organization": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "organizational_unit": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "state_or_province": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "version_number": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, }, + "type": "object", }, "matched": Object { "properties": Object { @@ -4000,36 +4563,227 @@ Object { "ignore_above": 1024, "type": "keyword", }, + "id": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "index": Object { + "ignore_above": 1024, + "type": "keyword", + }, "type": Object { "ignore_above": 1024, "type": "keyword", }, }, }, - "module": Object { - "ignore_above": 1024, - "type": "keyword", + "pe": Object { + "properties": Object { + "architecture": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "authentihash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "company": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "compile_timestamp": Object { + "type": "date", + }, + "compiler": Object { + "properties": Object { + "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "creation_date": Object { + "type": "date", + }, + "debug": Object { + "properties": Object { + "offset": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "size": Object { + "type": "long", + }, + "timestamp": Object { + "type": "date", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + "type": "nested", + }, + "description": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "entry_point": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "exports": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "file_version": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "icon": Object { + "properties": Object { + "hash": Object { + "properties": Object { + "dhash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + }, + }, + "imphash": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "imports": Object { + "type": "flattened", + }, + "machine_type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "original_file_name": Object { + "type": "wildcard", + }, + "packers": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "product": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "resources": Object { + "properties": Object { + "chi2": Object { + "type": "long", + }, + "entropy": Object { + "type": "long", + }, + "filetype": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "language": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "sha256": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + "type": "nested", + }, + "rich_header": Object { + "properties": Object { + "hash": Object { + "properties": Object { + "md5": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + }, + }, + "sections": Object { + "properties": Object { + "chi2": Object { + "type": "long", + }, + "entropy": Object { + "type": "float", + }, + "flags": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "name": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "raw_size": Object { + "type": "long", + }, + "virtual_address": Object { + "type": "long", + }, + }, + "type": "nested", + }, + }, }, - "port": Object { - "type": "long", - }, - "provider": Object { - "ignore_above": 1024, - "type": "keyword", - }, - "scanner_stats": Object { - "type": "long", - }, - "sightings": Object { - "type": "long", - }, - "type": Object { - "ignore_above": 1024, - "type": "keyword", + "registry": Object { + "properties": Object { + "data": Object { + "properties": Object { + "bytes": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "strings": Object { + "type": "wildcard", + }, + "type": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, + }, + "hive": Object { + "ignore_above": 1024, + "type": "keyword", + }, + "key": Object { + "type": "wildcard", + }, + "path": Object { + "type": "wildcard", + }, + "value": Object { + "ignore_above": 1024, + "type": "keyword", + }, + }, }, }, "type": "nested", }, + "framework": Object { + "ignore_above": 1024, + "type": "keyword", + }, "tactic": Object { "properties": Object { "id": Object { @@ -4930,6 +5684,6 @@ Object { }, }, }, - "version": 55, + "version": 56, } `; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_signals_template.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_signals_template.ts index 989c73f97997..d1a369d571d0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_signals_template.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_signals_template.ts @@ -29,7 +29,7 @@ import aadFieldConversion from './signal_aad_mapping.json'; incremented by 10 in order to add "room" for the aforementioned patch release */ -export const SIGNALS_TEMPLATE_VERSION = 55; +export const SIGNALS_TEMPLATE_VERSION = 56; /** @constant @type {number} @@ -78,12 +78,8 @@ export const getSignalsTemplate = (index: string, spaceId: string, aadIndexAlias ...ecsMapping.mappings.properties.threat, properties: { ...ecsMapping.mappings.properties.threat.properties, - indicator: { - ...otherMapping.mappings.properties.threat.properties.indicator, - properties: { - ...otherMapping.mappings.properties.threat.properties.indicator.properties, - event: ecsMapping.mappings.properties.event, - }, + enrichments: { + ...otherMapping.mappings.properties.threat.properties.enrichments, }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/other_mappings.json b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/other_mappings.json index 43bc1a548a6a..3b1ae9a9caa5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/other_mappings.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/other_mappings.json @@ -180,104 +180,767 @@ }, "threat": { "properties": { - "indicator": { - "type": "nested", + "enrichments": { "properties": { - "as": { + "indicator": { "properties": { - "number": { - "type": "long" - }, - "organization": { + "as": { "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "type": "wildcard" + } + } + } + } + }, + "confidence": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "type": "wildcard" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { "fields": { "text": { "norms": false, "type": "text" } }, + "type": "wildcard" + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "type": "wildcard" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "modified_at": { + "type": "date" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "authentihash": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "compile_timestamp": { + "type": "date" + }, + "compiler": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "creation_date": { + "type": "date" + }, + "debug": { + "properties": { + "offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "timestamp": { + "type": "date" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "entry_point": { + "ignore_above": 1024, + "type": "keyword" + }, + "exports": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "icon": { + "properties": { + "hash": { + "properties": { + "dhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "imports": { + "type": "flattened" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "type": "wildcard" + }, + "packers": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "resources": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "filetype": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "rich_header": { + "properties": { + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "float" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "raw_size": { + "type": "long" + }, + "virtual_address": { + "type": "long" + } + }, + "type": "nested" + } + } + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "type": "wildcard" + }, + "path": { + "type": "wildcard" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "properties": { + "domain": { + "type": "wildcard" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "type": "wildcard" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "type": "wildcard" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "type": "wildcard" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "type": "wildcard" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "type": "wildcard" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "doc_values": false, + "index": false, + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "type": "wildcard" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { "ignore_above": 1024, "type": "keyword" } } } - } - }, - "confidence": { - "ignore_above": 1024, - "type": "keyword" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "type": "wildcard" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "first_seen": { - "type": "date" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "last_seen": { - "type": "date" - }, - "marking": { - "properties": { - "tlp": { - "ignore_above": 1024, - "type": "keyword" - } - } + }, + "type": "object" }, "matched": { "properties": { @@ -289,34 +952,222 @@ "ignore_above": 1024, "type": "keyword" }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, "type": { "ignore_above": 1024, "type": "keyword" } } }, - "module": { - "ignore_above": 1024, - "type": "keyword" + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "authentihash": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "compile_timestamp": { + "type": "date" + }, + "compiler": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "creation_date": { + "type": "date" + }, + "debug": { + "properties": { + "offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "timestamp": { + "type": "date" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "entry_point": { + "ignore_above": 1024, + "type": "keyword" + }, + "exports": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "icon": { + "properties": { + "hash": { + "properties": { + "dhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "imports": { + "type": "flattened" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "type": "wildcard" + }, + "packers": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "resources": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "filetype": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "rich_header": { + "properties": { + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "float" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "raw_size": { + "type": "long" + }, + "virtual_address": { + "type": "long" + } + }, + "type": "nested" + } + } }, - "port": { - "type": "long" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner_stats": { - "type": "long" - }, - "sightings": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "type": "wildcard" + }, + "path": { + "type": "wildcard" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } } - } + }, + "type": "nested" } } }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson index bee8f542b527..a02951e55580 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson @@ -11,4 +11,4 @@ {"savedObjectId":null,"version":null,"columns":[{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"@timestamp","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"signal.rule.description","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"event.action","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"process.name","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"The working directory of the process.","columnHeaderType":"not-filtered","id":"process.working_directory","category":"process","type":"string","searchable":null,"example":"/home/alice"},{"indexes":null,"aggregatable":true,"name":null,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","searchable":null,"example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"process.pid","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"Absolute path to the process executable.","columnHeaderType":"not-filtered","id":"process.parent.executable","category":"process","type":"string","searchable":null,"example":"/usr/bin/ssh"},{"indexes":null,"aggregatable":true,"name":null,"description":"Array of process arguments.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.parent.args","category":"process","type":"string","searchable":null,"example":"[\"ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"indexes":null,"aggregatable":true,"name":null,"description":"Process id.","columnHeaderType":"not-filtered","id":"process.parent.pid","category":"process","type":"number","searchable":null,"example":"4242"},{"indexes":null,"aggregatable":true,"name":null,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","searchable":null,"example":"albert"},{"indexes":null,"aggregatable":true,"name":null,"description":"Name of the host.\n\nIt can contain what `hostname` returns on Unix systems, the fully qualified\ndomain name, or a name specified by the user. The sender decides which value\nto use.","columnHeaderType":"not-filtered","id":"host.name","category":"host","type":"string","searchable":null}],"dataProviders":[{"excluded":false,"and":[],"kqlQuery":"","name":"","queryMatch":{"displayValue":"endpoint","field":"agent.type","displayField":"agent.type","value":"endpoint","operator":":"},"id":"timeline-1-4685da24-35c1-43f3-892d-1f926dbf5568","type":"default","enabled":true}],"description":"","eventType":"all","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"title":"Generic Endpoint Timeline","timelineType":"template","templateTimelineVersion":2,"templateTimelineId":"db366523-f1c6-4c1f-8731-6ce5ed9e5717","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":{"columnId":"@timestamp","sortDirection":"desc"},"created":1594735857110,"createdBy":"Elastic","updated":1611609999115,"updatedBy":"Elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} {"savedObjectId":null,"version":null,"columns":[{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"@timestamp","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"signal.rule.description","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"The action captured by the event.\n\nThis describes the information in the event. It is more specific than `event.category`.\nExamples are `group-add`, `process-started`, `file-created`. The value is\nnormally defined by the implementer.","columnHeaderType":"not-filtered","id":"event.action","category":"event","type":"string","searchable":null,"example":"user-password-change"},{"indexes":null,"aggregatable":true,"name":null,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","searchable":null,"example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"process.pid","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"IP address of the source (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"source.ip","category":"source","type":"ip","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"Port of the source.","columnHeaderType":"not-filtered","id":"source.port","category":"source","type":"number","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"IP address of the destination (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"destination.ip","category":"destination","type":"ip","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"destination.port","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","searchable":null,"example":"albert"},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"host.name","searchable":null}],"dataProviders":[{"and":[{"enabled":true,"excluded":false,"id":"timeline-1-e37e37c5-a6e7-4338-af30-47bfbc3c0e1e","kqlQuery":"","name":"{destination.ip}","queryMatch":{"displayField":"destination.ip","displayValue":"{destination.ip}","field":"destination.ip","operator":":","value":"{destination.ip}"},"type":"template"}],"enabled":true,"excluded":false,"id":"timeline-1-ec778f01-1802-40f0-9dfb-ed8de1f656cb","kqlQuery":"","name":"{source.ip}","queryMatch":{"displayField":"source.ip","displayValue":"{source.ip}","field":"source.ip","operator":":","value":"{source.ip}"},"type":"template"}],"description":"","eventType":"all","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"title":"Generic Network Timeline","timelineType":"template","templateTimelineVersion":2,"templateTimelineId":"91832785-286d-4ebe-b884-1a208d111a70","dateRange":{"start":1588255858373,"end":1588256218373},"savedQueryId":null,"sort":{"columnId":"@timestamp","sortDirection":"desc"},"created":1594735573866,"createdBy":"Elastic","updated":1611609960850,"updatedBy":"Elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} {"savedObjectId":null,"version":null,"columns":[{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"@timestamp","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"signal.rule.description","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"event.action","searchable":null},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"process.name","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"The working directory of the process.","columnHeaderType":"not-filtered","id":"process.working_directory","category":"process","type":"string","searchable":null,"example":"/home/alice"},{"indexes":null,"aggregatable":true,"name":null,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","searchable":null,"example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"indexes":null,"name":null,"columnHeaderType":"not-filtered","id":"process.pid","searchable":null},{"indexes":null,"aggregatable":true,"name":null,"description":"Absolute path to the process executable.","columnHeaderType":"not-filtered","id":"process.parent.executable","category":"process","type":"string","searchable":null,"example":"/usr/bin/ssh"},{"indexes":null,"aggregatable":true,"name":null,"description":"Array of process arguments.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.parent.args","category":"process","type":"string","searchable":null,"example":"[\"ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"indexes":null,"aggregatable":true,"name":null,"description":"Process id.","columnHeaderType":"not-filtered","id":"process.parent.pid","category":"process","type":"number","searchable":null,"example":"4242"},{"indexes":null,"aggregatable":true,"name":null,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","searchable":null,"example":"albert"},{"indexes":null,"aggregatable":true,"name":null,"description":"Name of the host.\n\nIt can contain what `hostname` returns on Unix systems, the fully qualified\ndomain name, or a name specified by the user. The sender decides which value\nto use.","columnHeaderType":"not-filtered","id":"host.name","category":"host","type":"string","searchable":null}],"dataProviders":[{"excluded":false,"and":[],"kqlQuery":"","name":"{process.name}","queryMatch":{"displayValue":null,"field":"process.name","displayField":null,"value":"{process.name}","operator":":"},"id":"timeline-1-8622010a-61fb-490d-b162-beac9c36a853","type":"template","enabled":true}],"description":"","eventType":"all","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"title":"Generic Process Timeline","timelineType":"template","templateTimelineVersion":2,"templateTimelineId":"76e52245-7519-4251-91ab-262fb1a1728c","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":{"columnId":"@timestamp","sortDirection":"desc"},"created":1594735629389,"createdBy":"Elastic","updated":1611609848602,"updatedBy":"Elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} -{"savedObjectId":null,"version":null,"columns":[{"columnHeaderType":"not-filtered","id":"@timestamp"},{"columnHeaderType":"not-filtered","id":"signal.rule.description"},{"aggregatable":true,"description":"The action captured by the event.\n\nThis describes the information in the event. It is more specific than `event.category`.\nExamples are `group-add`, `process-started`, `file-created`. The value is\nnormally defined by the implementer.","columnHeaderType":"not-filtered","id":"event.action","category":"event","type":"string","example":"user-password-change"},{"aggregatable":true,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"columnHeaderType":"not-filtered","id":"process.pid"},{"aggregatable":true,"description":"IP address of the source (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"source.ip","category":"source","type":"ip"},{"aggregatable":true,"description":"Port of the source.","columnHeaderType":"not-filtered","id":"source.port","category":"source","type":"number"},{"aggregatable":true,"description":"IP address of the destination (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"destination.ip","category":"destination","type":"ip"},{"columnHeaderType":"not-filtered","id":"destination.port"},{"aggregatable":true,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","example":"albert"},{"columnHeaderType":"not-filtered","id":"host.name"}],"dataProviders":[{"excluded":false,"and":[{"excluded":false,"kqlQuery":"","name":"{threat.indicator.matched.type}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.type","displayField":null,"value":"{threat.indicator.matched.type}","operator":":"},"id":"timeline-1-ae18ef4b-f690-4122-a24d-e13b6818fba8","type":"template","enabled":true},{"excluded":false,"kqlQuery":"","name":"{threat.indicator.matched.field}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.field","displayField":null,"value":"{threat.indicator.matched.field}","operator":":"},"id":"timeline-1-7b4cf27e-6788-4d8e-9188-7687f0eba0f2","type":"template","enabled":true}],"kqlQuery":"","name":"{threat.indicator.matched.atomic}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.atomic","displayField":null,"value":"{threat.indicator.matched.atomic}","operator":":"},"id":"timeline-1-7db7d278-a80a-4853-971a-904319c50777","type":"template","enabled":true}],"description":"This Timeline template is for alerts generated by Indicator Match detection rules.","eqlOptions":{"eventCategoryField":"event.category","tiebreakerField":"","timestampField":"@timestamp","query":"","size":100},"eventType":"alert","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"indexNames":[".siem-signals-default"],"title":"Generic Threat Match Timeline","timelineType":"template","templateTimelineVersion":1,"templateTimelineId":"495ad7a7-316e-4544-8a0f-9c098daee76e","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":[{"sortDirection":"desc","columnId":"@timestamp"}],"created":1616696609311,"createdBy":"elastic","updated":1616788372794,"updatedBy":"elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} +{"savedObjectId":null,"version":null,"columns":[{"columnHeaderType":"not-filtered","id":"@timestamp"},{"columnHeaderType":"not-filtered","id":"signal.rule.description"},{"aggregatable":true,"description":"The action captured by the event.\n\nThis describes the information in the event. It is more specific than `event.category`.\nExamples are `group-add`, `process-started`, `file-created`. The value is\nnormally defined by the implementer.","columnHeaderType":"not-filtered","id":"event.action","category":"event","type":"string","example":"user-password-change"},{"aggregatable":true,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"columnHeaderType":"not-filtered","id":"process.pid"},{"aggregatable":true,"description":"IP address of the source (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"source.ip","category":"source","type":"ip"},{"aggregatable":true,"description":"Port of the source.","columnHeaderType":"not-filtered","id":"source.port","category":"source","type":"number"},{"aggregatable":true,"description":"IP address of the destination (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"destination.ip","category":"destination","type":"ip"},{"columnHeaderType":"not-filtered","id":"destination.port"},{"aggregatable":true,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","example":"albert"},{"columnHeaderType":"not-filtered","id":"host.name"}],"dataProviders":[{"excluded":false,"and":[{"excluded":false,"kqlQuery":"","name":"{threat.enrichments.matched.type}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.type","displayField":null,"value":"{threat.enrichments.matched.type}","operator":":"},"id":"timeline-1-ae18ef4b-f690-4122-a24d-e13b6818fba8","type":"template","enabled":true},{"excluded":false,"kqlQuery":"","name":"{threat.enrichments.matched.field}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.field","displayField":null,"value":"{threat.enrichments.matched.field}","operator":":"},"id":"timeline-1-7b4cf27e-6788-4d8e-9188-7687f0eba0f2","type":"template","enabled":true}],"kqlQuery":"","name":"{threat.enrichments.matched.atomic}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.atomic","displayField":null,"value":"{threat.enrichments.matched.atomic}","operator":":"},"id":"timeline-1-7db7d278-a80a-4853-971a-904319c50777","type":"template","enabled":true}],"description":"This Timeline template is for alerts generated by Indicator Match detection rules.","eqlOptions":{"eventCategoryField":"event.category","tiebreakerField":"","timestampField":"@timestamp","query":"","size":100},"eventType":"alert","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"indexNames":[".siem-signals-default"],"title":"Generic Threat Match Timeline","timelineType":"template","templateTimelineVersion":2,"templateTimelineId":"495ad7a7-316e-4544-8a0f-9c098daee76e","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":[{"sortDirection":"desc","columnId":"@timestamp"}],"created":1616696609311,"createdBy":"elastic","updated":1616788372794,"updatedBy":"elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json index 01edb484f4a0..d777fdf17d65 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json @@ -1 +1 @@ -{"savedObjectId":null,"version":null,"columns":[{"columnHeaderType":"not-filtered","id":"@timestamp"},{"columnHeaderType":"not-filtered","id":"signal.rule.description"},{"aggregatable":true,"description":"The action captured by the event.\n\nThis describes the information in the event. It is more specific than `event.category`.\nExamples are `group-add`, `process-started`, `file-created`. The value is\nnormally defined by the implementer.","columnHeaderType":"not-filtered","id":"event.action","category":"event","type":"string","example":"user-password-change"},{"aggregatable":true,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"columnHeaderType":"not-filtered","id":"process.pid"},{"aggregatable":true,"description":"IP address of the source (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"source.ip","category":"source","type":"ip"},{"aggregatable":true,"description":"Port of the source.","columnHeaderType":"not-filtered","id":"source.port","category":"source","type":"number"},{"aggregatable":true,"description":"IP address of the destination (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"destination.ip","category":"destination","type":"ip"},{"columnHeaderType":"not-filtered","id":"destination.port"},{"aggregatable":true,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","example":"albert"},{"columnHeaderType":"not-filtered","id":"host.name"}],"dataProviders":[{"excluded":false,"and":[{"excluded":false,"kqlQuery":"","name":"{threat.indicator.matched.type}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.type","displayField":null,"value":"{threat.indicator.matched.type}","operator":":"},"id":"timeline-1-ae18ef4b-f690-4122-a24d-e13b6818fba8","type":"template","enabled":true},{"excluded":false,"kqlQuery":"","name":"{threat.indicator.matched.field}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.field","displayField":null,"value":"{threat.indicator.matched.field}","operator":":"},"id":"timeline-1-7b4cf27e-6788-4d8e-9188-7687f0eba0f2","type":"template","enabled":true}],"kqlQuery":"","name":"{threat.indicator.matched.atomic}","queryMatch":{"displayValue":null,"field":"threat.indicator.matched.atomic","displayField":null,"value":"{threat.indicator.matched.atomic}","operator":":"},"id":"timeline-1-7db7d278-a80a-4853-971a-904319c50777","type":"template","enabled":true}],"description":"This Timeline template is for alerts generated by Indicator Match detection rules.","eqlOptions":{"eventCategoryField":"event.category","tiebreakerField":"","timestampField":"@timestamp","query":"","size":100},"eventType":"alert","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"indexNames":[".siem-signals-default"],"title":"Generic Threat Match Timeline","timelineType":"template","templateTimelineVersion":1,"templateTimelineId":"495ad7a7-316e-4544-8a0f-9c098daee76e","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":[{"sortDirection":"desc","columnId":"@timestamp"}],"created":1616696609311,"createdBy":"elastic","updated":1616788372794,"updatedBy":"elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} +{"savedObjectId":null,"version":null,"columns":[{"columnHeaderType":"not-filtered","id":"@timestamp"},{"columnHeaderType":"not-filtered","id":"signal.rule.description"},{"aggregatable":true,"description":"The action captured by the event.\n\nThis describes the information in the event. It is more specific than `event.category`.\nExamples are `group-add`, `process-started`, `file-created`. The value is\nnormally defined by the implementer.","columnHeaderType":"not-filtered","id":"event.action","category":"event","type":"string","example":"user-password-change"},{"aggregatable":true,"description":"Array of process arguments, starting with the absolute path to\nthe executable.\n\nMay be filtered to protect sensitive information.","columnHeaderType":"not-filtered","id":"process.args","category":"process","type":"string","example":"[\"/usr/bin/ssh\",\"-l\",\"user\",\"10.0.0.16\"]"},{"columnHeaderType":"not-filtered","id":"process.pid"},{"aggregatable":true,"description":"IP address of the source (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"source.ip","category":"source","type":"ip"},{"aggregatable":true,"description":"Port of the source.","columnHeaderType":"not-filtered","id":"source.port","category":"source","type":"number"},{"aggregatable":true,"description":"IP address of the destination (IPv4 or IPv6).","columnHeaderType":"not-filtered","id":"destination.ip","category":"destination","type":"ip"},{"columnHeaderType":"not-filtered","id":"destination.port"},{"aggregatable":true,"description":"Short name or login of the user.","columnHeaderType":"not-filtered","id":"user.name","category":"user","type":"string","example":"albert"},{"columnHeaderType":"not-filtered","id":"host.name"}],"dataProviders":[{"excluded":false,"and":[{"excluded":false,"kqlQuery":"","name":"{threat.enrichments.matched.type}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.type","displayField":null,"value":"{threat.enrichments.matched.type}","operator":":"},"id":"timeline-1-ae18ef4b-f690-4122-a24d-e13b6818fba8","type":"template","enabled":true},{"excluded":false,"kqlQuery":"","name":"{threat.enrichments.matched.field}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.field","displayField":null,"value":"{threat.enrichments.matched.field}","operator":":"},"id":"timeline-1-7b4cf27e-6788-4d8e-9188-7687f0eba0f2","type":"template","enabled":true}],"kqlQuery":"","name":"{threat.enrichments.matched.atomic}","queryMatch":{"displayValue":null,"field":"threat.enrichments.matched.atomic","displayField":null,"value":"{threat.enrichments.matched.atomic}","operator":":"},"id":"timeline-1-7db7d278-a80a-4853-971a-904319c50777","type":"template","enabled":true}],"description":"This Timeline template is for alerts generated by Indicator Match detection rules.","eqlOptions":{"eventCategoryField":"event.category","tiebreakerField":"","timestampField":"@timestamp","query":"","size":100},"eventType":"alert","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"kind":"kuery","expression":""},"serializedQuery":""}},"indexNames":[".siem-signals-default"],"title":"Generic Threat Match Timeline","timelineType":"template","templateTimelineVersion":2,"templateTimelineId":"495ad7a7-316e-4544-8a0f-9c098daee76e","dateRange":{"start":1588161020848,"end":1588162280848},"savedQueryId":null,"sort":[{"sortDirection":"desc","columnId":"@timestamp"}],"created":1616696609311,"createdBy":"elastic","updated":1616788372794,"updatedBy":"elastic","eventNotes":[],"globalNotes":[],"pinnedEventIds":[],"status":"immutable"} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts index 4a51880e0f22..8768fa7a0814 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts @@ -6,12 +6,12 @@ */ import { get } from 'lodash'; -import { INDICATOR_DESTINATION_PATH } from '../../../../../common/constants'; +import { ENRICHMENT_DESTINATION_PATH } from '../../../../../common/constants'; import { ENRICHMENT_TYPES } from '../../../../../common/cti/constants'; import { getThreatListItemMock } from './build_threat_mapping_filter.mock'; import { - buildMatchedIndicator, + buildEnrichments, enrichSignalThreatMatches, groupAndMergeSignalMatches, } from './enrich_signal_threat_matches'; @@ -73,7 +73,7 @@ describe('groupAndMergeSignalMatches', () => { }); }); -describe('buildMatchedIndicator', () => { +describe('buildEnrichments', () => { let threats: ThreatListItem[]; let queries: ThreatMatchNamedQuery[]; let indicatorPath: string; @@ -85,7 +85,14 @@ describe('buildMatchedIndicator', () => { _id: '123', _source: { event: { dataset: 'abuse.ch', reference: 'https://test.com' }, - threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, + threat: { + indicator: { + domain: 'domain_1', + other: 'other_1', + reference: 'https://test.com', + type: 'type_1', + }, + }, }, }), ]; @@ -100,91 +107,100 @@ describe('buildMatchedIndicator', () => { }); it('returns an empty list if queries is empty', () => { - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries: [], threats, indicatorPath, }); - expect(indicators).toEqual([]); + expect(enrichments).toEqual([]); }); it('returns the value of the matched indicator as matched.atomic', () => { - const [indicator] = buildMatchedIndicator({ + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - expect(get(indicator, 'matched.atomic')).toEqual('domain_1'); + expect(get(enrichment, 'matched.atomic')).toEqual('domain_1'); }); - it('returns event values as a part of threat', () => { - const [indicator] = buildMatchedIndicator({ + it('does not enrich from other fields in the indicator document', () => { + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - const expectedEvent = threats[0]._source!.event; - expect(get(indicator, 'event')).toEqual(expectedEvent); + expect(Object.keys(enrichment)).toEqual(['indicator', 'matched']); }); it('returns the _id of the matched indicator as matched.id', () => { - const [indicator] = buildMatchedIndicator({ + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - expect(get(indicator, 'matched.id')).toEqual('123'); + expect(get(enrichment, 'matched.id')).toEqual('123'); }); it('returns the _index of the matched indicator as matched.index', () => { - const [indicator] = buildMatchedIndicator({ + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - expect(get(indicator, 'matched.index')).toEqual('threat-index'); + expect(get(enrichment, 'matched.index')).toEqual('threat-index'); }); it('returns the field of the matched indicator as matched.field', () => { - const [indicator] = buildMatchedIndicator({ + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - expect(get(indicator, 'matched.field')).toEqual('event.field'); + expect(get(enrichment, 'matched.field')).toEqual('event.field'); }); it('returns the type of the enrichment as an indicator match type', () => { - const [indicator] = buildMatchedIndicator({ + const [enrichment] = buildEnrichments({ queries, threats, indicatorPath, }); - expect(get(indicator, 'matched.type')).toEqual(ENRICHMENT_TYPES.IndicatorMatchRule); + expect(get(enrichment, 'matched.type')).toEqual(ENRICHMENT_TYPES.IndicatorMatchRule); }); - it('returns indicators for each provided query', () => { + it('returns enrichments for each provided query', () => { threats = [ getThreatListItemMock({ _id: '123', _source: { - event: { reference: 'https://test.com' }, threat: { - indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' }, + indicator: { + domain: 'domain_1', + other: 'other_1', + reference: 'https://test.com', + type: 'type_1', + }, }, }, }), getThreatListItemMock({ _id: '456', _source: { - event: { reference: 'https://test2.com' }, - threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, + threat: { + indicator: { + domain: 'domain_1', + other: 'other_1', + reference: 'https://test2.com', + type: 'type_1', + }, + }, }, }), ]; @@ -193,25 +209,30 @@ describe('buildMatchedIndicator', () => { getNamedQueryMock({ id: '456', value: 'threat.indicator.other' }), getNamedQueryMock({ id: '456', value: 'threat.indicator.domain' }), ]; - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath, }); - expect(indicators).toHaveLength(queries.length); + expect(enrichments).toHaveLength(queries.length); }); it('returns the indicator data specified at threat.indicator by default', () => { - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath, }); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { - domain: 'domain_1', + indicator: { + domain: 'domain_1', + other: 'other_1', + type: 'type_1', + reference: 'https://test.com', + }, matched: { atomic: 'domain_1', id: '123', @@ -219,12 +240,6 @@ describe('buildMatchedIndicator', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - other: 'other_1', - type: 'type_1', - event: { - reference: 'https://test.com', - dataset: 'abuse.ch', - }, }, ]); }); @@ -234,14 +249,12 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { - event: { - reference: 'https://test3.com', - }, 'threat.indicator.domain': 'domain_1', custom: { indicator: { path: { indicator_field: 'indicator_field_1', + reference: 'https://test3.com', type: 'indicator_type', }, }, @@ -250,15 +263,19 @@ describe('buildMatchedIndicator', () => { }), ]; - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath: 'custom.indicator.path', }); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { - indicator_field: 'indicator_field_1', + indicator: { + indicator_field: 'indicator_field_1', + reference: 'https://test3.com', + type: 'indicator_type', + }, matched: { atomic: 'domain_1', id: '123', @@ -266,10 +283,6 @@ describe('buildMatchedIndicator', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - type: 'indicator_type', - event: { - reference: 'https://test3.com', - }, }, ]); }); @@ -282,14 +295,15 @@ describe('buildMatchedIndicator', () => { }), ]; - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath, }); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { + indicator: {}, matched: { atomic: undefined, id: '123', @@ -309,14 +323,15 @@ describe('buildMatchedIndicator', () => { }), ]; - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath, }); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { + indicator: {}, matched: { atomic: undefined, id: '123', @@ -333,28 +348,29 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { - event: { - reference: 'https://test4.com', - }, threat: { indicator: [ - { domain: 'foo', type: 'first' }, - { domain: 'bar', type: 'second' }, + { domain: 'foo', reference: 'https://test4.com', type: 'first' }, + { domain: 'bar', reference: 'https://test5.com', type: 'second' }, ], }, }, }), ]; - const indicators = buildMatchedIndicator({ + const enrichments = buildEnrichments({ queries, threats, indicatorPath, }); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { - domain: 'foo', + indicator: { + domain: 'foo', + reference: 'https://test4.com', + type: 'first', + }, matched: { atomic: undefined, id: '123', @@ -362,10 +378,6 @@ describe('buildMatchedIndicator', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - type: 'first', - event: { - reference: 'https://test4.com', - }, }, ]); }); @@ -383,7 +395,7 @@ describe('buildMatchedIndicator', () => { ]; expect(() => - buildMatchedIndicator({ + buildEnrichments({ queries, threats, indicatorPath, @@ -404,7 +416,7 @@ describe('buildMatchedIndicator', () => { ]; expect(() => - buildMatchedIndicator({ + buildEnrichments({ queries, threats, indicatorPath, @@ -452,12 +464,12 @@ describe('enrichSignalThreatMatches', () => { expect(enrichedSignals.hits.hits).toEqual([]); }); - it('preserves existing threat.indicator objects on signals', async () => { + it('preserves existing threat.enrichments objects on signals', async () => { const signalHit = getSignalHitMock({ _source: { '@timestamp': 'mocked', event: { category: 'malware' }, - threat: { indicator: [{ existing: 'indicator' }] }, + threat: { enrichments: [{ existing: 'indicator' }] }, }, matched_queries: [matchedQuery], }); @@ -468,12 +480,16 @@ describe('enrichSignalThreatMatches', () => { indicatorPath ); const [enrichedHit] = enrichedSignals.hits.hits; - const indicators = get(enrichedHit._source, INDICATOR_DESTINATION_PATH); + const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { existing: 'indicator' }, { - domain: 'domain_1', + indicator: { + domain: 'domain_1', + other: 'other_1', + type: 'type_1', + }, matched: { atomic: 'domain_1', id: '123', @@ -481,11 +497,6 @@ describe('enrichSignalThreatMatches', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - other: 'other_1', - type: 'type_1', - event: { - category: 'malware', - }, }, ]); }); @@ -502,10 +513,11 @@ describe('enrichSignalThreatMatches', () => { indicatorPath ); const [enrichedHit] = enrichedSignals.hits.hits; - const indicators = get(enrichedHit._source, INDICATOR_DESTINATION_PATH); + const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { + indicator: {}, matched: { atomic: undefined, id: '123', @@ -517,12 +529,17 @@ describe('enrichSignalThreatMatches', () => { ]); }); - it('preserves an existing threat.indicator object on signals', async () => { + it('preserves an existing threat.enrichments object on signals', async () => { const signalHit = getSignalHitMock({ _source: { '@timestamp': 'mocked', event: { category: 'virus' }, - threat: { indicator: { existing: 'indicator' } }, + threat: { + enrichments: [ + { indicator: { existing: 'indicator' } }, + { indicator: { existing: 'indicator2' } }, + ], + }, }, matched_queries: [matchedQuery], }); @@ -533,12 +550,17 @@ describe('enrichSignalThreatMatches', () => { indicatorPath ); const [enrichedHit] = enrichedSignals.hits.hits; - const indicators = get(enrichedHit._source, INDICATOR_DESTINATION_PATH); + const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); - expect(indicators).toEqual([ - { existing: 'indicator' }, + expect(enrichments).toEqual([ + { indicator: { existing: 'indicator' } }, + { indicator: { existing: 'indicator2' } }, { - domain: 'domain_1', + indicator: { + domain: 'domain_1', + other: 'other_1', + type: 'type_1', + }, matched: { atomic: 'domain_1', id: '123', @@ -546,11 +568,6 @@ describe('enrichSignalThreatMatches', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - other: 'other_1', - type: 'type_1', - event: { - category: 'malware', - }, }, ]); }); @@ -599,11 +616,15 @@ describe('enrichSignalThreatMatches', () => { 'custom_threat.custom_indicator' ); const [enrichedHit] = enrichedSignals.hits.hits; - const indicators = get(enrichedHit._source, INDICATOR_DESTINATION_PATH); + const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { - domain: 'custom_domain', + indicator: { + domain: 'custom_domain', + other: 'custom_other', + type: 'custom_type', + }, matched: { atomic: 'custom_domain', id: '123', @@ -611,13 +632,11 @@ describe('enrichSignalThreatMatches', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - other: 'custom_other', - type: 'custom_type', }, ]); }); - it('merges duplicate matched signals into a single signal with multiple indicators', async () => { + it('merges duplicate matched signals into a single signal with multiple enrichments', async () => { getMatchedThreats = async () => [ getThreatListItemMock({ _id: '123', @@ -661,11 +680,15 @@ describe('enrichSignalThreatMatches', () => { expect(enrichedSignals.hits.hits).toHaveLength(1); const [enrichedHit] = enrichedSignals.hits.hits; - const indicators = get(enrichedHit._source, INDICATOR_DESTINATION_PATH); + const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); - expect(indicators).toEqual([ + expect(enrichments).toEqual([ { - domain: 'domain_1', + indicator: { + domain: 'domain_1', + other: 'other_1', + type: 'type_1', + }, matched: { atomic: 'domain_1', id: '123', @@ -673,14 +696,13 @@ describe('enrichSignalThreatMatches', () => { field: 'event.field', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - event: { - category: 'threat', - }, - other: 'other_1', - type: 'type_1', }, { - domain: 'domain_2', + indicator: { + domain: 'domain_2', + other: 'other_2', + type: 'type_2', + }, matched: { atomic: 'domain_2', id: '456', @@ -688,11 +710,6 @@ describe('enrichSignalThreatMatches', () => { field: 'event.other', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - event: { - category: 'bad', - }, - other: 'other_2', - type: 'type_2', }, ]); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts index 3423cc1a8744..9da593448902 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts @@ -11,7 +11,7 @@ import { ENRICHMENT_TYPES } from '../../../../../common/cti/constants'; import type { SignalSearchResponse, SignalSourceHit } from '../types'; import type { GetMatchedThreats, - ThreatIndicator, + ThreatEnrichment, ThreatListItem, ThreatMatchNamedQuery, } from './types'; @@ -40,7 +40,7 @@ export const groupAndMergeSignalMatches = (signalHits: SignalSourceHit[]): Signa return dedupedHits; }; -export const buildMatchedIndicator = ({ +export const buildEnrichments = ({ queries, threats, indicatorPath, @@ -48,20 +48,18 @@ export const buildMatchedIndicator = ({ queries: ThreatMatchNamedQuery[]; threats: ThreatListItem[]; indicatorPath: string; -}): ThreatIndicator[] => +}): ThreatEnrichment[] => queries.map((query) => { const matchedThreat = threats.find((threat) => threat._id === query.id); const indicatorValue = get(matchedThreat?._source, indicatorPath) as unknown; - const indicator = [indicatorValue].flat()[0] ?? {}; + const indicator = ([indicatorValue].flat()[0] ?? {}) as Record; if (!isObject(indicator)) { throw new Error(`Expected indicator field to be an object, but found: ${indicator}`); } const atomic = get(matchedThreat?._source, query.value) as unknown; - const event = get(matchedThreat?._source, 'event') as unknown; return { - ...indicator, - event, + indicator, matched: { atomic, field: query.field, @@ -86,8 +84,8 @@ export const enrichSignalThreatMatches = async ( const signalMatches = uniqueHits.map((signalHit) => extractNamedQueries(signalHit)); const matchedThreatIds = [...new Set(signalMatches.flat().map(({ id }) => id))]; const matchedThreats = await getMatchedThreats(matchedThreatIds); - const matchedIndicators = signalMatches.map((queries) => - buildMatchedIndicator({ + const enrichments = signalMatches.map((queries) => + buildEnrichments({ indicatorPath, queries, threats: matchedThreats, @@ -99,12 +97,12 @@ export const enrichSignalThreatMatches = async ( if (!isObject(threat)) { throw new Error(`Expected threat field to be an object, but found: ${threat}`); } - // We are not using INDICATOR_DESTINATION_PATH here because the code above - // and below make assumptions about its current value, 'threat.indicator', + // We are not using ENRICHMENT_DESTINATION_PATH here because the code above + // and below make assumptions about its current value, 'threat.enrichments', // and making this code dynamic on an arbitrary path would introduce several // new issues. - const existingIndicatorValue = get(signalHit._source, 'threat.indicator') ?? []; - const existingIndicators = [existingIndicatorValue].flat(); // ensure indicators is an array + const existingEnrichmentValue = get(signalHit._source, 'threat.enrichments') ?? []; + const existingEnrichments = [existingEnrichmentValue].flat(); // ensure enrichments is an array return { ...signalHit, @@ -112,7 +110,7 @@ export const enrichSignalThreatMatches = async ( ...signalHit._source!, threat: { ...threat, - indicator: [...existingIndicators, ...matchedIndicators[i]], + enrichments: [...existingEnrichments, ...enrichments[i]], }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts index ded79fc647ac..38d9d42a4602 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts @@ -173,8 +173,9 @@ export interface ThreatListDoc { */ export type ThreatListItem = estypes.SearchHit; -export interface ThreatIndicator { - [key: string]: unknown; +export interface ThreatEnrichment { + indicator: Record; + matched: Record; } export interface SortWithTieBreaker { diff --git a/x-pack/plugins/timelines/common/ecs/threat/index.ts b/x-pack/plugins/timelines/common/ecs/threat/index.ts index 19923a82dc84..8136c5693d0e 100644 --- a/x-pack/plugins/timelines/common/ecs/threat/index.ts +++ b/x-pack/plugins/timelines/common/ecs/threat/index.ts @@ -6,20 +6,37 @@ */ import { EventEcs } from '../event'; +import { UrlEcs } from '../url'; interface ThreatMatchEcs { atomic?: string[]; field?: string[]; + id?: string[]; + index?: string[]; type?: string[]; } -export interface ThreatIndicatorEcs { +export interface LegacyThreatIndicatorEcs { + domain?: string[]; matched?: ThreatMatchEcs; event?: EventEcs & { reference?: string[] }; provider?: string[]; type?: string[]; } -export interface ThreatEcs { - indicator: ThreatIndicatorEcs[]; +export interface ThreatIndicatorEcs { + url?: UrlEcs; + provider?: string[]; + reference?: string[]; + type?: string[]; +} + +export interface ThreatEnrichmentEcs { + indicator?: ThreatIndicatorEcs; + matched?: ThreatMatchEcs; +} + +export interface ThreatEcs { + indicator?: LegacyThreatIndicatorEcs[]; + enrichments?: ThreatEnrichmentEcs[]; } diff --git a/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts index d286f518a37e..c6f13f83812c 100644 --- a/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts +++ b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts @@ -1096,18 +1096,17 @@ export const mockTimelineData: TimelineItem[] = [ _id: 'BuBP4W0BOpWiDweSoYSg', timestamp: '2019-10-18T23:59:15.091Z', threat: { - indicator: [ + enrichments: [ { + indicator: { + provider: ['indicator_provider'], + reference: ['https://example.com'], + }, matched: { atomic: ['192.168.1.1'], field: ['source.ip'], type: ['ip'], }, - event: { - dataset: ['threatintel.example_dataset'], - reference: ['https://example.com'], - }, - provider: ['indicator_provider'], }, ], }, diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts index 9b45a5bebfc2..ffe3ea5abd68 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts @@ -8,34 +8,33 @@ // import { CTI_ROW_RENDERER_FIELDS } from '../../../../../../common/cti/constants'; // TODO: share with security_solution/common/cti/constants.ts -export const INDICATOR_DESTINATION_PATH = 'threat.indicator'; +export const ENRICHMENT_DESTINATION_PATH = 'threat.enrichments'; export const MATCHED_ATOMIC = 'matched.atomic'; export const MATCHED_FIELD = 'matched.field'; export const MATCHED_TYPE = 'matched.type'; export const INDICATOR_MATCH_SUBFIELDS = [MATCHED_ATOMIC, MATCHED_FIELD, MATCHED_TYPE]; -export const INDICATOR_MATCHED_ATOMIC = `${INDICATOR_DESTINATION_PATH}.${MATCHED_ATOMIC}`; -export const INDICATOR_MATCHED_FIELD = `${INDICATOR_DESTINATION_PATH}.${MATCHED_FIELD}`; -export const INDICATOR_MATCHED_TYPE = `${INDICATOR_DESTINATION_PATH}.${MATCHED_TYPE}`; +export const INDICATOR_MATCHED_ATOMIC = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_ATOMIC}`; +export const INDICATOR_MATCHED_FIELD = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_FIELD}`; +export const INDICATOR_MATCHED_TYPE = `${ENRICHMENT_DESTINATION_PATH}.${MATCHED_TYPE}`; export const EVENT_DATASET = 'event.dataset'; -export const EVENT_REFERENCE = 'event.reference'; -export const PROVIDER = 'provider'; -export const FIRSTSEEN = 'first_seen'; -export const INDICATOR_DATASET = `${INDICATOR_DESTINATION_PATH}.${EVENT_DATASET}`; -export const INDICATOR_EVENT_URL = `${INDICATOR_DESTINATION_PATH}.event.url`; -export const INDICATOR_FIRSTSEEN = `${INDICATOR_DESTINATION_PATH}.${FIRSTSEEN}`; -export const INDICATOR_LASTSEEN = `${INDICATOR_DESTINATION_PATH}.last_seen`; -export const INDICATOR_PROVIDER = `${INDICATOR_DESTINATION_PATH}.${PROVIDER}`; -export const INDICATOR_REFERENCE = `${INDICATOR_DESTINATION_PATH}.${EVENT_REFERENCE}`; +export const FIRST_SEEN = 'indicator.first_seen'; +export const LAST_SEEN = 'indicator.last_seen'; +export const PROVIDER = 'indicator.provider'; +export const REFERENCE = 'indicator.reference'; + +export const INDICATOR_FIRSTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${FIRST_SEEN}`; +export const INDICATOR_LASTSEEN = `${ENRICHMENT_DESTINATION_PATH}.${LAST_SEEN}`; +export const INDICATOR_PROVIDER = `${ENRICHMENT_DESTINATION_PATH}.${PROVIDER}`; +export const INDICATOR_REFERENCE = `${ENRICHMENT_DESTINATION_PATH}.${REFERENCE}`; export const CTI_ROW_RENDERER_FIELDS = [ INDICATOR_MATCHED_ATOMIC, INDICATOR_MATCHED_FIELD, INDICATOR_MATCHED_TYPE, - INDICATOR_DATASET, INDICATOR_REFERENCE, INDICATOR_PROVIDER, ]; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts index c9be6582015f..4fb67cc3a797 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts @@ -19,7 +19,7 @@ describe('#formatTimelineData', () => { 'destination.ip', 'source.ip', 'source.geo.location', - 'threat.indicator.matched.field', + 'threat.enrichments.matched.field', ], TIMELINE_EVENTS_FIELDS, eventHit @@ -42,7 +42,7 @@ describe('#formatTimelineData', () => { value: ['beats-ci-immutable-ubuntu-1804-1605624279743236239'], }, { - field: 'threat.indicator.matched.field', + field: 'threat.enrichments.matched.field', value: ['matched_field', 'other_matched_field', 'matched_field_2'], }, { @@ -95,10 +95,10 @@ describe('#formatTimelineData', () => { name: ['jenkins'], }, threat: { - indicator: [ + enrichments: [ { - event: { - dataset: [], + indicator: { + provider: ['yourself'], reference: [], }, matched: { @@ -106,11 +106,10 @@ describe('#formatTimelineData', () => { field: ['matched_field', 'other_matched_field'], type: [], }, - provider: ['yourself'], }, { - event: { - dataset: [], + indicator: { + provider: ['other_you'], reference: [], }, matched: { @@ -118,7 +117,6 @@ describe('#formatTimelineData', () => { field: ['matched_field_2'], type: [], }, - provider: ['other_you'], }, ], }, @@ -466,9 +464,9 @@ describe('#formatTimelineData', () => { }); it('builds intermediate objects at multiple levels', () => { - expect(buildObjectForFieldPath('threat.indicator.matched.atomic', eventHit)).toEqual({ + expect(buildObjectForFieldPath('threat.enrichments.matched.atomic', eventHit)).toEqual({ threat: { - indicator: [ + enrichments: [ { matched: { atomic: ['matched_atomic'], @@ -485,9 +483,9 @@ describe('#formatTimelineData', () => { }); it('preserves multiple values for a single leaf', () => { - expect(buildObjectForFieldPath('threat.indicator.matched.field', eventHit)).toEqual({ + expect(buildObjectForFieldPath('threat.enrichments.matched.field', eventHit)).toEqual({ threat: { - indicator: [ + enrichments: [ { matched: { field: ['matched_field', 'other_matched_field'], diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c4f00491e017..3a7cbdfcee7b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20169,7 +20169,6 @@ "xpack.securitySolution.alerts.riskScoreMapping.riskScoreMappingTitle": "リスクスコア無効化", "xpack.securitySolution.alerts.riskScoreMapping.riskScoreTitle": "リスクスコア", "xpack.securitySolution.alerts.riskScoreMapping.sourceFieldTitle": "ソースフィールド", - "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.datasetPreposition": "開始", "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.matchedVerb": "一致", "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.providerPreposition": "提供者", "xpack.securitySolution.alerts.severityMapping.defaultDescriptionLabel": "このルールで生成されたすべてのアラートの重要度sレベルを選択します。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0c383b5023d0..590e611058fe 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20437,7 +20437,6 @@ "xpack.securitySolution.alerts.riskScoreMapping.riskScoreMappingTitle": "风险分数覆盖", "xpack.securitySolution.alerts.riskScoreMapping.riskScoreTitle": "风险分数", "xpack.securitySolution.alerts.riskScoreMapping.sourceFieldTitle": "源字段", - "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.datasetPreposition": "来自", "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.matchedVerb": "已匹配", "xpack.securitySolution.alerts.rowRenderers.cti.threatMatch.providerPreposition": "提供者", "xpack.securitySolution.alerts.severityMapping.defaultDescriptionLabel": "选择此规则生成的所有告警的严重性级别。", diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/alerts_compatibility.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/alerts_compatibility.ts new file mode 100644 index 000000000000..8d12f9192e13 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/alerts_compatibility.ts @@ -0,0 +1,157 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { estypes } from '@elastic/elasticsearch'; +import expect from '@kbn/expect'; + +import { + DETECTION_ENGINE_QUERY_SIGNALS_URL, + DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL, +} from '../../../../../plugins/security_solution/common/constants'; +import { + createSignalsIndex, + deleteSignalsIndex, + finalizeSignalsMigration, + startSignalsMigration, + waitFor, +} from '../../../utils'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { ThreatEcs } from '../../../../../plugins/security_solution/common/ecs/threat'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertest'); + + describe('Alerts Compatibility', function () { + describe('CTI', () => { + const expectedDomain = 'elastic.local'; + const expectedProvider = 'provider1'; + const expectedEnrichmentMatch = { + atomic: expectedDomain, + field: 'host.name', + id: '_tdUD3sBcVT20cvWAkpd', + index: 'filebeat-7.14.0-2021.08.04-000001', + type: 'indicator_match_rule', + }; + + beforeEach(async () => { + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/legacy_cti_signals' + ); + await createSignalsIndex(supertest); + }); + + afterEach(async () => { + await esArchiver.unload( + 'x-pack/test/functional/es_archives/security_solution/legacy_cti_signals' + ); + await deleteSignalsIndex(supertest); + }); + + it('allows querying of legacy enriched signals by threat.indicator', async () => { + const { + body: { + hits: { hits }, + }, + }: { body: estypes.SearchResponse<{ threat: ThreatEcs }> } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send({ + query: { + nested: { + path: 'threat.indicator', + query: { + bool: { + should: [ + { + exists: { + field: 'threat.indicator.first_seen', + }, + }, + ], + }, + }, + }, + }, + }) + .expect(200); + expect(hits.length).to.eql(2); + const indicators = hits.flatMap((hit) => hit._source?.threat.indicator); + const indicatorMatches = indicators.map((indicator) => indicator?.matched); + expect(indicatorMatches).to.eql([expectedEnrichmentMatch, expectedEnrichmentMatch]); + const indicatorDomains = indicators.map((indicator) => indicator?.domain); + expect(indicatorDomains).to.eql([expectedDomain, expectedDomain]); + const indicatorProviders = indicators.map((indicator) => indicator?.provider); + expect(indicatorProviders).to.eql([expectedProvider, expectedProvider]); + }); + + it('migrates legacy enriched signals to be queried by threat.enrichments', async () => { + const { + body: { indices }, + }: { + body: { indices: Array<{ index: string; is_outdated: boolean; version: number }> }; + } = await supertest + .get(DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL) + .set('kbn-xsrf', 'true') + .query({ from: '2021-08-01' }) + .expect(200); + expect(indices.length).to.eql(1); + expect(indices[0].is_outdated).to.eql(true); + + const [migration] = await startSignalsMigration({ indices: [indices[0].index], supertest }); + await waitFor(async () => { + const [{ completed }] = await finalizeSignalsMigration({ + migrationIds: [migration.migration_id], + supertest, + }); + + return completed === true; + }, `polling finalize_migration until complete`); + + const { + body: { + hits: { hits }, + }, + }: { body: estypes.SearchResponse<{ threat: ThreatEcs }> } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send({ + query: { + nested: { + path: 'threat.enrichments', + query: { + bool: { + should: [ + { + exists: { + field: 'threat.enrichments.indicator.first_seen', + }, + }, + ], + }, + }, + }, + }, + }) + .expect(200); + expect(hits.length).to.eql(2); + const enrichments = hits.flatMap((hit) => hit._source?.threat.enrichments); + const enrichmentMatches = enrichments.map((enrichment) => enrichment?.matched); + expect(enrichmentMatches).to.eql([expectedEnrichmentMatch, expectedEnrichmentMatch]); + const enrichmentDomains = enrichments.map( + (enrichment) => enrichment?.indicator?.url?.domain + ); + expect(enrichmentDomains).to.eql([expectedDomain, expectedDomain]); + const enrichmentProviders = enrichments.map( + (enrichment) => enrichment?.indicator?.provider + ); + expect(enrichmentProviders).to.eql([expectedProvider, expectedProvider]); + }); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/index.ts new file mode 100644 index 000000000000..b06d6cb26e33 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/alerts/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default ({ loadTestFile }: FtrProviderContext): void => { + describe('Detection engine signals/alerts compatibility', function () { + describe('', function () { + this.tags('ciGroup11'); + + loadTestFile(require.resolve('./alerts_compatibility')); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_threat_matching.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_threat_matching.ts index 399eafc475a8..a85b5ba764d8 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_threat_matching.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_threat_matching.ts @@ -280,7 +280,7 @@ export default ({ getService }: FtrProviderContext) => { status: 'open', }, threat: { - indicator: get(fullSignal, 'threat.indicator'), + enrichments: get(fullSignal, 'threat.enrichments'), }, }); }); @@ -446,21 +446,19 @@ export default ({ getService }: FtrProviderContext) => { const threats = hits.map((hit) => hit._source?.threat); expect(threats).to.eql([ { - indicator: [ + enrichments: [ { - description: "domain should match the auditbeat hosts' data's source.ip", - domain: '159.89.119.67', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.595350Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978783/', - type: 'indicator', + indicator: { + description: "domain should match the auditbeat hosts' data's source.ip", + domain: '159.89.119.67', + first_seen: '2021-01-26T11:09:04.000Z', + provider: 'geenensp', + url: { + full: 'http://159.89.119.67:59600/bin.sh', + scheme: 'http', + }, + type: 'url', }, - first_seen: '2021-01-26T11:09:04.000Z', matched: { atomic: '159.89.119.67', id: '978783', @@ -468,31 +466,23 @@ export default ({ getService }: FtrProviderContext) => { field: 'destination.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'geenensp', - type: 'url', - url: { - full: 'http://159.89.119.67:59600/bin.sh', - scheme: 'http', - }, }, ], }, { - indicator: [ + enrichments: [ { - description: "domain should match the auditbeat hosts' data's source.ip", - domain: '159.89.119.67', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.595350Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978783/', - type: 'indicator', + indicator: { + description: "domain should match the auditbeat hosts' data's source.ip", + domain: '159.89.119.67', + first_seen: '2021-01-26T11:09:04.000Z', + provider: 'geenensp', + url: { + full: 'http://159.89.119.67:59600/bin.sh', + scheme: 'http', + }, + type: 'url', }, - first_seen: '2021-01-26T11:09:04.000Z', matched: { atomic: '159.89.119.67', id: '978783', @@ -500,12 +490,6 @@ export default ({ getService }: FtrProviderContext) => { field: 'destination.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'geenensp', - type: 'url', - url: { - full: 'http://159.89.119.67:59600/bin.sh', - scheme: 'http', - }, }, ], }, @@ -549,14 +533,19 @@ export default ({ getService }: FtrProviderContext) => { const { hits } = signalsOpen.hits; const [threat] = hits.map((hit) => hit._source?.threat) as Array<{ - indicator: unknown[]; + enrichments: unknown[]; }>; - assertContains(threat.indicator, [ + assertContains(threat.enrichments, [ { - description: 'this should match auditbeat/hosts on both port and ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on both port and ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + port: 57324, + provider: 'geenensp', + type: 'url', + }, matched: { atomic: '45.115.45.3', id: '978785', @@ -564,24 +553,16 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - port: 57324, - provider: 'geenensp', - type: 'url', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, { - description: 'this should match auditbeat/hosts on ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + provider: 'other_provider', + type: 'ip', + }, + matched: { atomic: '45.115.45.3', id: '978787', @@ -589,18 +570,6 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'other_provider', - type: 'ip', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, ]); }); @@ -651,14 +620,19 @@ export default ({ getService }: FtrProviderContext) => { const { hits } = signalsOpen.hits; const [threat] = hits.map((hit) => hit._source?.threat) as Array<{ - indicator: unknown[]; + enrichments: unknown[]; }>; - assertContains(threat.indicator, [ + assertContains(threat.enrichments, [ { - description: 'this should match auditbeat/hosts on both port and ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on both port and ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + port: 57324, + provider: 'geenensp', + type: 'url', + }, matched: { atomic: '45.115.45.3', id: '978785', @@ -666,19 +640,6 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - port: 57324, - provider: 'geenensp', - type: 'url', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, // We do not merge matched indicators during enrichment, so in // certain circumstances a given indicator document could appear @@ -686,9 +647,15 @@ export default ({ getService }: FtrProviderContext) => { // threat.indicator.matched data). That's the case with the // first and third indicators matched, here. { - description: 'this should match auditbeat/hosts on both port and ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on both port and ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + port: 57324, + provider: 'geenensp', + type: 'url', + }, + matched: { atomic: 57324, id: '978785', @@ -696,24 +663,15 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.port', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - port: 57324, - provider: 'geenensp', - type: 'url', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, { - description: 'this should match auditbeat/hosts on ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + provider: 'other_provider', + type: 'ip', + }, matched: { atomic: '45.115.45.3', id: '978787', @@ -721,18 +679,6 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'other_provider', - type: 'ip', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, ]); }); @@ -787,13 +733,23 @@ export default ({ getService }: FtrProviderContext) => { expect(signalsOpen.hits.hits.length).equal(2); const { hits } = signalsOpen.hits; - const threats = hits.map((hit) => hit._source?.threat) as Array<{ indicator: unknown[] }>; + const threats = hits.map((hit) => hit._source?.threat) as Array<{ + enrichments: unknown[]; + }>; - assertContains(threats[0].indicator, [ + assertContains(threats[0].enrichments, [ { - description: "domain should match the auditbeat hosts' data's source.ip", - domain: '159.89.119.67', - first_seen: '2021-01-26T11:09:04.000Z', + indicator: { + description: "domain should match the auditbeat hosts' data's source.ip", + domain: '159.89.119.67', + first_seen: '2021-01-26T11:09:04.000Z', + provider: 'geenensp', + type: 'url', + url: { + full: 'http://159.89.119.67:59600/bin.sh', + scheme: 'http', + }, + }, matched: { atomic: '159.89.119.67', id: '978783', @@ -801,27 +757,16 @@ export default ({ getService }: FtrProviderContext) => { field: 'destination.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'geenensp', - type: 'url', - url: { - full: 'http://159.89.119.67:59600/bin.sh', - scheme: 'http', - }, - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.595350Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978783/', - type: 'indicator', - }, }, { - description: 'this should match auditbeat/hosts on both port and ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on both port and ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + port: 57324, + provider: 'geenensp', + type: 'url', + }, matched: { atomic: '45.115.45.3', id: '978785', @@ -829,24 +774,16 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - port: 57324, - provider: 'geenensp', - type: 'url', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, { - description: 'this should match auditbeat/hosts on both port and ip', - first_seen: '2021-01-26T11:06:03.000Z', - ip: '45.115.45.3', + indicator: { + description: 'this should match auditbeat/hosts on both port and ip', + first_seen: '2021-01-26T11:06:03.000Z', + ip: '45.115.45.3', + port: 57324, + provider: 'geenensp', + type: 'url', + }, matched: { atomic: 57324, id: '978785', @@ -854,27 +791,22 @@ export default ({ getService }: FtrProviderContext) => { field: 'source.port', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - port: 57324, - provider: 'geenensp', - type: 'url', - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.616763Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978782/', - type: 'indicator', - }, }, ]); - assertContains(threats[1].indicator, [ + assertContains(threats[1].enrichments, [ { - description: "domain should match the auditbeat hosts' data's source.ip", - domain: '159.89.119.67', - first_seen: '2021-01-26T11:09:04.000Z', + indicator: { + description: "domain should match the auditbeat hosts' data's source.ip", + domain: '159.89.119.67', + first_seen: '2021-01-26T11:09:04.000Z', + provider: 'geenensp', + type: 'url', + url: { + full: 'http://159.89.119.67:59600/bin.sh', + scheme: 'http', + }, + }, matched: { atomic: '159.89.119.67', id: '978783', @@ -882,22 +814,6 @@ export default ({ getService }: FtrProviderContext) => { field: 'destination.ip', type: ENRICHMENT_TYPES.IndicatorMatchRule, }, - provider: 'geenensp', - type: 'url', - url: { - full: 'http://159.89.119.67:59600/bin.sh', - scheme: 'http', - }, - event: { - category: 'threat', - created: '2021-01-26T11:09:05.529Z', - dataset: 'threatintel.abuseurl', - ingested: '2021-01-26T11:09:06.595350Z', - kind: 'enrichment', - module: 'threatintel', - reference: 'https://urlhaus.abuse.ch/url/978783/', - type: 'indicator', - }, }, ]); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts index 44e6023bf366..2e3469520989 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts @@ -60,5 +60,9 @@ export default ({ loadTestFile }: FtrProviderContext): void => { describe('', function () { loadTestFile(require.resolve('./keyword_family/index')); }); + + describe('', function () { + loadTestFile(require.resolve('./alerts/index')); + }); }); }; diff --git a/x-pack/test/detection_engine_api_integration/utils.ts b/x-pack/test/detection_engine_api_integration/utils.ts index bd2ce12b6dcb..28c9cdad401a 100644 --- a/x-pack/test/detection_engine_api_integration/utils.ts +++ b/x-pack/test/detection_engine_api_integration/utils.ts @@ -45,6 +45,8 @@ import { DETECTION_ENGINE_PREPACKAGED_URL, DETECTION_ENGINE_QUERY_SIGNALS_URL, DETECTION_ENGINE_RULES_URL, + DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL, + DETECTION_ENGINE_SIGNALS_MIGRATION_URL, INTERNAL_IMMUTABLE_KEY, INTERNAL_RULE_ID_KEY, } from '../../plugins/security_solution/common/constants'; @@ -1355,6 +1357,54 @@ export const deleteMigrations = async ({ ); }; +interface CreateMigrationResponse { + index: string; + migration_index: string; + migration_id: string; +} + +export const startSignalsMigration = async ({ + indices, + supertest, +}: { + supertest: SuperTest; + indices: string[]; +}): Promise => { + const { + body: { indices: created }, + }: { body: { indices: CreateMigrationResponse[] } } = await supertest + .post(DETECTION_ENGINE_SIGNALS_MIGRATION_URL) + .set('kbn-xsrf', 'true') + .send({ index: indices }) + .expect(200); + + return created; +}; + +interface FinalizeMigrationResponse { + id: string; + completed?: boolean; + error?: unknown; +} + +export const finalizeSignalsMigration = async ({ + migrationIds, + supertest, +}: { + supertest: SuperTest; + migrationIds: string[]; +}): Promise => { + const { + body: { migrations }, + }: { body: { migrations: FinalizeMigrationResponse[] } } = await supertest + .post(DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL) + .set('kbn-xsrf', 'true') + .send({ migration_ids: migrationIds }) + .expect(200); + + return migrations; +}; + export const getOpenSignals = async ( supertest: SuperTest, es: KibanaClient, diff --git a/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/data.json b/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/data.json new file mode 100644 index 000000000000..bcc8d5f86e1d --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/data.json @@ -0,0 +1,487 @@ +{ + "type": "doc", + "value": { + "id": "47fc9c7b3220142effa382d78dfa828a5ca79fd5773140af1a1d96045628f171", + "index": ".siem-signals-default-000001", + "source": { + "@timestamp": "2021-08-04T04:14:58.974Z", + "agent": { + "ephemeral_id": "07c24b1e-3663-4372-b982-f2d831e033eb", + "hostname": "elastic.local", + "id": "ce7741d9-3f0a-466d-8ae6-d7d8f883fcec", + "name": "elastic.local", + "type": "auditbeat", + "version": "7.14.0" + }, + "ecs": { + "version": "1.10.0" + }, + "event": { + "action": "process_stopped", + "category": [ + "process" + ], + "dataset": "process", + "kind": "signal", + "module": "system", + "type": [ + "end" + ] + }, + "host": { + "architecture": "x86_64", + "hostname": "elastic.local", + "id": "1633D595-A115-5BF5-870B-A471B49446C3", + "ip": [ "192.168.1.1" ], + "mac": [ "aa:bb:cc:dd:ee:ff" ], + "name": "elastic.local", + "os": { + "build": "20G80", + "family": "darwin", + "kernel": "20.6.0", + "name": "Mac OS X", + "platform": "darwin", + "type": "macos", + "version": "10.16" + } + }, + "message": "Process mdworker_shared (PID: 32162) by user elastic STOPPED", + "process": { + "args": [ + "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared", + "-s", + "mdworker", + "-c", + "MDSImporterWorker", + "-m", + "com.apple.mdworker.shared" + ], + "entity_id": "Bu0panfqz24AEqa+", + "executable": "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared", + "hash": { + "sha1": "5f3233fd75c14b315731684d59b632df36a731a6" + }, + "name": "mdworker_shared", + "pid": 32162, + "ppid": 1, + "start": "2021-08-04T04:07:26.900Z", + "working_directory": "/" + }, + "service": { + "type": "system" + }, + "signal": { + "_meta": { + "version": 45 + }, + "ancestors": [ + { + "depth": 0, + "id": "yddfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + } + ], + "depth": 1, + "original_event": { + "action": "process_stopped", + "category": [ + "process" + ], + "dataset": "process", + "kind": "event", + "module": "system", + "type": [ + "end" + ] + }, + "original_time": "2021-08-04T04:14:53.490Z", + "parent": { + "depth": 0, + "id": "yddfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + }, + "parents": [ + { + "depth": 0, + "id": "yddfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + } + ], + "rule": { + "actions": [ + ], + "author": [ + ], + "created_at": "2021-08-04T04:14:51.576Z", + "created_by": "elastic", + "description": "These should match a dummy indicator in filebeat.", + "enabled": true, + "exceptions_list": [ + ], + "false_positives": [ + ], + "filters": [ + ], + "from": "now-1200s", + "id": "832f86f0-f4da-11eb-989d-b758d09dbc85", + "immutable": false, + "index": [ + "auditbeat-*" + ], + "interval": "5m", + "language": "kuery", + "license": "", + "max_signals": 100, + "meta": { + "from": "15m", + "kibana_siem_app_url": "http://localhost:5601/app/security" + }, + "name": "Indicator Match on host.name", + "output_index": ".siem-signals-default", + "query": "host.name: \"elastic.local\" ", + "references": [ + ], + "risk_score": 21, + "risk_score_mapping": [ + ], + "rule_id": "2cc5f982-0de6-4325-9225-cdf88d3731ce", + "severity": "low", + "severity_mapping": [ + ], + "tags": [ + ], + "threat": [ + ], + "threat_filters": [ + ], + "threat_index": [ + "filebeat-*" + ], + "threat_indicator_path": "", + "threat_language": "kuery", + "threat_mapping": [ + { + "entries": [ + { + "field": "host.name", + "type": "mapping", + "value": "threatintel.indicator.domain" + } + ] + } + ], + "threat_query": "threatintel.indicator.type : \"url\"", + "throttle": null, + "to": "now", + "type": "threat_match", + "updated_at": "2021-08-04T04:14:52.129Z", + "updated_by": "elastic", + "version": 1 + }, + "status": "open" + }, + "threat": { + "indicator": [ + { + "domain": "elastic.local", + "event": { + "category": "threat", + "created": "2021-08-04T03:53:30.761Z", + "dataset": "threatintel.abuseurl", + "ingested": "2021-08-04T03:53:37.514040Z", + "kind": "enrichment", + "module": "threatintel", + "reference": "https://urlhaus.abuse.ch/url/12345/", + "type": "indicator" + }, + "first_seen": "2021-08-03T20:35:17.000Z", + "matched": { + "atomic": "elastic.local", + "field": "host.name", + "id": "_tdUD3sBcVT20cvWAkpd", + "index": "filebeat-7.14.0-2021.08.04-000001", + "type": "indicator_match_rule" + }, + "provider": "provider1", + "type": "url", + "url": { + "domain": "elastic.local", + "extension": "php", + "full": "http://elastic.local/thing", + "original": "http://elastic.local/thing", + "path": "/thing", + "scheme": "http" + } + } + ] + }, + "user": { + "effective": { + "group": { + "id": "20" + }, + "id": "501" + }, + "group": { + "id": "20", + "name": "staff" + }, + "id": "501", + "name": "elastic", + "saved": { + "group": { + "id": "20" + }, + "id": "501" + } + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "0527411874b23bcea85daf5bf7dcacd144536ba6d92d3230a4a0acfb7de7f512", + "index": ".siem-signals-default-000001", + "source": { + "@timestamp": "2021-08-04T04:14:58.973Z", + "agent": { + "ephemeral_id": "07c24b1e-3663-4372-b982-f2d831e033eb", + "hostname": "elastic.local", + "id": "ce7741d9-3f0a-466d-8ae6-d7d8f883fcec", + "name": "elastic.local", + "type": "auditbeat", + "version": "7.14.0" + }, + "ecs": { + "version": "1.10.0" + }, + "event": { + "action": "process_started", + "category": [ + "process" + ], + "dataset": "process", + "kind": "signal", + "module": "system", + "type": [ + "start" + ] + }, + "host": { + "architecture": "x86_64", + "hostname": "elastic.local", + "id": "1633D595-A115-5BF5-870B-A471B49446C3", + "ip": [ "192.168.1.1" ], + "mac": [ "aa:bb:cc:dd:ee:ff" ], + "name": "elastic.local", + "os": { + "build": "20G80", + "family": "darwin", + "kernel": "20.6.0", + "name": "Mac OS X", + "platform": "darwin", + "type": "macos", + "version": "10.16" + } + }, + "message": "Process mdworker_shared (PID: 32306) by user elastic STARTED", + "process": { + "args": [ + "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared", + "-s", + "mdworker", + "-c", + "MDSImporterWorker", + "-m", + "com.apple.mdworker.shared" + ], + "entity_id": "wfc7zUuEinqxUbZ6", + "executable": "/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared", + "hash": { + "sha1": "5f3233fd75c14b315731684d59b632df36a731a6" + }, + "name": "mdworker_shared", + "pid": 32306, + "ppid": 1, + "start": "2021-08-04T04:14:48.830Z", + "working_directory": "/" + }, + "service": { + "type": "system" + }, + "signal": { + "_meta": { + "version": 45 + }, + "ancestors": [ + { + "depth": 0, + "id": "yNdfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + } + ], + "depth": 1, + "original_event": { + "action": "process_started", + "category": [ + "process" + ], + "dataset": "process", + "kind": "event", + "module": "system", + "type": [ + "start" + ] + }, + "original_time": "2021-08-04T04:14:53.490Z", + "parent": { + "depth": 0, + "id": "yNdfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + }, + "parents": [ + { + "depth": 0, + "id": "yNdfD3sBcVT20cvWFEs2", + "index": "auditbeat-7.14.0-2021.08.04-000001", + "type": "event" + } + ], + "rule": { + "actions": [ + ], + "author": [ + ], + "created_at": "2021-08-04T04:14:51.576Z", + "created_by": "elastic", + "description": "These should match a dummy indicator in filebeat.", + "enabled": true, + "exceptions_list": [ + ], + "false_positives": [ + ], + "filters": [ + ], + "from": "now-1200s", + "id": "832f86f0-f4da-11eb-989d-b758d09dbc85", + "immutable": false, + "index": [ + "auditbeat-*" + ], + "interval": "5m", + "language": "kuery", + "license": "", + "max_signals": 100, + "meta": { + "from": "15m", + "kibana_siem_app_url": "http://localhost:5601/app/security" + }, + "name": "Indicator Match on host.name", + "output_index": ".siem-signals-default", + "query": "host.name: \"elastic.local\" ", + "references": [ + ], + "risk_score": 21, + "risk_score_mapping": [ + ], + "rule_id": "2cc5f982-0de6-4325-9225-cdf88d3731ce", + "severity": "low", + "severity_mapping": [ + ], + "tags": [ + ], + "threat": [ + ], + "threat_filters": [ + ], + "threat_index": [ + "filebeat-*" + ], + "threat_indicator_path": "", + "threat_language": "kuery", + "threat_mapping": [ + { + "entries": [ + { + "field": "host.name", + "type": "mapping", + "value": "threatintel.indicator.domain" + } + ] + } + ], + "threat_query": "threatintel.indicator.type : \"url\"", + "throttle": null, + "to": "now", + "type": "threat_match", + "updated_at": "2021-08-04T04:14:52.129Z", + "updated_by": "elastic", + "version": 1 + }, + "status": "open" + }, + "threat": { + "indicator": [ + { + "domain": "elastic.local", + "event": { + "category": "threat", + "created": "2021-08-04T03:53:30.761Z", + "dataset": "threatintel.abuseurl", + "ingested": "2021-08-04T03:53:37.514040Z", + "kind": "enrichment", + "module": "threatintel", + "reference": "https://urlhaus.abuse.ch/url/12345/", + "type": "indicator" + }, + "first_seen": "2021-08-03T20:35:17.000Z", + "matched": { + "atomic": "elastic.local", + "field": "host.name", + "id": "_tdUD3sBcVT20cvWAkpd", + "index": "filebeat-7.14.0-2021.08.04-000001", + "type": "indicator_match_rule" + }, + "provider": "provider1", + "type": "url", + "url": { + "domain": "elastic.local", + "extension": "php", + "full": "http://elastic.local/thing", + "original": "http://elastic.local/thing", + "path": "/thing", + "scheme": "http" + } + } + ] + }, + "user": { + "effective": { + "group": { + "id": "20" + }, + "id": "501" + }, + "group": { + "id": "20", + "name": "staff" + }, + "id": "501", + "name": "elastic", + "saved": { + "group": { + "id": "20" + }, + "id": "501" + } + } + } + } +} diff --git a/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/mappings.json b/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/mappings.json new file mode 100644 index 000000000000..feda6d3ac85b --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/legacy_cti_signals/mappings.json @@ -0,0 +1,344 @@ +{ + "type": "index", + "value": { + "aliases": { + ".alerts-security.alerts-default": { + "is_write_index": false + }, + ".siem-signals-default": { + "is_write_index": true + } + }, + "index": ".siem-signals-default-000001", + "mappings": { + "_meta": { + "aliases_version": 1, + "version": 45 + }, + "dynamic": "false", + "properties": { + "@timestamp": { + "type": "date" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "indicator": { + "properties": { + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "confidence": { + "ignore_above": 1024, + "type": "keyword" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "type": "wildcard" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "matched": { + "properties": { + "atomic": { + "ignore_above": 1024, + "type": "keyword" + }, + "field": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "subtechnique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + } + } + }, + "settings": { + "index": { + "lifecycle": { + "name": ".siem-signals-default", + "rollover_alias": ".siem-signals-default" + }, + "mapping": { + "total_fields": { + "limit": "10000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +}