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 f0b173d2d4c48e..43576b80b3738c 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 @@ -5,7 +5,7 @@ * 2.0. */ -import { isEqual } from 'lodash'; +import { get, isEqual } from 'lodash'; import expect from '@kbn/expect'; import { CreateRulesSchema } from '../../../../plugins/security_solution/common/detection_engine/schemas/request'; @@ -150,6 +150,97 @@ export default ({ getService }: FtrProviderContext) => { await waitForSignalsToBePresent(supertest, 10, [id]); const signalsOpen = await getSignalsByIds(supertest, [id]); expect(signalsOpen.hits.hits.length).equal(10); + const fullSource = signalsOpen.hits.hits.find( + (signal) => signal._source.signal.parents[0].id === 'UBXOBmkBR346wHgnLP8T' + ); + const fullSignal = fullSource!._source; // If this doesn't exist the test is going to fail anyway so using a bang operator here to get rid of ts error + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + agent: { + ephemeral_id: '1b4978a0-48be-49b1-ac96-323425b389ab', + hostname: 'zeek-sensor-amsterdam', + id: 'e52588e6-7aa3-4c89-a2c4-d6bc5c286db1', + type: 'auditbeat', + version: '8.0.0', + }, + cloud: { + instance: { + id: '133551048', + }, + provider: 'digitalocean', + region: 'ams3', + }, + ecs: { + version: '1.0.0-beta2', + }, + event: { + action: 'boot', + dataset: 'login', + kind: 'signal', + module: 'system', + origin: '/var/log/wtmp', + }, + host: { + architecture: 'x86_64', + containerized: false, + hostname: 'zeek-sensor-amsterdam', + id: '2ce8b1e7d69e4a1d9c6bcddc473da9d9', + name: 'zeek-sensor-amsterdam', + os: { + codename: 'bionic', + family: 'debian', + kernel: '4.15.0-45-generic', + name: 'Ubuntu', + platform: 'ubuntu', + version: '18.04.2 LTS (Bionic Beaver)', + }, + }, + message: 'System boot', + service: { + type: 'system', + }, + signal: { + _meta: { + version: 35, + }, + ancestors: [ + { + depth: 0, + id: 'UBXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + depth: 1, + original_event: { + action: 'boot', + dataset: 'login', + kind: 'event', + module: 'system', + origin: '/var/log/wtmp', + }, + original_time: fullSignal.signal.original_time, + parent: { + depth: 0, + id: 'UBXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + parents: [ + { + depth: 0, + id: 'UBXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + rule: fullSignal.signal.rule, + status: 'open', + }, + threat: { + indicator: get(fullSignal, 'threat.indicator'), + }, + }); }); it('should return 0 matches if the mapping does not match against anything in the mapping', async () => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/generating_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/generating_signals.ts index d6cc7837acda55..f9f378bc4bfa83 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/generating_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/generating_signals.ts @@ -550,43 +550,149 @@ export default ({ getService }: FtrProviderContext) => { get(signal._source, 'signal.original_event.category') === 'anomoly' ); expect(buildingBlock).not.eql(undefined); - const signal = buildingBlock!._source.signal; + const fullSignal = buildingBlock!._source; - expect(signal).eql({ - rule: signal.rule, - group: signal.group, - original_time: signal.original_time, - status: 'open', - depth: 1, - ancestors: [ - { - depth: 0, - id: 'VhXOBmkBR346wHgnLP8T', - index: 'auditbeat-8.0.0-2019.02.19-000001', - type: 'event', + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + agent: { + ephemeral_id: '1b4978a0-48be-49b1-ac96-323425b389ab', + hostname: 'zeek-sensor-amsterdam', + id: 'e52588e6-7aa3-4c89-a2c4-d6bc5c286db1', + type: 'auditbeat', + version: '8.0.0', + }, + auditd: { + data: { + a0: '3', + a1: '107', + a2: '1', + a3: '7ffc186b58e0', + arch: 'x86_64', + auid: 'unset', + dev: 'eth0', + exit: '0', + gid: '0', + old_prom: '0', + prom: '256', + ses: 'unset', + syscall: 'setsockopt', + tty: '(none)', + uid: '0', }, - ], - original_event: { + message_type: 'anom_promiscuous', + result: 'success', + sequence: 1392, + session: 'unset', + summary: { + actor: { + primary: 'unset', + secondary: 'root', + }, + how: '/usr/bin/bro', + object: { + primary: 'eth0', + type: 'network-device', + }, + }, + }, + cloud: { instance: { id: '133551048' }, provider: 'digitalocean', region: 'ams3' }, + ecs: { version: '1.0.0-beta2' }, + event: { action: 'changed-promiscuous-mode-on-device', category: 'anomoly', module: 'auditd', + kind: 'signal', }, - parent: { - depth: 0, - id: 'VhXOBmkBR346wHgnLP8T', - index: 'auditbeat-8.0.0-2019.02.19-000001', - type: 'event', + host: { + architecture: 'x86_64', + containerized: false, + hostname: 'zeek-sensor-amsterdam', + id: '2ce8b1e7d69e4a1d9c6bcddc473da9d9', + name: 'zeek-sensor-amsterdam', + os: { + codename: 'bionic', + family: 'debian', + kernel: '4.15.0-45-generic', + name: 'Ubuntu', + platform: 'ubuntu', + version: '18.04.2 LTS (Bionic Beaver)', + }, }, - parents: [ - { + process: { + executable: '/usr/bin/bro', + name: 'bro', + pid: 30157, + ppid: 30151, + title: + '/usr/bin/bro -i eth0 -U .status -p broctl -p broctl-live -p standalone -p local -p bro local.bro broctl broctl/standalone broctl', + }, + service: { type: 'auditd' }, + user: { + audit: { id: 'unset' }, + effective: { + group: { + id: '0', + name: 'root', + }, + id: '0', + name: 'root', + }, + filesystem: { + group: { + id: '0', + name: 'root', + }, + id: '0', + name: 'root', + }, + group: { id: '0', name: 'root' }, + id: '0', + name: 'root', + saved: { + group: { + id: '0', + name: 'root', + }, + id: '0', + name: 'root', + }, + }, + signal: { + rule: fullSignal.signal.rule, + group: fullSignal.signal.group, + original_time: fullSignal.signal.original_time, + status: 'open', + depth: 1, + ancestors: [ + { + depth: 0, + id: 'VhXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + original_event: { + action: 'changed-promiscuous-mode-on-device', + category: 'anomoly', + module: 'auditd', + }, + parent: { depth: 0, id: 'VhXOBmkBR346wHgnLP8T', index: 'auditbeat-8.0.0-2019.02.19-000001', type: 'event', }, - ], - _meta: { - version: SIGNALS_TEMPLATE_VERSION, + parents: [ + { + depth: 0, + id: 'VhXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + _meta: { + version: SIGNALS_TEMPLATE_VERSION, + }, }, }); }); @@ -606,59 +712,90 @@ export default ({ getService }: FtrProviderContext) => { const sequenceSignal = signalsOpen.hits.hits.find( (signal) => signal._source.signal.depth === 2 ); - const signal = sequenceSignal!._source.signal; - const eventIds = signal.parents.map((event) => event.id); - expect(signal).eql({ - status: 'open', - depth: 2, - group: signal.group, - rule: signal.rule, - ancestors: [ - { - depth: 0, - id: 'VhXOBmkBR346wHgnLP8T', - index: 'auditbeat-8.0.0-2019.02.19-000001', - type: 'event', - }, - { - depth: 1, - id: eventIds[0], - index: '.siem-signals-default', - rule: signal.rule.id, - type: 'signal', - }, - { - depth: 0, - id: '4hbXBmkBR346wHgn6fdp', - index: 'auditbeat-8.0.0-2019.02.19-000001', - type: 'event', - }, - { - depth: 1, - id: eventIds[1], - index: '.siem-signals-default', - rule: signal.rule.id, - type: 'signal', - }, - ], - parents: [ - { - depth: 1, - id: eventIds[0], - index: '.siem-signals-default', - rule: signal.rule.id, - type: 'signal', + const source = sequenceSignal!._source; + const eventIds = source.signal.parents.map((event) => event.id); + expect(source).eql({ + '@timestamp': source['@timestamp'], + agent: { + ephemeral_id: '1b4978a0-48be-49b1-ac96-323425b389ab', + hostname: 'zeek-sensor-amsterdam', + id: 'e52588e6-7aa3-4c89-a2c4-d6bc5c286db1', + type: 'auditbeat', + version: '8.0.0', + }, + auditd: { session: 'unset', summary: { actor: { primary: 'unset' } } }, + cloud: { instance: { id: '133551048' }, provider: 'digitalocean', region: 'ams3' }, + ecs: { version: '1.0.0-beta2' }, + event: { kind: 'signal' }, + host: { + architecture: 'x86_64', + containerized: false, + hostname: 'zeek-sensor-amsterdam', + id: '2ce8b1e7d69e4a1d9c6bcddc473da9d9', + name: 'zeek-sensor-amsterdam', + os: { + codename: 'bionic', + family: 'debian', + kernel: '4.15.0-45-generic', + name: 'Ubuntu', + platform: 'ubuntu', + version: '18.04.2 LTS (Bionic Beaver)', }, - { - depth: 1, - id: eventIds[1], - index: '.siem-signals-default', - rule: signal.rule.id, - type: 'signal', + }, + service: { type: 'auditd' }, + user: { audit: { id: 'unset' }, id: '0', name: 'root' }, + signal: { + status: 'open', + depth: 2, + group: source.signal.group, + rule: source.signal.rule, + ancestors: [ + { + depth: 0, + id: 'VhXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + { + depth: 1, + id: eventIds[0], + index: '.siem-signals-default', + rule: source.signal.rule.id, + type: 'signal', + }, + { + depth: 0, + id: '4hbXBmkBR346wHgn6fdp', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + { + depth: 1, + id: eventIds[1], + index: '.siem-signals-default', + rule: source.signal.rule.id, + type: 'signal', + }, + ], + parents: [ + { + depth: 1, + id: eventIds[0], + index: '.siem-signals-default', + rule: source.signal.rule.id, + type: 'signal', + }, + { + depth: 1, + id: eventIds[1], + index: '.siem-signals-default', + rule: source.signal.rule.id, + type: 'signal', + }, + ], + _meta: { + version: SIGNALS_TEMPLATE_VERSION, }, - ], - _meta: { - version: SIGNALS_TEMPLATE_VERSION, }, }); }); @@ -709,16 +846,51 @@ export default ({ getService }: FtrProviderContext) => { await waitForSignalsToBePresent(supertest, 1, [id]); const signalsOpen = await getSignalsByRuleIds(supertest, [ruleId]); expect(signalsOpen.hits.hits.length).eql(1); - const signal = signalsOpen.hits.hits[0]; - expect(signal._source.signal.threshold_result).eql({ - terms: [ - { - field: 'host.id', - value: '8cc95778cce5407c809480e8e32ad76b', + const fullSignal = signalsOpen.hits.hits[0]._source; + const eventIds = fullSignal.signal.parents.map((event) => event.id); + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + 'host.id': '8cc95778cce5407c809480e8e32ad76b', + event: { kind: 'signal' }, + signal: { + _meta: { version: 35 }, + parents: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + ancestors: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + status: 'open', + rule: fullSignal.signal.rule, + original_time: fullSignal.signal.original_time, + depth: 1, + parent: { + id: eventIds[0], + type: 'event', + index: 'auditbeat-*', + depth: 0, }, - ], - count: 788, - from: '1900-01-01T00:00:00.000Z', + threshold_result: { + terms: [ + { + field: 'host.id', + value: '8cc95778cce5407c809480e8e32ad76b', + }, + ], + count: 788, + from: '1900-01-01T00:00:00.000Z', + }, + }, }); }); @@ -832,22 +1004,57 @@ export default ({ getService }: FtrProviderContext) => { const createdRule = await createRule(supertest, rule); const signalsOpen = await getOpenSignals(supertest, es, createdRule); expect(signalsOpen.hits.hits.length).eql(1); - const signal = signalsOpen.hits.hits[0]; - expect(signal._source.signal.threshold_result).eql({ - terms: [ - { - field: 'host.id', - value: '8cc95778cce5407c809480e8e32ad76b', + const fullSignal = signalsOpen.hits.hits[0]._source; + const eventIds = fullSignal.signal.parents.map((event) => event.id); + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + 'host.id': '8cc95778cce5407c809480e8e32ad76b', + event: { kind: 'signal' }, + signal: { + _meta: { version: 35 }, + parents: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + ancestors: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + status: 'open', + rule: fullSignal.signal.rule, + original_time: fullSignal.signal.original_time, + depth: 1, + parent: { + id: eventIds[0], + type: 'event', + index: 'auditbeat-*', + depth: 0, }, - ], - cardinality: [ - { - field: 'destination.ip', - value: 7, + threshold_result: { + terms: [ + { + field: 'host.id', + value: '8cc95778cce5407c809480e8e32ad76b', + }, + ], + cardinality: [ + { + field: 'destination.ip', + value: 7, + }, + ], + count: 788, + from: '1900-01-01T00:00:00.000Z', }, - ], - count: 788, - from: '1900-01-01T00:00:00.000Z', + }, }); }); @@ -885,24 +1092,61 @@ export default ({ getService }: FtrProviderContext) => { const createdRule = await createRule(supertest, rule); const signalsOpen = await getOpenSignals(supertest, es, createdRule); expect(signalsOpen.hits.hits.length).eql(1); - const signal = signalsOpen.hits.hits[0]; - expect(signal._source.signal.threshold_result).eql({ - terms: [ - { - field: 'event.module', - value: 'system', - }, - { - field: 'host.id', - value: '2ab45fc1c41e4c84bbd02202a7e5761f', + const fullSignal = signalsOpen.hits.hits[0]._source; + const eventIds = fullSignal.signal.parents.map((event) => event.id); + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + 'event.module': 'system', + 'host.id': '2ab45fc1c41e4c84bbd02202a7e5761f', + 'process.name': 'sshd', + event: { kind: 'signal' }, + signal: { + _meta: { version: 35 }, + parents: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + ancestors: [ + { + depth: 0, + id: eventIds[0], + index: 'auditbeat-*', + type: 'event', + }, + ], + status: 'open', + rule: fullSignal.signal.rule, + original_time: fullSignal.signal.original_time, + depth: 1, + parent: { + id: eventIds[0], + type: 'event', + index: 'auditbeat-*', + depth: 0, }, - { - field: 'process.name', - value: 'sshd', + threshold_result: { + terms: [ + { + field: 'event.module', + value: 'system', + }, + { + field: 'host.id', + value: '2ab45fc1c41e4c84bbd02202a7e5761f', + }, + { + field: 'process.name', + value: 'sshd', + }, + ], + count: 21, + from: '1900-01-01T00:00:00.000Z', }, - ], - count: 21, - from: '1900-01-01T00:00:00.000Z', + }, }); }); }); @@ -1484,5 +1728,114 @@ export default ({ getService }: FtrProviderContext) => { expect(signalsOrderedByEventId.length).equal(2); }); }); + + describe('Signals generated from events with name override field', async () => { + beforeEach(async () => { + await deleteSignalsIndex(supertest); + await createSignalsIndex(supertest); + await esArchiver.load('auditbeat/hosts'); + }); + + afterEach(async () => { + await deleteSignalsIndex(supertest); + await deleteAllAlerts(supertest); + await esArchiver.load('auditbeat/hosts'); + }); + + it('should generate signals with name_override field', async () => { + const rule: QueryCreateSchema = { + ...getRuleForSignalTesting(['auditbeat-*']), + rule_name_override: 'event.action', + }; + + const { id } = await createRule(supertest, rule); + + await waitForRuleSuccessOrStatus(supertest, id); + await waitForSignalsToBePresent(supertest, 1, [id]); + const signalsResponse = await getSignalsByIds(supertest, [id], 1); + const signals = signalsResponse.hits.hits.map((hit) => hit._source); + const signalsOrderedByEventId = orderBy(signals, 'signal.parent.id', 'asc'); + const fullSignal = signalsOrderedByEventId[0]; + + expect(fullSignal).eql({ + '@timestamp': fullSignal['@timestamp'], + agent: { + ephemeral_id: '1b4978a0-48be-49b1-ac96-323425b389ab', + hostname: 'zeek-sensor-amsterdam', + id: 'e52588e6-7aa3-4c89-a2c4-d6bc5c286db1', + type: 'auditbeat', + version: '8.0.0', + }, + cloud: { instance: { id: '133551048' }, provider: 'digitalocean', region: 'ams3' }, + ecs: { version: '1.0.0-beta2' }, + event: { + action: 'boot', + dataset: 'login', + kind: 'signal', + module: 'system', + origin: '/var/log/wtmp', + }, + host: { + architecture: 'x86_64', + containerized: false, + hostname: 'zeek-sensor-amsterdam', + id: '2ce8b1e7d69e4a1d9c6bcddc473da9d9', + name: 'zeek-sensor-amsterdam', + os: { + codename: 'bionic', + family: 'debian', + kernel: '4.15.0-45-generic', + name: 'Ubuntu', + platform: 'ubuntu', + version: '18.04.2 LTS (Bionic Beaver)', + }, + }, + message: 'System boot', + service: { type: 'system' }, + signal: { + _meta: { + version: SIGNALS_TEMPLATE_VERSION, + }, + parents: [ + { + depth: 0, + id: 'UBXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + ancestors: [ + { + depth: 0, + id: 'UBXOBmkBR346wHgnLP8T', + index: 'auditbeat-8.0.0-2019.02.19-000001', + type: 'event', + }, + ], + status: 'open', + rule: { + ...fullSignal.signal.rule, + name: 'boot', + rule_name_override: 'event.action', + }, + original_time: fullSignal.signal.original_time, + depth: 1, + parent: { + id: 'UBXOBmkBR346wHgnLP8T', + type: 'event', + index: 'auditbeat-8.0.0-2019.02.19-000001', + depth: 0, + }, + original_event: { + action: 'boot', + dataset: 'login', + kind: 'event', + module: 'system', + origin: '/var/log/wtmp', + }, + }, + }); + }); + }); }); };