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 e1e78f8e310e1..129d592edd264 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 @@ -502,7 +502,7 @@ describe('indicator match', () => { { 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\\",\\"matched\\":{\\"atomic\\":\\"a04ac6d98ad989312783d4fe3456c53730b212c79a426fb215708b6c6daa3de3\\",\\"field\\":\\"myhash.mysha256\\",\\"id\\":\\"84cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f\\",\\"index\\":\\"filebeat-7.12.0-2021.03.10-000001\\",\\"type\\":\\"file\\"}}"', + ' "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\\":\\"file\\"}}"', }, { line: 2, text: ' }' }, ]; 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 c6f432a28aee4..326d5777543be 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 @@ -21,7 +21,7 @@ import ecsMapping from './ecs_mapping.json'; incremented by 10 in order to add "room" for the aforementioned patch release */ -export const SIGNALS_TEMPLATE_VERSION = 25; +export const SIGNALS_TEMPLATE_VERSION = 26; export const MIN_EQL_RULE_INDEX_VERSION = 2; export const getSignalsTemplate = (index: string) => { @@ -45,6 +45,19 @@ export const getSignalsTemplate = (index: string) => { properties: { ...ecsMapping.mappings.properties, signal: signalsMapping.mappings.properties.signal, + threat: { + ...ecsMapping.mappings.properties.threat, + properties: { + ...ecsMapping.mappings.properties.threat.properties, + indicator: { + ...ecsMapping.mappings.properties.threat.properties.indicator, + properties: { + ...ecsMapping.mappings.properties.threat.properties.indicator.properties, + event: ecsMapping.mappings.properties.event, + }, + }, + }, + }, }, _meta: { version: SIGNALS_TEMPLATE_VERSION, 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 7b3ca099cc93c..7c80572f6b1ee 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 @@ -83,6 +83,7 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { + event: { dataset: 'abuse.ch', reference: 'https://test.com' }, threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, }, }), @@ -117,6 +118,16 @@ describe('buildMatchedIndicator', () => { expect(get(indicator, 'matched.atomic')).toEqual('domain_1'); }); + it('returns event values as a part of threat', () => { + const [indicator] = buildMatchedIndicator({ + queries, + threats, + indicatorPath, + }); + const expectedEvent = threats[0]._source!.event; + expect(get(indicator, 'event')).toEqual(expectedEvent); + }); + it('returns the _id of the matched indicator as matched.id', () => { const [indicator] = buildMatchedIndicator({ queries, @@ -162,12 +173,16 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { - threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, + event: { reference: 'https://test.com' }, + threat: { + indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' }, + }, }, }), getThreatListItemMock({ _id: '456', _source: { + event: { reference: 'https://test2.com' }, threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, }, }), @@ -205,6 +220,10 @@ describe('buildMatchedIndicator', () => { }, other: 'other_1', type: 'type_1', + event: { + reference: 'https://test.com', + dataset: 'abuse.ch', + }, }, ]); }); @@ -214,6 +233,9 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { + event: { + reference: 'https://test3.com', + }, 'threat.indicator.domain': 'domain_1', custom: { indicator: { @@ -244,6 +266,9 @@ describe('buildMatchedIndicator', () => { type: 'indicator_type', }, type: 'indicator_type', + event: { + reference: 'https://test3.com', + }, }, ]); }); @@ -307,6 +332,9 @@ describe('buildMatchedIndicator', () => { getThreatListItemMock({ _id: '123', _source: { + event: { + reference: 'https://test4.com', + }, threat: { indicator: [ { domain: 'foo', type: 'first' }, @@ -334,6 +362,9 @@ describe('buildMatchedIndicator', () => { type: 'first', }, type: 'first', + event: { + reference: 'https://test4.com', + }, }, ]); }); @@ -392,6 +423,9 @@ describe('enrichSignalThreatMatches', () => { getThreatListItemMock({ _id: '123', _source: { + event: { + category: 'malware', + }, threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, }, }), @@ -419,7 +453,11 @@ describe('enrichSignalThreatMatches', () => { it('preserves existing threat.indicator objects on signals', async () => { const signalHit = getSignalHitMock({ - _source: { '@timestamp': 'mocked', threat: { indicator: [{ existing: 'indicator' }] } }, + _source: { + '@timestamp': 'mocked', + event: { category: 'malware' }, + threat: { indicator: [{ existing: 'indicator' }] }, + }, matched_queries: [matchedQuery], }); const signals = getSignalsResponseMock([signalHit]); @@ -444,6 +482,9 @@ describe('enrichSignalThreatMatches', () => { }, other: 'other_1', type: 'type_1', + event: { + category: 'malware', + }, }, ]); }); @@ -477,7 +518,11 @@ describe('enrichSignalThreatMatches', () => { it('preserves an existing threat.indicator object on signals', async () => { const signalHit = getSignalHitMock({ - _source: { '@timestamp': 'mocked', threat: { indicator: { existing: 'indicator' } } }, + _source: { + '@timestamp': 'mocked', + event: { category: 'virus' }, + threat: { indicator: { existing: 'indicator' } }, + }, matched_queries: [matchedQuery], }); const signals = getSignalsResponseMock([signalHit]); @@ -502,6 +547,9 @@ describe('enrichSignalThreatMatches', () => { }, other: 'other_1', type: 'type_1', + event: { + category: 'malware', + }, }, ]); }); @@ -573,12 +621,14 @@ describe('enrichSignalThreatMatches', () => { getThreatListItemMock({ _id: '123', _source: { + event: { category: 'threat' }, threat: { indicator: { domain: 'domain_1', other: 'other_1', type: 'type_1' } }, }, }), getThreatListItemMock({ _id: '456', _source: { + event: { category: 'bad' }, threat: { indicator: { domain: 'domain_2', other: 'other_2', type: 'type_2' } }, }, }), @@ -622,6 +672,9 @@ describe('enrichSignalThreatMatches', () => { field: 'event.field', type: 'type_1', }, + event: { + category: 'threat', + }, other: 'other_1', type: 'type_1', }, @@ -634,6 +687,9 @@ describe('enrichSignalThreatMatches', () => { field: 'event.other', type: 'type_2', }, + 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 83a3ce8cb773f..c26f03d1dd480 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 @@ -57,9 +57,11 @@ export const buildMatchedIndicator = ({ } const atomic = get(matchedThreat?._source, query.value) as unknown; const type = get(indicator, 'type') as unknown; + const event = get(matchedThreat?._source, 'event') as unknown; return { ...indicator, + event, matched: { atomic, field: query.field, id: query.id, index: query.index, type }, }; }); 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 a7925fa756693..f0b173d2d4c48 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 @@ -317,6 +317,16 @@ export default ({ getService }: FtrProviderContext) => { { 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', + }, first_seen: '2021-01-26T11:09:04.000Z', matched: { atomic: '159.89.119.67', @@ -339,6 +349,16 @@ export default ({ getService }: FtrProviderContext) => { { 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', + }, first_seen: '2021-01-26T11:09:04.000Z', matched: { atomic: '159.89.119.67', @@ -412,6 +432,16 @@ export default ({ getService }: FtrProviderContext) => { 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', @@ -426,6 +456,16 @@ export default ({ getService }: FtrProviderContext) => { }, 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', + }, }, ]); }); @@ -492,6 +532,16 @@ export default ({ getService }: FtrProviderContext) => { 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 @@ -512,6 +562,16 @@ export default ({ getService }: FtrProviderContext) => { 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', @@ -526,6 +586,16 @@ export default ({ getService }: FtrProviderContext) => { }, 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', + }, }, ]); }); @@ -600,6 +670,16 @@ export default ({ getService }: FtrProviderContext) => { 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', + }, }, ]); @@ -621,6 +701,16 @@ export default ({ getService }: FtrProviderContext) => { 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', @@ -636,6 +726,16 @@ export default ({ getService }: FtrProviderContext) => { 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', @@ -651,6 +751,16 @@ export default ({ getService }: FtrProviderContext) => { 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', + }, }, ]); });