From f498b7aad2a16f12e62f518de688b1386e0e4088 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Thu, 12 Aug 2021 16:28:46 +0200 Subject: [PATCH 01/18] Update Alert page header style (#108359) --- .../detection_engine/detection_engine.tsx | 23 ++++--------------- .../pages/detection_engine/translations.ts | 2 +- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 323ef93133e24..4fc8d3e9167c2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -31,7 +31,6 @@ import { SiemSearchBar } from '../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { inputsSelectors } from '../../../common/store/inputs'; import { setAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; -import { useAlertInfo } from '../../components/alerts_info'; import { AlertsTable } from '../../components/alerts_table'; import { NoApiIntegrationKeyCallOut } from '../../components/callouts/no_api_integration_callout'; import { AlertsHistogramPanel } from '../../components/alerts_kpis/alerts_histogram_panel'; @@ -42,7 +41,7 @@ import { DetectionEngineHeaderPage } from '../../components/detection_engine_hea import { useListsConfig } from '../../containers/detection_engine/lists/use_lists_config'; import { DetectionEngineUserUnauthenticated } from './detection_engine_user_unauthenticated'; import * as i18n from './translations'; -import { LinkButton } from '../../../common/components/links'; +import { LinkAnchor } from '../../../common/components/links'; import { useFormatUrl } from '../../../common/components/link_to'; import { useGlobalFullScreen } from '../../../common/containers/use_full_screen'; import { Display } from '../../../hosts/pages/display'; @@ -122,7 +121,6 @@ const DetectionEnginePageComponent: React.FC = ({ loading: listsConfigLoading, needsConfiguration: needsListsConfiguration, } = useListsConfig(); - const [lastAlerts] = useAlertInfo({}); const { formatUrl } = useFormatUrl(SecurityPageName.rules); const [showBuildingBlockAlerts, setShowBuildingBlockAlerts] = useState(false); const [showOnlyThreatIndicatorAlerts, setShowOnlyThreatIndicatorAlerts] = useState(false); @@ -281,27 +279,14 @@ const DetectionEnginePageComponent: React.FC = ({ data-test-subj="detectionsAlertsPage" > - - {i18n.LAST_ALERT} - {': '} - {lastAlerts} - - ) - } - title={i18n.PAGE_TITLE} - > - + {i18n.BUTTON_MANAGE_RULES} - + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts index 9475701baf2fd..96e423aff1658 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts @@ -43,7 +43,7 @@ export const ALERT = i18n.translate('xpack.securitySolution.detectionEngine.aler export const BUTTON_MANAGE_RULES = i18n.translate( 'xpack.securitySolution.detectionEngine.buttonManageRules', { - defaultMessage: 'Manage detection rules', + defaultMessage: 'Manage rules', } ); From 6a51acc4085e3ee67de9c914bd6730fb36a98c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ece=20=C3=96zalp?= Date: Thu, 12 Aug 2021 10:34:06 -0400 Subject: [PATCH 02/18] [CTI][RAC] adds indicator match rule (#107977) --- .../rule_types/__mocks__/rule.ts | 5 +- .../rule_types/__mocks__/rule_type.ts | 10 +- .../rule_types/field_maps/cti.ts | 154 +++++++++++ .../lib/detection_engine/rule_types/index.ts | 1 + .../create_indicator_match_alert_type.test.ts | 260 ++++++++++++++++++ .../create_indicator_match_alert_type.ts | 99 +++++++ .../query/create_query_alert_type.ts | 19 +- .../scripts/create_rule_indicator_match.sh | 72 +++++ .../lib/detection_engine/rule_types/types.ts | 12 + .../security_solution/server/plugin.ts | 36 ++- 10 files changed, 634 insertions(+), 34 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/field_maps/cti.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/scripts/create_rule_indicator_match.sh diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts index 25e687050cf88..9d72d72e78b16 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts @@ -5,7 +5,9 @@ * 2.0. */ -export const createRuleMock = () => ({ +import { RuleParams } from '../../schemas/rule_schemas'; + +export const createRuleMock = (params: Partial) => ({ actions: [], author: [], buildingBlockType: undefined, @@ -49,4 +51,5 @@ export const createRuleMock = () => ({ updatedAt: '2020-01-10T21:11:45.839Z', updatedBy: 'elastic', version: 1, + ...params, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts index 0fa2bcc270a16..151b1d8b2fb13 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts @@ -18,8 +18,12 @@ import { AlertAttributes } from '../../signals/types'; import { createRuleMock } from './rule'; import { listMock } from '../../../../../../lists/server/mocks'; import { ruleRegistryMocks } from '../../../../../../rule_registry/server/mocks'; +import { RuleParams } from '../../schemas/rule_schemas'; -export const createRuleTypeMocks = () => { +export const createRuleTypeMocks = ( + ruleType: string = 'query', + ruleParams: Partial = {} +) => { /* eslint-disable @typescript-eslint/no-explicit-any */ let alertExecutor: (...args: any[]) => Promise; @@ -43,7 +47,7 @@ export const createRuleTypeMocks = () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); mockSavedObjectsClient.get.mockResolvedValue({ id: 'de2f6a49-28a3-4794-bad7-0e9482e075f8', - type: 'query', + type: ruleType, references: [], attributes: { actions: [], @@ -57,7 +61,7 @@ export const createRuleTypeMocks = () => { interval: '30m', }, throttle: '', - params: createRuleMock(), + params: createRuleMock(ruleParams), }, } as SavedObject); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/field_maps/cti.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/field_maps/cti.ts new file mode 100644 index 0000000000000..daf54e4f7cf5c --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/field_maps/cti.ts @@ -0,0 +1,154 @@ +/* + * 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. + */ + +export const ctiFieldMap = { + 'threat.indicator': { + type: 'nested', + array: false, + required: false, + }, + 'threat.indicator.as.number': { + type: 'long', + array: false, + required: false, + }, + 'threat.indicator.as.organization.name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.confidence': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.dataset': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.description': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.domain': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.email.address': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.first_seen': { + type: 'date', + array: false, + required: false, + }, + 'threat.indicator.geo.city_name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.continent_name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.country_iso_code': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.country_name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.location': { + type: 'geo_point', + array: false, + required: false, + }, + 'threat.indicator.geo.name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.region_iso_code': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.geo.region_name': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.ip': { + type: 'ip', + array: false, + required: false, + }, + 'threat.indicator.last_seen': { + type: 'date', + array: false, + required: false, + }, + 'threat.indicator.marking.tlp': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.matched.atomic': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.matched.field': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.matched.type': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.module': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.port': { + type: 'long', + array: false, + required: false, + }, + 'threat.indicator.provider': { + type: 'keyword', + array: false, + required: false, + }, + 'threat.indicator.scanner_stats': { + type: 'long', + array: false, + required: false, + }, + 'threat.indicator.sightings': { + type: 'long', + array: false, + required: false, + }, + 'threat.indicator.type': { + type: 'keyword', + array: false, + required: false, + }, +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/index.ts index 1b1fe48be00e0..75252cc3d47ae 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/index.ts @@ -6,3 +6,4 @@ */ export { createQueryAlertType } from './query/create_query_alert_type'; +export { createIndicatorMatchAlertType } from './indicator_match/create_indicator_match_alert_type'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts new file mode 100644 index 0000000000000..50aff00191396 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.test.ts @@ -0,0 +1,260 @@ +/* + * 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 { v4 } from 'uuid'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; + +import { allowedExperimentalValues } from '../../../../../common/experimental_features'; +import { createRuleTypeMocks } from '../__mocks__/rule_type'; +import { createIndicatorMatchAlertType } from './create_indicator_match_alert_type'; +import { sampleDocNoSortId } from '../../signals/__mocks__/es_results'; +import { CountResponse } from 'kibana/server'; +import { RuleParams } from '../../schemas/rule_schemas'; + +jest.mock('../utils/get_list_client', () => ({ + getListClient: jest.fn().mockReturnValue({ + listClient: { + getListItemIndex: jest.fn(), + }, + exceptionsClient: jest.fn(), + }), +})); + +jest.mock('../../signals/rule_status_service', () => ({ + ruleStatusServiceFactory: () => ({ + goingToRun: jest.fn(), + success: jest.fn(), + partialFailure: jest.fn(), + error: jest.fn(), + }), +})); + +describe('Indicator Match Alerts', () => { + const params: Partial = { + from: 'now-1m', + index: ['*'], + threatIndex: ['filebeat-*'], + threatLanguage: 'kuery', + threatMapping: [ + { + entries: [ + { + field: 'file.hash.md5', + type: 'mapping', + value: 'threatintel.indicator.file.hash.md5', + }, + ], + }, + ], + threatQuery: '*:*', + to: 'now', + type: 'threat_match', + }; + + it('does not send an alert when no events found', async () => { + const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); + const indicatorMatchAlertType = createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + indexAlias: 'alerts.security-alerts', + lists: dependencies.lists, + logger: dependencies.logger, + mergeStrategy: 'allFields', + ruleDataClient: dependencies.ruleDataClient, + ruleDataService: dependencies.ruleDataService, + version: '1.0.0', + }); + + dependencies.alerting.registerType(indicatorMatchAlertType); + + services.scopedClusterClient.asCurrentUser.search.mockReturnValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [], + sequences: [], + events: [], + total: { + relation: 'eq', + value: 0, + }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }) + ); + + await executor({ params }); + expect(dependencies.ruleDataClient.getWriter).not.toBeCalled(); + }); + + it('does not send an alert when no enrichments are found', async () => { + const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); + const indicatorMatchAlertType = createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + indexAlias: 'alerts.security-alerts', + lists: dependencies.lists, + logger: dependencies.logger, + mergeStrategy: 'allFields', + ruleDataClient: dependencies.ruleDataClient, + ruleDataService: dependencies.ruleDataService, + version: '1.0.0', + }); + + dependencies.alerting.registerType(indicatorMatchAlertType); + + services.scopedClusterClient.asCurrentUser.search.mockReturnValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [sampleDocNoSortId(v4()), sampleDocNoSortId(v4()), sampleDocNoSortId(v4())], + total: { + relation: 'eq', + value: 3, + }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }) + ); + + await executor({ params }); + expect(dependencies.ruleDataClient.getWriter).not.toBeCalled(); + }); + + it('sends an alert when enrichments are found', async () => { + const { services, dependencies, executor } = createRuleTypeMocks('threat_match', params); + const indicatorMatchAlertType = createIndicatorMatchAlertType({ + experimentalFeatures: allowedExperimentalValues, + indexAlias: 'alerts.security-alerts', + lists: dependencies.lists, + logger: dependencies.logger, + mergeStrategy: 'allFields', + ruleDataClient: dependencies.ruleDataClient, + ruleDataService: dependencies.ruleDataService, + version: '1.0.0', + }); + + dependencies.alerting.registerType(indicatorMatchAlertType); + + // threat list count + services.scopedClusterClient.asCurrentUser.count.mockReturnValue( + elasticsearchClientMock.createSuccessTransportRequestPromise({ count: 1 } as CountResponse) + ); + + services.scopedClusterClient.asCurrentUser.search.mockReturnValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + ...sampleDocNoSortId(v4()), + _source: { + ...sampleDocNoSortId(v4())._source, + 'threatintel.indicator.file.hash.md5': 'a1b2c3', + }, + fields: { + ...sampleDocNoSortId(v4()).fields, + 'threatintel.indicator.file.hash.md5': ['a1b2c3'], + }, + }, + ], + total: { + relation: 'eq', + value: 1, + }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }) + ); + + services.scopedClusterClient.asCurrentUser.search.mockReturnValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + ...sampleDocNoSortId(v4()), + _source: { + ...sampleDocNoSortId(v4())._source, + 'file.hash.md5': 'a1b2c3', + }, + fields: { + ...sampleDocNoSortId(v4()).fields, + 'file.hash.md5': ['a1b2c3'], + }, + }, + ], + total: { + relation: 'eq', + value: 1, + }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }) + ); + + services.scopedClusterClient.asCurrentUser.search.mockReturnValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ + hits: { + hits: [ + { + ...sampleDocNoSortId(v4()), + _source: { + ...sampleDocNoSortId(v4())._source, + 'file.hash.md5': 'a1b2c3', + }, + fields: { + ...sampleDocNoSortId(v4()).fields, + 'file.hash.md5': ['a1b2c3'], + }, + }, + ], + total: { + relation: 'eq', + value: 1, + }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }) + ); + + await executor({ params }); + + expect(dependencies.ruleDataClient.getWriter).toBeCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts new file mode 100644 index 0000000000000..61342981479ae --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts @@ -0,0 +1,99 @@ +/* + * 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 { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; +import { PersistenceServices } from '../../../../../../rule_registry/server'; +import { INDICATOR_ALERT_TYPE_ID } from '../../../../../common/constants'; +import { threatRuleParams, ThreatRuleParams } from '../../schemas/rule_schemas'; +import { threatMatchExecutor } from '../../signals/executors/threat_match'; +import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; +import { CreateRuleOptions } from '../types'; + +export const createIndicatorMatchAlertType = (createOptions: CreateRuleOptions) => { + const { + experimentalFeatures, + indexAlias, + lists, + logger, + mergeStrategy, + ruleDataClient, + version, + ruleDataService, + } = createOptions; + const createSecurityRuleType = createSecurityRuleTypeFactory({ + indexAlias, + lists, + logger, + mergeStrategy, + ruleDataClient, + ruleDataService, + }); + return createSecurityRuleType({ + id: INDICATOR_ALERT_TYPE_ID, + name: 'Indicator Match Rule', + validate: { + params: { + validate: (object: unknown) => { + const [validated, errors] = validateNonExact(object, threatRuleParams); + if (errors != null) { + throw new Error(errors); + } + if (validated == null) { + throw new Error('Validation of rule params failed'); + } + return validated; + }, + }, + }, + actionGroups: [ + { + id: 'default', + name: 'Default', + }, + ], + defaultActionGroupId: 'default', + actionVariables: { + context: [{ name: 'server', description: 'the server' }], + }, + minimumLicenseRequired: 'basic', + isExportable: false, + producer: 'security-solution', + async executor(execOptions) { + const { + runOpts: { + buildRuleMessage, + bulkCreate, + exceptionItems, + listClient, + rule, + searchAfterSize, + tuple, + wrapHits, + }, + services, + state, + } = execOptions; + + const result = await threatMatchExecutor({ + buildRuleMessage, + bulkCreate, + exceptionItems, + experimentalFeatures, + eventsTelemetry: undefined, + listClient, + logger, + rule, + searchAfterSize, + services, + tuple, + version, + wrapHits, + }); + return { ...result, state }; + }, + }); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts index c487d8c93119d..b66e76f598bf4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts @@ -5,28 +5,15 @@ * 2.0. */ -import { Logger } from '@kbn/logging'; import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; -import { PersistenceServices, RuleDataClient } from '../../../../../../rule_registry/server'; +import { PersistenceServices } from '../../../../../../rule_registry/server'; import { QUERY_ALERT_TYPE_ID } from '../../../../../common/constants'; -import { ExperimentalFeatures } from '../../../../../common/experimental_features'; -import { ConfigType } from '../../../../config'; -import { SetupPlugins } from '../../../../plugin'; -import { IRuleDataPluginService } from '../../rule_execution_log/types'; import { queryRuleParams, QueryRuleParams } from '../../schemas/rule_schemas'; import { queryExecutor } from '../../signals/executors/query'; import { createSecurityRuleTypeFactory } from '../create_security_rule_type_factory'; +import { CreateRuleOptions } from '../types'; -export const createQueryAlertType = (createOptions: { - experimentalFeatures: ExperimentalFeatures; - indexAlias: string; - lists: SetupPlugins['lists']; - logger: Logger; - mergeStrategy: ConfigType['alertMergeStrategy']; - ruleDataClient: RuleDataClient; - version: string; - ruleDataService: IRuleDataPluginService; -}) => { +export const createQueryAlertType = (createOptions: CreateRuleOptions) => { const { experimentalFeatures, indexAlias, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/scripts/create_rule_indicator_match.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/scripts/create_rule_indicator_match.sh new file mode 100644 index 0000000000000..f50aac30a69c5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/scripts/create_rule_indicator_match.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# 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. +# + +# to see alerts with this script +# 1. enable filebeat threatintel module and run filebeat +# 2. using Kibana DevTools, create `test-index` with the following mappings: @timestamp:date, file.hash.md5:text +# 3. run this script +# 4. using Kibana DevTools, post to test-index an existing file.hash.md5 value with a current timestamp +# 5. alert should be generated and can be viewed on the Alerts table + +curl -X POST ${KIBANA_URL}${SPACE_URL}/api/alerts/alert \ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ + -H 'kbn-xsrf: true' \ + -H 'Content-Type: application/json' \ + --verbose \ + -d ' +{ + "params":{ + "author": [], + "description": "Indicator Match Rule", + "exceptionsList": [], + "falsePositives": [], + "from": "now-300s", + "query": "*:*", + "immutable": false, + "index": ["test-*"], + "language": "kuery", + "maxSignals": 10, + "outputIndex": "", + "references": [], + "riskScore": 21, + "riskScoreMapping": [], + "ruleId": "81dec1ba-b779-469c-9667-6b0e865fb86c", + "severity": "low", + "severityMapping": [], + "threat": [], + "threatQuery": "*:*", + "threatMapping": [ + { + "entries":[ + { + "field":"file.hash.md5", + "type":"mapping", + "value":"threatintel.indicator.file.hash.md5" + } + ] + } + ], + "threatLanguage": "kuery", + "threatIndex": ["filebeat-*"], + "to": "now", + "type": "threat_match", + "version": 1 + }, + "consumer":"alerts", + "alertTypeId":"siem.indicatorRule", + "schedule":{ + "interval":"1m" + }, + "actions":[], + "tags":[ + "indicator match", + "persistence" + ], + "notifyWhen":"onActionGroupChange", + "name":"Basic Indicator Match Rule" +}' diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts index 20fb721308600..f0f11f470bc6c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts @@ -33,6 +33,7 @@ import { RuleParams } from '../schemas/rule_schemas'; import { BuildRuleMessage } from '../signals/rule_messages'; import { AlertAttributes, BulkCreate, WrapHits } from '../signals/types'; import { AlertsFieldMap, RulesFieldMap } from './field_maps'; +import { ExperimentalFeatures } from '../../../../common/experimental_features'; export interface SecurityAlertTypeReturnValue { bulkCreateTimes: string[]; @@ -118,3 +119,14 @@ export type RACAlert = Exclude< export type RACSourceHit = SearchHit; export type WrappedRACAlert = BaseHit; + +export interface CreateRuleOptions { + experimentalFeatures: ExperimentalFeatures; + indexAlias: string; + lists: SetupPlugins['lists']; + logger: Logger; + mergeStrategy: ConfigType['alertMergeStrategy']; + ruleDataClient: RuleDataClient; + version: string; + ruleDataService: IRuleDataPluginService; +} diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index e67c9fbfd8327..d19c799295cfb 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -66,6 +66,7 @@ import { NOTIFICATIONS_ID, QUERY_ALERT_TYPE_ID, DEFAULT_SPACE_ID, + INDICATOR_ALERT_TYPE_ID, } from '../common/constants'; import { registerEndpointRoutes } from './endpoint/routes/metadata'; import { registerLimitedConcurrencyRoutes } from './endpoint/routes/limited_concurrency'; @@ -94,6 +95,9 @@ import { rulesFieldMap } from './lib/detection_engine/rule_types/field_maps/rule import { RuleExecutionLogClient } from './lib/detection_engine/rule_execution_log/rule_execution_log_client'; import { getKibanaPrivilegesFeaturePrivileges } from './features'; import { EndpointMetadataService } from './endpoint/services/metadata'; +import { createIndicatorMatchAlertType } from './lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type'; +import { CreateRuleOptions } from './lib/detection_engine/rule_types/types'; +import { ctiFieldMap } from './lib/detection_engine/rule_types/field_maps/cti'; export interface SetupPlugins { alerting: AlertingSetup; @@ -231,7 +235,10 @@ export class Plugin implements IPlugin Date: Thu, 12 Aug 2021 10:40:21 -0400 Subject: [PATCH 03/18] Include additional functional test dirs in uptime CODEOWNERS entries. (#108368) --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 95c11b05a9783..26616ab237660 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -107,6 +107,8 @@ /x-pack/plugins/observability/public/components/shared/exploratory_view @elastic/uptime /x-pack/test/functional_with_es_ssl/apps/uptime @elastic/uptime /x-pack/test/functional/apps/uptime @elastic/uptime +/x-pack/test/functional/es_archives/uptime @elastic/uptime +/x-pack/test/functional/services/uptime @elastic/uptime /x-pack/test/api_integration/apis/uptime @elastic/uptime # Client Side Monitoring / Uptime (lives in APM directories but owned by Uptime) From 338f7c5d7f17e4db6eee197d20dd2bc239b2b1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Thu, 12 Aug 2021 16:00:29 +0100 Subject: [PATCH 04/18] [Monaco editor]: Fix accessibility focus trap issue (#107292) --- .../__snapshots__/code_editor.test.tsx.snap | 273 ++++++++++-- .../code_editor/code_editor.test.helpers.tsx | 105 +++++ .../public/code_editor/code_editor.test.tsx | 196 ++++++--- .../public/code_editor/code_editor.tsx | 407 +++++++++++++----- .../public/code_editor/editor.scss | 21 + .../expression_input.stories.storyshot | 39 +- 6 files changed, 826 insertions(+), 215 deletions(-) create mode 100644 src/plugins/kibana_react/public/code_editor/code_editor.test.helpers.tsx diff --git a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap index 230d31ac9e0b6..7b2729d2e1b68 100644 --- a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap +++ b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap @@ -1,52 +1,241 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`is rendered 1`] = ` - - hint element should be tabable 1`] = ` +
+`; + +exports[` is rendered 1`] = ` + +
+ +

+ + Enter + , + } + } + /> +

+

+ + Esc + , + } + } + /> +

+ + } + delay="regular" + display="block" + position="top" + > + +
+ + + - - + > +
+