= ({ viewErrorsPath }) => (
+
+ {SCHEMA_ERRORS_DESCRIPTION}
+
+ {SCHEMA_ERRORS_BUTTON}
+
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
index 04bef009587c9..b47d7ccabb57e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
@@ -7,3 +7,4 @@
export { SchemaAddFieldModal } from './schema_add_field_modal';
export { SchemaFieldTypeSelect } from './field_type_select';
+export { SchemaErrorsCallout } from './errors_callout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/constants.ts
index 0ab5962a17944..a540c6fc040e8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/constants.ts
@@ -77,13 +77,6 @@ export const SCHEMA_FILTER_PLACEHOLDER = i18n.translate(
}
);
-export const SCHEMA_UPDATING = i18n.translate(
- 'xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updating',
- {
- defaultMessage: 'Updating schema...',
- }
-);
-
export const SCHEMA_SAVE_BUTTON = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.contentSource.schema.save.button',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
index ccf3275ffd96f..6b656fbdc6ddb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
@@ -16,16 +16,14 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiFieldSearch } from '@elastic/eui';
-import { IndexingStatus } from '../../../../../shared/indexing_status';
import { Loading } from '../../../../../shared/loading';
-import { SchemaAddFieldModal } from '../../../../../shared/schema/schema_add_field_modal';
+import { SchemaAddFieldModal, SchemaErrorsCallout } from '../../../../../shared/schema';
import { Schema } from './schema';
import { SchemaFieldsTable } from './schema_fields_table';
describe('Schema', () => {
const initializeSchema = jest.fn();
- const onIndexingComplete = jest.fn();
const addNewField = jest.fn();
const updateFields = jest.fn();
const openAddFieldModal = jest.fn();
@@ -59,7 +57,6 @@ describe('Schema', () => {
setMockValues({ ...mockValues });
setMockActions({
initializeSchema,
- onIndexingComplete,
addNewField,
updateFields,
openAddFieldModal,
@@ -103,23 +100,13 @@ describe('Schema', () => {
expect(setFilterValue).toHaveBeenCalledWith('Query');
});
- it('renders IndexingStatus (org)', () => {
+ it('renders schema errors', () => {
setMockValues({ ...mockValues, mostRecentIndexJob });
const wrapper = shallow();
- expect(wrapper.find(IndexingStatus)).toHaveLength(1);
- expect(wrapper.find(IndexingStatus).prop('statusPath')).toEqual(
- '/api/workplace_search/org/sources/123/reindex_job/123/status'
- );
- });
-
- it('renders IndexingStatus (account)', () => {
- setMockValues({ ...mockValues, mostRecentIndexJob, isOrganization: false });
- const wrapper = shallow();
-
- expect(wrapper.find(IndexingStatus)).toHaveLength(1);
- expect(wrapper.find(IndexingStatus).prop('statusPath')).toEqual(
- '/api/workplace_search/account/sources/123/reindex_job/123/status'
+ expect(wrapper.find(SchemaErrorsCallout)).toHaveLength(1);
+ expect(wrapper.find(SchemaErrorsCallout).prop('viewErrorsPath')).toEqual(
+ '/sources/123/schema_errors/123'
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
index 72a3804c4443b..65ed988f45ff0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
@@ -20,9 +20,8 @@ import {
EuiPanel,
} from '@elastic/eui';
-import { IndexingStatus } from '../../../../../shared/indexing_status';
import { Loading } from '../../../../../shared/loading';
-import { SchemaAddFieldModal } from '../../../../../shared/schema/schema_add_field_modal';
+import { SchemaAddFieldModal, SchemaErrorsCallout } from '../../../../../shared/schema';
import { AppLogic } from '../../../../app_logic';
import { ViewContentHeader } from '../../../../components/shared/view_content_header';
import { getReindexJobRoute } from '../../../../routes';
@@ -32,7 +31,6 @@ import {
SCHEMA_MANAGE_SCHEMA_TITLE,
SCHEMA_MANAGE_SCHEMA_DESCRIPTION,
SCHEMA_FILTER_PLACEHOLDER,
- SCHEMA_UPDATING,
SCHEMA_SAVE_BUTTON,
SCHEMA_EMPTY_SCHEMA_TITLE,
SCHEMA_EMPTY_SCHEMA_DESCRIPTION,
@@ -43,7 +41,6 @@ import { SchemaLogic } from './schema_logic';
export const Schema: React.FC = () => {
const {
initializeSchema,
- onIndexingComplete,
addNewField,
updateFields,
openAddFieldModal,
@@ -71,16 +68,13 @@ export const Schema: React.FC = () => {
if (dataLoading) return ;
const hasSchemaFields = Object.keys(activeSchema).length > 0;
- const { isActive, hasErrors, percentageComplete, activeReindexJobId } = mostRecentIndexJob;
+ const { hasErrors, activeReindexJobId } = mostRecentIndexJob;
const addFieldButton = (
{SCHEMA_ADD_FIELD_BUTTON}
);
- const statusPath = isOrganization
- ? `/api/workplace_search/org/sources/${sourceId}/reindex_job/${activeReindexJobId}/status`
- : `/api/workplace_search/account/sources/${sourceId}/reindex_job/${activeReindexJobId}/status`;
return (
<>
@@ -89,17 +83,13 @@ export const Schema: React.FC = () => {
description={SCHEMA_MANAGE_SCHEMA_DESCRIPTION}
/>
- {(isActive || hasErrors) && (
-
)}
{hasSchemaFields ? (
@@ -118,20 +108,14 @@ export const Schema: React.FC = () => {
{addFieldButton}
- {percentageComplete < 100 ? (
-
- {SCHEMA_UPDATING}
-
- ) : (
-
- {SCHEMA_SAVE_BUTTON}
-
- )}
+
+ {SCHEMA_SAVE_BUTTON}
+
diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts
index 2fc4099a78615..4043f9daddaa7 100644
--- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.test.ts
@@ -24,7 +24,6 @@ import {
registerAccountSourceDisplaySettingsConfig,
registerAccountSourceSchemasRoute,
registerAccountSourceReindexJobRoute,
- registerAccountSourceReindexJobStatusRoute,
registerAccountSourceDownloadDiagnosticsRoute,
registerOrgSourcesRoute,
registerOrgSourcesStatusRoute,
@@ -40,7 +39,6 @@ import {
registerOrgSourceDisplaySettingsConfig,
registerOrgSourceSchemasRoute,
registerOrgSourceReindexJobRoute,
- registerOrgSourceReindexJobStatusRoute,
registerOrgSourceDownloadDiagnosticsRoute,
registerOrgSourceOauthConfigurationsRoute,
registerOrgSourceOauthConfigurationRoute,
@@ -542,29 +540,6 @@ describe('sources routes', () => {
});
});
- describe('GET /api/workplace_search/account/sources/{sourceId}/reindex_job/{jobId}/status', () => {
- let mockRouter: MockRouter;
-
- beforeEach(() => {
- jest.clearAllMocks();
- mockRouter = new MockRouter({
- method: 'get',
- path: '/api/workplace_search/account/sources/{sourceId}/reindex_job/{jobId}/status',
- });
-
- registerAccountSourceReindexJobStatusRoute({
- ...mockDependencies,
- router: mockRouter.router,
- });
- });
-
- it('creates a request handler', () => {
- expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
- path: '/ws/sources/:sourceId/reindex_job/:jobId/status',
- });
- });
- });
-
describe('GET /api/workplace_search/account/sources/{sourceId}/download_diagnostics', () => {
let mockRouter: MockRouter;
@@ -1063,29 +1038,6 @@ describe('sources routes', () => {
});
});
- describe('GET /api/workplace_search/org/sources/{sourceId}/reindex_job/{jobId}/status', () => {
- let mockRouter: MockRouter;
-
- beforeEach(() => {
- jest.clearAllMocks();
- mockRouter = new MockRouter({
- method: 'get',
- path: '/api/workplace_search/org/sources/{sourceId}/reindex_job/{jobId}/status',
- });
-
- registerOrgSourceReindexJobStatusRoute({
- ...mockDependencies,
- router: mockRouter.router,
- });
- });
-
- it('creates a request handler', () => {
- expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
- path: '/ws/org/sources/:sourceId/reindex_job/:jobId/status',
- });
- });
- });
-
describe('GET /api/workplace_search/org/sources/{sourceId}/download_diagnostics', () => {
let mockRouter: MockRouter;
diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
index 1dd6d859d88ad..7e9d7d92742ab 100644
--- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
@@ -381,26 +381,6 @@ export function registerAccountSourceReindexJobRoute({
);
}
-export function registerAccountSourceReindexJobStatusRoute({
- router,
- enterpriseSearchRequestHandler,
-}: RouteDependencies) {
- router.get(
- {
- path: '/api/workplace_search/account/sources/{sourceId}/reindex_job/{jobId}/status',
- validate: {
- params: schema.object({
- sourceId: schema.string(),
- jobId: schema.string(),
- }),
- },
- },
- enterpriseSearchRequestHandler.createRequest({
- path: '/ws/sources/:sourceId/reindex_job/:jobId/status',
- })
- );
-}
-
export function registerAccountSourceDownloadDiagnosticsRoute({
router,
enterpriseSearchRequestHandler,
@@ -749,26 +729,6 @@ export function registerOrgSourceReindexJobRoute({
);
}
-export function registerOrgSourceReindexJobStatusRoute({
- router,
- enterpriseSearchRequestHandler,
-}: RouteDependencies) {
- router.get(
- {
- path: '/api/workplace_search/org/sources/{sourceId}/reindex_job/{jobId}/status',
- validate: {
- params: schema.object({
- sourceId: schema.string(),
- jobId: schema.string(),
- }),
- },
- },
- enterpriseSearchRequestHandler.createRequest({
- path: '/ws/org/sources/:sourceId/reindex_job/:jobId/status',
- })
- );
-}
-
export function registerOrgSourceDownloadDiagnosticsRoute({
router,
enterpriseSearchRequestHandler,
@@ -937,7 +897,6 @@ export const registerSourcesRoutes = (dependencies: RouteDependencies) => {
registerAccountSourceDisplaySettingsConfig(dependencies);
registerAccountSourceSchemasRoute(dependencies);
registerAccountSourceReindexJobRoute(dependencies);
- registerAccountSourceReindexJobStatusRoute(dependencies);
registerAccountSourceDownloadDiagnosticsRoute(dependencies);
registerOrgSourcesRoute(dependencies);
registerOrgSourcesStatusRoute(dependencies);
@@ -953,7 +912,6 @@ export const registerSourcesRoutes = (dependencies: RouteDependencies) => {
registerOrgSourceDisplaySettingsConfig(dependencies);
registerOrgSourceSchemasRoute(dependencies);
registerOrgSourceReindexJobRoute(dependencies);
- registerOrgSourceReindexJobStatusRoute(dependencies);
registerOrgSourceDownloadDiagnosticsRoute(dependencies);
registerOrgSourceOauthConfigurationsRoute(dependencies);
registerOrgSourceOauthConfigurationRoute(dependencies);
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 27705764bf2b4..46074a0dbed13 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -7601,9 +7601,6 @@
"xpack.enterpriseSearch.featureCatalogueDescription2": "ユーザーを関連するデータにつなげます。",
"xpack.enterpriseSearch.featureCatalogueDescription3": "チームの内容を統合します。",
"xpack.enterpriseSearch.hiddenText": "非表示のテキスト",
- "xpack.enterpriseSearch.indexingStatus.hasErrors.button": "エラーを表示",
- "xpack.enterpriseSearch.indexingStatus.hasErrors.title": "複数のドキュメントでフィールド変換エラーがあります。",
- "xpack.enterpriseSearch.indexingStatus.progress.title": "インデックス中です",
"xpack.enterpriseSearch.nav.hierarchy": "セカンダリ",
"xpack.enterpriseSearch.nav.menu": "メニュー",
"xpack.enterpriseSearch.nav.toggleMenu": "セカンダリナビゲーションを切り替える",
@@ -7627,6 +7624,7 @@
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "フィールド名が変更されます",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.description": "追加すると、フィールドはスキーマから削除されます。",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.title": "新しいフィールドを追加",
+ "xpack.enterpriseSearch.schema.errorsCallout.buttonLabel": "エラーを表示",
"xpack.enterpriseSearch.schema.errorsTable.control.review": "見直し",
"xpack.enterpriseSearch.schema.errorsTable.heading.error": "エラー",
"xpack.enterpriseSearch.schema.errorsTable.heading.id": "ID",
@@ -7757,7 +7755,6 @@
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.newFieldExists.message": "新しいフィールドがすでに存在します:{fieldName}。",
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.save.button": "スキーマの保存",
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updated.message": "スキーマが更新されました。",
- "xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updating": "スキーマを更新しています...",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.text": "ドキュメントレベルのアクセス権は、定義されたルールに基づいて、ユーザーコンテンツアクセスを管理します。個人またはグループの特定のドキュメントへのアクセスを許可または拒否します。",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.title": "プラチナライセンスで提供されているドキュメントレベルのアクセス権",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.explore.button": "プラチナ機能の詳細",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index ce5203b682257..213e5415ceedd 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -7671,9 +7671,6 @@
"xpack.enterpriseSearch.featureCatalogueDescription2": "将您的用户连接到相关数据。",
"xpack.enterpriseSearch.featureCatalogueDescription3": "统一您的团队内容。",
"xpack.enterpriseSearch.hiddenText": "隐藏文本",
- "xpack.enterpriseSearch.indexingStatus.hasErrors.button": "查看错误",
- "xpack.enterpriseSearch.indexingStatus.hasErrors.title": "多个文档有字段转换错误。",
- "xpack.enterpriseSearch.indexingStatus.progress.title": "索引进度",
"xpack.enterpriseSearch.nav.hierarchy": "次级",
"xpack.enterpriseSearch.nav.menu": "菜单",
"xpack.enterpriseSearch.nav.toggleMenu": "切换次级导航",
@@ -7697,6 +7694,7 @@
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "该字段将被命名",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.description": "字段添加后,将无法从架构中删除。",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.title": "添加新字段",
+ "xpack.enterpriseSearch.schema.errorsCallout.buttonLabel": "查看错误",
"xpack.enterpriseSearch.schema.errorsTable.control.review": "复查",
"xpack.enterpriseSearch.schema.errorsTable.heading.error": "错误",
"xpack.enterpriseSearch.schema.errorsTable.heading.id": "ID",
@@ -7827,7 +7825,6 @@
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.newFieldExists.message": "新字段已存在:{fieldName}。",
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.save.button": "保存架构",
"xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updated.message": "架构已更新。",
- "xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updating": "正在更新架构......",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.text": "文档级别权限根据定义的规则管理用户内容访问权限。允许或拒绝个人和组对特定文档的访问。",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.title": "适用于白金级许可证的文档级别权限",
"xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.explore.button": "了解白金级功能",
From 4da34bb0f3adcdd31cd9fe416a34f6fcb48f3043 Mon Sep 17 00:00:00 2001
From: Dima Arnautov
Date: Mon, 3 May 2021 19:28:34 +0200
Subject: [PATCH 15/81] [ML] Fix pagination and sorting on trained models list
page (#99061)
---
.../models_management/expanded_row.tsx | 7 +++----
.../models_management/models_list.tsx | 18 +++++++++++-------
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx
index 5562fcbe093a1..476931e4b8551 100644
--- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx
+++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx
@@ -28,6 +28,7 @@ import { EuiDescriptionListProps } from '@elastic/eui/src/components/description
import { ModelItemFull } from './models_list';
import { useMlKibana } from '../../../../../contexts/kibana';
import { timeFormatter } from '../../../../../../../common/util/date_utils';
+import { isDefined } from '../../../../../../../common/types/guards';
interface ExpandedRowProps {
item: ModelItemFull;
@@ -81,6 +82,7 @@ export const ExpandedRow: FC = ({ item }) => {
function formatToListItems(items: Record): EuiDescriptionListProps['listItems'] {
return Object.entries(items)
+ .filter(([, value]) => isDefined(value))
.map(([title, value]) => {
if (title in formatterDictionary) {
return {
@@ -102,12 +104,9 @@ export const ExpandedRow: FC = ({ item }) => {
{JSON.stringify(value, null, 2)}
) : (
- value
+ value.toString()
),
};
- })
- .filter(({ description: d }) => {
- return d !== undefined;
});
}
diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/models_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/models_list.tsx
index 4c3da00ed7cad..79b8c7130e73c 100644
--- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/models_list.tsx
+++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/models_list.tsx
@@ -53,6 +53,7 @@ import { timeFormatter } from '../../../../../../../common/util/date_utils';
import { ListingPageUrlState } from '../../../../../../../common/types/common';
import { usePageUrlState } from '../../../../../util/url_state';
import { BUILT_IN_MODEL_TAG } from '../../../../../../../common/constants/data_frame_analytics';
+import { useTableSettings } from '../analytics_list/use_table_settings';
type Stats = Omit;
@@ -90,12 +91,6 @@ export const ModelsList: FC = () => {
);
const searchQueryText = pageState.queryText ?? '';
- const setSearchQueryText = useCallback(
- (value) => {
- updatePageState({ queryText: value });
- },
- [updatePageState]
- );
const canDeleteDataFrameAnalytics = capabilities.ml.canDeleteDataFrameAnalytics as boolean;
@@ -521,13 +516,19 @@ export const ModelsList: FC = () => {
}
: undefined;
+ const { onTableChange, pagination, sorting } = useTableSettings(
+ items,
+ pageState,
+ updatePageState
+ );
+
const search: EuiSearchBarProps = {
query: searchQueryText,
onChange: (searchChange) => {
if (searchChange.error !== null) {
return false;
}
- setSearchQueryText(searchChange.queryText);
+ updatePageState({ queryText: searchChange.queryText, pageIndex: 0 });
return true;
},
box: {
@@ -572,6 +573,9 @@ export const ModelsList: FC = () => {
rowProps={(item) => ({
'data-test-subj': `mlModelsTableRow row-${item.model_id}`,
})}
+ pagination={pagination}
+ onTableChange={onTableChange}
+ sorting={sorting}
/>
{modelsToDelete.length > 0 && (
From 1ce0cf6f5dd251b27302d3fde5c5d74d83a4ba4e Mon Sep 17 00:00:00 2001
From: Tim Sullivan
Date: Mon, 3 May 2021 10:35:12 -0700
Subject: [PATCH 16/81] Reporting/Docs: update version of reporting_user
deprecation (#98988)
---
docs/settings/reporting-settings.asciidoc | 4 ++--
docs/user/reporting/index.asciidoc | 2 +-
docs/user/security/reporting.asciidoc | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/settings/reporting-settings.asciidoc b/docs/settings/reporting-settings.asciidoc
index 084ac633e9bca..70f3e272fa5a9 100644
--- a/docs/settings/reporting-settings.asciidoc
+++ b/docs/settings/reporting-settings.asciidoc
@@ -276,14 +276,14 @@ For information about {kib} memory limits, see <>. It is recommended that *Reporting* is configured to
use {kib} privileges by setting <> to `false`. By using {kib} privileges, you can define
custom roles that grant *Reporting* privileges as sub-features of {kib} applications in *Role Management*.
diff --git a/docs/user/security/reporting.asciidoc b/docs/user/security/reporting.asciidoc
index 2f331e252c492..ab25dddd04694 100644
--- a/docs/user/security/reporting.asciidoc
+++ b/docs/user/security/reporting.asciidoc
@@ -17,7 +17,7 @@ For more information, see
[[reporting-app-users]]
Access to reporting features is limited to privileged users. In older versions of Kibana, you could only grant
-users the privilege by assigning them the `reporting_user` role in Elasticsearch. In 7.13 and above, you have
+users the privilege by assigning them the `reporting_user` role in Elasticsearch. In 7.14 and above, you have
the option to create your own roles that grant access to reporting features using <>.
It is recommended that you set `xpack.reporting.roles.enabled: false` in your kibana.yml to begin using Kibana
From da785eae041280581c4302676eb9319d1577c82c Mon Sep 17 00:00:00 2001
From: Poff Poffenberger
Date: Mon, 3 May 2021 12:42:26 -0500
Subject: [PATCH 17/81] Revert "Revert "Add essql search strategy and integrate
in canvas (#94754)" (#98841)
* Revert "Revert "Add essql search strategy and integrate in canvas (#94754)""
This reverts commit 0f15a12420cb195f813471aed81c3c932fc33dcb.
* Update squel usage to safe-squel
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../server/collectors/management/schema.ts | 4 +
.../server/collectors/management/types.ts | 1 +
src/plugins/presentation_util/common/labs.ts | 19 ++-
src/plugins/telemetry/schema/oss_plugins.json | 6 +
.../functions/browser/escount.ts | 94 ++++++++++++
.../functions/browser/esdocs.ts | 141 ++++++++++++++++++
.../functions/browser/essql.ts | 103 +++++++++++++
.../functions/browser/index.ts | 14 +-
.../functions/server/escount.ts | 5 +-
x-pack/plugins/canvas/common/lib/constants.ts | 1 +
.../lib/request}/build_bool_array.ts | 2 +-
.../lib/request}/build_es_request.js | 0
.../lib => common/lib/request}/filters.ts | 2 +-
.../lib/request}/format_response.js | 0
.../lib/request}/get_es_filter.ts | 2 +-
.../lib/request}/normalize_type.ts | 0
.../lib/request}/sanitize_name.ts | 0
.../canvas/i18n/functions/dict/escount.ts | 2 +-
.../canvas/i18n/functions/dict/esdocs.ts | 2 +-
.../canvas/i18n/functions/dict/essql.ts | 8 +-
x-pack/plugins/canvas/public/plugin.tsx | 3 +-
.../canvas/public/services/context.tsx | 2 +
.../canvas/public/services/expressions.ts | 14 +-
.../plugins/canvas/public/services/index.ts | 5 +
.../plugins/canvas/public/services/search.ts | 24 +++
.../canvas/public/services/stubs/index.ts | 2 +
.../canvas/public/services/stubs/search.ts | 11 ++
.../canvas/server/lib/essql_strategy.ts | 96 ++++++++++++
.../plugins/canvas/server/lib/query_es_sql.ts | 6 +-
x-pack/plugins/canvas/server/plugin.ts | 18 ++-
.../server/routes/es_fields/es_fields.ts | 2 +-
x-pack/plugins/canvas/types/index.ts | 1 +
x-pack/plugins/canvas/types/strategy.ts | 31 ++++
33 files changed, 603 insertions(+), 18 deletions(-)
create mode 100644 x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts
create mode 100644 x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts
create mode 100644 x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/build_bool_array.ts (92%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/build_es_request.js (100%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/filters.ts (98%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/format_response.js (100%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/get_es_filter.ts (93%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/normalize_type.ts (100%)
rename x-pack/plugins/canvas/{server/lib => common/lib/request}/sanitize_name.ts (100%)
create mode 100644 x-pack/plugins/canvas/public/services/search.ts
create mode 100644 x-pack/plugins/canvas/public/services/stubs/search.ts
create mode 100644 x-pack/plugins/canvas/server/lib/essql_strategy.ts
create mode 100644 x-pack/plugins/canvas/types/strategy.ts
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
index c5a2550723814..06d1cd290ffd5 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
@@ -440,4 +440,8 @@ export const stackManagementSchema: MakeSchemaFrom = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
+ 'labs:canvas:useDataService': {
+ type: 'boolean',
+ _meta: { description: 'Non-default value of setting.' },
+ },
};
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
index 4dc1773ecfbe2..dfbe6bd3e0485 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
@@ -119,5 +119,6 @@ export interface UsageStats {
'banners:textColor': string;
'banners:backgroundColor': string;
'labs:canvas:enable_ui': boolean;
+ 'labs:canvas:useDataService': boolean;
'labs:presentation:timeToPresent': boolean;
}
diff --git a/src/plugins/presentation_util/common/labs.ts b/src/plugins/presentation_util/common/labs.ts
index ce7855c516c8b..d551b733ecb8a 100644
--- a/src/plugins/presentation_util/common/labs.ts
+++ b/src/plugins/presentation_util/common/labs.ts
@@ -8,9 +8,10 @@
import { i18n } from '@kbn/i18n';
+export const USE_DATA_SERVICE = 'labs:canvas:useDataService';
export const TIME_TO_PRESENT = 'labs:presentation:timeToPresent';
-export const projectIDs = [TIME_TO_PRESENT] as const;
+export const projectIDs = [TIME_TO_PRESENT, USE_DATA_SERVICE] as const;
export const environmentNames = ['kibana', 'browser', 'session'] as const;
export const solutionNames = ['canvas', 'dashboard', 'presentation'] as const;
@@ -32,6 +33,22 @@ export const projects: { [ID in ProjectID]: ProjectConfig & { id: ID } } = {
}),
solutions: ['canvas'],
},
+ [USE_DATA_SERVICE]: {
+ id: USE_DATA_SERVICE,
+ isActive: true,
+ isDisplayed: true,
+ environments: ['kibana', 'browser', 'session'],
+ name: i18n.translate('presentationUtil.experiments.enableUseDataServiceExperimentName', {
+ defaultMessage: 'Use data service',
+ }),
+ description: i18n.translate(
+ 'presentationUtil.experiments.enableUseDataServiceExperimentDescription',
+ {
+ defaultMessage: 'An experiment of using the new data.search service for Canvas datasources',
+ }
+ ),
+ solutions: ['canvas'],
+ },
};
export type ProjectID = typeof projectIDs[number];
diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json
index 76460a57ee442..7cd66dc8eef30 100644
--- a/src/plugins/telemetry/schema/oss_plugins.json
+++ b/src/plugins/telemetry/schema/oss_plugins.json
@@ -8342,6 +8342,12 @@
"_meta": {
"description": "Non-default value of setting."
}
+ },
+ "labs:canvas:useDataService": {
+ "type": "boolean",
+ "_meta": {
+ "description": "Non-default value of setting."
+ }
}
}
},
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts
new file mode 100644
index 0000000000000..97aa934280414
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts
@@ -0,0 +1,94 @@
+/*
+ * 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 {
+ ExpressionFunctionDefinition,
+ ExpressionValueFilter,
+} from 'src/plugins/expressions/common';
+
+// @ts-expect-error untyped local
+import { buildESRequest } from '../../../common/lib/request/build_es_request';
+
+import { searchService } from '../../../public/services';
+
+import { getFunctionHelp } from '../../../i18n';
+
+interface Arguments {
+ index: string | null;
+ query: string;
+}
+
+export function escount(): ExpressionFunctionDefinition<
+ 'escount',
+ ExpressionValueFilter,
+ Arguments,
+ any
+> {
+ const { help, args: argHelp } = getFunctionHelp().escount;
+
+ return {
+ name: 'escount',
+ type: 'number',
+ context: {
+ types: ['filter'],
+ },
+ help,
+ args: {
+ query: {
+ types: ['string'],
+ aliases: ['_', 'q'],
+ help: argHelp.query,
+ default: '"-_index:.kibana"',
+ },
+ index: {
+ types: ['string'],
+ default: '_all',
+ help: argHelp.index,
+ },
+ },
+ fn: (input, args, handlers) => {
+ input.and = input.and.concat([
+ {
+ type: 'filter',
+ filterType: 'luceneQueryString',
+ query: args.query,
+ and: [],
+ },
+ ]);
+
+ const esRequest = buildESRequest(
+ {
+ index: args.index,
+ body: {
+ track_total_hits: true,
+ size: 0,
+ query: {
+ bool: {
+ must: [{ match_all: {} }],
+ },
+ },
+ },
+ },
+ input
+ );
+
+ const search = searchService.getService().search;
+ const req = {
+ params: {
+ ...esRequest,
+ },
+ };
+
+ return search
+ .search(req)
+ .toPromise()
+ .then((resp: any) => {
+ return resp.rawResponse.hits.total;
+ });
+ },
+ };
+}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts
new file mode 100644
index 0000000000000..c40e1ffd62439
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts
@@ -0,0 +1,141 @@
+/*
+ * 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 {
+ ExpressionFunctionDefinition,
+ ExpressionValueFilter,
+} from 'src/plugins/expressions/common';
+
+// @ts-expect-error untyped local
+import { buildESRequest } from '../../../common/lib/request/build_es_request';
+
+import { searchService } from '../../../public/services';
+import { ESSQL_SEARCH_STRATEGY } from '../../../common/lib/constants';
+import { EssqlSearchStrategyRequest, EssqlSearchStrategyResponse } from '../../../types';
+import { getFunctionHelp } from '../../../i18n';
+
+interface Arguments {
+ index: string;
+ query: string;
+ sort: string;
+ fields: string;
+ metaFields: string;
+ count: number;
+}
+
+export function esdocs(): ExpressionFunctionDefinition<
+ 'esdocs',
+ ExpressionValueFilter,
+ Arguments,
+ any
+> {
+ const { help, args: argHelp } = getFunctionHelp().esdocs;
+
+ return {
+ name: 'esdocs',
+ type: 'datatable',
+ context: {
+ types: ['filter'],
+ },
+ help,
+ args: {
+ query: {
+ types: ['string'],
+ aliases: ['_', 'q'],
+ help: argHelp.query,
+ default: '-_index:.kibana',
+ },
+ count: {
+ types: ['number'],
+ default: 1000,
+ help: argHelp.count,
+ },
+ fields: {
+ help: argHelp.fields,
+ types: ['string'],
+ },
+ index: {
+ types: ['string'],
+ default: '_all',
+ help: argHelp.index,
+ },
+ // TODO: This arg isn't being used in the function.
+ // We need to restore this functionality or remove it as an arg.
+ metaFields: {
+ help: argHelp.metaFields,
+ types: ['string'],
+ },
+ sort: {
+ types: ['string'],
+ help: argHelp.sort,
+ },
+ },
+ fn: async (input, args, handlers) => {
+ const { count, index, fields, sort } = args;
+
+ input.and = input.and.concat([
+ {
+ type: 'filter',
+ filterType: 'luceneQueryString',
+ query: args.query,
+ and: [],
+ },
+ ]);
+
+ // Load ad-hoc to avoid adding to the page load bundle size
+ const squel = await import('safe-squel');
+
+ let query = squel.select({
+ autoQuoteTableNames: true,
+ autoQuoteFieldNames: true,
+ autoQuoteAliasNames: true,
+ nameQuoteCharacter: '"',
+ });
+
+ if (index) {
+ query.from(index);
+ }
+
+ if (fields) {
+ const allFields = fields.split(',').map((field) => field.trim());
+ allFields.forEach((field) => (query = query.field(field)));
+ }
+
+ if (sort) {
+ const [sortField, sortOrder] = sort.split(',').map((str) => str.trim());
+ if (sortField) {
+ query.order(`"${sortField}"`, sortOrder === 'asc');
+ }
+ }
+
+ const search = searchService.getService().search;
+
+ const req = {
+ count,
+ query: query.toString(),
+ filter: input.and,
+ };
+
+ // We're requesting the data using the ESSQL strategy because
+ // the SQL routes return type information with the result set
+ return search
+ .search(req, {
+ strategy: ESSQL_SEARCH_STRATEGY,
+ })
+ .toPromise()
+ .then((resp: EssqlSearchStrategyResponse) => {
+ return {
+ type: 'datatable',
+ meta: {
+ type: 'essql',
+ },
+ ...resp,
+ };
+ });
+ },
+ };
+}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts
new file mode 100644
index 0000000000000..1339c93032ea9
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts
@@ -0,0 +1,103 @@
+/*
+ * 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 {
+ ExpressionFunctionDefinition,
+ ExpressionValueFilter,
+} from 'src/plugins/expressions/common';
+import { searchService } from '../../../public/services';
+import { ESSQL_SEARCH_STRATEGY } from '../../../common/lib/constants';
+import { EssqlSearchStrategyRequest, EssqlSearchStrategyResponse } from '../../../types';
+import { getFunctionHelp } from '../../../i18n';
+
+interface Arguments {
+ query: string;
+ parameter: Array;
+ count: number;
+ timezone: string;
+}
+
+export function essql(): ExpressionFunctionDefinition<
+ 'essql',
+ ExpressionValueFilter,
+ Arguments,
+ any
+> {
+ const { help, args: argHelp } = getFunctionHelp().essql;
+
+ return {
+ name: 'essql',
+ type: 'datatable',
+ context: {
+ types: ['filter'],
+ },
+ help,
+ args: {
+ query: {
+ aliases: ['_', 'q'],
+ types: ['string'],
+ help: argHelp.query,
+ },
+ parameter: {
+ aliases: ['param'],
+ types: ['string', 'number', 'boolean'],
+ multi: true,
+ help: argHelp.parameter,
+ },
+ count: {
+ types: ['number'],
+ help: argHelp.count,
+ default: 1000,
+ },
+ timezone: {
+ aliases: ['tz'],
+ types: ['string'],
+ default: 'UTC',
+ help: argHelp.timezone,
+ },
+ },
+ fn: (input, args, handlers) => {
+ const search = searchService.getService().search;
+ const { parameter, ...restOfArgs } = args;
+ const req = {
+ ...restOfArgs,
+ params: parameter,
+ filter: input.and,
+ };
+
+ return search
+ .search(req, {
+ strategy: ESSQL_SEARCH_STRATEGY,
+ })
+ .toPromise()
+ .then((resp: EssqlSearchStrategyResponse) => {
+ return {
+ type: 'datatable',
+ meta: {
+ type: 'essql',
+ },
+ ...resp,
+ };
+ })
+ .catch((e) => {
+ let message = `Unexpected error from Elasticsearch: ${e.message}`;
+ if (e.err) {
+ const { type, reason } = e.err.attributes;
+ if (type === 'parsing_exception') {
+ message = `Couldn't parse Elasticsearch SQL query. You may need to add double quotes to names containing special characters. Check your query and try again. Error: ${reason}`;
+ } else {
+ message = `Unexpected error from Elasticsearch: ${type} - ${reason}`;
+ }
+ }
+
+ // Re-write the error message before surfacing it up
+ e.message = message;
+ throw e;
+ });
+ },
+ };
+}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
index 6e7c43135f414..2cfdebafb70df 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
@@ -10,5 +10,17 @@ import { functions as externalFunctions } from '../external';
import { location } from './location';
import { markdown } from './markdown';
import { urlparam } from './urlparam';
+import { escount } from './escount';
+import { esdocs } from './esdocs';
+import { essql } from './essql';
-export const functions = [location, markdown, urlparam, ...commonFunctions, ...externalFunctions];
+export const functions = [
+ location,
+ markdown,
+ urlparam,
+ escount,
+ esdocs,
+ essql,
+ ...commonFunctions,
+ ...externalFunctions,
+];
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/escount.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/escount.ts
index 206e47413ae56..95f5ef446a470 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/escount.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/escount.ts
@@ -9,10 +9,9 @@ import {
ExpressionFunctionDefinition,
ExpressionValueFilter,
} from 'src/plugins/expressions/common';
-/* eslint-disable */
// @ts-expect-error untyped local
-import { buildESRequest } from '../../../server/lib/build_es_request';
-/* eslint-enable */
+import { buildESRequest } from '../../../common/lib/request/build_es_request';
+
import { getFunctionHelp } from '../../../i18n';
interface Arguments {
diff --git a/x-pack/plugins/canvas/common/lib/constants.ts b/x-pack/plugins/canvas/common/lib/constants.ts
index 697389fe2ce7c..2b916033ce557 100644
--- a/x-pack/plugins/canvas/common/lib/constants.ts
+++ b/x-pack/plugins/canvas/common/lib/constants.ts
@@ -44,3 +44,4 @@ export const API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD = `/public/canvas/${SHAREABLE_
export const CANVAS_EMBEDDABLE_CLASSNAME = `canvasEmbeddable`;
export const CONTEXT_MENU_TOP_BORDER_CLASSNAME = 'canvasContextMenu--topBorder';
export const API_ROUTE_FUNCTIONS = `${API_ROUTE}/fns`;
+export const ESSQL_SEARCH_STRATEGY = 'essql';
diff --git a/x-pack/plugins/canvas/server/lib/build_bool_array.ts b/x-pack/plugins/canvas/common/lib/request/build_bool_array.ts
similarity index 92%
rename from x-pack/plugins/canvas/server/lib/build_bool_array.ts
rename to x-pack/plugins/canvas/common/lib/request/build_bool_array.ts
index 826449ca6ad39..c0d630b4c405e 100644
--- a/x-pack/plugins/canvas/server/lib/build_bool_array.ts
+++ b/x-pack/plugins/canvas/common/lib/request/build_bool_array.ts
@@ -6,7 +6,7 @@
*/
import { getESFilter } from './get_es_filter';
-import { ExpressionValueFilter } from '../../types';
+import { ExpressionValueFilter } from '../../../types';
const compact = (arr: T[]) => (Array.isArray(arr) ? arr.filter((val) => Boolean(val)) : []);
diff --git a/x-pack/plugins/canvas/server/lib/build_es_request.js b/x-pack/plugins/canvas/common/lib/request/build_es_request.js
similarity index 100%
rename from x-pack/plugins/canvas/server/lib/build_es_request.js
rename to x-pack/plugins/canvas/common/lib/request/build_es_request.js
diff --git a/x-pack/plugins/canvas/server/lib/filters.ts b/x-pack/plugins/canvas/common/lib/request/filters.ts
similarity index 98%
rename from x-pack/plugins/canvas/server/lib/filters.ts
rename to x-pack/plugins/canvas/common/lib/request/filters.ts
index 8c6b485c4ccae..f1465fe48bdcf 100644
--- a/x-pack/plugins/canvas/server/lib/filters.ts
+++ b/x-pack/plugins/canvas/common/lib/request/filters.ts
@@ -11,7 +11,7 @@ import {
CanvasTimeFilter,
CanvasLuceneFilter,
CanvasExactlyFilter,
-} from '../../types';
+} from '../../../types';
/*
TODO: This could be pluggable
diff --git a/x-pack/plugins/canvas/server/lib/format_response.js b/x-pack/plugins/canvas/common/lib/request/format_response.js
similarity index 100%
rename from x-pack/plugins/canvas/server/lib/format_response.js
rename to x-pack/plugins/canvas/common/lib/request/format_response.js
diff --git a/x-pack/plugins/canvas/server/lib/get_es_filter.ts b/x-pack/plugins/canvas/common/lib/request/get_es_filter.ts
similarity index 93%
rename from x-pack/plugins/canvas/server/lib/get_es_filter.ts
rename to x-pack/plugins/canvas/common/lib/request/get_es_filter.ts
index 85335a4be06d7..353a793adcd17 100644
--- a/x-pack/plugins/canvas/server/lib/get_es_filter.ts
+++ b/x-pack/plugins/canvas/common/lib/request/get_es_filter.ts
@@ -12,7 +12,7 @@
*/
import { filters } from './filters';
-import { ExpressionValueFilter } from '../../types';
+import { ExpressionValueFilter } from '../../../types';
export function getESFilter(filter: ExpressionValueFilter) {
if (!filter.filterType || !filters[filter.filterType]) {
diff --git a/x-pack/plugins/canvas/server/lib/normalize_type.ts b/x-pack/plugins/canvas/common/lib/request/normalize_type.ts
similarity index 100%
rename from x-pack/plugins/canvas/server/lib/normalize_type.ts
rename to x-pack/plugins/canvas/common/lib/request/normalize_type.ts
diff --git a/x-pack/plugins/canvas/server/lib/sanitize_name.ts b/x-pack/plugins/canvas/common/lib/request/sanitize_name.ts
similarity index 100%
rename from x-pack/plugins/canvas/server/lib/sanitize_name.ts
rename to x-pack/plugins/canvas/common/lib/request/sanitize_name.ts
diff --git a/x-pack/plugins/canvas/i18n/functions/dict/escount.ts b/x-pack/plugins/canvas/i18n/functions/dict/escount.ts
index d88156ba32ce4..af1337360ba6d 100644
--- a/x-pack/plugins/canvas/i18n/functions/dict/escount.ts
+++ b/x-pack/plugins/canvas/i18n/functions/dict/escount.ts
@@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { escount } from '../../../canvas_plugin_src/functions/server/escount';
+import { escount } from '../../../canvas_plugin_src/functions/browser/escount';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';
import { ELASTICSEARCH, LUCENE } from '../../constants';
diff --git a/x-pack/plugins/canvas/i18n/functions/dict/esdocs.ts b/x-pack/plugins/canvas/i18n/functions/dict/esdocs.ts
index b78425de144ef..6be5acdb8bc90 100644
--- a/x-pack/plugins/canvas/i18n/functions/dict/esdocs.ts
+++ b/x-pack/plugins/canvas/i18n/functions/dict/esdocs.ts
@@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { esdocs } from '../../../canvas_plugin_src/functions/server/esdocs';
+import { esdocs } from '../../../canvas_plugin_src/functions/browser/esdocs';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';
import { ELASTICSEARCH, LUCENE } from '../../constants';
diff --git a/x-pack/plugins/canvas/i18n/functions/dict/essql.ts b/x-pack/plugins/canvas/i18n/functions/dict/essql.ts
index cfe848455dc3f..6304db945fc3f 100644
--- a/x-pack/plugins/canvas/i18n/functions/dict/essql.ts
+++ b/x-pack/plugins/canvas/i18n/functions/dict/essql.ts
@@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { essql } from '../../../canvas_plugin_src/functions/server/essql';
+import { essql } from '../../../canvas_plugin_src/functions/browser/essql';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';
import { ELASTICSEARCH, SQL, ISO8601, UTC } from '../../constants';
@@ -27,6 +27,12 @@ export const help: FunctionHelp> = {
SQL,
},
}),
+ parameter: i18n.translate('xpack.canvas.functions.essql.args.parameterHelpText', {
+ defaultMessage: 'A parameter to be passed to the {SQL} query.',
+ values: {
+ SQL,
+ },
+ }),
count: i18n.translate('xpack.canvas.functions.essql.args.countHelpText', {
defaultMessage:
'The number of documents to retrieve. For better performance, use a smaller data set.',
diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx
index 750b542116a75..d31a5a18cecc1 100644
--- a/x-pack/plugins/canvas/public/plugin.tsx
+++ b/x-pack/plugins/canvas/public/plugin.tsx
@@ -22,7 +22,7 @@ import { getSessionStorage } from './lib/storage';
import { SESSIONSTORAGE_LASTPATH } from '../common/lib/constants';
import { featureCatalogueEntry } from './feature_catalogue_entry';
import { ExpressionsSetup, ExpressionsStart } from '../../../../src/plugins/expressions/public';
-import { DataPublicPluginSetup } from '../../../../src/plugins/data/public';
+import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
import { UiActionsStart } from '../../../../src/plugins/ui_actions/public';
import { EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
@@ -54,6 +54,7 @@ export interface CanvasStartDeps {
inspector: InspectorStart;
uiActions: UiActionsStart;
charts: ChartsPluginStart;
+ data: DataPublicPluginStart;
presentationUtil: PresentationUtilPluginStart;
}
diff --git a/x-pack/plugins/canvas/public/services/context.tsx b/x-pack/plugins/canvas/public/services/context.tsx
index 4c18aa68fb51e..e078efe18b542 100644
--- a/x-pack/plugins/canvas/public/services/context.tsx
+++ b/x-pack/plugins/canvas/public/services/context.tsx
@@ -25,6 +25,7 @@ const defaultContextValue = {
notify: {},
platform: {},
navLink: {},
+ search: {},
};
const context = createContext(defaultContextValue as CanvasServices);
@@ -54,6 +55,7 @@ export const ServicesProvider: FC<{
notify: specifiedProviders.notify.getService(),
platform: specifiedProviders.platform.getService(),
navLink: specifiedProviders.navLink.getService(),
+ search: specifiedProviders.search.getService(),
reporting: specifiedProviders.reporting.getService(),
labs: specifiedProviders.labs.getService(),
};
diff --git a/x-pack/plugins/canvas/public/services/expressions.ts b/x-pack/plugins/canvas/public/services/expressions.ts
index 131919e1eefea..fd733862c4b67 100644
--- a/x-pack/plugins/canvas/public/services/expressions.ts
+++ b/x-pack/plugins/canvas/public/services/expressions.ts
@@ -24,6 +24,11 @@ export const expressionsServiceFactory: CanvasServiceFactory
const loadServerFunctionWrappers = async () => {
if (!cached) {
cached = (async () => {
+ const labService = startPlugins.presentationUtil.labsService;
+ const useDataSearchProject = labService.getProject('labs:canvas:useDataService');
+ const hasDataSearch = useDataSearchProject.status.isEnabled;
+ const dataSearchFns = ['essql', 'esdocs', 'escount'];
+
const serverFunctionList = await coreSetup.http.get(API_ROUTE_FUNCTIONS);
const batchedFunction = bfetch.batchedFunction({ url: API_ROUTE_FUNCTIONS });
const { serialize } = serializeProvider(expressions.getTypes());
@@ -32,9 +37,16 @@ export const expressionsServiceFactory: CanvasServiceFactory
// function that matches its definition, but which simply
// calls the server-side function endpoint.
Object.keys(serverFunctionList).forEach((functionName) => {
- if (expressions.getFunction(functionName)) {
+ // Allow function to be overwritten if we want to use
+ // the server-hosted essql, esdocs, and escount functions
+ if (dataSearchFns.includes(functionName)) {
+ if (hasDataSearch && expressions.getFunction(functionName)) {
+ return;
+ }
+ } else if (expressions.getFunction(functionName)) {
return;
}
+
const fn = () => ({
...serverFunctionList[functionName],
fn: (input: any, args: any) => {
diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts
index 1566d6f28085a..cbe7de43eff95 100644
--- a/x-pack/plugins/canvas/public/services/index.ts
+++ b/x-pack/plugins/canvas/public/services/index.ts
@@ -13,10 +13,12 @@ import { platformServiceFactory } from './platform';
import { navLinkServiceFactory } from './nav_link';
import { embeddablesServiceFactory } from './embeddables';
import { expressionsServiceFactory } from './expressions';
+import { searchServiceFactory } from './search';
import { labsServiceFactory } from './labs';
import { reportingServiceFactory } from './reporting';
export { NotifyService } from './notify';
+export { SearchService } from './search';
export { PlatformService } from './platform';
export { NavLinkService } from './nav_link';
export { EmbeddablesService } from './embeddables';
@@ -80,6 +82,7 @@ export const services = {
notify: new CanvasServiceProvider(notifyServiceFactory),
platform: new CanvasServiceProvider(platformServiceFactory),
navLink: new CanvasServiceProvider(navLinkServiceFactory),
+ search: new CanvasServiceProvider(searchServiceFactory),
reporting: new CanvasServiceProvider(reportingServiceFactory),
labs: new CanvasServiceProvider(labsServiceFactory),
};
@@ -92,6 +95,7 @@ export interface CanvasServices {
notify: ServiceFromProvider;
platform: ServiceFromProvider;
navLink: ServiceFromProvider;
+ search: ServiceFromProvider;
reporting: ServiceFromProvider;
labs: ServiceFromProvider;
}
@@ -120,5 +124,6 @@ export const {
platform: platformService,
navLink: navLinkService,
expressions: expressionsService,
+ search: searchService,
reporting: reportingService,
} = services;
diff --git a/x-pack/plugins/canvas/public/services/search.ts b/x-pack/plugins/canvas/public/services/search.ts
new file mode 100644
index 0000000000000..0fe5c89c77096
--- /dev/null
+++ b/x-pack/plugins/canvas/public/services/search.ts
@@ -0,0 +1,24 @@
+/*
+ * 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 { DataPublicPluginStart } from 'src/plugins/data/public';
+import { CanvasServiceFactory } from '.';
+
+export interface SearchService {
+ search: DataPublicPluginStart['search'];
+}
+
+export const searchServiceFactory: CanvasServiceFactory = (
+ setup,
+ start,
+ canvasSetup,
+ canvasStart
+) => {
+ return {
+ search: canvasStart.data.search,
+ };
+};
diff --git a/x-pack/plugins/canvas/public/services/stubs/index.ts b/x-pack/plugins/canvas/public/services/stubs/index.ts
index 786582ed94bd2..7246a34d7f491 100644
--- a/x-pack/plugins/canvas/public/services/stubs/index.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/index.ts
@@ -13,6 +13,7 @@ import { navLinkService } from './nav_link';
import { notifyService } from './notify';
import { labsService } from './labs';
import { platformService } from './platform';
+import { searchService } from './search';
export const stubs: CanvasServices = {
embeddables: embeddablesService,
@@ -21,6 +22,7 @@ export const stubs: CanvasServices = {
navLink: navLinkService,
notify: notifyService,
platform: platformService,
+ search: searchService,
labs: labsService,
};
diff --git a/x-pack/plugins/canvas/public/services/stubs/search.ts b/x-pack/plugins/canvas/public/services/stubs/search.ts
new file mode 100644
index 0000000000000..a4558a93e38a4
--- /dev/null
+++ b/x-pack/plugins/canvas/public/services/stubs/search.ts
@@ -0,0 +1,11 @@
+/*
+ * 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.
+ */
+const noop = (..._args: any[]): any => {};
+
+export const searchService: any = {
+ search: noop,
+};
diff --git a/x-pack/plugins/canvas/server/lib/essql_strategy.ts b/x-pack/plugins/canvas/server/lib/essql_strategy.ts
new file mode 100644
index 0000000000000..795b4fedaaaab
--- /dev/null
+++ b/x-pack/plugins/canvas/server/lib/essql_strategy.ts
@@ -0,0 +1,96 @@
+/*
+ * 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 { from } from 'rxjs';
+import { map, zipObject } from 'lodash';
+
+import { ISearchStrategy, PluginStart } from 'src/plugins/data/server';
+
+import { getKbnServerError } from '../../../../../src/plugins/kibana_utils/server';
+import { EssqlSearchStrategyRequest, EssqlSearchStrategyResponse } from '../../types';
+
+import { buildBoolArray } from '../../common/lib/request/build_bool_array';
+import { sanitizeName } from '../../common/lib/request/sanitize_name';
+import { normalizeType } from '../../common/lib/request/normalize_type';
+
+export const essqlSearchStrategyProvider = (
+ data: PluginStart
+): ISearchStrategy => {
+ return {
+ search: (request, options, { esClient }) => {
+ const { count, query, filter, timezone, params } = request;
+
+ const searchUntilEnd = async () => {
+ try {
+ let response = await esClient.asCurrentUser.sql.query({
+ format: 'json',
+ body: {
+ query,
+ // @ts-expect-error `params` missing from `QuerySqlRequest` type
+ params,
+ field_multi_value_leniency: true,
+ time_zone: timezone,
+ fetch_size: count,
+ client_id: 'canvas',
+ filter: {
+ bool: {
+ must: [{ match_all: {} }, ...buildBoolArray(filter)],
+ },
+ },
+ },
+ });
+
+ let body = response.body;
+
+ const columns = body.columns!.map(({ name, type }) => {
+ return {
+ id: sanitizeName(name),
+ name: sanitizeName(name),
+ meta: { type: normalizeType(type) },
+ };
+ });
+ const columnNames = map(columns, 'name');
+ let rows = body.rows.map((row) => zipObject(columnNames, row));
+
+ // If we still have rows to retrieve, continue requesting data
+ // using the cursor until we have everything
+ while (rows.length < count && body.cursor !== undefined) {
+ response = await esClient.asCurrentUser.sql.query({
+ format: 'json',
+ body: {
+ cursor: body.cursor,
+ },
+ });
+
+ body = response.body;
+
+ rows = [...rows, ...body.rows.map((row) => zipObject(columnNames, row))];
+ }
+
+ // If we used a cursor, clean it up
+ if (body.cursor !== undefined) {
+ await esClient.asCurrentUser.sql.clearCursor({
+ body: {
+ cursor: body.cursor,
+ },
+ });
+ }
+
+ return {
+ columns,
+ rows,
+ rawResponse: response,
+ };
+ } catch (e) {
+ throw getKbnServerError(e);
+ }
+ };
+
+ return from(searchUntilEnd());
+ },
+ };
+};
diff --git a/x-pack/plugins/canvas/server/lib/query_es_sql.ts b/x-pack/plugins/canvas/server/lib/query_es_sql.ts
index a315657dadd2b..2c4416094914d 100644
--- a/x-pack/plugins/canvas/server/lib/query_es_sql.ts
+++ b/x-pack/plugins/canvas/server/lib/query_es_sql.ts
@@ -6,9 +6,9 @@
*/
import { map, zipObject } from 'lodash';
-import { buildBoolArray } from './build_bool_array';
-import { sanitizeName } from './sanitize_name';
-import { normalizeType } from './normalize_type';
+import { buildBoolArray } from '../../common/lib/request/build_bool_array';
+import { sanitizeName } from '../../common/lib/request/sanitize_name';
+import { normalizeType } from '../../common/lib/request/normalize_type';
import { LegacyAPICaller } from '../../../../../src/core/server';
import { ExpressionValueFilter } from '../../types';
diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts
index 9360825830e56..9ccf3c251fecc 100644
--- a/x-pack/plugins/canvas/server/plugin.ts
+++ b/x-pack/plugins/canvas/server/plugin.ts
@@ -6,10 +6,15 @@
*/
import { CoreSetup, PluginInitializerContext, Plugin, Logger, CoreStart } from 'src/core/server';
+import {
+ PluginSetup as DataPluginSetup,
+ PluginStart as DataPluginStart,
+} from 'src/plugins/data/server';
import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
import { BfetchServerSetup } from 'src/plugins/bfetch/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { HomeServerPluginSetup } from 'src/plugins/home/server';
+import { ESSQL_SEARCH_STRATEGY } from '../common/lib/constants';
import { ReportingSetup } from '../../reporting/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import { getCanvasFeature } from './feature';
@@ -19,6 +24,7 @@ import { loadSampleData } from './sample_data';
import { setupInterpreter } from './setup_interpreter';
import { customElementType, workpadType, workpadTemplateType } from './saved_objects';
import { initializeTemplates } from './templates';
+import { essqlSearchStrategyProvider } from './lib/essql_strategy';
import { getUISettings } from './ui_settings';
interface PluginsSetup {
@@ -26,17 +32,22 @@ interface PluginsSetup {
features: FeaturesPluginSetup;
home: HomeServerPluginSetup;
bfetch: BfetchServerSetup;
+ data: DataPluginSetup;
reporting?: ReportingSetup;
usageCollection?: UsageCollectionSetup;
}
+interface PluginsStart {
+ data: DataPluginStart;
+}
+
export class CanvasPlugin implements Plugin {
private readonly logger: Logger;
constructor(public readonly initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}
- public setup(coreSetup: CoreSetup, plugins: PluginsSetup) {
+ public setup(coreSetup: CoreSetup, plugins: PluginsSetup) {
coreSetup.uiSettings.register(getUISettings());
coreSetup.savedObjects.registerType(customElementType);
coreSetup.savedObjects.registerType(workpadType);
@@ -64,6 +75,11 @@ export class CanvasPlugin implements Plugin {
registerCanvasUsageCollector(plugins.usageCollection, globalConfig.kibana.index);
setupInterpreter(plugins.expressions);
+
+ coreSetup.getStartServices().then(([_, depsStart]) => {
+ const strategy = essqlSearchStrategyProvider(depsStart.data);
+ plugins.data.search.registerSearchStrategy(ESSQL_SEARCH_STRATEGY, strategy);
+ });
}
public start(coreStart: CoreStart) {
diff --git a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts
index 7ceace8b84dbd..20a4775847c91 100644
--- a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts
+++ b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts
@@ -9,7 +9,7 @@ import { mapValues, keys } from 'lodash';
import { schema } from '@kbn/config-schema';
import { API_ROUTE } from '../../../common/lib';
import { catchErrorHandler } from '../catch_error_handler';
-import { normalizeType } from '../../lib/normalize_type';
+import { normalizeType } from '../../../common/lib/request/normalize_type';
import { RouteInitializerDeps } from '..';
const ESFieldsRequestSchema = schema.object({
diff --git a/x-pack/plugins/canvas/types/index.ts b/x-pack/plugins/canvas/types/index.ts
index 80314cab06258..09ae1510be6da 100644
--- a/x-pack/plugins/canvas/types/index.ts
+++ b/x-pack/plugins/canvas/types/index.ts
@@ -14,5 +14,6 @@ export * from './functions';
export * from './renderers';
export * from './shortcuts';
export * from './state';
+export * from './strategy';
export * from './style';
export * from './telemetry';
diff --git a/x-pack/plugins/canvas/types/strategy.ts b/x-pack/plugins/canvas/types/strategy.ts
new file mode 100644
index 0000000000000..1c94059f0c9ca
--- /dev/null
+++ b/x-pack/plugins/canvas/types/strategy.ts
@@ -0,0 +1,31 @@
+/*
+ * 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 { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
+import { QuerySqlResponse } from '@elastic/elasticsearch/api/types';
+import { IKibanaSearchRequest } from 'src/plugins/data/common';
+import { ExpressionValueFilter } from '.';
+export interface EssqlSearchStrategyRequest extends IKibanaSearchRequest {
+ count: number;
+ query: string;
+ params?: Array;
+ timezone?: string;
+ filter: ExpressionValueFilter[];
+}
+
+export interface EssqlSearchStrategyResponse {
+ columns: Array<{
+ id: string;
+ name: string;
+ meta: {
+ type: string;
+ };
+ }>;
+ rows: any[];
+
+ rawResponse: ApiResponse;
+}
From f404305eaa47013a8843ac74ddb5625e11432ebb Mon Sep 17 00:00:00 2001
From: Brian Seeders
Date: Mon, 3 May 2021 13:53:22 -0400
Subject: [PATCH 18/81] [CI] Create a ciGroup just for tests that use Docker
(#98535)
---
.ci/es-snapshots/Jenkinsfile_verify_es | 1 +
.ci/jobs.yml | 1 +
test/scripts/jenkins_xpack_build_kibana.sh | 15 ++++++++-
vars/kibanaPipeline.groovy | 31 +++++++++++++++++--
vars/tasks.groovy | 18 ++++++++++-
vars/workers.groovy | 2 ++
.../test/fleet_api_integration/apis/index.js | 2 +-
.../apps/endpoint/index.ts | 2 +-
.../apis/index.ts | 2 +-
9 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/.ci/es-snapshots/Jenkinsfile_verify_es b/.ci/es-snapshots/Jenkinsfile_verify_es
index b22406e389276..6f46650a2c635 100644
--- a/.ci/es-snapshots/Jenkinsfile_verify_es
+++ b/.ci/es-snapshots/Jenkinsfile_verify_es
@@ -44,6 +44,7 @@ kibanaPipeline(timeoutMinutes: 210) {
task {
kibanaPipeline.buildXpack(10)
tasks.xpackCiGroups()
+ tasks.xpackCiGroupDocker()
}
}
}
diff --git a/.ci/jobs.yml b/.ci/jobs.yml
index 6aa93d4a1056a..1440c6870a86d 100644
--- a/.ci/jobs.yml
+++ b/.ci/jobs.yml
@@ -33,6 +33,7 @@ JOB:
- x-pack-ciGroup11
- x-pack-ciGroup12
- x-pack-ciGroup13
+ - x-pack-ciGroupDocker
- x-pack-accessibility
- x-pack-visualRegression
diff --git a/test/scripts/jenkins_xpack_build_kibana.sh b/test/scripts/jenkins_xpack_build_kibana.sh
index 2887a51f26283..b5fd7492d7961 100755
--- a/test/scripts/jenkins_xpack_build_kibana.sh
+++ b/test/scripts/jenkins_xpack_build_kibana.sh
@@ -25,7 +25,8 @@ node scripts/functional_tests --assert-none-excluded \
--include-tag ciGroup10 \
--include-tag ciGroup11 \
--include-tag ciGroup12 \
- --include-tag ciGroup13
+ --include-tag ciGroup13 \
+ --include-tag ciGroupDocker
# Do not build kibana for code coverage run
if [[ -z "$CODE_COVERAGE" ]] ; then
@@ -42,7 +43,19 @@ if [[ -z "$CODE_COVERAGE" ]] ; then
installDir="$KIBANA_DIR/install/kibana"
mkdir -p "$installDir"
tar -xzf "$linuxBuild" -C "$installDir" --strip=1
+ cp "$linuxBuild" "$WORKSPACE/kibana-default.tar.gz"
mkdir -p "$WORKSPACE/kibana-build-xpack"
cp -pR install/kibana/. $WORKSPACE/kibana-build-xpack/
+
+ echo " -> Archive built plugins"
+ shopt -s globstar
+ tar -zcf \
+ "$WORKSPACE/kibana-default-plugins.tar.gz" \
+ x-pack/plugins/**/target/public \
+ x-pack/test/**/target/public \
+ examples/**/target/public \
+ x-pack/examples/**/target/public \
+ test/**/target/public
+ shopt -u globstar
fi
diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy
index 76ed71ebbf270..6cccdfaefecba 100644
--- a/vars/kibanaPipeline.groovy
+++ b/vars/kibanaPipeline.groovy
@@ -130,7 +130,7 @@ def functionalTestProcess(String name, String script) {
def ossCiGroupProcess(ciGroup, withDelay = false) {
return functionalTestProcess("ciGroup" + ciGroup) {
- if (withDelay) {
+ if (withDelay && !(ciGroup instanceof String) && !(ciGroup instanceof GString)) {
sleep((ciGroup-1)*30) // smooth out CPU spikes from ES startup
}
@@ -147,7 +147,7 @@ def ossCiGroupProcess(ciGroup, withDelay = false) {
def xpackCiGroupProcess(ciGroup, withDelay = false) {
return functionalTestProcess("xpack-ciGroup" + ciGroup) {
- if (withDelay) {
+ if (withDelay && !(ciGroup instanceof String) && !(ciGroup instanceof GString)) {
sleep((ciGroup-1)*30) // smooth out CPU spikes from ES startup
}
withEnv([
@@ -311,11 +311,36 @@ def buildOss(maxWorkers = '') {
}
}
-def buildXpack(maxWorkers = '') {
+def getBuildArtifactBucket() {
+ def dir = env.ghprbPullId ? "pr-${env.ghprbPullId}" : buildState.get('checkoutInfo').branch.replace("/", "__")
+ return "gs://ci-artifacts.kibana.dev/default-build/${dir}/${buildState.get('checkoutInfo').commit}"
+}
+
+def buildXpack(maxWorkers = '', uploadArtifacts = false) {
notifyOnError {
withEnv(["KBN_OPTIMIZER_MAX_WORKERS=${maxWorkers}"]) {
runbld("./test/scripts/jenkins_xpack_build_kibana.sh", "Build X-Pack Kibana")
}
+
+ if (uploadArtifacts) {
+ withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') {
+ bash("""
+ cd "${env.WORKSPACE}"
+ gsutil -q -m cp 'kibana-default.tar.gz' '${getBuildArtifactBucket()}/'
+ gsutil -q -m cp 'kibana-default-plugins.tar.gz' '${getBuildArtifactBucket()}/'
+ """, "Upload Default Build artifacts to GCS")
+ }
+ }
+ }
+}
+
+def downloadDefaultBuildArtifacts() {
+ withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') {
+ bash("""
+ cd "${env.WORKSPACE}"
+ gsutil -q -m cp '${getBuildArtifactBucket()}/kibana-default.tar.gz' ./
+ gsutil -q -m cp '${getBuildArtifactBucket()}/kibana-default-plugins.tar.gz' ./
+ """, "Download Default Build artifacts from GCS")
}
}
diff --git a/vars/tasks.groovy b/vars/tasks.groovy
index 7ed6de8094067..1d33fd1249681 100644
--- a/vars/tasks.groovy
+++ b/vars/tasks.groovy
@@ -49,6 +49,21 @@ def xpackCiGroups() {
tasks(ciGroups.collect { kibanaPipeline.xpackCiGroupProcess(it, true) })
}
+def xpackCiGroupDocker() {
+ task {
+ workers.ci(name: 'xpack-cigroups-docker', size: 'm', ramDisk: true) {
+ kibanaPipeline.downloadDefaultBuildArtifacts()
+ kibanaPipeline.bash("""
+ cd '${env.WORKSPACE}'
+ mkdir -p kibana-build-xpack
+ tar -xzf kibana-default.tar.gz -C kibana-build-xpack --strip=1
+ tar -xzf kibana-default-plugins.tar.gz -C kibana
+ """, "Extract Default Build artifacts")
+ kibanaPipeline.xpackCiGroupProcess('Docker', true)()
+ }
+ }
+}
+
def functionalOss(Map params = [:]) {
def config = params ?: [
serverIntegration: true,
@@ -100,10 +115,11 @@ def functionalXpack(Map params = [:]) {
]
task {
- kibanaPipeline.buildXpack(10)
+ kibanaPipeline.buildXpack(10, true)
if (config.ciGroups) {
xpackCiGroups()
+ xpackCiGroupDocker()
}
if (config.firefox) {
diff --git a/vars/workers.groovy b/vars/workers.groovy
index 83d439934cbfa..acd3fa51a3fe7 100644
--- a/vars/workers.groovy
+++ b/vars/workers.groovy
@@ -9,6 +9,8 @@ def label(size) {
return 'docker && linux && immutable'
case 's-highmem':
return 'docker && tests-s'
+ case 'm':
+ return 'docker && linux && immutable && gobld/machineType:n2-standard-8'
case 'm-highmem':
return 'docker && linux && immutable && gobld/machineType:n1-highmem-8'
case 'l':
diff --git a/x-pack/test/fleet_api_integration/apis/index.js b/x-pack/test/fleet_api_integration/apis/index.js
index 4d2bf1d74a495..503926960a2b7 100644
--- a/x-pack/test/fleet_api_integration/apis/index.js
+++ b/x-pack/test/fleet_api_integration/apis/index.js
@@ -7,7 +7,7 @@
export default function ({ loadTestFile }) {
describe('Fleet Endpoints', function () {
- this.tags('ciGroup10');
+ this.tags('ciGroupDocker');
// EPM
loadTestFile(require.resolve('./epm/index'));
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
index f28545f83a890..8639db45a23ee 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
@@ -16,7 +16,7 @@ export default function (providerContext: FtrProviderContext) {
const { loadTestFile, getService } = providerContext;
describe('endpoint', function () {
- this.tags('ciGroup7');
+ this.tags('ciGroupDocker');
const ingestManager = getService('ingestManager');
const log = getService('log');
diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts
index 9cf8a5e6e4c6d..d5f84e43f0807 100644
--- a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts
+++ b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts
@@ -15,7 +15,7 @@ export default function endpointAPIIntegrationTests(providerContext: FtrProvider
describe('Endpoint plugin', function () {
const ingestManager = getService('ingestManager');
- this.tags('ciGroup7');
+ this.tags('ciGroupDocker');
const log = getService('log');
if (!isRegistryEnabled()) {
From ad9f1c31550b0cc82a8422e234fe6628d311faa2 Mon Sep 17 00:00:00 2001
From: Jason Stoltzfus
Date: Mon, 3 May 2021 13:57:39 -0400
Subject: [PATCH 19/81] Fixed Search UI route (#99065)
---
.../server/routes/app_search/search_ui.test.ts | 2 +-
.../enterprise_search/server/routes/app_search/search_ui.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts
index 8ddb254a3cde1..ae308c8397536 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.test.ts
@@ -33,7 +33,7 @@ describe('reference application routes', () => {
});
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
- path: '/as/engines/:engineName/search_ui/field_config',
+ path: '/as/engines/:engineName/reference_application/field_config',
});
});
});
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.ts
index 160b1454c5f22..33684843b218a 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_ui.ts
@@ -23,7 +23,7 @@ export function registerSearchUIRoutes({
},
},
enterpriseSearchRequestHandler.createRequest({
- path: '/as/engines/:engineName/search_ui/field_config',
+ path: '/as/engines/:engineName/reference_application/field_config',
})
);
}
From 9acdfaaf6660cc41bb10f0b0cb5965a4bae1d169 Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Mon, 3 May 2021 12:29:57 -0700
Subject: [PATCH 20/81] Reintroduce 96111: Provide guidance of "Custom"
allocation behavior in ILM (#99007)
---
.../client_integration/app/app.helpers.tsx | 3 +-
.../edit_policy/edit_policy.helpers.tsx | 233 ++------
.../features/node_allocation.test.ts | 503 ------------------
.../cloud_aware_behavior.helpers.ts | 37 ++
.../cloud_aware_behavior.test.ts | 154 ++++++
.../node_allocation/cold_phase.helpers.ts | 25 +
.../node_allocation/cold_phase.test.ts | 226 ++++++++
.../general_behavior.helpers.ts | 26 +
.../node_allocation/general_behavior.test.ts | 128 +++++
.../node_allocation/warm_phase.helpers.ts | 25 +
.../node_allocation/warm_phase.test.ts | 214 ++++++++
.../edit_policy/init_test_bed.tsx | 55 ++
.../helpers/create_enable_phase_action.ts | 15 +
.../helpers/create_form_set_value_action.ts | 23 +
.../helpers/create_form_toggle_action.ts | 21 +
.../helpers/create_node_allocation_actions.ts | 83 +++
.../helpers/global_mocks.tsx | 34 ++
.../client_integration/helpers/index.ts | 27 +-
.../helpers/save_policy_action.ts | 19 +
.../helpers/set_replicas_action.ts | 21 +
.../client_integration/helpers/types.ts | 10 +
.../common/types/policies.ts | 2 +-
.../get_available_node_roles_for_phase.ts | 6 +-
.../components/data_tier_allocation.tsx | 16 +-
.../components/default_allocation_notice.tsx | 112 ----
.../components/default_allocation_warning.tsx | 72 ---
.../default_to_data_nodes_notice.tsx | 38 ++
.../default_to_data_tiers_notice.tsx | 60 +++
.../components/index.ts | 12 +-
.../no_custom_attributes_messages.tsx | 37 ++
.../components/no_node_attributes_warning.tsx | 60 ---
.../components/no_tiers_available_notice.tsx | 49 ++
...available_using_node_attributes_notice.tsx | 36 ++
.../components/node_allocation.tsx | 32 +-
.../node_role_to_fallback_tier_map.ts | 19 +
.../components/types.ts | 8 +-
.../will_use_fallback_tier_notice.tsx | 49 ++
...back_tier_using_node_attributes_notice.tsx | 47 ++
.../data_tier_allocation_field.tsx | 101 +++-
.../application/services/documentation.ts | 2 +
.../translations/translations/ja-JP.json | 13 -
.../translations/translations/zh-CN.json | 13 -
42 files changed, 1642 insertions(+), 1024 deletions(-)
delete mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation.test.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_enable_phase_action.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_set_value_action.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_toggle_action.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_node_allocation_actions.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/save_policy_action.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/set_replicas_action.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/types.ts
delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_allocation_notice.tsx
delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_allocation_warning.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_nodes_notice.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_tiers_notice.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_custom_attributes_messages.tsx
delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_node_attributes_warning.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_notice.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_using_node_attributes_notice.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_role_to_fallback_tier_map.ts
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_notice.tsx
create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_using_node_attributes_notice.tsx
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx
index 808d8ad238c3e..77b0372e24994 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx
@@ -12,7 +12,6 @@ import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_reac
import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock';
import { licensingMock } from '../../../../licensing/public/mocks';
import { App } from '../../../public/application/app';
-import { TestSubjects } from '../helpers';
const breadcrumbService = createBreadcrumbsMock();
@@ -37,7 +36,7 @@ const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({
const initTestBed = (initialEntries: string[]) =>
registerTestBed(AppWithContext, getTestBedConfig(initialEntries))();
-export interface AppTestBed extends TestBed {
+export interface AppTestBed extends TestBed {
actions: {
clickPolicyNameLink: () => void;
clickCreatePolicyButton: () => void;
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx
index 26ed0a7728d2f..67a978bb08471 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx
@@ -5,88 +5,23 @@
* 2.0.
*/
-import React from 'react';
import { act } from 'react-dom/test-utils';
+import { TestBedConfig } from '@kbn/test/jest';
-import { registerTestBed, TestBedConfig } from '@kbn/test/jest';
-
-import { licensingMock } from '../../../../licensing/public/mocks';
-
-import { EditPolicy } from '../../../public/application/sections/edit_policy';
-import { DataTierAllocationType } from '../../../public/application/sections/edit_policy/types';
-
-import { Phases as PolicyPhases } from '../../../common/types';
-
-import { KibanaContextProvider } from '../../../public/shared_imports';
import { AppServicesContext } from '../../../public/types';
-import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock';
-
-import { TestSubjects } from '../helpers';
-import { POLICY_NAME } from './constants';
-
-type Phases = keyof PolicyPhases;
-
-window.scrollTo = jest.fn();
-jest.mock('@elastic/eui', () => {
- const original = jest.requireActual('@elastic/eui');
-
- return {
- ...original,
- // Mocking EuiComboBox, as it utilizes "react-virtualized" for rendering search suggestions,
- // which does not produce a valid component wrapper
- EuiComboBox: (props: any) => (
- {
- props.onChange([syntheticEvent['0']]);
- }}
- />
- ),
- EuiIcon: 'eui-icon', // using custom react-svg icon causes issues, mocking for now.
- };
-});
-
-const getTestBedConfig = (testBedConfigArgs?: Partial): TestBedConfig => {
- return {
- memoryRouter: {
- initialEntries: [`/policies/edit/${POLICY_NAME}`],
- componentRoutePath: `/policies/edit/:policyName`,
- },
- defaultProps: {
- getUrlForApp: () => {},
- },
- ...testBedConfigArgs,
- };
-};
-
-const breadcrumbService = createBreadcrumbsMock();
-
-const MyComponent = ({ appServicesContext, ...rest }: any) => {
- return (
-
-
-
- );
-};
-
-const initTestBed = (arg?: {
- appServicesContext?: Partial;
- testBedConfig?: Partial;
-}) => {
- const { testBedConfig: testBedConfigArgs, ...rest } = arg || {};
- return registerTestBed(MyComponent, getTestBedConfig(testBedConfigArgs))(rest);
-};
+import {
+ Phase,
+ createEnablePhaseAction,
+ createNodeAllocationActions,
+ createFormToggleAction,
+ createFormSetValueAction,
+ setReplicas,
+ savePolicy,
+} from '../helpers';
+import { initTestBed } from './init_test_bed';
type SetupReturn = ReturnType;
-
export type EditPolicyTestBed = SetupReturn extends Promise ? U : SetupReturn;
export const setup = async (arg?: {
@@ -97,13 +32,6 @@ export const setup = async (arg?: {
const { find, component, form, exists } = testBed;
- const createFormToggleAction = (dataTestSubject: string) => async (checked: boolean) => {
- await act(async () => {
- form.toggleEuiSwitch(dataTestSubject, checked);
- });
- component.update();
- };
-
const createFormCheckboxAction = (dataTestSubject: string) => async (checked: boolean) => {
await act(async () => {
form.selectCheckBox(dataTestSubject, checked);
@@ -111,15 +39,6 @@ export const setup = async (arg?: {
component.update();
};
- function createFormSetValueAction(dataTestSubject: string) {
- return async (value: V) => {
- await act(async () => {
- form.setInputValue(dataTestSubject, value);
- });
- component.update();
- };
- }
-
const setWaitForSnapshotPolicy = async (snapshotPolicyName: string) => {
act(() => {
find('snapshotPolicyCombobox').simulate('change', [{ label: snapshotPolicyName }]);
@@ -127,16 +46,9 @@ export const setup = async (arg?: {
component.update();
};
- const savePolicy = async () => {
- await act(async () => {
- find('savePolicyButton').simulate('click');
- });
- component.update();
- };
-
- const toggleDefaultRollover = createFormToggleAction('useDefaultRolloverSwitch');
+ const toggleDefaultRollover = createFormToggleAction(testBed, 'useDefaultRolloverSwitch');
- const toggleRollover = createFormToggleAction('rolloverSwitch');
+ const toggleRollover = createFormToggleAction(testBed, 'rolloverSwitch');
const setMaxPrimaryShardSize = async (value: string, units?: string) => {
await act(async () => {
@@ -162,7 +74,7 @@ export const setup = async (arg?: {
component.update();
};
- const setMaxDocs = createFormSetValueAction('hot-selectedMaxDocuments');
+ const setMaxDocs = createFormSetValueAction(testBed, 'hot-selectedMaxDocuments');
const setMaxAge = async (value: string, units?: string) => {
await act(async () => {
@@ -174,69 +86,64 @@ export const setup = async (arg?: {
component.update();
};
- const createForceMergeActions = (phase: Phases) => {
+ const createForceMergeActions = (phase: Phase) => {
const toggleSelector = `${phase}-forceMergeSwitch`;
return {
forceMergeFieldExists: () => exists(toggleSelector),
- toggleForceMerge: createFormToggleAction(toggleSelector),
- setForcemergeSegmentsCount: createFormSetValueAction(`${phase}-selectedForceMergeSegments`),
+ toggleForceMerge: createFormToggleAction(testBed, toggleSelector),
+ setForcemergeSegmentsCount: createFormSetValueAction(
+ testBed,
+ `${phase}-selectedForceMergeSegments`
+ ),
setBestCompression: createFormCheckboxAction(`${phase}-bestCompression`),
};
};
- const createIndexPriorityActions = (phase: Phases) => {
+ const createIndexPriorityActions = (phase: Phase) => {
const toggleSelector = `${phase}-indexPrioritySwitch`;
return {
indexPriorityExists: () => exists(toggleSelector),
- toggleIndexPriority: createFormToggleAction(toggleSelector),
- setIndexPriority: createFormSetValueAction(`${phase}-indexPriority`),
+ toggleIndexPriority: createFormToggleAction(testBed, toggleSelector),
+ setIndexPriority: createFormSetValueAction(testBed, `${phase}-indexPriority`),
};
};
- const enable = (phase: Phases) => createFormToggleAction(`enablePhaseSwitch-${phase}`);
-
- const createMinAgeActions = (phase: Phases) => {
+ const createMinAgeActions = (phase: Phase) => {
return {
hasMinAgeInput: () => exists(`${phase}-selectedMinimumAge`),
- setMinAgeValue: createFormSetValueAction(`${phase}-selectedMinimumAge`),
- setMinAgeUnits: createFormSetValueAction(`${phase}-selectedMinimumAgeUnits`),
+ setMinAgeValue: createFormSetValueAction(testBed, `${phase}-selectedMinimumAge`),
+ setMinAgeUnits: createFormSetValueAction(testBed, `${phase}-selectedMinimumAgeUnits`),
hasRolloverTipOnMinAge: () => exists(`${phase}-rolloverMinAgeInputIconTip`),
};
};
- const setReplicas = (phase: Phases) => async (value: string) => {
- if (!exists(`${phase}-selectedReplicaCount`)) {
- await createFormToggleAction(`${phase}-setReplicasSwitch`)(true);
- }
- await createFormSetValueAction(`${phase}-selectedReplicaCount`)(value);
- };
-
- const createShrinkActions = (phase: Phases) => {
+ const createShrinkActions = (phase: Phase) => {
const toggleSelector = `${phase}-shrinkSwitch`;
return {
shrinkExists: () => exists(toggleSelector),
- toggleShrink: createFormToggleAction(toggleSelector),
- setShrink: createFormSetValueAction(`${phase}-primaryShardCount`),
+ toggleShrink: createFormToggleAction(testBed, toggleSelector),
+ setShrink: createFormSetValueAction(testBed, `${phase}-primaryShardCount`),
};
};
- const createSetFreeze = (phase: Phases) => createFormToggleAction(`${phase}-freezeSwitch`);
- const createFreezeExists = (phase: Phases) => () => exists(`${phase}-freezeSwitch`);
+ const createSetFreeze = (phase: Phase) =>
+ createFormToggleAction(testBed, `${phase}-freezeSwitch`);
+ const createFreezeExists = (phase: Phase) => () => exists(`${phase}-freezeSwitch`);
- const createReadonlyActions = (phase: Phases) => {
+ const createReadonlyActions = (phase: Phase) => {
const toggleSelector = `${phase}-readonlySwitch`;
return {
readonlyExists: () => exists(toggleSelector),
- toggleReadonly: createFormToggleAction(toggleSelector),
+ toggleReadonly: createFormToggleAction(testBed, toggleSelector),
};
};
- const createSearchableSnapshotActions = (phase: Phases) => {
+ const createSearchableSnapshotActions = (phase: Phase) => {
const fieldSelector = `searchableSnapshotField-${phase}`;
const licenseCalloutSelector = `${fieldSelector}.searchableSnapshotDisabledDueToLicense`;
const toggleSelector = `${fieldSelector}.searchableSnapshotToggle`;
- const toggleSearchableSnapshot = createFormToggleAction(toggleSelector);
+ const toggleSearchableSnapshot = createFormToggleAction(testBed, toggleSelector);
return {
searchableSnapshotDisabled: () =>
exists(licenseCalloutSelector) && find(licenseCalloutSelector).props().disabled === true,
@@ -269,54 +176,6 @@ export const setup = async (arg?: {
const hasRolloverSettingRequiredCallout = (): boolean => exists('rolloverSettingsRequired');
- const createNodeAllocationActions = (phase: Phases) => {
- const controlsSelector = `${phase}-dataTierAllocationControls`;
- const dataTierSelector = `${controlsSelector}.dataTierSelect`;
- const nodeAttrsSelector = `${phase}-selectedNodeAttrs`;
-
- const openNodeAttributesSection = async () => {
- await act(async () => {
- find(dataTierSelector).simulate('click');
- });
- component.update();
- };
-
- return {
- hasDataTierAllocationControls: () => exists(controlsSelector),
- openNodeAttributesSection,
- hasNodeAttributesSelect: (): boolean => exists(nodeAttrsSelector),
- getNodeAttributesSelectOptions: () => find(nodeAttrsSelector).find('option'),
- setDataAllocation: async (value: DataTierAllocationType) => {
- await openNodeAttributesSection();
-
- await act(async () => {
- switch (value) {
- case 'node_roles':
- find(`${controlsSelector}.defaultDataAllocationOption`).simulate('click');
- break;
- case 'node_attrs':
- find(`${controlsSelector}.customDataAllocationOption`).simulate('click');
- break;
- default:
- find(`${controlsSelector}.noneDataAllocationOption`).simulate('click');
- }
- });
- component.update();
- },
- setSelectedNodeAttribute: createFormSetValueAction(nodeAttrsSelector),
- hasNoNodeAttrsWarning: () => exists('noNodeAttributesWarning'),
- hasDefaultAllocationWarning: () => exists('defaultAllocationWarning'),
- hasDefaultAllocationNotice: () => exists('defaultAllocationNotice'),
- hasNodeDetailsFlyout: () => exists(`${phase}-viewNodeDetailsFlyoutButton`),
- openNodeDetailsFlyout: async () => {
- await act(async () => {
- find(`${phase}-viewNodeDetailsFlyoutButton`).simulate('click');
- });
- component.update();
- },
- };
- };
-
const expectErrorMessages = (expectedMessages: string[]) => {
const errorMessages = component.find('.euiFormErrorText');
expect(errorMessages.length).toBe(expectedMessages.length);
@@ -346,10 +205,10 @@ export const setup = async (arg?: {
...testBed,
runTimers,
actions: {
- saveAsNewPolicy: createFormToggleAction('saveAsNewSwitch'),
- setPolicyName: createFormSetValueAction('policyNameField'),
+ saveAsNewPolicy: createFormToggleAction(testBed, 'saveAsNewSwitch'),
+ setPolicyName: createFormSetValueAction(testBed, 'policyNameField'),
setWaitForSnapshotPolicy,
- savePolicy,
+ savePolicy: () => savePolicy(testBed),
hasGlobalErrorCallout: () => exists('policyFormErrorsCallout'),
expectErrorMessages,
timeline: {
@@ -375,30 +234,30 @@ export const setup = async (arg?: {
...createSearchableSnapshotActions('hot'),
},
warm: {
- enable: enable('warm'),
+ enable: createEnablePhaseAction(testBed, 'warm'),
...createMinAgeActions('warm'),
- setReplicas: setReplicas('warm'),
+ setReplicas: (value: string) => setReplicas(testBed, 'warm', value),
hasErrorIndicator: () => exists('phaseErrorIndicator-warm'),
...createShrinkActions('warm'),
...createForceMergeActions('warm'),
...createReadonlyActions('warm'),
...createIndexPriorityActions('warm'),
- ...createNodeAllocationActions('warm'),
+ ...createNodeAllocationActions(testBed, 'warm'),
},
cold: {
- enable: enable('cold'),
+ enable: createEnablePhaseAction(testBed, 'cold'),
...createMinAgeActions('cold'),
- setReplicas: setReplicas('cold'),
+ setReplicas: (value: string) => setReplicas(testBed, 'cold', value),
setFreeze: createSetFreeze('cold'),
freezeExists: createFreezeExists('cold'),
...createReadonlyActions('cold'),
hasErrorIndicator: () => exists('phaseErrorIndicator-cold'),
...createIndexPriorityActions('cold'),
...createSearchableSnapshotActions('cold'),
- ...createNodeAllocationActions('cold'),
+ ...createNodeAllocationActions(testBed, 'cold'),
},
frozen: {
- enable: enable('frozen'),
+ enable: createEnablePhaseAction(testBed, 'frozen'),
...createMinAgeActions('frozen'),
hasErrorIndicator: () => exists('phaseErrorIndicator-frozen'),
...createSearchableSnapshotActions('frozen'),
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation.test.ts
deleted file mode 100644
index e289991780c04..0000000000000
--- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation.test.ts
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * 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 { act } from 'react-dom/test-utils';
-import { setupEnvironment } from '../../helpers/setup_environment';
-import { EditPolicyTestBed, setup } from '../edit_policy.helpers';
-import {
- POLICY_WITH_MIGRATE_OFF,
- POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION,
- POLICY_WITH_NODE_ROLE_ALLOCATION,
-} from '../constants';
-
-describe(' node allocation', () => {
- let testBed: EditPolicyTestBed;
- const { server, httpRequestsMockHelpers } = setupEnvironment();
-
- beforeAll(() => {
- jest.useFakeTimers();
- });
-
- afterAll(() => {
- jest.useRealTimers();
- server.restore();
- });
-
- beforeEach(async () => {
- server.respondImmediately = true;
- httpRequestsMockHelpers.setLoadPolicies([]);
- httpRequestsMockHelpers.setListNodes({
- nodesByRoles: { data: ['node1'] },
- nodesByAttributes: { 'attribute:true': ['node1'] },
- isUsingDeprecatedDataRoleConfig: true,
- });
- httpRequestsMockHelpers.setNodesDetails('attribute:true', [
- { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } },
- ]);
-
- await act(async () => {
- testBed = await setup();
- });
-
- const { component } = testBed;
- component.update();
- });
-
- describe('warm phase', () => {
- test('shows spinner for node attributes input when loading', async () => {
- server.respondImmediately = false;
-
- const { actions, component } = testBed;
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeTruthy();
- expect(actions.warm.hasDataTierAllocationControls()).toBeTruthy();
-
- expect(component.find('.euiCallOut--warning').exists()).toBeFalsy();
- expect(actions.warm.hasNodeAttributesSelect()).toBeFalsy();
- });
-
- test('shows warning instead of node attributes input when none exist', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: { data: ['node1'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
-
- await actions.warm.setDataAllocation('node_attrs');
- expect(actions.warm.hasNoNodeAttrsWarning()).toBeTruthy();
- expect(actions.warm.hasNodeAttributesSelect()).toBeFalsy();
- });
-
- test('shows node attributes input when attributes exist', async () => {
- const { actions, component } = testBed;
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- await actions.warm.setDataAllocation('node_attrs');
- expect(actions.warm.hasNoNodeAttrsWarning()).toBeFalsy();
- expect(actions.warm.hasNodeAttributesSelect()).toBeTruthy();
- expect(actions.warm.getNodeAttributesSelectOptions().length).toBe(2);
- });
-
- test('shows view node attributes link when attribute selected and shows flyout when clicked', async () => {
- const { actions, component } = testBed;
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- await actions.warm.setDataAllocation('node_attrs');
- expect(actions.warm.hasNoNodeAttrsWarning()).toBeFalsy();
- expect(actions.warm.hasNodeAttributesSelect()).toBeTruthy();
-
- expect(actions.warm.hasNodeDetailsFlyout()).toBeFalsy();
- expect(actions.warm.getNodeAttributesSelectOptions().length).toBe(2);
- await actions.warm.setSelectedNodeAttribute('attribute:true');
-
- await actions.warm.openNodeDetailsFlyout();
- expect(actions.warm.hasNodeDetailsFlyout()).toBeTruthy();
- });
-
- test('shows default allocation warning when no node roles are found', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: {},
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.warm.hasDefaultAllocationWarning()).toBeTruthy();
- });
-
- test('when configuring warm phase shows default allocation notice when hot tier exists, but not warm tier', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: { data_hot: ['test'], data_cold: ['test'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.warm.hasDefaultAllocationNotice()).toBeTruthy();
- });
-
- test(`doesn't show default allocation notice when node with "data" role exists`, async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: { data: ['test'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.warm.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.warm.hasDefaultAllocationNotice()).toBeFalsy();
- });
- });
-
- describe('cold phase', () => {
- test('shows spinner for node attributes input when loading', async () => {
- server.respondImmediately = false;
-
- const { actions, component } = testBed;
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeTruthy();
- expect(actions.cold.hasDataTierAllocationControls()).toBeTruthy();
-
- expect(component.find('.euiCallOut--warning').exists()).toBeFalsy();
- expect(actions.cold.hasNodeAttributesSelect()).toBeFalsy();
- });
-
- test('shows warning instead of node attributes input when none exist', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: { data: ['node1'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- await actions.cold.setDataAllocation('node_attrs');
- expect(actions.cold.hasNoNodeAttrsWarning()).toBeTruthy();
- expect(actions.cold.hasNodeAttributesSelect()).toBeFalsy();
- });
-
- test('shows node attributes input when attributes exist', async () => {
- const { actions, component } = testBed;
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- await actions.cold.setDataAllocation('node_attrs');
- expect(actions.cold.hasNoNodeAttrsWarning()).toBeFalsy();
- expect(actions.cold.hasNodeAttributesSelect()).toBeTruthy();
- expect(actions.cold.getNodeAttributesSelectOptions().length).toBe(2);
- });
-
- test('shows view node attributes link when attribute selected and shows flyout when clicked', async () => {
- const { actions, component } = testBed;
-
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- await actions.cold.setDataAllocation('node_attrs');
- expect(actions.cold.hasNoNodeAttrsWarning()).toBeFalsy();
- expect(actions.cold.hasNodeAttributesSelect()).toBeTruthy();
-
- expect(actions.cold.hasNodeDetailsFlyout()).toBeFalsy();
- expect(actions.cold.getNodeAttributesSelectOptions().length).toBe(2);
- await actions.cold.setSelectedNodeAttribute('attribute:true');
-
- await actions.cold.openNodeDetailsFlyout();
- expect(actions.cold.hasNodeDetailsFlyout()).toBeTruthy();
- });
-
- test('shows default allocation warning when no node roles are found', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: {},
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.cold.hasDefaultAllocationWarning()).toBeTruthy();
- });
-
- [
- {
- nodesByRoles: { data_hot: ['test'] },
- previousActiveRole: 'hot',
- },
- {
- nodesByRoles: { data_hot: ['test'], data_warm: ['test'] },
- previousActiveRole: 'warm',
- },
- ].forEach(({ nodesByRoles, previousActiveRole }) => {
- test(`shows default allocation notice when ${previousActiveRole} tiers exists, but not cold tier`, async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles,
- isUsingDeprecatedDataRoleConfig: false,
- });
-
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component, find } = testBed;
-
- component.update();
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.cold.hasDefaultAllocationNotice()).toBeTruthy();
- expect(find('defaultAllocationNotice').text()).toContain(
- `This policy will move data in the cold phase to ${previousActiveRole} tier nodes`
- );
- });
- });
-
- test(`doesn't show default allocation notice when node with "data" role exists`, async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: {},
- nodesByRoles: { data: ['test'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component } = testBed;
-
- component.update();
- await actions.cold.enable(true);
-
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
- expect(actions.cold.hasDefaultAllocationNotice()).toBeFalsy();
- });
- });
-
- describe('not on cloud', () => {
- test('shows all allocation options, even if using legacy config', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: { test: ['123'] },
- nodesByRoles: { data: ['test'], data_hot: ['test'], data_warm: ['test'] },
- isUsingDeprecatedDataRoleConfig: true,
- });
- await act(async () => {
- testBed = await setup();
- });
- const { actions, component, exists } = testBed;
-
- component.update();
- await actions.warm.enable(true);
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
-
- // Assert that default, custom and 'none' options exist
- await actions.warm.openNodeAttributesSection();
- expect(exists('defaultDataAllocationOption')).toBeTruthy();
- expect(exists('customDataAllocationOption')).toBeTruthy();
- expect(exists('noneDataAllocationOption')).toBeTruthy();
- });
- });
-
- describe('on cloud', () => {
- describe('using legacy data role config', () => {
- test('should hide data tier option on cloud', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: { test: ['123'] },
- // On cloud, if using legacy config there will not be any "data_*" roles set.
- nodesByRoles: { data: ['test'] },
- isUsingDeprecatedDataRoleConfig: true,
- });
- await act(async () => {
- testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } });
- });
- const { actions, component, exists, find } = testBed;
-
- component.update();
- await actions.warm.enable(true);
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
-
- // Assert that custom and 'none' options exist
- await actions.warm.openNodeAttributesSection();
- expect(exists('defaultDataAllocationOption')).toBeFalsy();
- expect(exists('customDataAllocationOption')).toBeTruthy();
- expect(exists('noneDataAllocationOption')).toBeTruthy();
- // Show the call-to-action for users to migrate their cluster to use node roles
- expect(find('cloudDataTierCallout').exists()).toBeTruthy();
- });
- });
-
- describe('using node role config', () => {
- test('shows recommended, custom and "off" options on cloud with data roles', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: { test: ['123'] },
- nodesByRoles: { data: ['test'], data_hot: ['test'], data_warm: ['test'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
- await act(async () => {
- testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } });
- });
- testBed.component.update();
-
- const { actions, component, exists, find } = testBed;
- await actions.warm.enable(true);
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
-
- await actions.warm.openNodeAttributesSection();
- expect(exists('defaultDataAllocationOption')).toBeTruthy();
- expect(exists('customDataAllocationOption')).toBeTruthy();
- expect(exists('noneDataAllocationOption')).toBeTruthy();
- // Do not show the call-to-action for users to migrate their cluster to use node roles
- expect(find('cloudDataTierCallout').exists()).toBeFalsy();
- });
- test('do not show node allocation specific warnings on cloud', async () => {
- httpRequestsMockHelpers.setListNodes({
- nodesByAttributes: { test: ['123'] },
- // No nodes with node roles like "data_hot" or "data_warm"
- nodesByRoles: {},
- isUsingDeprecatedDataRoleConfig: false,
- });
- await act(async () => {
- testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } });
- });
- testBed.component.update();
-
- const { actions, component, exists } = testBed;
- await actions.warm.enable(true);
- await actions.cold.enable(true);
- expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
-
- expect(exists('cloudDataTierCallout')).toBeFalsy();
- expect(exists('defaultAllocationNotice')).toBeFalsy();
- expect(exists('defaultAllocationWarning')).toBeFalsy();
- });
- });
- });
-
- describe('data allocation', () => {
- beforeEach(async () => {
- httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_MIGRATE_OFF]);
- httpRequestsMockHelpers.setListNodes({
- nodesByRoles: {},
- nodesByAttributes: { test: ['123'] },
- isUsingDeprecatedDataRoleConfig: false,
- });
- httpRequestsMockHelpers.setLoadSnapshotPolicies([]);
-
- await act(async () => {
- testBed = await setup();
- });
-
- const { component } = testBed;
- component.update();
- });
-
- test('setting node_attr based allocation, but not selecting node attribute', async () => {
- const { actions } = testBed;
- await actions.warm.setDataAllocation('node_attrs');
- await actions.savePolicy();
- const latestRequest = server.requests[server.requests.length - 1];
- const warmPhase = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm;
-
- expect(warmPhase.actions.migrate).toEqual({ enabled: false });
- });
-
- describe('node roles', () => {
- beforeEach(async () => {
- httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_NODE_ROLE_ALLOCATION]);
- httpRequestsMockHelpers.setListNodes({
- isUsingDeprecatedDataRoleConfig: false,
- nodesByAttributes: { test: ['123'] },
- nodesByRoles: { data: ['123'] },
- });
-
- await act(async () => {
- testBed = await setup();
- });
-
- const { component } = testBed;
- component.update();
- });
-
- test('detecting use of the recommended allocation type', () => {
- const { find } = testBed;
- const selectedDataAllocation = find(
- 'warm-dataTierAllocationControls.dataTierSelect'
- ).text();
- expect(selectedDataAllocation).toBe('Use warm nodes (recommended)');
- });
-
- test('setting replicas serialization', async () => {
- const { actions } = testBed;
- await actions.warm.setReplicas('123');
- await actions.savePolicy();
- const latestRequest = server.requests[server.requests.length - 1];
- const warmPhaseActions = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm
- .actions;
- expect(warmPhaseActions).toMatchInlineSnapshot(`
- Object {
- "allocate": Object {
- "number_of_replicas": 123,
- },
- }
- `);
- });
- });
-
- describe('node attr and none', () => {
- beforeEach(async () => {
- httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION]);
- httpRequestsMockHelpers.setListNodes({
- isUsingDeprecatedDataRoleConfig: false,
- nodesByAttributes: { test: ['123'] },
- nodesByRoles: { data: ['123'] },
- });
-
- await act(async () => {
- testBed = await setup();
- });
-
- const { component } = testBed;
- component.update();
- });
-
- test('detecting use of the custom allocation type', () => {
- const { find } = testBed;
- expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).toBe('Custom');
- });
-
- test('detecting use of the "off" allocation type', () => {
- const { find } = testBed;
- expect(find('cold-dataTierAllocationControls.dataTierSelect').text()).toContain('Off');
- });
- });
- });
-});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts
new file mode 100644
index 0000000000000..ba376f9cddd93
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { TestBedConfig } from '@kbn/test/jest';
+
+import { AppServicesContext } from '../../../../../public/types';
+import { createEnablePhaseAction, createNodeAllocationActions } from '../../../helpers';
+import { initTestBed } from '../../init_test_bed';
+
+type SetupReturn = ReturnType;
+
+export type CloudNodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn;
+
+export const setupCloudNodeAllocation = async (arg?: {
+ appServicesContext?: Partial;
+ testBedConfig?: Partial;
+}) => {
+ const testBed = await initTestBed(arg);
+
+ return {
+ ...testBed,
+ actions: {
+ warm: {
+ enable: createEnablePhaseAction(testBed, 'warm'),
+ ...createNodeAllocationActions(testBed, 'warm'),
+ },
+ cold: {
+ enable: createEnablePhaseAction(testBed, 'cold'),
+ ...createNodeAllocationActions(testBed, 'cold'),
+ },
+ },
+ };
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts
new file mode 100644
index 0000000000000..06b667f666808
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.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.
+ */
+
+import { act } from 'react-dom/test-utils';
+import { setupEnvironment } from '../../../helpers/setup_environment';
+import {
+ CloudNodeAllocationTestBed,
+ setupCloudNodeAllocation,
+} from './cloud_aware_behavior.helpers';
+
+describe(' node allocation cloud-aware behavior', () => {
+ let testBed: CloudNodeAllocationTestBed;
+ const { server, httpRequestsMockHelpers } = setupEnvironment();
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ server.restore();
+ });
+
+ const setup = async (isOnCloud?: boolean) => {
+ await act(async () => {
+ if (Boolean(isOnCloud)) {
+ testBed = await setupCloudNodeAllocation({
+ appServicesContext: { cloud: { isCloudEnabled: true } },
+ });
+ } else {
+ testBed = await setupCloudNodeAllocation();
+ }
+ });
+ };
+
+ beforeEach(async () => {
+ server.respondImmediately = true;
+ httpRequestsMockHelpers.setLoadPolicies([]);
+ httpRequestsMockHelpers.setListNodes({
+ nodesByRoles: { data: ['node1'] },
+ nodesByAttributes: { 'attribute:true': ['node1'] },
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+ httpRequestsMockHelpers.setNodesDetails('attribute:true', [
+ { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } },
+ ]);
+
+ await setup();
+
+ const { component } = testBed;
+ component.update();
+ });
+
+ describe('when not on cloud', () => {
+ test('shows all allocation options, even if using legacy config', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: { test: ['123'] },
+ nodesByRoles: { data: ['test'], data_hot: ['test'], data_warm: ['test'] },
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+
+ await setup();
+ const { actions, component, exists } = testBed;
+
+ component.update();
+ await actions.warm.enable(true);
+ expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
+
+ // Assert that default, custom and 'none' options exist
+ await actions.warm.openNodeAttributesSection();
+ expect(exists('defaultDataAllocationOption')).toBeTruthy();
+ expect(exists('customDataAllocationOption')).toBeTruthy();
+ expect(exists('noneDataAllocationOption')).toBeTruthy();
+ });
+ });
+
+ describe('when on cloud', () => {
+ describe('using legacy data role config', () => {
+ test('should hide data tier option on cloud', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: { test: ['123'] },
+ // On cloud, if using legacy config there will not be any "data_*" roles set.
+ nodesByRoles: { data: ['test'] },
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+ await setup(true);
+ const { actions, component, exists, find } = testBed;
+
+ component.update();
+ await actions.warm.enable(true);
+ expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
+
+ // Assert that custom and 'none' options exist
+ await actions.warm.openNodeAttributesSection();
+ expect(exists('defaultDataAllocationOption')).toBeFalsy();
+ expect(exists('customDataAllocationOption')).toBeTruthy();
+ expect(exists('noneDataAllocationOption')).toBeTruthy();
+ // Show the call-to-action for users to migrate their cluster to use node roles
+ expect(find('cloudDataTierCallout').exists()).toBeTruthy();
+ });
+ });
+
+ describe('using node role config', () => {
+ test('shows recommended, custom and "off" options on cloud with data roles', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: { test: ['123'] },
+ nodesByRoles: { data: ['test'], data_hot: ['test'], data_warm: ['test'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+ await setup(true);
+ testBed.component.update();
+
+ const { actions, component, exists, find } = testBed;
+ await actions.warm.enable(true);
+ expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
+
+ await actions.warm.openNodeAttributesSection();
+ expect(exists('defaultDataAllocationOption')).toBeTruthy();
+ expect(exists('customDataAllocationOption')).toBeTruthy();
+ expect(exists('noneDataAllocationOption')).toBeTruthy();
+ // Do not show the call-to-action for users to migrate their cluster to use node roles
+ expect(find('cloudDataTierCallout').exists()).toBeFalsy();
+ });
+
+ test('do not show node allocation specific warnings on cloud', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: { test: ['123'] },
+ // No nodes with node roles like "data_hot" or "data_warm"
+ nodesByRoles: {},
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+ await setup(true);
+ testBed.component.update();
+
+ const { actions, component, exists } = testBed;
+ await actions.warm.enable(true);
+ await actions.cold.enable(true);
+ expect(component.find('.euiLoadingSpinner').exists()).toBeFalsy();
+
+ expect(exists('cloudDataTierCallout')).toBeFalsy();
+ expect(
+ actions.warm.hasWillUseFallbackTierNotice() || actions.cold.hasWillUseFallbackTierNotice()
+ ).toBeFalsy();
+ expect(
+ actions.warm.hasNoTiersAvailableNotice() || actions.cold.hasNoTiersAvailableNotice()
+ ).toBeFalsy();
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts
new file mode 100644
index 0000000000000..52593e67df768
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts
@@ -0,0 +1,25 @@
+/*
+ * 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 { createEnablePhaseAction, createNodeAllocationActions } from '../../../helpers';
+import { initTestBed } from '../../init_test_bed';
+
+type SetupReturn = ReturnType;
+
+export type NodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn;
+
+export const setupColdPhaseNodeAllocation = async () => {
+ const testBed = await initTestBed();
+
+ return {
+ ...testBed,
+ actions: {
+ enable: createEnablePhaseAction(testBed, 'cold'),
+ ...createNodeAllocationActions(testBed, 'cold'),
+ },
+ };
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts
new file mode 100644
index 0000000000000..f833c8e316117
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts
@@ -0,0 +1,226 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { setupEnvironment } from '../../../helpers/setup_environment';
+import { NodeAllocationTestBed, setupColdPhaseNodeAllocation } from './cold_phase.helpers';
+
+describe(' node allocation in the cold phase', () => {
+ let testBed: NodeAllocationTestBed;
+ const { server, httpRequestsMockHelpers } = setupEnvironment();
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ server.restore();
+ });
+
+ const setup = async () => {
+ await act(async () => {
+ testBed = await setupColdPhaseNodeAllocation();
+ });
+ };
+
+ beforeEach(async () => {
+ server.respondImmediately = true;
+ httpRequestsMockHelpers.setLoadPolicies([]);
+ httpRequestsMockHelpers.setListNodes({
+ nodesByRoles: { data: ['node1'] },
+ nodesByAttributes: { 'attribute:true': ['node1'] },
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+ httpRequestsMockHelpers.setNodesDetails('attribute:true', [
+ { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } },
+ ]);
+
+ await setup();
+
+ const { component } = testBed;
+ component.update();
+ });
+
+ test(`doesn't offer allocation guidance when node with deprecated "data" role exists`, async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data: ['test'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasWillUseFallbackTierNotice()).toBeFalsy();
+ });
+
+ describe('when using node attributes', () => {
+ test('shows spinner for node attributes input when loading', async () => {
+ server.respondImmediately = false;
+
+ const { actions } = testBed;
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeTruthy();
+ expect(actions.hasDataTierAllocationControls()).toBeTruthy();
+ expect(actions.hasNodeAttributesSelect()).toBeFalsy();
+
+ // No notices will be shown.
+ expect(actions.hasDefaultToDataTiersNotice()).toBeFalsy();
+ expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeFalsy();
+ expect(actions.hasDefaultToDataNodesNotice()).toBeFalsy();
+ expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeFalsy();
+ });
+
+ describe('and some are defined', () => {
+ test('shows the node attributes input', async () => {
+ const { actions } = testBed;
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasDefaultAllocationBehaviorNotice()).toBeFalsy();
+ expect(actions.hasNodeAttributesSelect()).toBeTruthy();
+ expect(actions.getNodeAttributesSelectOptions().length).toBe(2);
+ });
+
+ test('shows view node attributes link when an attribute is selected and shows flyout when clicked', async () => {
+ const { actions } = testBed;
+
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasDefaultAllocationBehaviorNotice()).toBeFalsy();
+ expect(actions.hasNodeAttributesSelect()).toBeTruthy();
+
+ expect(actions.hasNodeDetailsFlyout()).toBeFalsy();
+ expect(actions.getNodeAttributesSelectOptions().length).toBe(2);
+ await actions.setSelectedNodeAttribute('attribute:true');
+
+ await actions.openNodeDetailsFlyout();
+ expect(actions.hasNodeDetailsFlyout()).toBeTruthy();
+ });
+ });
+
+ describe('and none are defined', () => {
+ const commonSetupAndBaselineAssertions = async () => {
+ await setup();
+ const { actions, component } = testBed;
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasNodeAttributesSelect()).toBeFalsy();
+ };
+
+ test('and data tiers are available, shows DefaultToDataTiersNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasDefaultToDataTiersNotice()).toBeTruthy();
+ });
+
+ test('and data tiers are available, but not for the cold phase, shows WillUseFallbackTierUsingNodeAttributesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data_warm: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeTruthy();
+ });
+
+ test('when data nodes are in use, shows DefaultToDataNodesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: {},
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasDefaultToDataNodesNotice()).toBeTruthy();
+ });
+
+ test('when no data tier node roles are defined, shows NoTiersAvailableUsingNodeAttributesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ // data_content is a node role so they're technically in use, but it's not a data tier node role.
+ nodesByRoles: { data_content: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeTruthy();
+ });
+ });
+ });
+
+ describe('when using node roles', () => {
+ test('when no node roles are defined, shows NoTiersAvailableNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: {},
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasNoTiersAvailableNotice()).toBeTruthy();
+ });
+
+ [
+ {
+ nodesByRoles: { data_hot: ['test'] },
+ fallbackTier: 'hot',
+ },
+ {
+ nodesByRoles: { data_hot: ['test'], data_warm: ['test'] },
+ fallbackTier: 'warm',
+ },
+ ].forEach(({ nodesByRoles, fallbackTier }) => {
+ test(`when allocation will fallback to the ${fallbackTier} tier, shows WillUseFallbackTierNotice and defines the fallback tier`, async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles,
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasWillUseFallbackTierNotice()).toBeTruthy();
+ expect(actions.getWillUseFallbackTierNoticeText()).toContain(
+ `No nodes assigned to the cold tierIf no cold nodes are available, data is stored in the ${fallbackTier} tier.`
+ );
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts
new file mode 100644
index 0000000000000..8dd5a75ac0d22
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts
@@ -0,0 +1,26 @@
+/*
+ * 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 { createNodeAllocationActions, savePolicy, setReplicas } from '../../../helpers';
+import { initTestBed } from '../../init_test_bed';
+
+type SetupReturn = ReturnType;
+
+export type GeneralNodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn;
+
+export const setupGeneralNodeAllocation = async () => {
+ const testBed = await initTestBed();
+
+ return {
+ ...testBed,
+ actions: {
+ ...createNodeAllocationActions(testBed, 'warm'),
+ savePolicy: () => savePolicy(testBed),
+ setReplicas: (value: string) => setReplicas(testBed, 'warm', value),
+ },
+ };
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts
new file mode 100644
index 0000000000000..d45e1cfe9567b
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts
@@ -0,0 +1,128 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { setupEnvironment } from '../../../helpers/setup_environment';
+import {
+ GeneralNodeAllocationTestBed,
+ setupGeneralNodeAllocation,
+} from './general_behavior.helpers';
+import {
+ POLICY_WITH_MIGRATE_OFF,
+ POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION,
+ POLICY_WITH_NODE_ROLE_ALLOCATION,
+} from '../../constants';
+
+describe(' node allocation general behavior', () => {
+ let testBed: GeneralNodeAllocationTestBed;
+ const { server, httpRequestsMockHelpers } = setupEnvironment();
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ server.restore();
+ });
+
+ const setup = async () => {
+ await act(async () => {
+ testBed = await setupGeneralNodeAllocation();
+ });
+ };
+
+ describe('data allocation', () => {
+ test('setting node_attr based allocation, but not selecting node attribute', async () => {
+ httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_MIGRATE_OFF]);
+ httpRequestsMockHelpers.setListNodes({
+ nodesByRoles: {},
+ nodesByAttributes: { test: ['123'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+ httpRequestsMockHelpers.setLoadSnapshotPolicies([]);
+
+ await setup();
+
+ const { component, actions } = testBed;
+ component.update();
+
+ await actions.setDataAllocation('node_attrs');
+ await actions.savePolicy();
+ const latestRequest = server.requests[server.requests.length - 1];
+ const warmPhase = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm;
+
+ expect(warmPhase.actions.migrate).toEqual({ enabled: false });
+ });
+
+ describe('node roles', () => {
+ beforeEach(async () => {
+ httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_NODE_ROLE_ALLOCATION]);
+ httpRequestsMockHelpers.setListNodes({
+ isUsingDeprecatedDataRoleConfig: false,
+ nodesByAttributes: { test: ['123'] },
+ nodesByRoles: { data: ['123'] },
+ });
+
+ await setup();
+
+ const { component } = testBed;
+ component.update();
+ });
+
+ test('detecting use of the recommended allocation type', () => {
+ const { find } = testBed;
+ const selectedDataAllocation = find(
+ 'warm-dataTierAllocationControls.dataTierSelect'
+ ).text();
+ expect(selectedDataAllocation).toBe('Use warm nodes (recommended)');
+ });
+
+ test('setting replicas serialization', async () => {
+ const { actions } = testBed;
+ await actions.setReplicas('123');
+ await actions.savePolicy();
+ const latestRequest = server.requests[server.requests.length - 1];
+ const warmPhaseActions = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm
+ .actions;
+ expect(warmPhaseActions).toMatchInlineSnapshot(`
+ Object {
+ "allocate": Object {
+ "number_of_replicas": 123,
+ },
+ }
+ `);
+ });
+ });
+
+ describe('node attr and none', () => {
+ beforeEach(async () => {
+ httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION]);
+ httpRequestsMockHelpers.setListNodes({
+ isUsingDeprecatedDataRoleConfig: false,
+ nodesByAttributes: { test: ['123'] },
+ nodesByRoles: { data: ['123'] },
+ });
+
+ await setup();
+
+ const { component } = testBed;
+ component.update();
+ });
+
+ test('detecting use of the custom allocation type', () => {
+ const { find } = testBed;
+ expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).toBe('Custom');
+ });
+
+ test('detecting use of the "off" allocation type', () => {
+ const { find } = testBed;
+ expect(find('cold-dataTierAllocationControls.dataTierSelect').text()).toContain('Off');
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts
new file mode 100644
index 0000000000000..e39629da79cd8
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts
@@ -0,0 +1,25 @@
+/*
+ * 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 { createNodeAllocationActions, createEnablePhaseAction } from '../../../helpers';
+import { initTestBed } from '../../init_test_bed';
+
+type SetupReturn = ReturnType;
+
+export type NodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn;
+
+export const setupWarmPhaseNodeAllocation = async () => {
+ const testBed = await initTestBed();
+
+ return {
+ ...testBed,
+ actions: {
+ enable: createEnablePhaseAction(testBed, 'warm'),
+ ...createNodeAllocationActions(testBed, 'warm'),
+ },
+ };
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts
new file mode 100644
index 0000000000000..0ab18c6e05736
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts
@@ -0,0 +1,214 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { setupEnvironment } from '../../../helpers/setup_environment';
+import { NodeAllocationTestBed, setupWarmPhaseNodeAllocation } from './warm_phase.helpers';
+
+describe(' node allocation in the warm phase', () => {
+ let testBed: NodeAllocationTestBed;
+ const { server, httpRequestsMockHelpers } = setupEnvironment();
+
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ server.restore();
+ });
+
+ const setup = async () => {
+ await act(async () => {
+ testBed = await setupWarmPhaseNodeAllocation();
+ });
+ };
+
+ beforeEach(async () => {
+ server.respondImmediately = true;
+ httpRequestsMockHelpers.setLoadPolicies([]);
+ httpRequestsMockHelpers.setListNodes({
+ nodesByRoles: { data: ['node1'] },
+ nodesByAttributes: { 'attribute:true': ['node1'] },
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+ httpRequestsMockHelpers.setNodesDetails('attribute:true', [
+ { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } },
+ ]);
+
+ await setup();
+
+ const { component } = testBed;
+ component.update();
+ });
+
+ test(`doesn't offer allocation guidance when node with deprecated "data" role exists`, async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data: ['test'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasDefaultAllocationBehaviorNotice()).toBeFalsy();
+ });
+
+ describe('when using node attributes', () => {
+ test('shows spinner for node attributes input when loading', async () => {
+ server.respondImmediately = false;
+
+ const { actions } = testBed;
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeTruthy();
+ expect(actions.hasDataTierAllocationControls()).toBeTruthy();
+ expect(actions.hasNodeAttributesSelect()).toBeFalsy();
+
+ // No notices will be shown.
+ expect(actions.hasDefaultToDataTiersNotice()).toBeFalsy();
+ expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeFalsy();
+ expect(actions.hasDefaultToDataNodesNotice()).toBeFalsy();
+ expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeFalsy();
+ });
+
+ describe('and some are defined', () => {
+ test('shows the node attributes input', async () => {
+ const { actions } = testBed;
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasDefaultAllocationBehaviorNotice()).toBeFalsy();
+ expect(actions.hasNodeAttributesSelect()).toBeTruthy();
+ expect(actions.getNodeAttributesSelectOptions().length).toBe(2);
+ });
+
+ test('shows view node attributes link when an attribute is selected and shows flyout when clicked', async () => {
+ const { actions } = testBed;
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasDefaultAllocationBehaviorNotice()).toBeFalsy();
+ expect(actions.hasNodeAttributesSelect()).toBeTruthy();
+
+ expect(actions.hasNodeDetailsFlyout()).toBeFalsy();
+ expect(actions.getNodeAttributesSelectOptions().length).toBe(2);
+ await actions.setSelectedNodeAttribute('attribute:true');
+
+ await actions.openNodeDetailsFlyout();
+ expect(actions.hasNodeDetailsFlyout()).toBeTruthy();
+ });
+ });
+
+ describe('and none are defined', () => {
+ const commonSetupAndBaselineAssertions = async () => {
+ await setup();
+ const { actions, component } = testBed;
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ await actions.setDataAllocation('node_attrs');
+ expect(actions.hasNodeAttributesSelect()).toBeFalsy();
+ };
+
+ test('and data tiers are available, shows DefaultToDataTiersNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasDefaultToDataTiersNotice()).toBeTruthy();
+ });
+
+ test('and data tiers are available, but not for the warm phase, shows WillUseFallbackTierUsingNodeAttributesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data_hot: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeTruthy();
+ });
+
+ test('when data nodes are in use, shows DefaultToDataNodesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: {},
+ isUsingDeprecatedDataRoleConfig: true,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasDefaultToDataNodesNotice()).toBeTruthy();
+ });
+
+ test('when no data tier node roles are defined, shows NoTiersAvailableUsingNodeAttributesNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ // data_content is a node role so they're technically in use, but it's not a data tier node role.
+ nodesByRoles: { data_content: ['node1'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await commonSetupAndBaselineAssertions();
+ const { actions } = testBed;
+ expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeTruthy();
+ });
+ });
+ });
+
+ describe('when using node roles', () => {
+ test('when no node roles are defined, shows NoTiersAvailableNotice', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: {},
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasNoTiersAvailableNotice()).toBeTruthy();
+ });
+
+ test('when allocation will fallback to the hot tier, shows WillUseFallbackTierNotice and defines the fallback tier', async () => {
+ httpRequestsMockHelpers.setListNodes({
+ nodesByAttributes: {},
+ nodesByRoles: { data_hot: ['test'], data_cold: ['test'] },
+ isUsingDeprecatedDataRoleConfig: false,
+ });
+
+ await setup();
+ const { actions, component } = testBed;
+
+ component.update();
+ await actions.enable(true);
+
+ expect(actions.isAllocationLoading()).toBeFalsy();
+ expect(actions.hasWillUseFallbackTierNotice()).toBeTruthy();
+ expect(actions.getWillUseFallbackTierNoticeText()).toContain(
+ `No nodes assigned to the warm tierIf no warm nodes are available, data is stored in the hot tier.`
+ );
+ });
+ });
+});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx
new file mode 100644
index 0000000000000..4f057e04c85d4
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx
@@ -0,0 +1,55 @@
+/*
+ * 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 React from 'react';
+import { registerTestBed, TestBedConfig } from '@kbn/test/jest';
+
+import '../helpers/global_mocks';
+
+import { licensingMock } from '../../../../licensing/public/mocks';
+import { EditPolicy } from '../../../public/application/sections/edit_policy';
+import { KibanaContextProvider } from '../../../public/shared_imports';
+import { AppServicesContext } from '../../../public/types';
+import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock';
+import { POLICY_NAME } from './constants';
+
+const getTestBedConfig = (testBedConfigArgs?: Partial): TestBedConfig => {
+ return {
+ memoryRouter: {
+ initialEntries: [`/policies/edit/${POLICY_NAME}`],
+ componentRoutePath: `/policies/edit/:policyName`,
+ },
+ defaultProps: {
+ getUrlForApp: () => {},
+ },
+ ...testBedConfigArgs,
+ };
+};
+
+const breadcrumbService = createBreadcrumbsMock();
+
+const EditPolicyContainer = ({ appServicesContext, ...rest }: any) => {
+ return (
+
+
+
+ );
+};
+
+export const initTestBed = (arg?: {
+ appServicesContext?: Partial;
+ testBedConfig?: Partial;
+}) => {
+ const { testBedConfig: testBedConfigArgs, ...rest } = arg || {};
+ return registerTestBed(EditPolicyContainer, getTestBedConfig(testBedConfigArgs))(rest);
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_enable_phase_action.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_enable_phase_action.ts
new file mode 100644
index 0000000000000..e0988daf52192
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_enable_phase_action.ts
@@ -0,0 +1,15 @@
+/*
+ * 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 { TestBed } from '@kbn/test/jest';
+
+import { Phase } from './types';
+import { createFormToggleAction } from './create_form_toggle_action';
+
+export const createEnablePhaseAction = (testBed: TestBed, phase: Phase) => {
+ return createFormToggleAction(testBed, `enablePhaseSwitch-${phase}`);
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_set_value_action.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_set_value_action.ts
new file mode 100644
index 0000000000000..95e90ac04192b
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_set_value_action.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { TestBed } from '@kbn/test/jest';
+
+export function createFormSetValueAction(
+ testBed: TestBed,
+ dataTestSubject: string
+) {
+ const { form, component } = testBed;
+
+ return async (value: V) => {
+ await act(async () => {
+ form.setInputValue(dataTestSubject, value);
+ });
+ component.update();
+ };
+}
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_toggle_action.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_toggle_action.ts
new file mode 100644
index 0000000000000..579bb661871da
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_form_toggle_action.ts
@@ -0,0 +1,21 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { TestBed } from '@kbn/test/jest';
+
+export const createFormToggleAction = (testBed: TestBed, dataTestSubject: string) => async (
+ checked: boolean
+) => {
+ const { form, component } = testBed;
+
+ await act(async () => {
+ form.toggleEuiSwitch(dataTestSubject, checked);
+ });
+
+ component.update();
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_node_allocation_actions.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_node_allocation_actions.ts
new file mode 100644
index 0000000000000..416a2afa54d54
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/create_node_allocation_actions.ts
@@ -0,0 +1,83 @@
+/*
+ * 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 { act } from 'react-dom/test-utils';
+import { TestBed } from '@kbn/test/jest';
+
+import { Phase } from './types';
+import { DataTierAllocationType } from '../../../public/application/sections/edit_policy/types';
+import { createFormSetValueAction } from './create_form_set_value_action';
+
+export const createNodeAllocationActions = (testBed: TestBed, phase: Phase) => {
+ const { component, find, exists } = testBed;
+
+ const controlsSelector = `${phase}-dataTierAllocationControls`;
+ const dataTierSelector = `${controlsSelector}.dataTierSelect`;
+ const nodeAttrsSelector = `${phase}-selectedNodeAttrs`;
+
+ const openNodeAttributesSection = async () => {
+ await act(async () => {
+ find(dataTierSelector).simulate('click');
+ });
+ component.update();
+ };
+
+ const isAllocationLoading = () => find(`${phase}-phase.allocationLoadingSpinner`).exists();
+ const hasDefaultToDataNodesNotice = () => exists(`${phase}-phase.defaultToDataNodesNotice`);
+ const hasDefaultToDataTiersNotice = () => exists(`${phase}-phase.defaultToDataTiersNotice`);
+ const hasDefaultAllocationBehaviorNotice = () =>
+ hasDefaultToDataNodesNotice() && hasDefaultToDataTiersNotice();
+ const hasNoTiersAvailableNotice = () => exists(`${phase}-phase.noTiersAvailableNotice`);
+ const hasNoTiersAvailableUsingNodeAttributesNotice = () =>
+ exists(`${phase}-phase.noTiersAvailableUsingNodeAttributesNotice`);
+ const hasWillUseFallbackTierNotice = () => exists(`${phase}-phase.willUseFallbackTierNotice`);
+ const hasWillUseFallbackTierUsingNodeAttributesNotice = () =>
+ exists(`${phase}-phase.willUseFallbackTierUsingNodeAttributesNotice`);
+ const getWillUseFallbackTierNoticeText = () =>
+ find(`${phase}-phase.willUseFallbackTierNotice`).text();
+
+ return {
+ hasDataTierAllocationControls: () => exists(controlsSelector),
+ openNodeAttributesSection,
+ hasNodeAttributesSelect: (): boolean => exists(nodeAttrsSelector),
+ getNodeAttributesSelectOptions: () => find(nodeAttrsSelector).find('option'),
+ setDataAllocation: async (value: DataTierAllocationType) => {
+ await openNodeAttributesSection();
+
+ await act(async () => {
+ switch (value) {
+ case 'node_roles':
+ find(`${controlsSelector}.defaultDataAllocationOption`).simulate('click');
+ break;
+ case 'node_attrs':
+ find(`${controlsSelector}.customDataAllocationOption`).simulate('click');
+ break;
+ default:
+ find(`${controlsSelector}.noneDataAllocationOption`).simulate('click');
+ }
+ });
+ component.update();
+ },
+ setSelectedNodeAttribute: createFormSetValueAction(testBed, nodeAttrsSelector),
+ isAllocationLoading,
+ hasDefaultToDataNodesNotice,
+ hasDefaultToDataTiersNotice,
+ hasDefaultAllocationBehaviorNotice,
+ hasNoTiersAvailableNotice,
+ hasNoTiersAvailableUsingNodeAttributesNotice,
+ hasWillUseFallbackTierNotice,
+ hasWillUseFallbackTierUsingNodeAttributesNotice,
+ getWillUseFallbackTierNoticeText,
+ hasNodeDetailsFlyout: () => exists(`${phase}-viewNodeDetailsFlyoutButton`),
+ openNodeDetailsFlyout: async () => {
+ await act(async () => {
+ find(`${phase}-viewNodeDetailsFlyoutButton`).simulate('click');
+ });
+ component.update();
+ },
+ };
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx
new file mode 100644
index 0000000000000..5ed5e6e8fcce7
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx
@@ -0,0 +1,34 @@
+/*
+ * 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 React from 'react';
+
+// NOTE: Import this file for its side-effects. You must import it before the code that it mocks
+// is imported. Typically this means just importing above your other imports.
+// See https://jestjs.io/docs/manual-mocks for more info.
+
+window.scrollTo = jest.fn();
+
+jest.mock('@elastic/eui', () => {
+ const original = jest.requireActual('@elastic/eui');
+
+ return {
+ ...original,
+ // Mocking EuiComboBox, as it utilizes "react-virtualized" for rendering search suggestions,
+ // which does not produce a valid component wrapper
+ EuiComboBox: (props: any) => (
+ {
+ props.onChange([syntheticEvent['0']]);
+ }}
+ />
+ ),
+ EuiIcon: 'eui-icon', // using custom react-svg icon causes issues, mocking for now.
+ };
+});
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts
index 56f5815633a1d..1388cf97d4e22 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts
@@ -5,22 +5,11 @@
* 2.0.
*/
-export type TestSubjects =
- | 'snapshotPolicyCombobox'
- | 'savePolicyButton'
- | 'customPolicyCallout'
- | 'noPoliciesCallout'
- | 'policiesErrorCallout'
- | 'rolloverSwitch'
- | 'rolloverSettingsRequired'
- | 'hot-selectedMaxSizeStored'
- | 'hot-selectedMaxSizeStoredUnits'
- | 'hot-selectedMaxDocuments'
- | 'hot-selectedMaxAge'
- | 'hot-selectedMaxAgeUnits'
- | 'policyTablePolicyNameLink'
- | 'policyTitle'
- | 'createPolicyButton'
- | 'cold-freezeSwitch'
- | 'frozen-freezeSwitch'
- | string;
+export { Phase } from './types';
+
+export { createNodeAllocationActions } from './create_node_allocation_actions';
+export { createEnablePhaseAction } from './create_enable_phase_action';
+export { setReplicas } from './set_replicas_action';
+export { savePolicy } from './save_policy_action';
+export { createFormToggleAction } from './create_form_toggle_action';
+export { createFormSetValueAction } from './create_form_set_value_action';
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/save_policy_action.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/save_policy_action.ts
new file mode 100644
index 0000000000000..37ce4f84f03ba
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/save_policy_action.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 { act } from 'react-dom/test-utils';
+import { TestBed } from '@kbn/test/jest';
+
+export const savePolicy = async (testBed: TestBed) => {
+ const { find, component } = testBed;
+
+ await act(async () => {
+ find('savePolicyButton').simulate('click');
+ });
+
+ component.update();
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/set_replicas_action.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/set_replicas_action.ts
new file mode 100644
index 0000000000000..049c1a205cbd4
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/set_replicas_action.ts
@@ -0,0 +1,21 @@
+/*
+ * 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 { TestBed } from '@kbn/test/jest';
+
+import { Phase } from './types';
+import { createFormToggleAction } from './create_form_toggle_action';
+import { createFormSetValueAction } from './create_form_set_value_action';
+
+export const setReplicas = async (testBed: TestBed, phase: Phase, value: string) => {
+ const { exists } = testBed;
+
+ if (!exists(`${phase}-selectedReplicaCount`)) {
+ await createFormToggleAction(testBed, `${phase}-setReplicasSwitch`)(true);
+ }
+ await createFormSetValueAction(testBed, `${phase}-selectedReplicaCount`)(value);
+};
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/types.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/types.ts
new file mode 100644
index 0000000000000..644ada96a9f05
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/types.ts
@@ -0,0 +1,10 @@
+/*
+ * 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 { Phases } from '../../../common/types';
+
+export type Phase = keyof Phases;
diff --git a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts
index 337a1be2b2fbc..385751f31d5bc 100644
--- a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts
+++ b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts
@@ -7,7 +7,7 @@
import { Index as IndexInterface } from '../../../index_management/common/types';
-export type PhaseWithAllocation = 'warm' | 'cold' | 'frozen';
+export type PhaseWithAllocation = 'warm' | 'cold';
export interface SerializedPolicy {
name: string;
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts
index f2596cac8b920..d5ba7fb785069 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts
+++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts
@@ -13,8 +13,6 @@ import {
import { phaseToNodePreferenceMap } from '../../../../common/constants';
-export type AllocationNodeRole = DataTierRole | 'none';
-
/**
* Given a phase and current cluster node roles, determine which nodes the phase
* will allocate data to. For instance, for the warm phase, with warm
@@ -26,7 +24,7 @@ export type AllocationNodeRole = DataTierRole | 'none';
export const getAvailableNodeRoleForPhase = (
phase: PhaseWithAllocation,
nodesByRoles: ListNodesRouteResponse['nodesByRoles']
-): AllocationNodeRole => {
+): DataTierRole | undefined => {
const preferredNodeRoles = phaseToNodePreferenceMap[phase];
// The 'data' role covers all node roles, so if we have at least one node with the data role
@@ -35,5 +33,5 @@ export const getAvailableNodeRoleForPhase = (
return preferredNodeRoles[0];
}
- return preferredNodeRoles.find((role) => Boolean(nodesByRoles[role]?.length)) ?? 'none';
+ return preferredNodeRoles.find((role) => Boolean(nodesByRoles[role]?.length));
};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/data_tier_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/data_tier_allocation.tsx
index 254063ac1a9ea..1eeb32d84f677 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/data_tier_allocation.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/data_tier_allocation.tsx
@@ -161,7 +161,20 @@ const getSelectOptions = (phase: PhaseWithAllocation, disableDataTierOption: boo
].filter(Boolean) as SelectOptions[];
export const DataTierAllocation: FunctionComponent = (props) => {
- const { phase, hasNodeAttributes, disableDataTierOption, isLoading } = props;
+ const {
+ phase,
+ hasNodeAttributes,
+ isCloudEnabled,
+ isUsingDeprecatedDataRoleConfig,
+ isLoading,
+ } = props;
+
+ /**
+ * On Cloud we want to disable the data tier allocation option when we detect that we are not
+ * using node roles in our Node config yet. See {@link ListNodesRouteResponse} for information about how this is
+ * detected.
+ */
+ const disableDataTierOption = Boolean(isCloudEnabled && isUsingDeprecatedDataRoleConfig);
const dataTierAllocationTypePath = `_meta.${phase}.dataTierAllocationType`;
@@ -185,6 +198,7 @@ export const DataTierAllocation: FunctionComponent = (props) => {
if (disableDataTierOption && field.value === 'node_roles') {
field.setValue('node_attrs');
}
+
return (
= {
- data_hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel', {
- defaultMessage: 'hot',
- }),
- data_warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel', {
- defaultMessage: 'warm',
- }),
- data_cold: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel', {
- defaultMessage: 'cold',
- }),
- data_frozen: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierFrozenLabel', {
- defaultMessage: 'frozen',
- }),
-};
-
-const i18nTexts = {
- notice: {
- warm: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title',
- { defaultMessage: 'No nodes assigned to the warm tier' }
- ),
- body: (nodeRole: DataTierRole) =>
- i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm', {
- defaultMessage:
- 'This policy will move data in the warm phase to {tier} tier nodes instead.',
- values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] },
- }),
- },
- cold: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title',
- { defaultMessage: 'No nodes assigned to the cold tier' }
- ),
- body: (nodeRole: DataTierRole) =>
- i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold', {
- defaultMessage:
- 'This policy will move data in the cold phase to {tier} tier nodes instead.',
- values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] },
- }),
- },
- frozen: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.frozen.title',
- { defaultMessage: 'No nodes assigned to the frozen tier' }
- ),
- body: (nodeRole: DataTierRole) =>
- i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.frozen',
- {
- defaultMessage:
- 'This policy will move data in the frozen phase to {tier} tier nodes instead.',
- values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] },
- }
- ),
- },
- },
- warning: {
- warm: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle',
- { defaultMessage: 'No nodes assigned to the warm tier' }
- ),
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody',
- {
- defaultMessage:
- 'Assign at least one node to the warm or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.',
- }
- ),
- },
- cold: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle',
- { defaultMessage: 'No nodes assigned to the cold tier' }
- ),
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody',
- {
- defaultMessage:
- 'Assign at least one node to the cold, warm, or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.',
- }
- ),
- },
- },
-};
-
-interface Props {
- phase: PhaseWithAllocation;
- targetNodeRole: DataTierRole;
-}
-
-export const DefaultAllocationNotice: FunctionComponent = ({ phase, targetNodeRole }) => {
- return (
-
- {i18nTexts.notice[phase].body(targetNodeRole)}
-
- );
-};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_allocation_warning.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_allocation_warning.tsx
deleted file mode 100644
index 649eb9f2fcb7f..0000000000000
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_allocation_warning.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 { i18n } from '@kbn/i18n';
-import React, { FunctionComponent } from 'react';
-import { EuiCallOut } from '@elastic/eui';
-
-import { PhaseWithAllocation } from '../../../../../../../../../common/types';
-
-const i18nTexts = {
- warning: {
- warm: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle',
- { defaultMessage: 'No nodes assigned to the warm tier' }
- ),
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody',
- {
- defaultMessage:
- 'Assign at least one node to the warm or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.',
- }
- ),
- },
- cold: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle',
- { defaultMessage: 'No nodes assigned to the cold tier' }
- ),
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody',
- {
- defaultMessage:
- 'Assign at least one node to the cold, warm, or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.',
- }
- ),
- },
- frozen: {
- title: i18n.translate(
- 'xpack.indexLifecycleMgmt.frozenPhase.dataTier.defaultAllocationNotAvailableTitle',
- { defaultMessage: 'No nodes assigned to the frozen tier' }
- ),
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.frozenPhase.dataTier.defaultAllocationNotAvailableBody',
- {
- defaultMessage:
- 'Assign at least one node to the frozen, cold, warm, or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.',
- }
- ),
- },
- },
-};
-
-interface Props {
- phase: PhaseWithAllocation;
-}
-
-export const DefaultAllocationWarning: FunctionComponent = ({ phase }) => {
- return (
-
- {i18nTexts.warning[phase].body}
-
- );
-};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_nodes_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_nodes_notice.tsx
new file mode 100644
index 0000000000000..b29ddb75c18cf
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_nodes_notice.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { PhaseWithAllocation } from '../../../../../../../../../common/types';
+import {
+ noCustomAttributesTitle,
+ nodeAllocationMigrationGuidance,
+} from './no_custom_attributes_messages';
+
+export const DefaultToDataNodesNotice: FunctionComponent<{ phase: PhaseWithAllocation }> = ({
+ phase,
+}) => {
+ return (
+
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultToDataNodesDescription',
+ { defaultMessage: 'Data will be allocated to any available data node.' }
+ )}
+
+
+ {nodeAllocationMigrationGuidance}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_tiers_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_tiers_notice.tsx
new file mode 100644
index 0000000000000..25414406e67b5
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/default_to_data_tiers_notice.tsx
@@ -0,0 +1,60 @@
+/*
+ * 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 React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { PhaseWithAllocation } from '../../../../../../../../../common/types';
+import {
+ noCustomAttributesTitle,
+ nodeAllocationMigrationGuidance,
+} from './no_custom_attributes_messages';
+
+const i18nTexts = {
+ body: {
+ warm: (
+ <>
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableDescription',
+ { defaultMessage: 'Data will be allocated to the warm tier.' }
+ )}
+
+
+ {nodeAllocationMigrationGuidance}
+ >
+ ),
+ cold: (
+ <>
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableDescription',
+ { defaultMessage: 'Data will be allocated to the cold tier.' }
+ )}
+
+
+ {nodeAllocationMigrationGuidance}
+ >
+ ),
+ },
+};
+
+export const DefaultToDataTiersNotice: FunctionComponent<{ phase: PhaseWithAllocation }> = ({
+ phase,
+}) => {
+ return (
+
+ {i18nTexts.body[phase]}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/index.ts
index e9c884a42fa93..ce5685ba98307 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/index.ts
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/index.ts
@@ -11,11 +11,17 @@ export { NodeAttrsDetails } from './node_attrs_details';
export { DataTierAllocation } from './data_tier_allocation';
-export { DefaultAllocationNotice } from './default_allocation_notice';
+export { WillUseFallbackTierNotice } from './will_use_fallback_tier_notice';
-export { DefaultAllocationWarning } from './default_allocation_warning';
+export { WillUseFallbackTierUsingNodeAttributesNotice } from './will_use_fallback_tier_using_node_attributes_notice';
-export { NoNodeAttributesWarning } from './no_node_attributes_warning';
+export { NoTiersAvailableNotice } from './no_tiers_available_notice';
+
+export { NoTiersAvailableUsingNodeAttributesNotice } from './no_tiers_available_using_node_attributes_notice';
+
+export { DefaultToDataTiersNotice } from './default_to_data_tiers_notice';
+
+export { DefaultToDataNodesNotice } from './default_to_data_nodes_notice';
export { CloudDataTierCallout } from './cloud_data_tier_callout';
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_custom_attributes_messages.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_custom_attributes_messages.tsx
new file mode 100644
index 0000000000000..4d948ac202eb8
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_custom_attributes_messages.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 React from 'react';
+import { EuiLink } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+
+import { getNodeAllocationMigrationLink } from '../../../../../../../services/documentation';
+
+export const noCustomAttributesTitle = i18n.translate(
+ 'xpack.indexLifecycleMgmt.editPolicy.noCustomAttributesTitle',
+ { defaultMessage: 'No custom attributes defined' }
+);
+
+export const nodeAllocationMigrationGuidance = (
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.editPolicy.defaultToDataNodesDescription.migrationGuidanceMessage',
+ {
+ defaultMessage: 'use role-based allocation',
+ }
+ )}
+
+ ),
+ }}
+ />
+);
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_node_attributes_warning.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_node_attributes_warning.tsx
deleted file mode 100644
index e6cadf7049962..0000000000000
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_node_attributes_warning.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 React, { FunctionComponent } from 'react';
-import { EuiCallOut } from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
-
-import { PhaseWithAllocation } from '../../../../../../../../../common/types';
-
-const i18nTexts = {
- title: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel', {
- defaultMessage: 'No custom node attributes configured',
- }),
- warm: {
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription',
- {
- defaultMessage:
- 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation.',
- }
- ),
- },
- cold: {
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription',
- {
- defaultMessage:
- 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation.',
- }
- ),
- },
- frozen: {
- body: i18n.translate(
- 'xpack.indexLifecycleMgmt.editPolicy.frozen.nodeAttributesMissingDescription',
- {
- defaultMessage:
- 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation.',
- }
- ),
- },
-};
-
-export const NoNodeAttributesWarning: FunctionComponent<{ phase: PhaseWithAllocation }> = ({
- phase,
-}) => {
- return (
-
- {i18nTexts[phase].body}
-
- );
-};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_notice.tsx
new file mode 100644
index 0000000000000..d4e8e98e9b2be
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_notice.tsx
@@ -0,0 +1,49 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+
+import { PhaseWithAllocation } from '../../../../../../../../../common/types';
+
+const i18nTexts = {
+ warm: {
+ title: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.noTiersAvailableTitle', {
+ defaultMessage: 'No nodes assigned to the warm tier',
+ }),
+ body: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.noTiersAvailableBody', {
+ defaultMessage:
+ 'To use role-based allocation, assign one or more nodes to the warm or hot tiers. Allocation will fail if there are no available nodes.',
+ }),
+ },
+ cold: {
+ title: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.noTiersAvailableTitle', {
+ defaultMessage: 'No nodes assigned to the cold tier',
+ }),
+ body: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.noTiersAvailableBody', {
+ defaultMessage:
+ 'To use role-based allocation, assign one or more nodes to the cold, warm, or hot tiers. Allocation will fail if there are no available nodes.',
+ }),
+ },
+};
+
+interface Props {
+ phase: PhaseWithAllocation;
+}
+
+export const NoTiersAvailableNotice: FunctionComponent = ({ phase }) => {
+ return (
+
+ {i18nTexts[phase].body}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_using_node_attributes_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_using_node_attributes_notice.tsx
new file mode 100644
index 0000000000000..02dbd1baff25f
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/no_tiers_available_using_node_attributes_notice.tsx
@@ -0,0 +1,36 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+
+import {
+ noCustomAttributesTitle,
+ nodeAllocationMigrationGuidance,
+} from './no_custom_attributes_messages';
+
+export const NoTiersAvailableUsingNodeAttributesNotice: FunctionComponent = () => {
+ return (
+
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.dataTier.noTiersAvailableUsingNodeAttributesDescription',
+ {
+ defaultMessage: 'Unable to allocate data: no available data nodes.',
+ }
+ )}
+
+
+ {nodeAllocationMigrationGuidance}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx
index f8f77ed909a91..e7b1f7420d132 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx
@@ -34,13 +34,19 @@ const learnMoreLink = (
);
const i18nTexts = {
- doNotModifyAllocationOption: i18n.translate(
- 'xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption',
- { defaultMessage: 'Do not modify allocation configuration' }
+ allocateToDataNodesOption: i18n.translate(
+ 'xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.allocateToDataNodesOption',
+ { defaultMessage: 'Any data node' }
),
};
-export const NodeAllocation: FunctionComponent = ({ phase, nodes, isLoading }) => {
+export const NodeAllocation: FunctionComponent = ({
+ phase,
+ nodes,
+ isLoading,
+ isCloudEnabled,
+ isUsingDeprecatedDataRoleConfig,
+}) => {
const allocationNodeAttributePath = `_meta.${phase}.allocationNodeAttribute`;
const [formData] = useFormData({
@@ -60,6 +66,20 @@ export const NodeAllocation: FunctionComponent = ({ phase, nodes, i
nodeOptions.sort((a, b) => a.value.localeCompare(b.value));
+ let nodeAllocationOptions = [];
+
+ // On Cloud, allocating to data tiers and allocating to data nodes is mutually exclusive. So we
+ // only let users select this option if they're using data nodes. Otherwise we remove it.
+ //
+ // On prem, users should have the freedom to choose this option, even if they're using node roles.
+ // So we always give them this option.
+ if (!isCloudEnabled || isUsingDeprecatedDataRoleConfig) {
+ const allocateToDataNodesOption = { text: i18nTexts.allocateToDataNodesOption, value: '' };
+ nodeAllocationOptions.push(allocateToDataNodesOption);
+ }
+
+ nodeAllocationOptions = nodeAllocationOptions.concat(nodeOptions);
+
return (
<>
@@ -97,9 +117,7 @@ export const NodeAllocation: FunctionComponent = ({ phase, nodes, i
) : undefined,
euiFieldProps: {
'data-test-subj': `${phase}-selectedNodeAttrs`,
- options: [{ text: i18nTexts.doNotModifyAllocationOption, value: '' }].concat(
- nodeOptions
- ),
+ options: nodeAllocationOptions,
hasNoInitialSelection: false,
isLoading,
},
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_role_to_fallback_tier_map.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_role_to_fallback_tier_map.ts
new file mode 100644
index 0000000000000..ad17855f307c7
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_role_to_fallback_tier_map.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 { i18n } from '@kbn/i18n';
+
+import { DataTierRole } from '../../../../../../../../../common/types';
+
+export const nodeRoleToFallbackTierMap: Partial> = {
+ data_hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel', {
+ defaultMessage: 'hot',
+ }),
+ data_warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel', {
+ defaultMessage: 'warm',
+ }),
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/types.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/types.ts
index b78ab720618ef..aba044e1862ef 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/types.ts
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/types.ts
@@ -14,12 +14,8 @@ export interface SharedProps {
phase: PhaseWithAllocation;
nodes: ListNodesRouteResponse['nodesByAttributes'];
hasNodeAttributes: boolean;
- /**
- * When on Cloud we want to disable the data tier allocation option when we detect that we are not
- * using node roles in our Node config yet. See {@link ListNodesRouteResponse} for information about how this is
- * detected.
- */
- disableDataTierOption: boolean;
+ isCloudEnabled: boolean;
+ isUsingDeprecatedDataRoleConfig: boolean;
/**
* A flag to indicate whether input fields should be showing a loading spinner
*/
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_notice.tsx
new file mode 100644
index 0000000000000..90ac6e02ef9e2
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_notice.tsx
@@ -0,0 +1,49 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+
+import { PhaseWithAllocation, DataTierRole } from '../../../../../../../../../common/types';
+import { nodeRoleToFallbackTierMap } from './node_role_to_fallback_tier_map';
+
+const i18nTexts = {
+ warm: {
+ title: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.willUseFallbackTierTitle', {
+ defaultMessage: 'No nodes assigned to the warm tier',
+ }),
+ body: (nodeRole: DataTierRole) =>
+ i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.willUseFallbackTierDescription', {
+ defaultMessage: 'If no warm nodes are available, data is stored in the {tier} tier.',
+ values: { tier: nodeRoleToFallbackTierMap[nodeRole] },
+ }),
+ },
+ cold: {
+ title: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.willUseFallbackTierTitle', {
+ defaultMessage: 'No nodes assigned to the cold tier',
+ }),
+ body: (nodeRole: DataTierRole) =>
+ i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.willUseFallbackTierDescription', {
+ defaultMessage: 'If no cold nodes are available, data is stored in the {tier} tier.',
+ values: { tier: nodeRoleToFallbackTierMap[nodeRole] },
+ }),
+ },
+};
+
+interface Props {
+ phase: PhaseWithAllocation;
+ targetNodeRole: DataTierRole;
+}
+
+export const WillUseFallbackTierNotice: FunctionComponent = ({ phase, targetNodeRole }) => {
+ return (
+
+ {i18nTexts[phase].body(targetNodeRole)}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_using_node_attributes_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_using_node_attributes_notice.tsx
new file mode 100644
index 0000000000000..199f1001f4276
--- /dev/null
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/will_use_fallback_tier_using_node_attributes_notice.tsx
@@ -0,0 +1,47 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+import React, { FunctionComponent } from 'react';
+import { EuiCallOut } from '@elastic/eui';
+
+import { PhaseWithAllocation, DataTierRole } from '../../../../../../../../../common/types';
+import {
+ noCustomAttributesTitle,
+ nodeAllocationMigrationGuidance,
+} from './no_custom_attributes_messages';
+import { nodeRoleToFallbackTierMap } from './node_role_to_fallback_tier_map';
+
+interface Props {
+ phase: PhaseWithAllocation;
+ targetNodeRole: DataTierRole;
+}
+
+export const WillUseFallbackTierUsingNodeAttributesNotice: FunctionComponent = ({
+ phase,
+ targetNodeRole,
+}) => {
+ return (
+
+
+ {i18n.translate(
+ 'xpack.indexLifecycleMgmt.dataTier.willUseFallbackTierUsingNodeAttributesDescription',
+ {
+ defaultMessage:
+ 'No {phase} nodes available. Data will be allocated to the {fallbackTier} tier.',
+ values: { phase, fallbackTier: nodeRoleToFallbackTierMap[targetNodeRole] },
+ }
+ )}
+
+
+ {nodeAllocationMigrationGuidance}
+
+ );
+};
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/data_tier_allocation_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/data_tier_allocation_field.tsx
index 8c90a738d2c09..c45e172868938 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/data_tier_allocation_field.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/data_tier_allocation_field.tsx
@@ -11,20 +11,19 @@ import { i18n } from '@kbn/i18n';
import { EuiDescribedFormGroup, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui';
import { useKibana, useFormData } from '../../../../../../../shared_imports';
-
-import { PhaseWithAllocation } from '../../../../../../../../common/types';
-
+import { PhaseWithAllocation, DataTierRole } from '../../../../../../../../common/types';
import { getAvailableNodeRoleForPhase, isNodeRoleFirstPreference } from '../../../../../../lib';
-
import { useLoadNodes } from '../../../../../../services/api';
-
import { DataTierAllocationType } from '../../../../types';
import {
DataTierAllocation,
- DefaultAllocationNotice,
- DefaultAllocationWarning,
- NoNodeAttributesWarning,
+ WillUseFallbackTierNotice,
+ WillUseFallbackTierUsingNodeAttributesNotice,
+ NoTiersAvailableNotice,
+ NoTiersAvailableUsingNodeAttributesNotice,
+ DefaultToDataNodesNotice,
+ DefaultToDataTiersNotice,
CloudDataTierCallout,
LoadingError,
} from './components';
@@ -58,31 +57,37 @@ export const DataTierAllocationField: FunctionComponent = ({ phase, descr
const { nodesByRoles, nodesByAttributes, isUsingDeprecatedDataRoleConfig } = data!;
- const hasNodeAttrs = Boolean(Object.keys(nodesByAttributes ?? {}).length);
+ const hasNodeAttributes = Boolean(Object.keys(nodesByAttributes ?? {}).length);
const isCloudEnabled = cloud?.isCloudEnabled ?? false;
const cloudDeploymentUrl = cloud?.deploymentUrl;
+ const allocationNodeRoleForPhase = getAvailableNodeRoleForPhase(phase, nodesByRoles);
+ const noTiersAvailable = allocationNodeRoleForPhase === undefined;
+ const willUseFallbackTier =
+ allocationNodeRoleForPhase !== undefined &&
+ !isNodeRoleFirstPreference(phase, allocationNodeRoleForPhase);
+
const renderNotice = () => {
switch (allocationType) {
case 'node_roles':
/**
- * On cloud most users should be using autoscaling which will provision tiers as they are needed. We do not surface any
+ * On Cloud most users should be using autoscaling which will provision tiers as they are needed. We do not surface any
* of the notices below.
*/
if (isCloudEnabled) {
return null;
}
+
/**
* Node role allocation moves data in a phase to a corresponding tier of the same name. To prevent policy execution from getting
* stuck ILM allocation will fall back to a previous tier if possible. We show the WARNING below to inform a user when even
* this fallback will not succeed.
*/
- const allocationNodeRole = getAvailableNodeRoleForPhase(phase, nodesByRoles);
- if (allocationNodeRole === 'none') {
+ if (noTiersAvailable) {
return (
<>
-
+
>
);
}
@@ -91,26 +96,79 @@ export const DataTierAllocationField: FunctionComponent = ({ phase, descr
* If we are able to fallback to a data tier that does not map to this phase, we show a notice informing the user that their
* data will not be assigned to a corresponding tier.
*/
- if (!isNodeRoleFirstPreference(phase, allocationNodeRole)) {
+ if (willUseFallbackTier) {
return (
<>
-
+
>
);
}
break;
+
case 'node_attrs':
- if (!hasNodeAttrs) {
+ /**
+ * If there are no node attributes, advise the user on the default allocation behavior.
+ */
+ if (!hasNodeAttributes) {
+ /**
+ * If data nodes are available, default allocation behavior will be to those nodes.
+ */
+ if (isUsingDeprecatedDataRoleConfig) {
+ return (
+ <>
+
+
+ >
+ );
+ }
+
+ /**
+ * Node role allocation moves data in a phase to a corresponding tier of the same name. To prevent policy execution from getting
+ * stuck ILM allocation will fall back to a previous tier if possible. We show the WARNING below to inform a user when even
+ * this fallback will not succeed, for example if the user only has 'data' node roles, and no `data_` node roles.
+ */
+ if (noTiersAvailable) {
+ return (
+ <>
+
+
+ >
+ );
+ }
+
+ /**
+ * If we are able to fallback to a data tier that does not map to this phase, we show a notice informing the user that their
+ * data will not be assigned to a corresponding tier.
+ */
+ if (willUseFallbackTier) {
+ return (
+ <>
+
+
+ >
+ );
+ }
+
+ /**
+ * If using node roles, default allocation behavior will be to the preferred nodes, depending on the phase.
+ */
return (
<>
-
+
>
);
}
+
/**
- * Special cloud case: when deprecated data role configuration is in use, it means that this deployment is not using
+ * Special Cloud case: when deprecated data role configuration is in use, it means that this deployment is not using
* the new node role based allocation. We drive users to the cloud console to migrate to node role based allocation
* in that case.
*/
@@ -137,7 +195,7 @@ export const DataTierAllocationField: FunctionComponent = ({ phase, descr
{isLoading ? (
<>
-
+
>
) : (
error && (
@@ -154,10 +212,11 @@ export const DataTierAllocationField: FunctionComponent = ({ phase, descr
>
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/documentation.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/documentation.ts
index bb14f1d03f31c..27e571248d66d 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/services/documentation.ts
+++ b/x-pack/plugins/index_lifecycle_management/public/application/services/documentation.ts
@@ -22,3 +22,5 @@ export function init(esDocBasePath: string): void {
}
export const createDocLink = (docPath: string): string => `${_esDocBasePath}${docPath}`;
+export const getNodeAllocationMigrationLink = () =>
+ `${_esDocBasePath}migrate-index-allocation-filters.html`;
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 46074a0dbed13..a3fef7f6bbf09 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -9914,8 +9914,6 @@
"xpack.indexLifecycleMgmt.appTitle": "インデックスライフサイクルポリシー",
"xpack.indexLifecycleMgmt.breadcrumb.editPolicyLabel": "ポリシーの編集",
"xpack.indexLifecycleMgmt.breadcrumb.homeLabel": "インデックスライフサイクル管理",
- "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody": "ロールに基づく割り当てを使用するには、1 つ以上のノードを、コールド、ウォーム、またはホットティアに割り当てます。使用可能なノードがない場合、ポリシーは割り当てを完了できません。",
- "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle": "コールドティアに割り当てられているノードがありません",
"xpack.indexLifecycleMgmt.coldPhase.dataTier.description": "頻度が低い読み取り専用アクセス用に最適化されたノードにデータを移動します。安価なハードウェアのコールドフェーズにデータを格納します。",
"xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel": "インデックスを凍結",
"xpack.indexLifecycleMgmt.common.dataTier.title": "データ割り当て",
@@ -9928,7 +9926,6 @@
"xpack.indexLifecycleMgmt.editPolicy.cancelButton": "キャンセル",
"xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.body": "Elastic Cloud デプロイを編集し、色ティアを設定します。",
"xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.title": "コールドティアを作成",
- "xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription": "属性に基づく割り当てを使用するには、elasticsearch.yml でカスタムノード属性を定義します。",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.activateColdPhaseSwitchLabel": "コールドフェーズを有効にする",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseDescription": "データをコールドティアに移動します。これは、検索パフォーマンスよりもコスト削減を優先するように最適化されています。通常、コールドフェーズではデータが読み取り専用です。",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseTitle": "コールドフェーズ",
@@ -9946,7 +9943,6 @@
"xpack.indexLifecycleMgmt.editPolicy.createSnapshotRepositoryLink": "新しいスナップショットリポジドリを作成",
"xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.allocationFieldLabel": "データティアオプション",
"xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.nodeAllocationFieldLabel": "ノード属性を選択",
- "xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel": "コールド",
"xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel": "ホット",
"xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel": "ウォーム",
"xpack.indexLifecycleMgmt.editPolicy.daysOptionLabel": "日",
@@ -10011,9 +10007,7 @@
"xpack.indexLifecycleMgmt.editPolicy.minutesOptionLabel": "分",
"xpack.indexLifecycleMgmt.editPolicy.nanoSecondsOptionLabel": "ナノ秒",
"xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "ノード属性を使用して、シャード割り当てを制御します。{learnMoreLink}。",
- "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "割り当て構成を修正しない",
"xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "ノードデータを読み込めません",
- "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "カスタムノード属性が構成されていません",
"xpack.indexLifecycleMgmt.editPolicy.nodeAttributesReloadButton": "再試行",
"xpack.indexLifecycleMgmt.editPolicy.nodeDetailsLoadingFailedTitle": "ノード属性詳細を読み込めません",
"xpack.indexLifecycleMgmt.editPolicy.nodeDetailsReloadButton": "再試行",
@@ -10059,7 +10053,6 @@
"xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage": "ポリシー名の頭にアンダーラインを使用することはできず、カンマやスペースを含めることもできません。",
"xpack.indexLifecycleMgmt.editPolicy.viewNodeDetailsButton": "選択した属性のノードを表示",
"xpack.indexLifecycleMgmt.editPolicy.waitForSnapshot.snapshotPolicyFieldLabel": "ポリシー名 (任意) ",
- "xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription": "属性に基づく割り当てを使用するには、elasticsearch.yml でカスタムノード属性を定義します。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "ウォームフェーズを有効にする",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "ノードの再起動後にインデックスを復元する優先順位を設定します。優先順位の高いインデックスは優先順位の低いインデックスよりも先に復元されます。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescription": "データをウォームティアに移動します。これは、インデックスパフォーマンスよりも検索パフォーマンスを優先するように最適化されています。ウォームフェーズでは、データの追加または更新頻度は高くありません。",
@@ -10203,12 +10196,6 @@
"xpack.indexLifecycleMgmt.timeline.hotPhaseSectionTitle": "ホットフェーズ",
"xpack.indexLifecycleMgmt.timeline.title": "ポリシー概要",
"xpack.indexLifecycleMgmt.timeline.warmPhaseSectionTitle": "ウォームフェーズ",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody": "ロールに基づく割り当てを使用するには、1つ以上のノードを、ウォームまたはホットティアに割り当てます。使用可能なノードがない場合、ポリシーは割り当てを完了できません。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle": "ウォームティアに割り当てられているノードがありません",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold": "このポリシーはコールドフェーズのデータを{tier}ティアノードに移動します。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title": "コールドティアに割り当てられているノードがありません",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm": "このポリシーはウォームフェーズのデータを{tier}ティアノードに移動します。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "ウォームティアに割り当てられているノードがありません",
"xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "頻度が低い読み取り専用アクセス用に最適化されたノードにデータを移動します。",
"xpack.infra.alerting.alertDropdownTitle": "アラート",
"xpack.infra.alerting.alertFlyout.groupBy.placeholder": "なし (グループなし) ",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 213e5415ceedd..413983c7c8f83 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -10045,8 +10045,6 @@
"xpack.indexLifecycleMgmt.appTitle": "索引生命周期策略",
"xpack.indexLifecycleMgmt.breadcrumb.editPolicyLabel": "编辑策略",
"xpack.indexLifecycleMgmt.breadcrumb.homeLabel": "索引生命周期管理",
- "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody": "至少将一个节点分配到冷层、温层或热层,以使用基于角色的分配。如果没有可用节点,则策略无法完成分配。",
- "xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle": "没有分配到冷层的节点",
"xpack.indexLifecycleMgmt.coldPhase.dataTier.description": "将数据移到针对不太频繁的只读访问优化的节点。将处于冷阶段的数据存储在成本较低的硬件上。",
"xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel": "冻结索引",
"xpack.indexLifecycleMgmt.common.dataTier.title": "数据分配",
@@ -10059,7 +10057,6 @@
"xpack.indexLifecycleMgmt.editPolicy.cancelButton": "取消",
"xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.body": "编辑您的 Elastic Cloud 部署以设置冷层。",
"xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.title": "创建冷层",
- "xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription": "在 elasticsearch.yml 中定义定制节点属性,以使用基于属性的分配。",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.activateColdPhaseSwitchLabel": "激活冷阶段",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseDescription": "将数据移到经过优化后节省了成本但牺牲了搜索性能的冷层。数据在冷阶段通常为只读。",
"xpack.indexLifecycleMgmt.editPolicy.coldPhase.coldPhaseTitle": "冷阶段",
@@ -10077,7 +10074,6 @@
"xpack.indexLifecycleMgmt.editPolicy.createSnapshotRepositoryLink": "创建新的快照库",
"xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.allocationFieldLabel": "数据层选项",
"xpack.indexLifecycleMgmt.editPolicy.dataTierAllocation.nodeAllocationFieldLabel": "选择节点属性",
- "xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel": "冷",
"xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel": "热",
"xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel": "温",
"xpack.indexLifecycleMgmt.editPolicy.daysOptionLabel": "天",
@@ -10142,9 +10138,7 @@
"xpack.indexLifecycleMgmt.editPolicy.minutesOptionLabel": "分钟",
"xpack.indexLifecycleMgmt.editPolicy.nanoSecondsOptionLabel": "纳秒",
"xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "使用节点属性控制分片分配。{learnMoreLink}。",
- "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "切勿修改分配配置",
"xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "无法加载节点数据",
- "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "未配置定制节点属性",
"xpack.indexLifecycleMgmt.editPolicy.nodeAttributesReloadButton": "重试",
"xpack.indexLifecycleMgmt.editPolicy.nodeDetailsLoadingFailedTitle": "无法加载节点属性详情",
"xpack.indexLifecycleMgmt.editPolicy.nodeDetailsReloadButton": "重试",
@@ -10190,7 +10184,6 @@
"xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage": "策略名称不能以下划线开头,且不能包含逗号或空格。",
"xpack.indexLifecycleMgmt.editPolicy.viewNodeDetailsButton": "查看具有选定属性的节点",
"xpack.indexLifecycleMgmt.editPolicy.waitForSnapshot.snapshotPolicyFieldLabel": "策略名称 (可选) ",
- "xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription": "在 elasticsearch.yml 中定义定制节点属性,以使用基于属性的分配。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "激活温阶段",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "设置在节点重新启动后恢复索引的优先级。较高优先级的索引会在较低优先级的索引之前恢复。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescription": "将数据移到优化了搜索性能但牺牲了索引性能的温层。在温层不经常添加或更新数据。",
@@ -10338,12 +10331,6 @@
"xpack.indexLifecycleMgmt.timeline.hotPhaseSectionTitle": "热阶段",
"xpack.indexLifecycleMgmt.timeline.title": "策略摘要",
"xpack.indexLifecycleMgmt.timeline.warmPhaseSectionTitle": "温阶段",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody": "至少将一个节点分配到温层或冷层,以使用基于角色的分配。如果没有可用节点,则策略无法完成分配。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle": "没有分配到温层的节点",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold": "此策略会改为将冷阶段的数据移到{tier}层节点。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title": "没有分配到冷层的节点",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm": "此策略会改为将温阶段的数据移到{tier}层节点。",
- "xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "没有分配到温层的节点",
"xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "将数据移到针对不太频繁的只读访问优化的节点。",
"xpack.infra.alerting.alertDropdownTitle": "告警",
"xpack.infra.alerting.alertFlyout.groupBy.placeholder": "无内容 (未分组) ",
From a5c7f6cfdc02942dba98a8332067faf6bd8c3c00 Mon Sep 17 00:00:00 2001
From: Spencer
Date: Mon, 3 May 2021 12:34:16 -0700
Subject: [PATCH 21/81] [x-pack/build] exclude plugins/*/target when copying
source to build (#99009)
Co-authored-by: spalger
---
x-pack/tasks/build.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/x-pack/tasks/build.ts b/x-pack/tasks/build.ts
index 1b52b073b3cef..96ec1c22687d1 100644
--- a/x-pack/tasks/build.ts
+++ b/x-pack/tasks/build.ts
@@ -76,6 +76,7 @@ async function copySourceAndBabelify() {
'**/node_modules/**',
'**/public/**/*.{js,ts,tsx,json}',
'**/{__tests__,__mocks__,__snapshots__}/**',
+ 'plugins/*/target/**',
'plugins/canvas/shareable_runtime/test/**',
'plugins/telemetry_collection_xpack/schema/**', // Skip telemetry schemas
],
From 28168714f0015072e820bab211676f7d9a33e01d Mon Sep 17 00:00:00 2001
From: Justin Ibarra
Date: Mon, 3 May 2021 11:43:41 -0800
Subject: [PATCH 22/81] [Detection Rules] Add 7.13 rules (#98975)
---
...collection_cloudtrail_logging_created.json | 4 +-
...llection_microsoft_365_new_inbox_rule.json | 64 +
...ommand_and_control_common_webservices.json | 4 +-
...fer_protocol_activity_to_the_internet.json | 58 -
.../command_and_control_iexplore_via_com.json | 7 +-
...hat_protocol_activity_to_the_internet.json | 58 -
...ol_port_8000_activity_to_the_internet.json | 43 -
..._to_point_tunneling_protocol_activity.json | 43 -
...l_proxy_port_activity_to_the_internet.json | 43 -
...ol_remote_file_copy_desktopimgdownldr.json | 8 +-
...and_control_remote_file_copy_mpcmdrun.json | 8 +-
...mand_and_control_smtp_to_the_internet.json | 58 -
..._server_port_activity_to_the_internet.json | 43 -
...ol_ssh_secure_shell_from_the_internet.json | 73 --
...trol_ssh_secure_shell_to_the_internet.json | 43 -
...control_sunburst_c2_activity_detected.json | 8 +-
...d_control_teamviewer_remote_file_copy.json | 8 +-
..._control_tor_activity_to_the_internet.json | 56 -
...d_and_control_tunneling_via_earthworm.json | 49 +
...ial_access_credential_dumping_msbuild.json | 8 +-
...edential_access_credentials_keychains.json | 4 +-
...cess_domain_backup_dpapi_private_keys.json | 8 +-
...ial_access_iam_user_addition_to_group.json | 4 +-
...s_keychain_pwd_retrieval_security_cmd.json | 22 +-
...ial_access_lsass_memdump_file_created.json | 8 +-
...l_access_mimikatz_memssp_default_logs.json | 8 +-
...ential_access_mitm_localhost_webproxy.json | 4 +-
...e_network_logon_provider_modification.json | 69 ++
.../credential_access_tcpdump_activity.json | 63 -
...den_file_attribute_with_via_attribexe.json | 8 +-
..._base64_encoding_or_decoding_activity.json | 53 -
...e_evasion_clearing_windows_event_logs.json | 8 +-
...se_evasion_cloudtrail_logging_deleted.json | 4 +-
..._evasion_cloudtrail_logging_suspended.json | 4 +-
...nse_evasion_cloudwatch_alarm_deletion.json | 4 +-
...efense_evasion_code_injection_conhost.json | 8 +-
..._evasion_config_service_rule_deletion.json | 11 +-
...vasion_configuration_recorder_stopped.json | 4 +-
...delete_volume_usn_journal_with_fsutil.json | 8 +-
...deleting_backup_catalogs_with_wbadmin.json | 8 +-
...ble_windows_firewall_rules_with_netsh.json | 8 +-
...defense_evasion_ec2_flow_log_deletion.json | 4 +-
...ense_evasion_ec2_network_acl_deletion.json | 4 +-
...coding_or_decoding_files_via_certutil.json | 8 +-
...ecution_msbuild_started_by_office_app.json | 8 +-
...n_execution_msbuild_started_by_script.json | 8 +-
...ion_msbuild_started_by_system_process.json | 8 +-
...ion_execution_msbuild_started_renamed.json | 8 +-
...cution_msbuild_started_unusal_process.json | 8 +-
...execution_suspicious_explorer_winword.json | 8 +-
...ution_via_trusted_developer_utilities.json | 58 -
...storage_bucket_configuration_modified.json | 4 +-
...p_storage_bucket_permissions_modified.json | 4 +-
...e_evasion_guardduty_detector_deletion.json | 4 +-
...ion_hex_encoding_or_decoding_activity.json | 53 -
...ense_evasion_iis_httplogging_disabled.json | 8 +-
...erading_suspicious_werfault_childproc.json | 10 +-
...vasion_masquerading_trusted_directory.json | 4 +-
...e_evasion_modification_of_boot_config.json | 8 +-
..._evasion_modify_environment_launchctl.json | 4 +-
...sion_s3_bucket_configuration_deletion.json | 4 +-
...n_suspicious_managedcode_host_process.json | 8 +-
...efense_evasion_suspicious_scrobj_load.json | 20 +-
..._critical_proc_abnormal_file_activity.json | 8 +-
.../defense_evasion_timestomp_touch.json | 4 +-
.../defense_evasion_unusual_dir_ads.json | 4 +-
...usual_network_connection_via_rundll32.json | 4 +-
...asion_unusual_system_vp_child_program.json | 8 +-
.../defense_evasion_via_filter_manager.json | 12 +-
..._volume_shadow_copy_deletion_via_wmic.json | 8 +-
.../defense_evasion_waf_acl_deletion.json | 4 +-
.../discovery_net_command_system_account.json | 8 +-
..._post_exploitation_external_ip_lookup.json | 53 +
...exploitation_public_ip_reconnaissance.json | 50 -
...rocess_discovery_via_tasklist_command.json | 49 -
.../discovery_query_registry_via_reg.json | 46 -
.../discovery_security_software_grep.json | 20 +-
...covery_users_domain_built_in_commands.json | 4 +-
.../discovery_whoami_command_activity.json | 8 +-
.../discovery_whoami_commmand.json | 48 -
...n_command_shell_started_by_powershell.json | 53 -
...tion_command_shell_started_by_svchost.json | 8 +-
...mand_shell_started_by_unusual_process.json | 8 +-
.../execution_command_shell_via_rundll32.json | 7 +-
.../execution_from_unusual_path_cmdline.json | 4 +-
...er_program_connecting_to_the_internet.json | 4 +-
.../execution_suspicious_pdf_reader.json | 8 +-
.../execution_via_compiled_html_file.json | 12 +-
.../execution_via_hidden_shell_conhost.json | 8 +-
.../execution_via_net_com_assemblies.json | 62 -
...ia_xp_cmdshell_mssql_stored_procedure.json | 8 +-
.../impact_cloudtrail_logging_updated.json | 4 +-
.../impact_cloudwatch_log_group_deletion.json | 4 +-
...impact_cloudwatch_log_stream_deletion.json | 4 +-
.../impact_ec2_disable_ebs_encryption.json | 4 +-
.../impact_gcp_storage_bucket_deleted.json | 4 +-
...p_virtual_private_cloud_route_created.json | 4 +-
.../impact_hosts_file_modified.json | 8 +-
.../impact_iam_deactivate_mfa_device.json | 7 +-
.../impact_iam_group_deletion.json | 4 +-
.../impact_rds_cluster_deletion.json | 4 +-
.../impact_rds_instance_cluster_stoppage.json | 4 +-
...ume_shadow_copy_deletion_via_vssadmin.json | 8 +-
.../rules/prepackaged_rules/index.ts | 1048 ++++++++---------
.../initial_access_console_login_root.json | 4 +-
.../initial_access_password_recovery.json | 4 +-
...mote_desktop_protocol_to_the_internet.json | 64 -
...al_access_script_executing_powershell.json | 8 +-
...uspicious_mac_ms_office_child_process.json | 4 +-
...l_access_suspicious_ms_exchange_files.json | 8 +-
...s_suspicious_ms_outlook_child_process.json | 8 +-
...l_access_unusual_dns_service_children.json | 8 +-
...ccess_unusual_dns_service_file_writes.json | 8 +-
...explorer_suspicious_child_parent_args.json | 4 +-
...n_lanman_nullsessionpipe_modification.json | 57 +
...ateral_movement_evasion_rdp_shadowing.json | 50 +
...teral_movement_local_service_commands.json | 46 -
...nt_service_control_spawned_script_int.json | 46 +
.../linux_mknod_activity.json | 33 -
.../linux_nmap_activity.json | 33 -
.../linux_socat_activity.json | 33 -
.../ml_cloudtrail_rare_error_code.json | 4 +-
.../ml_cloudtrail_rare_method_by_city.json | 4 +-
.../ml_cloudtrail_rare_method_by_country.json | 4 +-
.../ml_cloudtrail_rare_method_by_user.json | 4 +-
.../ml_high_count_network_denies.json | 29 +
.../ml_high_count_network_events.json | 29 +
.../ml_rare_destination_country.json | 29 +
.../ml_spike_in_traffic_to_a_country.json | 29 +
.../persistence_adobe_hijack_persistence.json | 8 +-
...ence_azure_automation_webhook_created.json | 3 +-
...l_access_modify_auth_module_or_config.json | 4 +-
...stence_cron_jobs_creation_and_runtime.json | 60 -
.../persistence_ec2_network_acl_creation.json | 4 +-
...egistry_startup_shell_folder_modified.json | 54 +
...sistence_gpo_schtask_service_creation.json | 8 +-
.../persistence_iam_group_creation.json | 4 +-
.../persistence_kernel_module_activity.json | 58 -
...istence_local_scheduled_job_creation.json} | 20 +-
...istence_local_scheduled_task_creation.json | 56 +
...rsistence_login_logout_hooks_defaults.json | 4 +-
.../persistence_rds_cluster_creation.json | 4 +-
...persistence_run_key_and_startup_broad.json | 4 +-
.../persistence_services_registry.json | 4 +-
...ersistence_system_shells_via_services.json | 8 +-
..._account_added_to_privileged_group_ad.json | 13 +-
.../persistence_user_account_creation.json | 8 +-
.../persistence_via_application_shimming.json | 8 +-
...rsistence_via_bits_job_notify_command.json | 52 +
...emetrycontroller_scheduledtask_hijack.json | 8 +-
...tence_via_wmi_stdregprov_run_services.json | 83 ++
..._printspooler_service_suspicious_file.json | 8 +-
...tion_printspooler_suspicious_spl_file.json | 8 +-
...ation_setuid_setgid_bit_set_via_chmod.json | 4 +-
...alation_uac_bypass_diskcleanup_hijack.json | 4 +-
...ge_escalation_uac_bypass_event_viewer.json | 12 +-
.../threat_intel_module_match.json | 198 ++++
157 files changed, 1861 insertions(+), 2282 deletions(-)
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_public_ip_reconnaissance.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_process_discovery_via_tasklist_command.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_query_registry_via_reg.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rdp_remote_desktop_protocol_to_the_internet.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_cron_jobs_creation_and_runtime.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json
delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json
rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{persistence_local_scheduled_task_commands.json => persistence_local_scheduled_job_creation.json} (53%)
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json
create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json
index 376293c399a76..0287565be0d7c 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudTrail Log Created",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:CreateTrail and event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:CreateTrail and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_CreateTrail.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/create-trail.html"
@@ -51,5 +51,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json
new file mode 100644
index 0000000000000..778b7ecc30192
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json
@@ -0,0 +1,64 @@
+{
+ "author": [
+ "Elastic",
+ "Gary Blackwell",
+ "Austin Songer"
+ ],
+ "description": "Identifies when a new Inbox rule is created in Microsoft 365. Inbox rules process messages in the Inbox based on conditions and take actions, such as moving a message to a specified folder or deleting a message. Adequate permissions are required on the mailbox to create an Inbox rule.",
+ "false_positives": [
+ "An inbox rule may be created by a system or network administrator. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior."
+ ],
+ "from": "now-30m",
+ "index": [
+ "filebeat-*",
+ "logs-o365*"
+ ],
+ "language": "kuery",
+ "license": "Elastic License v2",
+ "name": "Microsoft 365 New Inbox Rule Created",
+ "note": "The Microsoft 365 Fleet integration or Filebeat module must be enabled to use this rule.",
+ "query": "event.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:\"New-InboxRule\" and event.outcome:success",
+ "references": [
+ "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/responding-to-a-compromised-email-account?view=o365-worldwide",
+ "https://docs.microsoft.com/en-us/powershell/module/exchange/new-inboxrule?view=exchange-ps",
+ "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-outlook-rules-forms-attack?view=o365-worldwide"
+ ],
+ "risk_score": 21,
+ "rule_id": "ec8efb0c-604d-42fa-ac46-ed1cfbc38f78",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Cloud",
+ "Microsoft 365",
+ "Continuous Monitoring",
+ "SecOps",
+ "Configuration Audit"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0009",
+ "name": "Collection",
+ "reference": "https://attack.mitre.org/tactics/TA0009/"
+ },
+ "technique": [
+ {
+ "id": "T1114",
+ "name": "Email Collection",
+ "reference": "https://attack.mitre.org/techniques/T1114/",
+ "subtechnique": [
+ {
+ "id": "T1114.003",
+ "name": "Email Forwarding Rule",
+ "reference": "https://attack.mitre.org/techniques/T1114/003/"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "query",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json
index e2c521ca8d4dc..0d80e78c556b9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Connection to Commonly Abused Web Services",
- "query": "network where network.protocol == \"dns\" and\n /* Add new WebSvc domains here */\n dns.question.name :\n (\n \"*.githubusercontent.*\",\n \"*.pastebin.*\",\n \"*drive.google.*\",\n \"*docs.live.*\",\n \"*api.dropboxapi.*\",\n \"*dropboxusercontent.*\",\n \"*onedrive.*\",\n \"*4shared.*\",\n \"*.file.io\",\n \"*filebin.net\",\n \"*slack-files.com\",\n \"*ghostbin.*\",\n \"*ngrok.*\",\n \"*portmap.*\",\n \"*serveo.net\",\n \"*localtunnel.me\",\n \"*pagekite.me\",\n \"*localxpose.io\",\n \"*notabug.org\"\n ) and\n /* Insert noisy false positives here */\n not process.name :\n (\n \"MicrosoftEdgeCP.exe\",\n \"MicrosoftEdge.exe\",\n \"iexplore.exe\",\n \"chrome.exe\",\n \"msedge.exe\",\n \"opera.exe\",\n \"firefox.exe\",\n \"Dropbox.exe\",\n \"slack.exe\",\n \"svchost.exe\",\n \"thunderbird.exe\",\n \"outlook.exe\",\n \"OneDrive.exe\"\n )\n",
+ "query": "network where network.protocol == \"dns\" and\n process.name != null and user.id not in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and\n /* Add new WebSvc domains here */\n dns.question.name :\n (\n \"raw.githubusercontent.*\",\n \"*.pastebin.*\",\n \"*drive.google.*\",\n \"*docs.live.*\",\n \"*api.dropboxapi.*\",\n \"*dropboxusercontent.*\",\n \"*onedrive.*\",\n \"*4shared.*\",\n \"*.file.io\",\n \"*filebin.net\",\n \"*slack-files.com\",\n \"*ghostbin.*\",\n \"*ngrok.*\",\n \"*portmap.*\",\n \"*serveo.net\",\n \"*localtunnel.me\",\n \"*pagekite.me\",\n \"*localxpose.io\",\n \"*notabug.org\",\n \"rawcdn.githack.*\",\n \"paste.nrecom.net\",\n \"zerobin.net\",\n \"controlc.com\",\n \"requestbin.net\"\n ) and\n /* Insert noisy false positives here */\n not process.executable :\n (\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\WWAHost.exe\",\n \"?:\\\\Windows\\\\System32\\\\smartscreen.exe\",\n \"?:\\\\Windows\\\\System32\\\\MicrosoftEdgeCP.exe\",\n \"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\Platform\\\\*\\\\MsMpEng.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Fiddler\\\\Fiddler.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Microsoft VS Code\\\\Code.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\OneDrive\\\\OneDrive.exe\",\n \"?:\\\\Windows\\\\system32\\\\mobsync.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\mobsync.exe\"\n )\n",
"risk_score": 21,
"rule_id": "66883649-f908-4a5b-a1e0-54090a1d3a32",
"severity": "low",
@@ -42,5 +42,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json
deleted file mode 100644
index 526df5012899b..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that may indicate the use of FTP network connections to the Internet. The File Transfer Protocol (FTP) has been around in its current form since the 1980s. It can be a common and efficient procedure on your network to send and receive files. Because of this, adversaries will also often use this protocol to exfiltrate data from your network or download new tools. Additionally, FTP is a plain-text protocol which, if intercepted, may expose usernames and passwords. FTP activity involving servers subject to regulations or compliance standards may be unauthorized.",
- "false_positives": [
- "FTP servers should be excluded from this rule as this is expected behavior. Some business workflows may use FTP for data exchange. These workflows often have expected characteristics such as users, sources, and destinations. FTP activity involving an unusual source or destination may be more suspicious. FTP activity involving a production server that has no known associated FTP workflow or business requirement is often suspicious."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "FTP (File Transfer Protocol) Activity to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:(20 or 21) or event.dataset:zeek.ftp) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 21,
- "rule_id": "87ec6396-9ac4-4706-bcf0-2ebb22002f43",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0010",
- "name": "Exfiltration",
- "reference": "https://attack.mitre.org/tactics/TA0010/"
- },
- "technique": [
- {
- "id": "T1048",
- "name": "Exfiltration Over Alternative Protocol",
- "reference": "https://attack.mitre.org/techniques/T1048/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json
index cc586c80778e3..2cfbbc1c5e101 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json
@@ -3,6 +3,9 @@
"Elastic"
],
"description": "Identifies instances of Internet Explorer (iexplore.exe) being started via the Component Object Model (COM) making unusual network connections. Adversaries could abuse Internet Explorer via COM to avoid suspicious processes making network connections and bypass host-based firewall restrictions.",
+ "false_positives": [
+ "Processes such as MS Office using IEproxy to render HTML content."
+ ],
"from": "now-9m",
"index": [
"winlogbeat-*",
@@ -12,7 +15,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Potential Command and Control via Internet Explorer",
- "query": "sequence by host.id, process.entity_id with maxspan = 1s\n [process where event.type == \"start\" and process.parent.name : \"iexplore.exe\" and process.parent.args : \"-Embedding\"]\n /* IE started via COM in normal conditions makes few connections, mainly to Microsoft and OCSP related domains, add FPs here */\n [network where network.protocol == \"dns\" and process.name : \"iexplore.exe\" and\n not dns.question.name :\n (\n \"*.microsoft.com\",\n \"*.digicert.com\",\n \"*.msocsp.com\",\n \"*.windowsupdate.com\",\n \"*.bing.com\",\n \"*.identrust.com\"\n )\n ]\n",
+ "query": "sequence by host.id, user.id with maxspan = 5s\n [library where dll.name : \"IEProxy.dll\" and process.name : (\"rundll32.exe\", \"regsvr32.exe\")]\n [process where event.type == \"start\" and process.parent.name : \"iexplore.exe\" and process.parent.args : \"-Embedding\"]\n /* IE started via COM in normal conditions makes few connections, mainly to Microsoft and OCSP related domains, add FPs here */\n [network where network.protocol == \"dns\" and process.name : \"iexplore.exe\" and\n not dns.question.name :\n (\n \"*.microsoft.com\",\n \"*.digicert.com\",\n \"*.msocsp.com\",\n \"*.windowsupdate.com\",\n \"*.bing.com\",\n \"*.identrust.com\",\n \"*.sharepoint.com\",\n \"*.office365.com\",\n \"*.office.com\"\n )\n ]\n",
"risk_score": 47,
"rule_id": "acd611f3-2b93-47b3-a0a3-7723bcc46f6d",
"severity": "medium",
@@ -41,5 +44,5 @@
}
],
"type": "eql",
- "version": 2
+ "version": 3
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json
deleted file mode 100644
index be1dcc5dfd1ba..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that use common ports for Internet Relay Chat (IRC) to the Internet. IRC is a common protocol that can be used for chat and file transfers. This protocol is also a good candidate for remote control of malware and data transfers to and from a network.",
- "false_positives": [
- "IRC activity may be normal behavior for developers and engineers but is unusual for non-engineering end users. IRC activity involving an unusual source or destination may be more suspicious. IRC activity involving a production server is often suspicious. Because these ports are in the ephemeral range, this rule may false under certain conditions, such as when a NAT-ed web server replies to a client which has used a port in the range by coincidence. In this case, these servers can be excluded. Some legacy applications may use these ports, but this is very uncommon and usually only appears in local traffic using private IPs, which does not match this rule's conditions."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "IRC (Internet Relay Chat) Protocol Activity to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:(6667 or 6697) or event.dataset:zeek.irc) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 47,
- "rule_id": "c6474c34-4953-447a-903e-9fcb7b6661aa",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0010",
- "name": "Exfiltration",
- "reference": "https://attack.mitre.org/tactics/TA0010/"
- },
- "technique": [
- {
- "id": "T1048",
- "name": "Exfiltration Over Alternative Protocol",
- "reference": "https://attack.mitre.org/techniques/T1048/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json
deleted file mode 100644
index 8ba395fea25eb..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_8000_activity_to_the_internet.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "TCP Port 8000 is commonly used for development environments of web server software. It generally should not be exposed directly to the Internet. If you are running software like this on the Internet, you should consider placing it behind a reverse proxy.",
- "false_positives": [
- "Because this port is in the ephemeral range, this rule may false under certain conditions, such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded. Some applications may use this port but this is very uncommon and usually appears in local traffic using private IPs, which this rule does not match. Some cloud environments, particularly development environments, may use this port when VPNs or direct connects are not in use and cloud instances are accessed across the Internet."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "TCP Port 8000 Activity to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and destination.port:8000 and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 21,
- "rule_id": "08d5d7e2-740f-44d8-aeda-e41f4263efaf",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json
deleted file mode 100644
index 8180275e4c456..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_pptp_point_to_point_tunneling_protocol_activity.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that may indicate use of a PPTP VPN connection. Some threat actors use these types of connections to tunnel their traffic while avoiding detection.",
- "false_positives": [
- "Some networks may utilize PPTP protocols but this is uncommon as more modern VPN technologies are available. Usage that is unfamiliar to local network administrators can be unexpected and suspicious. Torrenting applications may use this port. Because this port is in the ephemeral range, this rule may false under certain conditions, such as when an application server replies to a client that used this port by coincidence. This is uncommon but such servers can be excluded."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "PPTP (Point to Point Tunneling Protocol) Activity",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and destination.port:1723",
- "risk_score": 21,
- "rule_id": "d2053495-8fe7-4168-b3df-dad844046be3",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json
deleted file mode 100644
index b970c00fb7c4a..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_proxy_port_activity_to_the_internet.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that may describe network events of proxy use to the Internet. It includes popular HTTP proxy ports and SOCKS proxy ports. Typically, environments will use an internal IP address for a proxy server. It can also be used to circumvent network controls and detection mechanisms.",
- "false_positives": [
- "Some proxied applications may use these ports but this usually occurs in local traffic using private IPs which this rule does not match. Proxies are widely used as a security technology but in enterprise environments this is usually local traffic which this rule does not match. If desired, internet proxy services using these ports can be added to allowlists. Some screen recording applications may use these ports. Proxy port activity involving an unusual source or destination may be more suspicious. Some cloud environments may use this port when VPNs or direct connects are not in use and cloud instances are accessed across the Internet. Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded if desired."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Proxy Port Activity to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:(1080 or 3128 or 8080) or event.dataset:zeek.socks) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 47,
- "rule_id": "ad0e5e75-dd89-4875-8d0a-dfdc1828b5f3",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json
index 4c982df62ed8c..3adeb4f71808a 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Remote File Download via Desktopimgdownldr Utility",
- "query": "event.category:process and event.type:(start or process_started) and (process.name:desktopimgdownldr.exe or process.pe.original_file_name:desktopimgdownldr.exe) and process.args:/lockscreenurl\\:http*",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"desktopimgdownldr.exe\" or process.pe.original_file_name == \"desktopimgdownldr.exe\") and\n process.args : \"/lockscreenurl:http*\"\n",
"references": [
"https://labs.sentinelone.com/living-off-windows-land-a-new-native-file-downldr/"
],
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json
index c88c0c1f48da1..bbda3c0a4f49b 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json
@@ -9,11 +9,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Remote File Download via MpCmdRun",
"note": "### Investigating Remote File Download via MpCmdRun\nVerify details such as the parent process, URL reputation, and downloaded file details. Additionally, `MpCmdRun` logs this information in the Appdata Temp folder in `MpCmdRun.log`.",
- "query": "event.category:process and event.type:(start or process_started) and (process.name:MpCmdRun.exe or process.pe.original_file_name:MpCmdRun.exe) and process.args:((\"-DownloadFile\" or \"-downloadfile\") and \"-url\" and \"-path\")",
+ "query": "process where event.type == \"start\" and\n (process.name : \"MpCmdRun.exe\" or process.pe.original_file_name == \"MpCmdRun.exe\") and\n process.args : \"-DownloadFile\" and process.args : \"-url\" and process.args : \"-path\"\n",
"references": [
"https://twitter.com/mohammadaskar2/status/1301263551638761477",
"https://www.bleepingcomputer.com/news/microsoft/microsoft-defender-can-ironically-be-used-to-download-malware/"
@@ -46,6 +46,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json
deleted file mode 100644
index 528485a984252..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_smtp_to_the_internet.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that may describe SMTP traffic from internal hosts to a host across the Internet. In an enterprise network, there is typically a dedicated internal host that performs this function. It is also frequently abused by threat actors for command and control, or data exfiltration.",
- "false_positives": [
- "NATed servers that process email traffic may false and should be excluded from this rule as this is expected behavior for them. Consumer and personal devices may send email traffic to remote Internet destinations. In this case, such devices or networks can be excluded from this rule if this is expected behavior."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "SMTP to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:(25 or 465 or 587) or event.dataset:zeek.smtp) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 21,
- "rule_id": "67a9beba-830d-4035-bfe8-40b7e28f8ac4",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0010",
- "name": "Exfiltration",
- "reference": "https://attack.mitre.org/tactics/TA0010/"
- },
- "technique": [
- {
- "id": "T1048",
- "name": "Exfiltration Over Alternative Protocol",
- "reference": "https://attack.mitre.org/techniques/T1048/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json
deleted file mode 100644
index e3e237107257c..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sql_server_port_activity_to_the_internet.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects events that may describe database traffic (MS SQL, Oracle, MySQL, and Postgresql) across the Internet. Databases should almost never be directly exposed to the Internet, as they are frequently targeted by threat actors to gain initial access to network resources.",
- "false_positives": [
- "Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used a port in the range by coincidence. In this case, such servers can be excluded if desired. Some cloud environments may use this port when VPNs or direct connects are not in use and database instances are accessed directly across the Internet."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "SQL Traffic to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:(1433 or 1521 or 3306 or 5432) or event.dataset:zeek.mysql) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 47,
- "rule_id": "139c7458-566a-410c-a5cd-f80238d6a5cd",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json
deleted file mode 100644
index 74a1bda6c7077..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_from_the_internet.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects network events that may indicate the use of SSH traffic from the Internet. SSH is commonly used by system administrators to remotely control a system using the command line shell. If it is exposed to the Internet, it should be done with strong security controls as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
- "false_positives": [
- "Some network security policies allow SSH directly from the Internet but usage that is unfamiliar to server or network owners can be unexpected and suspicious. SSH services may be exposed directly to the Internet in some networks such as cloud environments. In such cases, only SSH gateways, bastions or jump servers may be expected expose SSH directly to the Internet and can be exempted from this rule. SSH may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "SSH (Secure Shell) from the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:22 or event.dataset:zeek.ssh) and not source.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" ) and destination.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 )",
- "risk_score": 47,
- "rule_id": "ea0784f0-a4d7-4fea-ae86-4baaf27a6f17",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0008",
- "name": "Lateral Movement",
- "reference": "https://attack.mitre.org/tactics/TA0008/"
- },
- "technique": [
- {
- "id": "T1021",
- "name": "Remote Services",
- "reference": "https://attack.mitre.org/techniques/T1021/"
- }
- ]
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0001",
- "name": "Initial Access",
- "reference": "https://attack.mitre.org/tactics/TA0001/"
- },
- "technique": [
- {
- "id": "T1190",
- "name": "Exploit Public-Facing Application",
- "reference": "https://attack.mitre.org/techniques/T1190/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json
deleted file mode 100644
index 9c13293e5719f..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ssh_secure_shell_to_the_internet.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects network events that may indicate the use of SSH traffic from the Internet. SSH is commonly used by system administrators to remotely control a system using the command line shell. If it is exposed to the Internet, it should be done with strong security controls as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
- "false_positives": [
- "SSH connections may be made directly to Internet destinations in order to access Linux cloud server instances but such connections are usually made only by engineers. In such cases, only SSH gateways, bastions or jump servers may be expected Internet destinations and can be exempted from this rule. SSH may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "SSH (Secure Shell) to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:22 or event.dataset:zeek.ssh) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 21,
- "rule_id": "6f1500bc-62d7-4eb9-8601-7485e87da2f4",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json
index 6c4437b11b88e..1aede9216de12 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json
@@ -7,11 +7,11 @@
"index": [
"logs-endpoint.events.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "SUNBURST Command and Control Activity",
"note": "The SUNBURST malware attempts to hide within the Orion Improvement Program (OIP) network traffic. As this rule detects post-exploitation network traffic, investigations into this should be prioritized.",
- "query": "event.category:network and event.type:protocol and network.protocol:http and process.name:( ConfigurationWizard.exe or NetFlowService.exe or NetflowDatabaseMaintenance.exe or SolarWinds.Administration.exe or SolarWinds.BusinessLayerHost.exe or SolarWinds.BusinessLayerHostx64.exe or SolarWinds.Collector.Service.exe or SolarwindsDiagnostics.exe) and http.request.body.content:(( (*/swip/Upload.ashx* and (POST* or PUT*)) or (*/swip/SystemDescription* and (GET* or HEAD*)) or (*/swip/Events* and (GET* or HEAD*))) and not *solarwinds.com*)",
+ "query": "network where event.type == \"protocol\" and network.protocol == \"http\" and\n process.name : (\"ConfigurationWizard.exe\",\n \"NetFlowService.exe\",\n \"NetflowDatabaseMaintenance.exe\",\n \"SolarWinds.Administration.exe\",\n \"SolarWinds.BusinessLayerHost.exe\",\n \"SolarWinds.BusinessLayerHostx64.exe\",\n \"SolarWinds.Collector.Service.exe\",\n \"SolarwindsDiagnostics.exe\") and\n (http.request.body.content : \"*/swip/Upload.ashx*\" and http.request.body.content : (\"POST*\", \"PUT*\")) or\n (http.request.body.content : (\"*/swip/SystemDescription*\", \"*/swip/Events*\") and http.request.body.content : (\"GET*\", \"HEAD*\")) and\n not http.request.body.content : \"*solarwinds.com*\"\n",
"references": [
"https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html"
],
@@ -72,6 +72,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json
index b8fdc02d24628..08d4df2556f6a 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Remote File Copy via TeamViewer",
- "query": "event.category:file and event.type:creation and process.name:TeamViewer.exe and file.extension:(exe or dll or scr or com or bat or ps1 or vbs or vbe or js or wsh or hta)",
+ "query": "file where event.type == \"creation\" and process.name : \"TeamViewer.exe\" and\n file.extension : (\"exe\", \"dll\", \"scr\", \"com\", \"bat\", \"ps1\", \"vbs\", \"vbe\", \"js\", \"wsh\", \"hta\")\n",
"references": [
"https://blog.menasec.net/2019/11/hunting-for-suspicious-use-of.html"
],
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json
deleted file mode 100644
index 9f06808a3d9ba..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tor_activity_to_the_internet.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects network events that may indicate the use of Tor traffic to the Internet. Tor is a network protocol that sends traffic through a series of encrypted tunnels used to conceal a user's location and usage. Tor may be used by threat actors as an alternate communication pathway to conceal the actor's identity and avoid detection.",
- "false_positives": [
- "Tor client activity is uncommon in managed enterprise networks but may be common in unmanaged or public networks where few security policies apply. Because these ports are in the ephemeral range, this rule may false under certain conditions such as when a NATed web server replies to a client which has used one of these ports by coincidence. In this case, such servers can be excluded if desired."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Tor Activity to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and destination.port:(9001 or 9030) and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and not destination.ip:(10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\")",
- "risk_score": 47,
- "rule_id": "7d2c38d7-ede7-4bdf-b140-445906e6c540",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Command and Control"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0011",
- "name": "Command and Control",
- "reference": "https://attack.mitre.org/tactics/TA0011/"
- },
- "technique": [
- {
- "id": "T1090",
- "name": "Proxy",
- "reference": "https://attack.mitre.org/techniques/T1090/",
- "subtechnique": [
- {
- "id": "T1090.003",
- "name": "Multi-hop Proxy",
- "reference": "https://attack.mitre.org/techniques/T1090/003/"
- }
- ]
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json
new file mode 100644
index 0000000000000..eafe28709a0d2
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json
@@ -0,0 +1,49 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies the execution of the EarthWorm tunneler. Adversaries may tunnel network communications to and from a victim system within a separate protocol to avoid detection and network filtering, or to enable access to otherwise unreachable systems.",
+ "from": "now-9m",
+ "index": [
+ "auditbeat-*",
+ "logs-endpoint.events.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Potential Protocol Tunneling via EarthWorm",
+ "query": "process where event.type == \"start\" and\n process.args : \"-s\" and process.args : \"-d\" and process.args : \"rssocks\"\n",
+ "references": [
+ "http://rootkiter.com/EarthWorm/",
+ "https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/"
+ ],
+ "risk_score": 47,
+ "rule_id": "9f1c4ca3-44b5-481d-ba42-32dc215a2769",
+ "severity": "medium",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Linux",
+ "Threat Detection",
+ "Command and Control"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0011",
+ "name": "Command and Control",
+ "reference": "https://attack.mitre.org/tactics/TA0011/"
+ },
+ "technique": [
+ {
+ "id": "T1572",
+ "name": "Protocol Tunneling",
+ "reference": "https://attack.mitre.org/techniques/T1572/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json
index 10d988075226c..da4689ed12d70 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Loading Windows Credential Libraries",
- "query": "event.category:process and event.type:change and (process.pe.original_file_name:(vaultcli.dll or SAMLib.DLL) or dll.name:(vaultcli.dll or SAMLib.DLL)) and process.name: MSBuild.exe",
+ "query": "sequence by process.entity_id\n [process where event.type == \"start\" and (process.name : \"MSBuild.exe\" or process.pe.original_file_name == \"MSBuild.exe\")]\n [library where dll.name : (\"vaultcli.dll\", \"SAMLib.DLL\")]\n",
"risk_score": 73,
"rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae5",
"severity": "high",
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json
index 8d4c6f7e0f605..9c8f2943c44d8 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json
@@ -11,7 +11,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Access to Keychain Credentials Directories",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.args :\n (\n \"/Users/*/Library/Keychains/*\",\n \"/Library/Keychains/*\",\n \"/Network/Library/Keychains/*\",\n \"System.keychain\",\n \"login.keychain-db\",\n \"login.keychain\"\n )\n",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.args :\n (\n \"/Users/*/Library/Keychains/*\",\n \"/Library/Keychains/*\",\n \"/Network/Library/Keychains/*\",\n \"System.keychain\",\n \"login.keychain-db\",\n \"login.keychain\"\n ) and\n not process.args : (\"find-certificate\",\n \"add-trusted-cert\",\n \"set-keychain-settings\",\n \"delete-certificate\",\n \"/Users/*/Library/Keychains/openvpn.keychain-db\",\n \"show-keychain-info\",\n \"lock-keychain\",\n \"set-key-partition-list\",\n \"import\",\n \"find-identity\") and\n not process.parent.executable : \"/Applications/OpenVPN Connect/OpenVPN Connect.app/Contents/MacOS/OpenVPN Connect\"\n",
"references": [
"https://objective-see.com/blog/blog_0x25.html",
"https://securelist.com/calisto-trojan-for-macos/86543/"
@@ -52,5 +52,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json
index 159b51a2a9e0a..361b5f9e3e62e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json
@@ -9,11 +9,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Creation or Modification of Domain Backup DPAPI private key",
"note": "### Domain DPAPI Backup keys are stored on domain controllers and can be dumped remotely with tools such as Mimikatz. The resulting .pvk private key can be used to decrypt ANY domain user masterkeys, which then can be used to decrypt any secrets protected by those keys.",
- "query": "event.category:file and not event.type:deletion and file.name:(ntds_capi_*.pfx or ntds_capi_*.pvk)",
+ "query": "file where event.type != \"deletion\" and file.name : (\"ntds_capi_*.pfx\", \"ntds_capi_*.pvk\")\n",
"references": [
"https://www.dsinternals.com/en/retrieving-dpapi-backup-keys-from-active-directory/",
"https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/"
@@ -53,6 +53,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json
index 122e15352f973..20674ebe4490e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS IAM User Addition to Group",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:AddUserToGroup and event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.action:AddUserToGroup and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/IAM/latest/APIReference/API_AddUserToGroup.html"
],
@@ -59,5 +59,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json
index d3d3276936825..cacf0e1f3676c 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json
@@ -4,17 +4,17 @@
],
"description": "Adversaries may collect keychain storage data from a system to in order to acquire credentials. Keychains are the built-in way for macOS to keep track of users' passwords and credentials for many services and features, including Wi-Fi and website passwords, secure notes, certificates, and Kerberos.",
"false_positives": [
- "Trusted parent processes accessing their respective application passwords."
+ "Applications for password management."
],
"from": "now-9m",
"index": [
"auditbeat-*",
"logs-endpoint.events.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Keychain Password Retrieval via Command Line",
- "query": "event.category:process and event.type:(start or process_started) and process.name:security and process.args:(\"find-generic-password\" or \"find-internet-password\")",
+ "query": "process where event.type == \"start\" and\n process.name : \"security\" and process.args : \"-wa\" and process.args : (\"find-generic-password\", \"find-internet-password\") and\n process.args : (\"Chrome*\", \"Chromium\", \"Opera\", \"Safari*\", \"Brave\", \"Microsoft Edge\", \"Edge\", \"Firefox*\") and\n not process.parent.executable : \"/Applications/Keeper Password Manager.app/Contents/Frameworks/Keeper Password Manager Helper*/Contents/MacOS/Keeper Password Manager Helper*\"\n",
"references": [
"https://www.netmeister.org/blog/keychain-passwords.html",
"https://github.com/priyankchheda/chrome_password_grabber/blob/master/chrome.py",
@@ -51,11 +51,23 @@
"reference": "https://attack.mitre.org/techniques/T1555/001/"
}
]
+ },
+ {
+ "id": "T1555",
+ "name": "Credentials from Password Stores",
+ "reference": "https://attack.mitre.org/techniques/T1555/",
+ "subtechnique": [
+ {
+ "id": "T1555.003",
+ "name": "Credentials from Web Browsers",
+ "reference": "https://attack.mitre.org/techniques/T1555/003/"
+ }
+ ]
}
]
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 1
+ "type": "eql",
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json
index 220c6e3befbf5..36b614c628b19 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "LSASS Memory Dump Creation",
- "query": "event.category:file and file.name:(lsass.DMP or lsass*.dmp or dumpert.dmp or Andrew.dmp or SQLDmpr*.mdmp or Coredump.dmp)",
+ "query": "file where file.name : (\"lsass*.dmp\", \"dumpert.dmp\", \"Andrew.dmp\", \"SQLDmpr*.mdmp\", \"Coredump.dmp\")\n",
"references": [
"https://github.com/outflanknl/Dumpert",
"https://github.com/hoangprod/AndrewSpecial"
@@ -45,6 +45,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json
index 0193a4e59dd0d..9f9bd297e17c1 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Mimikatz Memssp Log File Detected",
- "query": "event.category:file and file.name:mimilsa.log and process.name:lsass.exe",
+ "query": "file where file.name : \"mimilsa.log\" and process.name : \"lsass.exe\"\n",
"risk_score": 73,
"rule_id": "ebb200e8-adf0-43f8-a0bb-4ee5b5d852c6",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json
index 50429c3b0f169..e226df7a23da9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json
@@ -14,7 +14,7 @@
"language": "kuery",
"license": "Elastic License v2",
"name": "WebProxy Settings Modification",
- "query": "event.category:process and event.type:start and process.name:networksetup and process.args:(\"-setwebproxy\" or \"-setsecurewebproxy\" or \"-setautoproxyurl\")",
+ "query": "event.category : process and event.type : start and process.name : networksetup and process.args : ((\"-setwebproxy\" or \"-setsecurewebproxy\" or \"-setautoproxyurl\") and not (Bluetooth or off)) and not process.parent.executable : (\"/Library/PrivilegedHelperTools/com.80pct.FreedomHelper\" or \"/Applications/Fiddler Everywhere.app/Contents/Resources/app/out/WebServer/Fiddler.WebUi\" or \"/usr/libexec/xpcproxy\")",
"references": [
"https://unit42.paloaltonetworks.com/mac-malware-steals-cryptocurrency-exchanges-cookies/",
"https://objectivebythesea.com/v2/talks/OBTS_v2_Zohar.pdf"
@@ -48,5 +48,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json
new file mode 100644
index 0000000000000..166ddf7c5592d
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json
@@ -0,0 +1,69 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Adversaries may register a rogue network logon provider module for persistence and/or credential access via intercepting the authentication credentials in clear text during user logon.",
+ "false_positives": [
+ "Authorized third party network logon providers."
+ ],
+ "from": "now-9m",
+ "index": [
+ "auditbeat-*",
+ "logs-endpoint.events.*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Network Logon Provider Registry Modification",
+ "query": "registry where registry.data.strings != null and\n registry.path : \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\Services\\\\*\\\\NetworkProvider\\\\ProviderPath\" and\n /* Excluding default NetworkProviders RDPNP, LanmanWorkstation and webclient. */\n not ( user.id : \"S-1-5-18\" and\n registry.data.strings in\n (\"%SystemRoot%\\\\System32\\\\ntlanman.dll\",\n \"%SystemRoot%\\\\System32\\\\drprov.dll\",\n \"%SystemRoot%\\\\System32\\\\davclnt.dll\")\n )\n",
+ "references": [
+ "https://github.com/gtworek/PSBits/tree/master/PasswordStealing/NPPSpy",
+ "https://docs.microsoft.com/en-us/windows/win32/api/npapi/nf-npapi-nplogonnotify"
+ ],
+ "risk_score": 47,
+ "rule_id": "54c3d186-0461-4dc3-9b33-2dc5c7473936",
+ "severity": "medium",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Persistence",
+ "Credential Access"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0006",
+ "name": "Credential Access",
+ "reference": "https://attack.mitre.org/tactics/TA0006/"
+ },
+ "technique": [
+ {
+ "id": "T1556",
+ "name": "Modify Authentication Process",
+ "reference": "https://attack.mitre.org/techniques/T1556/"
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0003",
+ "name": "Persistence",
+ "reference": "https://attack.mitre.org/tactics/TA0003/"
+ },
+ "technique": [
+ {
+ "id": "T1543",
+ "name": "Create or Modify System Process",
+ "reference": "https://attack.mitre.org/techniques/T1543/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json
deleted file mode 100644
index 4721a43d116b4..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "The Tcpdump program ran on a Linux host. Tcpdump is a network monitoring or packet sniffing tool that can be used to capture insecure credentials or data in motion. Sniffing can also be used to discover details of network services as a prelude to lateral movement or defense evasion.",
- "false_positives": [
- "Some normal use of this command may originate from server or network administrators engaged in network troubleshooting."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Network Sniffing via Tcpdump",
- "query": "event.category:process and event.type:(start or process_started) and process.name:tcpdump",
- "risk_score": 21,
- "rule_id": "7a137d76-ce3d-48e2-947d-2747796a78c0",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection",
- "Credential Access"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0006",
- "name": "Credential Access",
- "reference": "https://attack.mitre.org/tactics/TA0006/"
- },
- "technique": [
- {
- "id": "T1040",
- "name": "Network Sniffing",
- "reference": "https://attack.mitre.org/techniques/T1040/"
- }
- ]
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0007",
- "name": "Discovery",
- "reference": "https://attack.mitre.org/tactics/TA0007/"
- },
- "technique": [
- {
- "id": "T1040",
- "name": "Network Sniffing",
- "reference": "https://attack.mitre.org/techniques/T1040/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json
index 2c505fa829b18..66d900975ff39 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Adding Hidden File Attribute via Attrib",
- "query": "event.category:process and event.type:(start or process_started) and process.name:attrib.exe and process.args:+h",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"attrib.exe\" and process.args : \"+h\"\n",
"risk_score": 21,
"rule_id": "4630d948-40d4-4cef-ac69-4002e29bc3db",
"severity": "low",
@@ -57,6 +57,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json
deleted file mode 100644
index 53610d0c4c89e..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Adversaries may encode/decode data in an attempt to evade detection by host- or network-based security controls.",
- "false_positives": [
- "Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Base64 Encoding/Decoding Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(base64 or base64plain or base64url or base64mime or base64pem)",
- "risk_score": 21,
- "rule_id": "97f22dab-84e8-409d-955e-dacd1d31670b",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection",
- "Defense Evasion"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0005",
- "name": "Defense Evasion",
- "reference": "https://attack.mitre.org/tactics/TA0005/"
- },
- "technique": [
- {
- "id": "T1140",
- "name": "Deobfuscate/Decode Files or Information",
- "reference": "https://attack.mitre.org/techniques/T1140/"
- },
- {
- "id": "T1027",
- "name": "Obfuscated Files or Information",
- "reference": "https://attack.mitre.org/techniques/T1027/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json
index f187be2225f6d..79e059d68a52a 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Clearing Windows Event Logs",
- "query": "event.category:process and event.type:(process_started or start) and (process.name:\"wevtutil.exe\" or process.pe.original_file_name:\"wevtutil.exe\") and process.args:(\"/e:false\" or cl or \"clear-log\") or process.name:\"powershell.exe\" and process.args:\"Clear-EventLog\"",
+ "query": "process where event.type in (\"process_started\", \"start\") and\n (process.name : \"wevtutil.exe\" or process.pe.original_file_name == \"wevtutil.exe\") and\n process.args : (\"/e:false\", \"cl\", \"clear-log\") or\n process.name : \"powershell.exe\" and process.args : \"Clear-EventLog\"\n",
"risk_score": 21,
"rule_id": "d331bbe2-6db4-4941-80a5-8270db72eb61",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json
index 305950feae54e..3ae05408ac81c 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudTrail Log Deleted",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteTrail and event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:DeleteTrail and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_DeleteTrail.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/delete-trail.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json
index fec0423debe7d..75e3e4f542c7d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudTrail Log Suspended",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:StopLogging and event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:StopLogging and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_StopLogging.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/stop-logging.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json
index 2d55f0b2e54fb..d05b043923482 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudWatch Alarm Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteAlarms and event.dataset:aws.cloudtrail and event.provider:monitoring.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:monitoring.amazonaws.com and event.action:DeleteAlarms and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudwatch/delete-alarms.html",
"https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DeleteAlarms.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_code_injection_conhost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_code_injection_conhost.json
index 7b675a04573f8..ba4fe13622733 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_code_injection_conhost.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_code_injection_conhost.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious Process from Conhost",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:conhost.exe and not process.executable:(\"C:\\Windows\\splwow64.exe\" or \"C:\\Windows\\System32\\WerFault.exe\" or \"C:\\\\Windows\\System32\\conhost.exe\")",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"conhost.exe\" and\n not process.executable : (\"?:\\\\Windows\\\\splwow64.exe\", \"?:\\\\Windows\\\\System32\\\\WerFault.exe\", \"?:\\\\Windows\\\\System32\\\\conhost.exe\")\n",
"references": [
"https://modexp.wordpress.com/2018/09/12/process-injection-user-data/",
"https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/Defense%20Evasion/evasion_codeinj_odzhan_conhost_sysmon_10_1.evtx"
@@ -45,6 +45,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json
index 409d318d5c98a..77d8deff1c191 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json
@@ -1,10 +1,11 @@
{
"author": [
- "Elastic"
+ "Elastic",
+ "Austin Songer"
],
- "description": "Identifies attempts to delete an AWS Config Service rule. An adversary may tamper with Config rules in order to reduce visibiltiy into the security posture of an account and / or its workload instances.",
+ "description": "Identifies attempts to delete an AWS Config Service resource. An adversary may tamper with Config services in order to reduce visibility into the security posture of an account and / or its workload instances.",
"false_positives": [
- "Privileged IAM users with security responsibilities may be expected to make changes to the Config rules in order to align with local security policies and requirements. Automation, orchestration, and security tools may also make changes to the Config service, where they are used to automate setup or configuration of AWS accounts. Other kinds of user or service contexts do not commonly make changes to this service."
+ "Privileged IAM users with security responsibilities may be expected to make changes to the Config service in order to align with local security policies and requirements. Automation, orchestration, and security tools may also make changes to the Config service, where they are used to automate setup or configuration of AWS accounts. Other kinds of user or service contexts do not commonly make changes to this service."
],
"from": "now-60m",
"index": [
@@ -16,7 +17,7 @@
"license": "Elastic License v2",
"name": "AWS Config Service Tampering",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.dataset: aws.cloudtrail and event.action: DeleteConfigRule and event.provider: config.amazonaws.com",
+ "query": "event.dataset:aws.cloudtrail and event.provider:config.amazonaws.com and event.action:(DeleteConfigRule or DeleteOrganizationConfigRule or DeleteConfigurationAggregator or DeleteConfigurationRecorder or DeleteConformancePack or DeleteOrganizationConformancePack or DeleteDeliveryChannel or DeleteRemediationConfiguration or DeleteRetentionConfiguration)",
"references": [
"https://docs.aws.amazon.com/config/latest/developerguide/how-does-config-work.html",
"https://docs.aws.amazon.com/config/latest/APIReference/API_Operations.html"
@@ -58,5 +59,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json
index 8ff04355d7294..7de02c3a3875d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS Configuration Recorder Stopped",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:StopConfigurationRecorder and event.dataset:aws.cloudtrail and event.provider:config.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:config.amazonaws.com and event.action:StopConfigurationRecorder and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/configservice/stop-configuration-recorder.html",
"https://docs.aws.amazon.com/config/latest/APIReference/API_StopConfigurationRecorder.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json
index df1609ea56c5e..caa6209fca745 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Delete Volume USN Journal with Fsutil",
- "query": "event.category:process and event.type:(start or process_started) and process.name:fsutil.exe and process.args:(deletejournal and usn)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"fsutil.exe\" or process.pe.original_file_name == \"fsutil.exe\") and \n process.args : \"deletejournal\" and process.args : \"usn\"\n",
"risk_score": 21,
"rule_id": "f675872f-6d85-40a3-b502-c0d2ef101e92",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json
index d54fbc08a21b8..5d1233ebfcb78 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Deleting Backup Catalogs with Wbadmin",
- "query": "event.category:process and event.type:(start or process_started) and process.name:wbadmin.exe and process.args:(catalog and delete)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"wbadmin.exe\" or process.pe.original_file_name == \"WBADMIN.EXE\") and\n process.args : \"catalog\" and process.args : \"delete\"\n",
"risk_score": 21,
"rule_id": "581add16-df76-42bb-af8e-c979bfb39a59",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json
index 7180871001ff6..00f18df34f864 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Disable Windows Firewall Rules via Netsh",
- "query": "event.category:process and event.type:(start or process_started) and process.name:netsh.exe and process.args:(disable and firewall and set) or process.args:(advfirewall and off and state)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"netsh.exe\" and\n (process.args : \"disable\" and process.args : \"firewall\" and process.args : \"set\") or\n (process.args : \"advfirewall\" and process.args : \"off\" and process.args : \"state\")\n",
"risk_score": 47,
"rule_id": "4b438734-3793-4fda-bd42-ceeada0be8f9",
"severity": "medium",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json
index df36941662bf0..9a3eace06d5fb 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS EC2 Flow Log Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteFlowLogs and event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.action:DeleteFlowLogs and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/delete-flow-logs.html",
"https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteFlowLogs.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json
index 656267753827b..79222e3ef4cfb 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS EC2 Network Access Control List Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(DeleteNetworkAcl or DeleteNetworkAclEntry) and event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.action:(DeleteNetworkAcl or DeleteNetworkAclEntry) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/delete-network-acl.html",
"https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkAcl.html",
@@ -60,5 +60,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json
index 65a59737ce4b9..9a4a8efd26f5b 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Encoding or Decoding Files via CertUtil",
- "query": "event.category:process and event.type:(start or process_started) and process.name:certutil.exe and process.args:(-decode or -encode or /decode or /encode)",
+ "query": "process where event.type == \"start\" and\n (process.name : \"certutil.exe\" or process.pe.original_file_name == \"CertUtil.exe\") and \n process.args : (\"?decode\", \"?encode\")\n",
"risk_score": 47,
"rule_id": "fd70c98a-c410-42dc-a2e3-761c71848acf",
"severity": "medium",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json
index 07ad86929b6d2..d56c90552d457 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Started by an Office Application",
- "query": "event.category:process and event.type:(start or process_started) and process.name:MSBuild.exe and process.parent.name:(eqnedt32.exe or excel.exe or fltldr.exe or msaccess.exe or mspub.exe or outlook.exe or powerpnt.exe or winword.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"MSBuild.exe\" and\n process.parent.name : (\"eqnedt32.exe\",\n \"excel.exe\",\n \"fltldr.exe\",\n \"msaccess.exe\",\n \"mspub.exe\",\n \"outlook.exe\",\n \"powerpnt.exe\",\n \"winword.exe\" )\n",
"references": [
"https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html"
],
@@ -56,6 +56,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json
index b5556559ec33e..3b640d8757b51 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Started by a Script Process",
- "query": "event.category:process and event.type: start and process.name:MSBuild.exe and process.parent.name:(cmd.exe or powershell.exe or cscript.exe or wscript.exe)",
+ "query": "process where event.type == \"start\" and\n (process.name : \"MSBuild.exe\" or process.pe.original_file_name == \"MSBuild.exe\") and\n process.parent.name : (\"cmd.exe\", \"powershell.exe\", \"cscript.exe\", \"wscript.exe\", \"mshta.exe\")\n",
"risk_score": 21,
"rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae2",
"severity": "low",
@@ -53,6 +53,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json
index ee63d950f0b24..33094a88af313 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Started by a System Process",
- "query": "event.category:process and event.type:(start or process_started) and process.name:MSBuild.exe and process.parent.name:(explorer.exe or wmiprvse.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"MSBuild.exe\" and\n process.parent.name : (\"explorer.exe\", \"wmiprvse.exe\")\n",
"risk_score": 47,
"rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae3",
"severity": "medium",
@@ -53,6 +53,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json
index a5980acd3bb17..43051cb8b27c9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Using an Alternate Name",
- "query": "event.category:process and event.type:(start or process_started) and process.pe.original_file_name:MSBuild.exe and not process.name: MSBuild.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.pe.original_file_name == \"MSBuild.exe\" and\n not process.name : \"MSBuild.exe\"\n",
"risk_score": 21,
"rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae4",
"severity": "low",
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json
index 0ff3ad33ebb0b..38a5a99370662 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Build Engine Started an Unusual Process",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:MSBuild.exe and process.name:(csc.exe or iexplore.exe or powershell.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"MSBuild.exe\" and\n process.name : (\"csc.exe\", \"iexplore.exe\", \"powershell.exe\")\n",
"references": [
"https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html"
],
@@ -54,6 +54,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json
index 9403a37e6e529..74aaa9a9c3615 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Potential DLL SideLoading via Trusted Microsoft Programs",
- "query": "event.category:process and event.type:(start or process_started) and process.pe.original_file_name:(WinWord.exe or EXPLORER.EXE or w3wp.exe or DISM.EXE) and not (process.name:(winword.exe or WINWORD.EXE or explorer.exe or w3wp.exe or Dism.exe) or process.executable:(\"C:\\Windows\\explorer.exe\" or C\\:\\\\Program?Files\\\\Microsoft?Office\\\\root\\\\Office*\\\\WINWORD.EXE or C\\:\\\\Program?Files?\\(x86\\)\\\\Microsoft?Office\\\\root\\\\Office*\\\\WINWORD.EXE or \"C:\\Windows\\System32\\Dism.exe\" or \"C:\\Windows\\SysWOW64\\Dism.exe\" or \"C:\\Windows\\System32\\inetsrv\\w3wp.exe\"))",
+ "query": "process where event.type == \"start\" and\n process.pe.original_file_name in (\"WinWord.exe\", \"EXPLORER.EXE\", \"w3wp.exe\", \"DISM.EXE\") and\n not (process.name : (\"winword.exe\", \"explorer.exe\", \"w3wp.exe\", \"Dism.exe\") or\n process.executable : (\"?:\\\\Windows\\\\explorer.exe\",\n \"?:\\\\Program Files\\\\Microsoft Office\\\\root\\\\Office*\\\\WINWORD.EXE\",\n \"?:\\\\Program Files?(x86)\\\\Microsoft Office\\\\root\\\\Office*\\\\WINWORD.EXE\",\n \"?:\\\\Windows\\\\System32\\\\Dism.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\Dism.exe\",\n \"?:\\\\Windows\\\\System32\\\\inetsrv\\\\w3wp.exe\")\n )\n",
"risk_score": 73,
"rule_id": "1160dcdb-0a0a-4a79-91d8-9b84616edebd",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json
deleted file mode 100644
index f6a3cdf222f36..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_via_trusted_developer_utilities.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies possibly suspicious activity using trusted Windows developer activity.",
- "false_positives": [
- "These programs may be used by Windows developers but use by non-engineers is unusual."
- ],
- "from": "now-9m",
- "index": [
- "winlogbeat-*",
- "logs-endpoint.events.*",
- "logs-windows.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Trusted Developer Application Usage",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(MSBuild.exe or msxsl.exe)",
- "risk_score": 21,
- "rule_id": "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae1",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Defense Evasion"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0005",
- "name": "Defense Evasion",
- "reference": "https://attack.mitre.org/tactics/TA0005/"
- },
- "technique": [
- {
- "id": "T1127",
- "name": "Trusted Developer Utilities Proxy Execution",
- "reference": "https://attack.mitre.org/techniques/T1127/"
- }
- ]
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0002",
- "name": "Execution",
- "reference": "https://attack.mitre.org/tactics/TA0002/"
- },
- "technique": []
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json
index 853c6514e0dd4..6512c5ad473b4 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json
@@ -14,7 +14,7 @@
"license": "Elastic License v2",
"name": "GCP Storage Bucket Configuration Modification",
"note": "The GCP Filebeat module must be enabled to use this rule.",
- "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.buckets.update and event.outcome:success",
+ "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:\"storage.buckets.update\" and event.outcome:success",
"references": [
"https://cloud.google.com/storage/docs/key-terms#buckets"
],
@@ -31,5 +31,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json
index 5a3db946e0a1d..e79c14e76cba7 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json
@@ -14,7 +14,7 @@
"license": "Elastic License v2",
"name": "GCP Storage Bucket Permissions Modification",
"note": "The GCP Filebeat module must be enabled to use this rule.",
- "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.setIamPermissions and event.outcome:success",
+ "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:\"storage.setIamPermissions\" and event.outcome:success",
"references": [
"https://cloud.google.com/storage/docs/access-control/iam-permissions"
],
@@ -48,5 +48,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json
index 31dd11ca719f7..a98f57a132ba4 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS GuardDuty Detector Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteDetector and event.dataset:aws.cloudtrail and event.provider:guardduty.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:guardduty.amazonaws.com and event.action:DeleteDetector and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/guardduty/delete-detector.html",
"https://docs.aws.amazon.com/guardduty/latest/APIReference/API_DeleteDetector.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json
deleted file mode 100644
index fde65e1d1f9d8..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Adversaries may encode/decode data in an attempt to evade detection by host- or network-based security controls.",
- "false_positives": [
- "Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Hex Encoding/Decoding Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(hexdump or od or xxd)",
- "risk_score": 21,
- "rule_id": "a9198571-b135-4a76-b055-e3e5a476fd83",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection",
- "Defense Evasion"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0005",
- "name": "Defense Evasion",
- "reference": "https://attack.mitre.org/tactics/TA0005/"
- },
- "technique": [
- {
- "id": "T1140",
- "name": "Deobfuscate/Decode Files or Information",
- "reference": "https://attack.mitre.org/techniques/T1140/"
- },
- {
- "id": "T1027",
- "name": "Obfuscated Files or Information",
- "reference": "https://attack.mitre.org/techniques/T1027/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json
index 30284a3c999bf..16de1c9c21f97 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json
@@ -9,11 +9,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"max_signals": 33,
"name": "IIS HTTP Logging Disabled",
- "query": "event.category:process and event.type:(start or process_started) and (process.name:appcmd.exe or process.pe.original_file_name:appcmd.exe) and process.args:/dontLog\\:\\\"True\\\" and not process.parent.name:iissetup.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"appcmd.exe\" or process.pe.original_file_name == \"appcmd.exe\") and\n process.args : \"/dontLog*:*True\" and\n not process.parent.name : \"iissetup.exe\"\n",
"risk_score": 73,
"rule_id": "ebf1adea-ccf2-4943-8b96-7ab11ca173a5",
"severity": "high",
@@ -42,6 +42,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json
index 670619cc5753a..e0f544ceb832c 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json
@@ -4,7 +4,7 @@
],
"description": "A suspicious WerFault child process was detected, which may indicate an attempt to run unnoticed. Verify process details such as command line, network connections, file writes and parent process details as well.",
"false_positives": [
- "Custom Windows Error Reporting Debugger"
+ "Custom Windows error reporting debugger or applications restarted by WerFault after a crash."
],
"from": "now-9m",
"index": [
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious WerFault Child Process",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:WerFault.exe and not process.name:(cofire.exe or psr.exe or VsJITDebugger.exe or TTTracer.exe or rundll32.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"WerFault.exe\" and\n not process.name : (\"cofire.exe\",\n \"psr.exe\",\n \"VsJITDebugger.exe\",\n \"TTTracer.exe\",\n \"rundll32.exe\",\n \"LogiOptionsMgr.exe\") and\n not process.args : (\"/LOADSAVEDWINDOWS\",\n \"/restore\",\n \"RestartByRestartManager*\",\n \"--restarted\",\n \"createdump\",\n \"dontsend\",\n \"/watson\")\n",
"references": [
"https://www.hexacorn.com/blog/2019/09/19/silentprocessexit-quick-look-under-the-hood/",
"https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/Persistence/persistence_SilentProcessExit_ImageHijack_sysmon_13_1.evtx",
@@ -49,6 +49,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json
index 7fda1a757a9d0..b0d11121c1a15 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Program Files Directory Masquerading",
- "query": "process where event.type in (\"start\", \"process_started\", \"info\") and\n /* capture both fake program files directory in process executable as well as if passed in process args as a dll*/\n process.args : (\"C:\\\\*Program*Files*\\\\*\", \"C:\\\\*Program*Files*\\\\*\") and\n not process.args : (\"C:\\\\Program Files\\\\*\", \"C:\\\\Program Files (x86)\\\\*\")\n",
+ "query": "process where event.type == \"start\" and\n process.executable : \"C:\\\\*Program*Files*\\\\*.exe\" and\n not process.executable : (\"C:\\\\Program Files\\\\*.exe\", \"C:\\\\Program Files (x86)\\\\*.exe\", \"C:\\\\Users\\\\*.exe\", \"C:\\\\ProgramData\\\\*.exe\")\n",
"risk_score": 47,
"rule_id": "32c5cf9c-2ef8-4e87-819e-5ccb7cd18b14",
"severity": "medium",
@@ -42,5 +42,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json
index 29668a1202d6a..7c58d82ec1061 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Modification of Boot Configuration",
- "query": "event.category:process and event.type:(start or process_started) and process.name:bcdedit.exe and process.args:(/set and (bootstatuspolicy and ignoreallfailures or no and recoveryenabled))",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"bcdedit.exe\" or process.pe.original_file_name == \"bcdedit.exe\") and\n (process.args : \"/set\" and process.args : \"bootstatuspolicy\" and process.args : \"ignoreallfailures\") or\n (process.args : \"no\" and process.args : \"recoveryenabled\")\n",
"risk_score": 21,
"rule_id": "69c251fb-a5d6-4035-b5ec-40438bd829ff",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json
index a27a207832d3f..d41804247945b 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json
@@ -11,7 +11,7 @@
"language": "kuery",
"license": "Elastic License v2",
"name": "Modification of Environment Variable via Launchctl",
- "query": "event.category:process and event.type:start and process.name:launchctl and process.args:(setenv and not (JAVA*_HOME or RUNTIME_JAVA_HOME or DBUS_LAUNCHD_SESSION_BUS_SOCKET or ANT_HOME))",
+ "query": "event.category:process and event.type:start and process.name:launchctl and process.args:(setenv and not (JAVA*_HOME or RUNTIME_JAVA_HOME or DBUS_LAUNCHD_SESSION_BUS_SOCKET or ANT_HOME or LG_WEBOS_TV_SDK_HOME or WEBOS_CLI_TV or EDEN_ENV) ) and not process.parent.executable:(\"/Applications/NoMachine.app/Contents/Frameworks/bin/nxserver.bin\" or \"/usr/local/bin/kr\" or \"/Applications/NoMachine.app/Contents/Frameworks/bin/nxserver.bin\" or \"/Applications/IntelliJ IDEA CE.app/Contents/jbr/Contents/Home/lib/jspawnhelper\")",
"references": [
"https://github.com/rapid7/metasploit-framework/blob/master//modules/post/osx/escalate/tccbypass.rb"
],
@@ -51,5 +51,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json
index 148e175ed677b..727bd4a579566 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS S3 Bucket Configuration Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(DeleteBucketPolicy or DeleteBucketReplication or DeleteBucketCors or DeleteBucketEncryption or DeleteBucketLifecycle) and event.dataset:aws.cloudtrail and event.provider:s3.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:s3.amazonaws.com and event.action:(DeleteBucketPolicy or DeleteBucketReplication or DeleteBucketCors or DeleteBucketEncryption or DeleteBucketLifecycle) and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketPolicy.html",
"https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html",
@@ -54,5 +54,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json
index 69451728e8fc0..3f5d69ff7f4ec 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious Managed Code Hosting Process",
- "query": "event.category:file and not event.type:deletion and file.name:(wscript.exe.log or mshta.exe.log or wscript.exe.log or wmic.exe.log or svchost.exe.log or dllhost.exe.log or cmstp.exe.log or regsvr32.exe.log)",
+ "query": "sequence by process.entity_id with maxspan=5m\n [process where event.type == \"start\" and \n process.name : (\"wscript.exe\", \"cscript.exe\", \"mshta.exe\", \"wmic.exe\", \"regsvr32.exe\", \"svchost.exe\", \"dllhost.exe\", \"cmstp.exe\")]\n [file where event.type != \"deletion\" and\n file.name : (\"wscript.exe.log\",\n \"cscript.exe\",\n \"mshta.exe.log\",\n \"wmic.exe.log\",\n \"svchost.exe.log\",\n \"dllhost.exe.log\",\n \"cmstp.exe.log\",\n \"regsvr32.exe.log\")]\n",
"references": [
"https://blog.menasec.net/2019/07/interesting-difr-traces-of-net-clr.html"
],
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json
index 8460293f0be1f..7af9829cb43f5 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json
@@ -5,15 +5,13 @@
"description": "Identifies scrobj.dll loaded into unusual Microsoft processes. This usually means a malicious scriptlet is being executed in the target process.",
"from": "now-9m",
"index": [
- "logs-endpoint.events.*",
- "winlogbeat-*",
- "logs-windows.*"
+ "logs-endpoint.events.*"
],
"language": "eql",
"license": "Elastic License v2",
- "name": "Windows Suspicious Script Object Execution",
- "query": "/* add winlogbeat-* when process.code_signature.* fields are populated */\n\nsequence by process.entity_id with maxspan = 2m\n [process where event.type in (\"start\", \"process_started\") and\n /* uncomment once in winlogbeat */\n /* process.code_signature.subject_name : \"Microsoft Corporation\" and process.code_signature.trusted : true and */\n not process.name : (\n \"cscript.exe\",\n \"iexplore.exe\",\n \"MicrosoftEdge.exe\",\n \"msiexec.exe\",\n \"smartscreen.exe\",\n \"taskhostw.exe\",\n \"w3wp.exe\",\n \"wscript.exe\")]\n [library where event.type == \"start\" and dll.name : \"scrobj.dll\"]\n",
- "risk_score": 21,
+ "name": "Suspicious Script Object Execution",
+ "query": "sequence by process.entity_id with maxspan=2m\n [process where event.type == \"start\" \n and (process.code_signature.subject_name in (\"Microsoft Corporation\", \"Microsoft Windows\") and \n process.code_signature.trusted == true) and\n not process.executable : (\n \"?:\\\\Windows\\\\System32\\\\cscript.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\cscript.exe\",\n \"?:\\\\Program Files (x86)\\\\Internet Explorer\\\\iexplore.exe\",\n \"?:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe\",\n \"?:\\\\Windows\\\\SystemApps\\\\Microsoft.MicrosoftEdge_*\\\\MicrosoftEdge.exe\",\n \"?:\\\\Windows\\\\system32\\\\msiexec.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\msiexec.exe\",\n \"?:\\\\Windows\\\\System32\\\\smartscreen.exe\",\n \"?:\\\\Windows\\\\system32\\\\taskhostw.exe\",\n \"?:\\\\windows\\\\system32\\\\inetsrv\\\\w3wp.exe\",\n \"?:\\\\windows\\\\SysWOW64\\\\inetsrv\\\\w3wp.exe\",\n \"?:\\\\Windows\\\\system32\\\\wscript.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\wscript.exe\",\n \"?:\\\\Windows\\\\system32\\\\mobsync.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\mobsync.exe\",\n \"?:\\\\Windows\\\\System32\\\\cmd.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\cmd.exe\")]\n [library where event.type == \"start\" and dll.name : \"scrobj.dll\"]\n",
+ "risk_score": 47,
"rule_id": "4ed678a9-3a4f-41fb-9fea-f85a6e0a0dff",
"severity": "medium",
"tags": [
@@ -31,9 +29,15 @@
"name": "Defense Evasion",
"reference": "https://attack.mitre.org/tactics/TA0005/"
},
- "technique": []
+ "technique": [
+ {
+ "id": "T1218",
+ "name": "Signed Binary Proxy Execution",
+ "reference": "https://attack.mitre.org/techniques/T1218/"
+ }
+ ]
}
],
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json
index ea60b9a38d27c..6fa6f0ab569a8 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Unusual Executable File Creation by a System Critical Process",
- "query": "event.category:file and not event.type:deletion and file.extension:(exe or dll) and process.name:(smss.exe or autochk.exe or csrss.exe or wininit.exe or services.exe or lsass.exe or winlogon.exe or userinit.exe or LogonUI.exe)",
+ "query": "file where event.type != \"deletion\" and\n file.extension : (\"exe\", \"dll\") and\n process.name : (\"smss.exe\",\n \"autochk.exe\",\n \"csrss.exe\",\n \"wininit.exe\",\n \"services.exe\",\n \"lsass.exe\",\n \"winlogon.exe\",\n \"userinit.exe\",\n \"LogonUI.exe\")\n",
"risk_score": 73,
"rule_id": "e94262f2-c1e9-4d3f-a907-aeab16712e1a",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json
index 74dbc53ee1c0a..ee45ffce416d2 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json
@@ -12,7 +12,7 @@
"license": "Elastic License v2",
"max_signals": 33,
"name": "Timestomping using Touch Command",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"touch\" and process.args : (\"-r\", \"-t\", \"-a*\",\"-m*\")\n",
+ "query": "process where event.type == \"start\" and\n process.name : \"touch\" and user.id != \"0\" and\n process.args : (\"-r\", \"-t\", \"-a*\",\"-m*\") and\n not process.args : (\"/usr/lib/go-*/bin/go\", \"/usr/lib/dracut/dracut-functions.sh\", \"/tmp/KSInstallAction.*/m/.patch/*\")\n",
"risk_score": 47,
"rule_id": "b0046934-486e-462f-9487-0d4cf9e429c6",
"severity": "medium",
@@ -50,5 +50,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json
index 4e354e69ca1e0..196a3de9b9e6f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Unusual Process Execution Path - Alternate Data Stream",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.args : \"C:\\\\*:*\"\n",
+ "query": "process where event.type == \"start\" and\n process.args : \"?:\\\\*:*\" and process.args_count == 1\n",
"risk_score": 47,
"rule_id": "4bd1c1af-79d4-4d37-9efa-6e0240640242",
"severity": "medium",
@@ -42,5 +42,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json
index 7413d91523820..d920c4f853dfd 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Unusual Network Connection via RunDLL32",
- "query": "sequence by host.id, process.entity_id with maxspan=1m\n [process where event.type in (\"start\", \"process_started\", \"info\") and process.name : \"rundll32.exe\" and process.args_count == 1]\n [network where process.name : \"rundll32.exe\" and network.protocol != \"dns\" and network.direction == \"outgoing\" and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\", \"127.0.0.0/8\")]\n",
+ "query": "sequence by host.id, process.entity_id with maxspan=1m\n [process where event.type in (\"start\", \"process_started\") and process.name : \"rundll32.exe\" and process.args_count == 1]\n [network where process.name : \"rundll32.exe\" and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\", \"127.0.0.0/8\", \"FE80::/10\", \"::1/128\")]\n",
"risk_score": 47,
"rule_id": "52aaab7b-b51c-441a-89ce-4387b3aea886",
"severity": "medium",
@@ -48,5 +48,5 @@
}
],
"type": "eql",
- "version": 8
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json
index e629aefec2a67..2153b4c8e8c04 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Unusual Child Process from a System Virtual Process",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.pid:4 and not process.executable:(Registry or MemCompression or \"C:\\Windows\\System32\\smss.exe\")",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.pid == 4 and\n not process.executable : (\"Registry\", \"MemCompression\", \"?:\\\\Windows\\\\System32\\\\smss.exe\")\n",
"risk_score": 73,
"rule_id": "de9bd7e0-49e9-4e92-a64d-53ade2e66af1",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json
index 82a75d0920b6f..51d1789804548 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json
@@ -9,13 +9,13 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Potential Evasion via Filter Manager",
- "query": "event.category:process and event.type:(start or process_started) and process.name:fltMC.exe",
- "risk_score": 21,
+ "query": "process where event.type in (\"start\", \"process_started\") and \n process.name : \"fltMC.exe\" and process.args : \"unload\"\n",
+ "risk_score": 47,
"rule_id": "06dceabf-adca-48af-ac79-ffdf4c3b1e9a",
- "severity": "low",
+ "severity": "medium",
"tags": [
"Elastic",
"Host",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 6
+ "type": "eql",
+ "version": 7
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json
index 6a1f32cf5fb75..e519b23a32b0d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Volume Shadow Copy Deletion via WMIC",
- "query": "event.category:process and event.type:(start or process_started) and process.name:WMIC.exe and process.args:(delete and shadowcopy)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"WMIC.exe\" or process.pe.original_file_name == \"wmic.exe\") and\n process.args : \"delete\" and process.args : \"shadowcopy\"\n",
"risk_score": 73,
"rule_id": "dc9c1f74-dac3-48e3-b47f-eb79db358f57",
"severity": "high",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json
index a489ce7fd54cc..ebe1cbf18d6a8 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS WAF Access Control List Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteWebACL and event.dataset:aws.cloudtrail and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.action:DeleteWebACL and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/waf-regional/delete-web-acl.html",
"https://docs.aws.amazon.com/waf/latest/APIReference/API_wafRegional_DeleteWebACL.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json
index 218704ed5714c..87b32d14791bb 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Net command via SYSTEM account",
- "query": "event.category:process and event.type:(start or process_started) and (process.name:(whoami.exe or net.exe) or process.name:net1.exe and not process.parent.name:net.exe) and user.name:SYSTEM",
+ "query": "process where event.type in (\"start\", \"process_started\") and \n user.id in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and\n process.name : \"whoami.exe\" or\n (process.name : \"net1.exe\" and not process.parent.name : \"net.exe\")\n",
"risk_score": 21,
"rule_id": "2856446a-34e6-435b-9fb5-f8f040bfa7ed",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 6
+ "type": "eql",
+ "version": 7
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json
new file mode 100644
index 0000000000000..1df7e2138b969
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json
@@ -0,0 +1,53 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies domains commonly used by adversaries for post-exploitation IP lookups. It is common for adversaries to test for Internet access and acquire their external IP address after they have gained access to a system. Among others, this has been observed in campaigns leveraging the information stealer, Trickbot.",
+ "false_positives": [
+ "If the domains listed in this rule are used as part of an authorized workflow, this rule will be triggered by those events. Validate that this is expected activity and tune the rule to fit your environment variables."
+ ],
+ "from": "now-9m",
+ "index": [
+ "winlogbeat-*",
+ "logs-endpoint.events.*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "External IP Lookup fron Non-Browser Process",
+ "query": "network where network.protocol == \"dns\" and\n process.name != null and user.id not in (\"S-1-5-19\", \"S-1-5-20\") and\n event.action == \"lookup_requested\" and\n /* Add new external IP lookup services here */\n dns.question.name :\n (\n \"*api.ipify.org\",\n \"*freegeoip.app\",\n \"*checkip.amazonaws.com\",\n \"*checkip.dyndns.org\",\n \"*freegeoip.app\",\n \"*icanhazip.com\",\n \"*ifconfig.*\",\n \"*ipecho.net\",\n \"*ipgeoapi.com\",\n \"*ipinfo.io\",\n \"*ip.anysrc.net\",\n \"*myexternalip.com\",\n \"*myipaddress.com\",\n \"*showipaddress.com\",\n \"*whatismyipaddress.com\",\n \"*wtfismyip.com\"\n ) and\n /* Insert noisy false positives here */\n not process.executable :\n (\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\WWAHost.exe\",\n \"?:\\\\Windows\\\\System32\\\\smartscreen.exe\",\n \"?:\\\\Windows\\\\System32\\\\MicrosoftEdgeCP.exe\",\n \"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\Platform\\\\*\\\\MsMpEng.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Fiddler\\\\Fiddler.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Microsoft VS Code\\\\Code.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\OneDrive\\\\OneDrive.exe\"\n )\n",
+ "references": [
+ "https://community.jisc.ac.uk/blogs/csirt/article/trickbot-analysis-and-mitigation",
+ "https://www.cybereason.com/blog/dropping-anchor-from-a-trickbot-infection-to-the-discovery-of-the-anchor-malware"
+ ],
+ "risk_score": 21,
+ "rule_id": "1d72d014-e2ab-4707-b056-9b96abe7b511",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Discovery"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0007",
+ "name": "Discovery",
+ "reference": "https://attack.mitre.org/tactics/TA0007/"
+ },
+ "technique": [
+ {
+ "id": "T1016",
+ "name": "System Network Configuration Discovery",
+ "reference": "https://attack.mitre.org/techniques/T1016/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 4
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_public_ip_reconnaissance.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_public_ip_reconnaissance.json
deleted file mode 100644
index a4e2b89a6d8ca..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_public_ip_reconnaissance.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies domains commonly used by adversaries for post-exploitation IP reconnaissance. It is common for adversaries to test for Internet access and acquire their public IP address after they have gained access to a system. Among others, this has been observed in campaigns leveraging the information stealer, Trickbot.",
- "false_positives": [
- "If the domains listed in this rule are used as part of an authorized workflow, this rule will be triggered by those events. Validate that this is expected activity and tune the rule to fit your environment variables."
- ],
- "index": [
- "packetbeat-*"
- ],
- "language": "lucene",
- "license": "Elastic License v2",
- "name": "Public IP Reconnaissance Activity",
- "note": "This rule takes HTTP redirects and HTTP referrer's into account, however neither HTTP redirect status codes nor HTTP referrer's are visible with TLS traffic which can lead to multiple events per alert.",
- "query": "event.category:network AND event.type:connection AND server.domain:(ipecho.net OR ipinfo.io OR ifconfig.co OR ifconfig.me OR icanhazip.com OR myexternalip.com OR api.ipify.org OR bot.whatismyipaddress.com OR ip.anysrc.net OR wtfismyip.com) AND NOT http.response.status_code:302 AND status:OK AND NOT _exists_:http.request.referrer",
- "references": [
- "https://community.jisc.ac.uk/blogs/csirt/article/trickbot-analysis-and-mitigation",
- "https://www.cybereason.com/blog/dropping-anchor-from-a-trickbot-infection-to-the-discovery-of-the-anchor-malware"
- ],
- "risk_score": 21,
- "rule_id": "1d72d014-e2ab-4707-b056-9b96abe7b511",
- "severity": "low",
- "tags": [
- "Elastic",
- "Network",
- "Threat Detection",
- "Discovery"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0007",
- "name": "Discovery",
- "reference": "https://attack.mitre.org/tactics/TA0007/"
- },
- "technique": [
- {
- "id": "T1016",
- "name": "System Network Configuration Discovery",
- "reference": "https://attack.mitre.org/techniques/T1016/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_process_discovery_via_tasklist_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_process_discovery_via_tasklist_command.json
deleted file mode 100644
index f0839c5229d42..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_process_discovery_via_tasklist_command.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Adversaries may attempt to get information about running processes on a system.",
- "false_positives": [
- "Administrators may use the tasklist command to display a list of currently running processes. By itself, it does not indicate malicious activity. After obtaining a foothold, it's possible adversaries may use discovery commands like tasklist to get information about running processes."
- ],
- "from": "now-9m",
- "index": [
- "winlogbeat-*",
- "logs-endpoint.events.*",
- "logs-windows.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Process Discovery via Tasklist",
- "query": "event.category:process and event.type:(start or process_started) and process.name:tasklist.exe",
- "risk_score": 21,
- "rule_id": "cc16f774-59f9-462d-8b98-d27ccd4519ec",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Discovery"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0007",
- "name": "Discovery",
- "reference": "https://attack.mitre.org/tactics/TA0007/"
- },
- "technique": [
- {
- "id": "T1057",
- "name": "Process Discovery",
- "reference": "https://attack.mitre.org/techniques/T1057/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 6
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_query_registry_via_reg.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_query_registry_via_reg.json
deleted file mode 100644
index 7694f6ae30048..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_query_registry_via_reg.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Enumeration or discovery of the Windows registry using reg.exe. This information can be used to perform follow-on activities.",
- "from": "now-9m",
- "index": [
- "logs-endpoint.events.*",
- "winlogbeat-*",
- "logs-windows.*"
- ],
- "language": "eql",
- "license": "Elastic License v2",
- "name": "Query Registry via reg.exe",
- "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"reg.exe\" or process.pe.original_file_name == \"reg.exe\") and\n process.args == \"query\"\n",
- "risk_score": 21,
- "rule_id": "68113fdc-3105-4cdd-85bb-e643c416ef0b",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Discovery"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0007",
- "name": "Discovery",
- "reference": "https://attack.mitre.org/tactics/TA0007/"
- },
- "technique": [
- {
- "id": "T1012",
- "name": "Query Registry",
- "reference": "https://attack.mitre.org/techniques/T1012/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "eql",
- "version": 3
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json
index 486c7c8a978a6..4862cf42e92c3 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json
@@ -3,15 +3,18 @@
"Elastic"
],
"description": "Identifies the use of the grep command to discover known third-party macOS and Linux security tools, such as Antivirus or Host Firewall details.",
+ "false_positives": [
+ "Endpoint Security installers, updaters and post installation verification scripts."
+ ],
"from": "now-9m",
"index": [
"logs-endpoint.events.*",
"auditbeat-*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Security Software Discovery via Grep",
- "query": "event.category : process and event.type : (start or process_started) and process.name : grep and process.args : (\"Little Snitch\" or Avast* or Avira* or ESET* or esets_* or BlockBlock or 360* or LuLu or KnockKnock* or kav or KIS or RTProtectionDaemon or Malware* or VShieldScanner or WebProtection or webinspectord or McAfee* or isecespd* or macmnsvc* or masvc or kesl or avscan or guard or rtvscand or symcfgd or scmdaemon or symantec or elastic-endpoint )",
+ "query": "process where event.type == \"start\" and\nprocess.name : \"grep\" and user.id != \"0\" and\n not process.parent.executable : \"/Library/Application Support/*\" and\n process.args :\n (\"Little Snitch*\",\n \"Avast*\",\n \"Avira*\",\n \"ESET*\",\n \"BlockBlock*\",\n \"360Sec*\",\n \"LuLu*\",\n \"KnockKnock*\",\n \"kav\",\n \"KIS\",\n \"RTProtectionDaemon*\",\n \"Malware*\",\n \"VShieldScanner*\",\n \"WebProtection*\",\n \"webinspectord*\",\n \"McAfee*\",\n \"isecespd*\",\n \"macmnsvc*\",\n \"masvc*\",\n \"kesl*\",\n \"avscan*\",\n \"guard*\",\n \"rtvscand*\",\n \"symcfgd*\",\n \"scmdaemon*\",\n \"symantec*\",\n \"sophos*\",\n \"osquery*\",\n \"elastic-endpoint*\"\n ) and\n not (process.args : \"Avast\" and process.args : \"Passwords\")\n",
"risk_score": 47,
"rule_id": "870aecc0-cea4-4110-af3f-e02e9b373655",
"severity": "medium",
@@ -35,12 +38,19 @@
{
"id": "T1518",
"name": "Software Discovery",
- "reference": "https://attack.mitre.org/techniques/T1518/"
+ "reference": "https://attack.mitre.org/techniques/T1518/",
+ "subtechnique": [
+ {
+ "id": "T1518.001",
+ "name": "Security Software Discovery",
+ "reference": "https://attack.mitre.org/techniques/T1518/001/"
+ }
+ ]
}
]
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 1
+ "type": "eql",
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json
index da5f8941701c3..a9276ca950fa5 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json
@@ -11,7 +11,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Enumeration of Users or Groups via Built-in Commands",
- "query": "process where event.type in (\"start\", \"process_started\") and\n not process.parent.executable : (\"/Applications/NoMAD.app/Contents/MacOS/NoMAD\", \n \"/Applications/ZoomPresence.app/Contents/MacOS/ZoomPresence\") and \n process.name : (\"ldapsearch\", \"dsmemberutil\") or\n (process.name : \"dscl\" and \n process.args : (\"read\", \"-read\", \"list\", \"-list\", \"ls\", \"search\", \"-search\") and \n process.args : (\"/Active Directory/*\", \"/Users*\", \"/Groups*\"))\n",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n not process.parent.executable : (\"/Applications/NoMAD.app/Contents/MacOS/NoMAD\", \n \"/Applications/ZoomPresence.app/Contents/MacOS/ZoomPresence\",\n \"/Applications/Sourcetree.app/Contents/MacOS/Sourcetree\",\n \"/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon\",\n \"/usr/local/jamf/bin/jamf\"\n ) and \n process.name : (\"ldapsearch\", \"dsmemberutil\") or\n (process.name : \"dscl\" and \n process.args : (\"read\", \"-read\", \"list\", \"-list\", \"ls\", \"search\", \"-search\") and \n process.args : (\"/Active Directory/*\", \"/Users*\", \"/Groups*\"))\n",
"risk_score": 21,
"rule_id": "6e9b351e-a531-4bdc-b73e-7034d6eed7ff",
"severity": "low",
@@ -46,5 +46,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json
index 95f4ab50a7c46..9999ab2ffb973 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json
@@ -12,10 +12,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Whoami Process Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:whoami.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and process.name : \"whoami.exe\"\n",
"risk_score": 21,
"rule_id": "ef862985-3f13-4262-a686-5f357bbb9bc2",
"severity": "low",
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 6
+ "type": "eql",
+ "version": 7
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json
deleted file mode 100644
index 712b729c3f82f..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "The whoami application was executed on a Linux host. This is often used by tools and persistence mechanisms to test for privileged access.",
- "false_positives": [
- "Security testing tools and frameworks may run this command. Some normal use of this command may originate from automation tools and frameworks."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "User Discovery via Whoami",
- "query": "event.category:process and event.type:(start or process_started) and process.name:whoami",
- "risk_score": 21,
- "rule_id": "120559c6-5e24-49f4-9e30-8ffe697df6b9",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection",
- "Discovery"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0007",
- "name": "Discovery",
- "reference": "https://attack.mitre.org/tactics/TA0007/"
- },
- "technique": [
- {
- "id": "T1033",
- "name": "System Owner/User Discovery",
- "reference": "https://attack.mitre.org/techniques/T1033/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json
deleted file mode 100644
index 6b44764b54f2b..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies a suspicious parent child process relationship with cmd.exe descending from PowerShell.exe.",
- "from": "now-9m",
- "index": [
- "winlogbeat-*",
- "logs-endpoint.events.*",
- "logs-windows.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "PowerShell spawning Cmd",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:powershell.exe and process.name:cmd.exe",
- "risk_score": 21,
- "rule_id": "0f616aee-8161-4120-857e-742366f5eeb3",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Execution"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0002",
- "name": "Execution",
- "reference": "https://attack.mitre.org/tactics/TA0002/"
- },
- "technique": [
- {
- "id": "T1059",
- "name": "Command and Scripting Interpreter",
- "reference": "https://attack.mitre.org/techniques/T1059/",
- "subtechnique": [
- {
- "id": "T1059.001",
- "name": "PowerShell",
- "reference": "https://attack.mitre.org/techniques/T1059/001/"
- }
- ]
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json
index bfb1c2a667cf9..f0270a576c88b 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Svchost spawning Cmd",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:svchost.exe and process.name:cmd.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"svchost.exe\" and process.name : \"cmd.exe\" and \n not (process.pe.original_file_name == \"Cmd.Exe\" and process.args : \"?:\\\\Program Files\\\\Npcap\\\\CheckStatus.bat??\")\n",
"risk_score": 21,
"rule_id": "fd7a6052-58fa-4397-93c3-4795249ccfa2",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json
index db473becae526..ac21f5be5eaef 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Unusual Parent Process for cmd.exe",
- "query": "event.category:process and event.type:(start or process_started) and process.name:cmd.exe and process.parent.name:(lsass.exe or csrss.exe or notepad.exe or regsvr32.exe or dllhost.exe or LogonUI.exe or wermgr.exe or spoolsv.exe or jucheck.exe or jusched.exe or ctfmon.exe or taskhostw.exe or GoogleUpdate.exe or sppsvc.exe or sihost.exe or slui.exe or SIHClient.exe or SearchIndexer.exe or SearchProtocolHost.exe or FlashPlayerUpdateService.exe or WerFault.exe or WUDFHost.exe or unsecapp.exe or wlanext.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"cmd.exe\" and\n process.parent.name : (\"lsass.exe\",\n \"csrss.exe\",\n \"epad.exe\",\n \"regsvr32.exe\",\n \"dllhost.exe\",\n \"LogonUI.exe\",\n \"wermgr.exe\",\n \"spoolsv.exe\",\n \"jucheck.exe\",\n \"jusched.exe\",\n \"ctfmon.exe\",\n \"taskhostw.exe\",\n \"GoogleUpdate.exe\",\n \"sppsvc.exe\",\n \"sihost.exe\",\n \"slui.exe\",\n \"SIHClient.exe\",\n \"SearchIndexer.exe\",\n \"SearchProtocolHost.exe\",\n \"FlashPlayerUpdateService.exe\",\n \"WerFault.exe\",\n \"WUDFHost.exe\",\n \"unsecapp.exe\",\n \"wlanext.exe\" )\n",
"risk_score": 47,
"rule_id": "3b47900d-e793-49e8-968f-c90dc3526aa1",
"severity": "medium",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json
index 519694cf2e730..1b25b865a4f29 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json
@@ -3,6 +3,9 @@
"Elastic"
],
"description": "Identifies command shell activity started via RunDLL32, which is commonly abused by attackers to host malicious code.",
+ "false_positives": [
+ "Microsoft Windows installers leveraging RunDLL32 for installation."
+ ],
"from": "now-9m",
"index": [
"winlogbeat-*",
@@ -12,7 +15,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Command Shell Activity Started via RunDLL32",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : (\"cmd.exe\", \"powershell.exe\") and\n process.parent.name : \"rundll32.exe\" and \n /* common FPs can be added here */\n not process.parent.args : \"C:\\\\Windows\\\\System32\\\\SHELL32.dll,RunAsNewUser_RunDLL\"\n",
+ "query": "process where event.type == \"start\" and\n process.name : (\"cmd.exe\", \"powershell.exe\") and\n process.parent.name : \"rundll32.exe\" and process.parent.command_line != null and\n /* common FPs can be added here */\n not process.parent.args : (\"C:\\\\Windows\\\\System32\\\\SHELL32.dll,RunAsNewUser_RunDLL\",\n \"C:\\\\WINDOWS\\\\*.tmp,zzzzInvokeManagedCustomActionOutOfProc\")\n",
"risk_score": 21,
"rule_id": "9ccf3ce0-0057-440a-91f5-870c6ad39093",
"severity": "low",
@@ -49,5 +52,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json
index 738d090f4c2be..f05496fc641a1 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json
@@ -13,7 +13,7 @@
"license": "Elastic License v2",
"name": "Execution from Unusual Directory - Command Line",
"note": "This is related to the Process Execution from an Unusual Directory rule",
- "query": "process where event.type in (\"start\", \"process_started\", \"info\") and\n process.name : (\"wscript.exe\",\"cscript.exe\",\"rundll32.exe\",\"regsvr32.exe\",\"cmstp.exe\",\"RegAsm.exe\",\"installutil.exe\",\"mshta.exe\",\"RegSvcs.exe\", \"powershell.exe\", \"pwsh.exe\", \"cmd.exe\") and\n /* add suspicious execution paths here */\nprocess.args : (\"C:\\\\PerfLogs\\\\*\",\"C:\\\\Users\\\\Public\\\\*\",\"C:\\\\Users\\\\Default\\\\*\",\"C:\\\\Windows\\\\Tasks\\\\*\",\"C:\\\\Intel\\\\*\", \"C:\\\\AMD\\\\Temp\\\\*\", \n \"C:\\\\Windows\\\\AppReadiness\\\\*\", \"C:\\\\Windows\\\\ServiceState\\\\*\",\"C:\\\\Windows\\\\security\\\\*\",\"C:\\\\Windows\\\\IdentityCRL\\\\*\",\"C:\\\\Windows\\\\Branding\\\\*\",\"C:\\\\Windows\\\\csc\\\\*\",\n \"C:\\\\Windows\\\\DigitalLocker\\\\*\",\"C:\\\\Windows\\\\en-US\\\\*\",\"C:\\\\Windows\\\\wlansvc\\\\*\",\"C:\\\\Windows\\\\Prefetch\\\\*\",\"C:\\\\Windows\\\\Fonts\\\\*\",\n \"C:\\\\Windows\\\\diagnostics\\\\*\",\"C:\\\\Windows\\\\TAPI\\\\*\",\"C:\\\\Windows\\\\INF\\\\*\",\"C:\\\\Windows\\\\System32\\\\Speech\\\\*\",\"C:\\\\windows\\\\tracing\\\\*\",\n \"c:\\\\windows\\\\IME\\\\*\",\"c:\\\\Windows\\\\Performance\\\\*\",\"c:\\\\windows\\\\intel\\\\*\",\"c:\\\\windows\\\\ms\\\\*\",\"C:\\\\Windows\\\\dot3svc\\\\*\",\"C:\\\\Windows\\\\ServiceProfiles\\\\*\",\n \"C:\\\\Windows\\\\panther\\\\*\",\"C:\\\\Windows\\\\RemotePackages\\\\*\",\"C:\\\\Windows\\\\OCR\\\\*\",\"C:\\\\Windows\\\\appcompat\\\\*\",\"C:\\\\Windows\\\\apppatch\\\\*\",\"C:\\\\Windows\\\\addins\\\\*\",\n \"C:\\\\Windows\\\\Setup\\\\*\",\"C:\\\\Windows\\\\Help\\\\*\",\"C:\\\\Windows\\\\SKB\\\\*\",\"C:\\\\Windows\\\\Vss\\\\*\",\"C:\\\\Windows\\\\Web\\\\*\",\"C:\\\\Windows\\\\servicing\\\\*\",\"C:\\\\Windows\\\\CbsTemp\\\\*\",\n \"C:\\\\Windows\\\\Logs\\\\*\",\"C:\\\\Windows\\\\WaaS\\\\*\",\"C:\\\\Windows\\\\twain_32\\\\*\",\"C:\\\\Windows\\\\ShellExperiences\\\\*\",\"C:\\\\Windows\\\\ShellComponents\\\\*\",\"C:\\\\Windows\\\\PLA\\\\*\",\n \"C:\\\\Windows\\\\Migration\\\\*\",\"C:\\\\Windows\\\\debug\\\\*\",\"C:\\\\Windows\\\\Cursors\\\\*\",\"C:\\\\Windows\\\\Containers\\\\*\",\"C:\\\\Windows\\\\Boot\\\\*\",\"C:\\\\Windows\\\\bcastdvr\\\\*\",\n \"C:\\\\Windows\\\\assembly\\\\*\",\"C:\\\\Windows\\\\TextInput\\\\*\",\"C:\\\\Windows\\\\security\\\\*\",\"C:\\\\Windows\\\\schemas\\\\*\",\"C:\\\\Windows\\\\SchCache\\\\*\",\"C:\\\\Windows\\\\Resources\\\\*\",\n \"C:\\\\Windows\\\\rescache\\\\*\",\"C:\\\\Windows\\\\Provisioning\\\\*\",\"C:\\\\Windows\\\\PrintDialog\\\\*\",\"C:\\\\Windows\\\\PolicyDefinitions\\\\*\",\"C:\\\\Windows\\\\media\\\\*\",\n \"C:\\\\Windows\\\\Globalization\\\\*\",\"C:\\\\Windows\\\\L2Schemas\\\\*\",\"C:\\\\Windows\\\\LiveKernelReports\\\\*\",\"C:\\\\Windows\\\\ModemLogs\\\\*\",\"C:\\\\Windows\\\\ImmersiveControlPanel\\\\*\",\n \"C:\\\\$Recycle.Bin\\\\*\")\n",
+ "query": "process where event.type in (\"start\", \"process_started\", \"info\") and\n process.name : (\"wscript.exe\", \n \"cscript.exe\", \n \"rundll32.exe\", \n \"regsvr32.exe\", \n \"cmstp.exe\",\n \"RegAsm.exe\",\n \"installutil.exe\",\n \"mshta.exe\",\n \"RegSvcs.exe\", \n \"powershell.exe\", \n \"pwsh.exe\", \n \"cmd.exe\") and\n \n /* add suspicious execution paths here */\n process.args : (\"C:\\\\PerfLogs\\\\*\",\n \"C:\\\\Users\\\\Public\\\\*\",\n \"C:\\\\Users\\\\Default\\\\*\",\n \"C:\\\\Windows\\\\Tasks\\\\*\",\n \"C:\\\\Intel\\\\*\", \n \"C:\\\\AMD\\\\Temp\\\\*\", \n \"C:\\\\Windows\\\\AppReadiness\\\\*\", \n \"C:\\\\Windows\\\\ServiceState\\\\*\",\n \"C:\\\\Windows\\\\security\\\\*\",\n \"C:\\\\Windows\\\\IdentityCRL\\\\*\",\n \"C:\\\\Windows\\\\Branding\\\\*\",\n \"C:\\\\Windows\\\\csc\\\\*\",\n \"C:\\\\Windows\\\\DigitalLocker\\\\*\",\n \"C:\\\\Windows\\\\en-US\\\\*\",\n \"C:\\\\Windows\\\\wlansvc\\\\*\",\n \"C:\\\\Windows\\\\Prefetch\\\\*\",\n \"C:\\\\Windows\\\\Fonts\\\\*\",\n \"C:\\\\Windows\\\\diagnostics\\\\*\",\n \"C:\\\\Windows\\\\TAPI\\\\*\",\n \"C:\\\\Windows\\\\INF\\\\*\",\n \"C:\\\\Windows\\\\System32\\\\Speech\\\\*\",\n \"C:\\\\windows\\\\tracing\\\\*\",\n \"c:\\\\windows\\\\IME\\\\*\",\n \"c:\\\\Windows\\\\Performance\\\\*\",\n \"c:\\\\windows\\\\intel\\\\*\",\n \"c:\\\\windows\\\\ms\\\\*\",\n \"C:\\\\Windows\\\\dot3svc\\\\*\",\n \"C:\\\\Windows\\\\ServiceProfiles\\\\*\",\n \"C:\\\\Windows\\\\panther\\\\*\",\n \"C:\\\\Windows\\\\RemotePackages\\\\*\",\n \"C:\\\\Windows\\\\OCR\\\\*\",\n \"C:\\\\Windows\\\\appcompat\\\\*\",\n \"C:\\\\Windows\\\\apppatch\\\\*\",\n \"C:\\\\Windows\\\\addins\\\\*\",\n \"C:\\\\Windows\\\\Setup\\\\*\",\n \"C:\\\\Windows\\\\Help\\\\*\",\n \"C:\\\\Windows\\\\SKB\\\\*\",\n \"C:\\\\Windows\\\\Vss\\\\*\",\n \"C:\\\\Windows\\\\Web\\\\*\",\n \"C:\\\\Windows\\\\servicing\\\\*\",\n \"C:\\\\Windows\\\\CbsTemp\\\\*\",\n \"C:\\\\Windows\\\\Logs\\\\*\",\n \"C:\\\\Windows\\\\WaaS\\\\*\",\n \"C:\\\\Windows\\\\twain_32\\\\*\",\n \"C:\\\\Windows\\\\ShellExperiences\\\\*\",\n \"C:\\\\Windows\\\\ShellComponents\\\\*\",\n \"C:\\\\Windows\\\\PLA\\\\*\",\n \"C:\\\\Windows\\\\Migration\\\\*\",\n \"C:\\\\Windows\\\\debug\\\\*\",\n \"C:\\\\Windows\\\\Cursors\\\\*\",\n \"C:\\\\Windows\\\\Containers\\\\*\",\n \"C:\\\\Windows\\\\Boot\\\\*\",\n \"C:\\\\Windows\\\\bcastdvr\\\\*\",\n \"C:\\\\Windows\\\\assembly\\\\*\",\n \"C:\\\\Windows\\\\TextInput\\\\*\",\n \"C:\\\\Windows\\\\security\\\\*\",\n \"C:\\\\Windows\\\\schemas\\\\*\",\n \"C:\\\\Windows\\\\SchCache\\\\*\",\n \"C:\\\\Windows\\\\Resources\\\\*\",\n \"C:\\\\Windows\\\\rescache\\\\*\",\n \"C:\\\\Windows\\\\Provisioning\\\\*\",\n \"C:\\\\Windows\\\\PrintDialog\\\\*\",\n \"C:\\\\Windows\\\\PolicyDefinitions\\\\*\",\n \"C:\\\\Windows\\\\media\\\\*\",\n \"C:\\\\Windows\\\\Globalization\\\\*\",\n \"C:\\\\Windows\\\\L2Schemas\\\\*\",\n \"C:\\\\Windows\\\\LiveKernelReports\\\\*\",\n \"C:\\\\Windows\\\\ModemLogs\\\\*\",\n \"C:\\\\Windows\\\\ImmersiveControlPanel\\\\*\",\n \"C:\\\\$Recycle.Bin\\\\*\") and\n not process.parent.executable : (\"C:\\\\WINDOWS\\\\System32\\\\DriverStore\\\\FileRepository\\\\*\\\\igfxCUIService*.exe\",\n \"C:\\\\Windows\\\\System32\\\\spacedeskService.exe\",\n \"C:\\\\Program Files\\\\Dell\\\\SupportAssistAgent\\\\SRE\\\\SRE.exe\") and\n not (process.name : \"rundll32.exe\" and process.args : (\"uxtheme.dll,#64\", \"PRINTUI.DLL,PrintUIEntry\"))\n",
"risk_score": 47,
"rule_id": "cff92c41-2225-4763-b4ce-6f71e5bda5e6",
"severity": "medium",
@@ -26,5 +26,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json
index 3bebf4b415506..ca919d06e34a4 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json
@@ -15,7 +15,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Network Connection via Registration Utility",
- "query": "sequence by process.entity_id\n [process where (process.name : \"regsvr32.exe\" or process.name : \"regsvr64.exe\" or\n process.name : \"RegAsm.exe\" or process.name : \"RegSvcs.exe\") and\n event.type == \"start\"]\n [network where (process.name : \"regsvr32.exe\" or process.name : \"regsvr64.exe\" or\n process.name : \"RegAsm.exe\" or process.name : \"RegSvcs.exe\") and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"169.254.169.254\", \"172.16.0.0/12\", \"192.168.0.0/16\")]\n",
+ "query": "sequence by process.entity_id\n [process where event.type == \"start\" and\n process.name : (\"regsvr32.exe\", \"RegAsm.exe\", \"RegSvcs.exe\") and\n not (\n user.id == \"S-1-5-18\" and\n (process.parent.name : \"msiexec.exe\" or process.parent.executable : (\"C:\\\\Program Files (x86)\\\\*.exe\", \"C:\\\\Program Files\\\\*.exe\"))\n )\n ]\n [network where process.name : (\"regsvr32.exe\", \"RegAsm.exe\", \"RegSvcs.exe\") and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"169.254.169.254\", \"172.16.0.0/12\", \"192.168.0.0/16\") and network.protocol != \"dns\"]\n",
"risk_score": 21,
"rule_id": "fb02b8d3-71ee-4af1-bacd-215d23f17efa",
"severity": "low",
@@ -60,5 +60,5 @@
}
],
"type": "eql",
- "version": 7
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json
index c637ac93d3d6d..e4e58e89c7d38 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious PDF Reader Child Process",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:(AcroRd32.exe or Acrobat.exe or FoxitPhantomPDF.exe or FoxitReader.exe) and process.name:(arp.exe or dsquery.exe or dsget.exe or gpresult.exe or hostname.exe or ipconfig.exe or nbtstat.exe or net.exe or net1.exe or netsh.exe or netstat.exe or nltest.exe or ping.exe or qprocess.exe or quser.exe or qwinsta.exe or reg.exe or sc.exe or systeminfo.exe or tasklist.exe or tracert.exe or whoami.exe or bginfo.exe or cdb.exe or cmstp.exe or csi.exe or dnx.exe or fsi.exe or ieexec.exe or iexpress.exe or installutil.exe or Microsoft.Workflow.Compiler.exe or msbuild.exe or mshta.exe or msxsl.exe or odbcconf.exe or rcsi.exe or regsvr32.exe or xwizard.exe or atbroker.exe or forfiles.exe or schtasks.exe or regasm.exe or regsvcs.exe or cmd.exe or cscript.exe or powershell.exe or pwsh.exe or wmic.exe or wscript.exe or bitsadmin.exe or certutil.exe or ftp.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : (\"AcroRd32.exe\",\n \"Acrobat.exe\",\n \"FoxitPhantomPDF.exe\",\n \"FoxitReader.exe\") and\n process.name : (\"arp.exe\", \"dsquery.exe\", \"dsget.exe\", \"gpresult.exe\", \"hostname.exe\", \"ipconfig.exe\", \"nbtstat.exe\",\n \"net.exe\", \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"ping.exe\", \"qprocess.exe\",\n \"quser.exe\", \"qwinsta.exe\", \"reg.exe\", \"sc.exe\", \"systeminfo.exe\", \"tasklist.exe\", \"tracert.exe\",\n \"whoami.exe\", \"bginfo.exe\", \"cdb.exe\", \"cmstp.exe\", \"csi.exe\", \"dnx.exe\", \"fsi.exe\", \"ieexec.exe\",\n \"iexpress.exe\", \"installutil.exe\", \"Microsoft.Workflow.Compiler.exe\", \"msbuild.exe\", \"mshta.exe\",\n \"msxsl.exe\", \"odbcconf.exe\", \"rcsi.exe\", \"regsvr32.exe\", \"xwizard.exe\", \"atbroker.exe\",\n \"forfiles.exe\", \"schtasks.exe\", \"regasm.exe\", \"regsvcs.exe\", \"cmd.exe\", \"cscript.exe\",\n \"powershell.exe\", \"pwsh.exe\", \"wmic.exe\", \"wscript.exe\", \"bitsadmin.exe\", \"certutil.exe\", \"ftp.exe\")\n",
"risk_score": 21,
"rule_id": "53a26770-9cbd-40c5-8b57-61d01a325e14",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 6
+ "type": "eql",
+ "version": 7
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json
index 53d070e048681..efc3884b417fb 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json
@@ -12,13 +12,13 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Process Activity via Compiled HTML File",
- "query": "event.category:process and event.type:(start or process_started) and process.name:hh.exe",
- "risk_score": 21,
+ "query": "process where event.type in (\"start\", \"process_started\") and \n process.parent.name : \"hh.exe\" and \n process.name : (\"mshta.exe\", \"cmd.exe\", \"powershell.exe\", \"pwsh.exe\", \"cscript.exe\", \"wscript.exe\")\n",
+ "risk_score": 47,
"rule_id": "e3343ab9-4245-4715-b344-e11c56b0a47f",
- "severity": "low",
+ "severity": "medium",
"tags": [
"Elastic",
"Host",
@@ -60,6 +60,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json
index c69f0d5d41755..4b5e38d65e43b 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Conhost Spawned By Suspicious Parent Process",
- "query": "event.category:process and event.type:(start or process_started) and process.name:conhost.exe and process.parent.name:(svchost.exe or lsass.exe or services.exe or smss.exe or winlogon.exe or explorer.exe or dllhost.exe or rundll32.exe or regsvr32.exe or userinit.exe or wininit.exe or spoolsv.exe or wermgr.exe or csrss.exe or ctfmon.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"conhost.exe\" and\n process.parent.name : (\"svchost.exe\", \"lsass.exe\", \"services.exe\", \"smss.exe\", \"winlogon.exe\", \"explorer.exe\",\n \"dllhost.exe\", \"rundll32.exe\", \"regsvr32.exe\", \"userinit.exe\", \"wininit.exe\", \"spoolsv.exe\",\n \"wermgr.exe\", \"csrss.exe\", \"ctfmon.exe\")\n",
"references": [
"https://www.fireeye.com/blog/threat-research/2017/08/monitoring-windows-console-activity-part-one.html"
],
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json
deleted file mode 100644
index fcda4aa7e3c28..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "RegSvcs.exe and RegAsm.exe are Windows command line utilities that are used to register .NET Component Object Model (COM) assemblies. Adversaries can use RegSvcs.exe and RegAsm.exe to proxy execution of code through a trusted Windows utility.",
- "from": "now-9m",
- "index": [
- "winlogbeat-*",
- "logs-endpoint.events.*",
- "logs-windows.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Execution via Regsvcs/Regasm",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(RegAsm.exe or RegSvcs.exe)",
- "risk_score": 21,
- "rule_id": "47f09343-8d1f-4bb5-8bb0-00c9d18f5010",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Execution"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0002",
- "name": "Execution",
- "reference": "https://attack.mitre.org/tactics/TA0002/"
- },
- "technique": []
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0005",
- "name": "Defense Evasion",
- "reference": "https://attack.mitre.org/tactics/TA0005/"
- },
- "technique": [
- {
- "id": "T1218",
- "name": "Signed Binary Proxy Execution",
- "reference": "https://attack.mitre.org/techniques/T1218/",
- "subtechnique": [
- {
- "id": "T1218.009",
- "name": "Regsvcs/Regasm",
- "reference": "https://attack.mitre.org/techniques/T1218/009/"
- }
- ]
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json
index e34469bdde78a..e5be955247bd0 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Execution via MSSQL xp_cmdshell Stored Procedure",
- "query": "event.category:process and event.type:(start or process_started) and process.name:cmd.exe and process.parent.name:sqlservr.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : \"cmd.exe\" and process.parent.name : \"sqlservr.exe\"\n",
"risk_score": 73,
"rule_id": "4ed493fc-d637-4a36-80ff-ac84937e5461",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json
index 86ef5c6d8c131..33534d777272d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudTrail Log Updated",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:UpdateTrail and event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:cloudtrail.amazonaws.com and event.action:UpdateTrail and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_UpdateTrail.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/update-trail.html"
@@ -73,5 +73,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json
index 2af9118b9f0a2..1fa046a285a4d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudWatch Log Group Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteLogGroup and event.dataset:aws.cloudtrail and event.provider:logs.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:logs.amazonaws.com and event.action:DeleteLogGroup and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/delete-log-group.html",
"https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogGroup.html"
@@ -73,5 +73,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json
index 10ac9f12af19c..800e576e22c10 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS CloudWatch Log Stream Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteLogStream and event.dataset:aws.cloudtrail and event.provider:logs.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:logs.amazonaws.com and event.action:DeleteLogStream and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/delete-log-stream.html",
"https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogStream.html"
@@ -73,5 +73,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json
index d766d0dd3a94c..944814f1b47d1 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS EC2 Encryption Disabled",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DisableEbsEncryptionByDefault and event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.action:DisableEbsEncryptionByDefault and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/disable-ebs-encryption-by-default.html",
@@ -59,5 +59,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json
index 1ae1dae1a164b..e5875576c5190 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json
@@ -14,7 +14,7 @@
"license": "Elastic License v2",
"name": "GCP Storage Bucket Deletion",
"note": "The GCP Filebeat module must be enabled to use this rule.",
- "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:storage.buckets.delete",
+ "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:\"storage.buckets.delete\"",
"references": [
"https://cloud.google.com/storage/docs/key-terms#buckets"
],
@@ -48,5 +48,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json
index a5d94832647cb..4e21cb82c4cd6 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_virtual_private_cloud_route_created.json
@@ -14,7 +14,7 @@
"license": "Elastic License v2",
"name": "GCP Virtual Private Cloud Route Creation",
"note": "The GCP Filebeat module must be enabled to use this rule.",
- "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:(v*.compute.routes.insert or beta.compute.routes.insert)",
+ "query": "event.dataset:(googlecloud.audit or gcp.audit) and event.action:(v*.compute.routes.insert or \"beta.compute.routes.insert\")",
"references": [
"https://cloud.google.com/vpc/docs/routes",
"https://cloud.google.com/vpc/docs/using-routes"
@@ -32,5 +32,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json
index 8885b30d8be8f..d202cc6e84ee9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json
@@ -10,11 +10,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Hosts File Modified",
"note": "For Windows systems using Auditbeat, this rule requires adding 'C:/Windows/System32/drivers/etc' as an additional path in the 'file_integrity' module of auditbeat.yml.",
- "query": "event.category:file and event.type:(change or creation) and file.path:(\"/private/etc/hosts\" or \"/etc/hosts\" or \"C:\\Windows\\System32\\drivers\\etc\\hosts\")",
+ "query": "file where event.type in (\"change\", \"creation\") and\n file.path : (\"/private/etc/hosts\", \"/etc/hosts\", \"?:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts\") \n",
"references": [
"https://www.elastic.co/guide/en/beats/auditbeat/current/auditbeat-reference-yml.html"
],
@@ -55,6 +55,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json
index 3783f9ab1f00f..1f0d48e2ecbc4 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json
@@ -1,6 +1,7 @@
{
"author": [
- "Elastic"
+ "Elastic",
+ "Austin Songer"
],
"description": "Identifies the deactivation of a specified multi-factor authentication (MFA) device and removes it from association with the user name for which it was originally enabled. In AWS Identity and Access Management (IAM), a device must be deactivated before it can be deleted.",
"false_positives": [
@@ -16,7 +17,7 @@
"license": "Elastic License v2",
"name": "AWS IAM Deactivation of MFA Device",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeactivateMFADevice and event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.action:(DeactivateMFADevice or DeleteVirtualMFADevice) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/deactivate-mfa-device.html",
"https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeactivateMFADevice.html"
@@ -51,5 +52,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json
index 02dcb16607a0f..ebe8df9c785ca 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS IAM Group Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:DeleteGroup and event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.action:DeleteGroup and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/delete-group.html",
"https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteGroup.html"
@@ -51,5 +51,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_cluster_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_cluster_deletion.json
index 3a265298e1414..b8c81e467fabb 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_cluster_deletion.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_cluster_deletion.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS RDS Cluster Deletion",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(DeleteDBCluster or DeleteGlobalCluster) and event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.action:(DeleteDBCluster or DeleteGlobalCluster) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/delete-db-cluster.html",
"https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DeleteDBCluster.html",
@@ -53,5 +53,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json
index b30da3e0a912b..bd56daf3c6c9c 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS RDS Instance/Cluster Stoppage",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(StopDBCluster or StopDBInstance) and event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.action:(StopDBCluster or StopDBInstance) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/stop-db-cluster.html",
"https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_StopDBCluster.html",
@@ -53,5 +53,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json
index cfe0632b28728..f0ac38e98441e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_vssadmin.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Volume Shadow Copy Deletion via VssAdmin",
- "query": "event.category:process and event.type:(start or process_started) and process.name:vssadmin.exe and process.args:(delete and shadows)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (process.name : \"vssadmin.exe\" or process.pe.original_file_name == \"VSSADMIN.EXE\") and\n process.args : \"delete\" and process.args : \"shadows\"\n",
"risk_score": 73,
"rule_id": "b5ea4bfe-a1b2-421f-9d47-22a75a6f2921",
"severity": "high",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts
index 081b0dd288c7b..e910b1a10f586 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts
@@ -32,530 +32,519 @@ import rule19 from './apm_405_response_method_not_allowed.json';
import rule20 from './apm_null_user_agent.json';
import rule21 from './apm_sqlmap_user_agent.json';
import rule22 from './command_and_control_dns_directly_to_the_internet.json';
-import rule23 from './command_and_control_ftp_file_transfer_protocol_activity_to_the_internet.json';
-import rule24 from './command_and_control_irc_internet_relay_chat_protocol_activity_to_the_internet.json';
-import rule25 from './command_and_control_nat_traversal_port_activity.json';
-import rule26 from './command_and_control_port_26_activity.json';
-import rule27 from './command_and_control_port_8000_activity_to_the_internet.json';
-import rule28 from './command_and_control_pptp_point_to_point_tunneling_protocol_activity.json';
-import rule29 from './command_and_control_proxy_port_activity_to_the_internet.json';
-import rule30 from './command_and_control_rdp_remote_desktop_protocol_from_the_internet.json';
-import rule31 from './command_and_control_smtp_to_the_internet.json';
-import rule32 from './command_and_control_sql_server_port_activity_to_the_internet.json';
-import rule33 from './command_and_control_ssh_secure_shell_from_the_internet.json';
-import rule34 from './command_and_control_ssh_secure_shell_to_the_internet.json';
-import rule35 from './command_and_control_telnet_port_activity.json';
-import rule36 from './command_and_control_tor_activity_to_the_internet.json';
-import rule37 from './command_and_control_vnc_virtual_network_computing_from_the_internet.json';
-import rule38 from './command_and_control_vnc_virtual_network_computing_to_the_internet.json';
-import rule39 from './credential_access_tcpdump_activity.json';
-import rule40 from './defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json';
-import rule41 from './defense_evasion_clearing_windows_event_logs.json';
-import rule42 from './defense_evasion_delete_volume_usn_journal_with_fsutil.json';
-import rule43 from './defense_evasion_deleting_backup_catalogs_with_wbadmin.json';
-import rule44 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json';
-import rule45 from './defense_evasion_encoding_or_decoding_files_via_certutil.json';
-import rule46 from './defense_evasion_execution_via_trusted_developer_utilities.json';
-import rule47 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json';
-import rule48 from './defense_evasion_msbuild_making_network_connections.json';
-import rule49 from './defense_evasion_unusual_network_connection_via_rundll32.json';
-import rule50 from './defense_evasion_unusual_process_network_connection.json';
-import rule51 from './defense_evasion_via_filter_manager.json';
-import rule52 from './defense_evasion_volume_shadow_copy_deletion_via_wmic.json';
-import rule53 from './discovery_process_discovery_via_tasklist_command.json';
-import rule54 from './discovery_whoami_command_activity.json';
-import rule55 from './discovery_whoami_commmand.json';
-import rule56 from './endgame_adversary_behavior_detected.json';
-import rule57 from './endgame_cred_dumping_detected.json';
-import rule58 from './endgame_cred_dumping_prevented.json';
-import rule59 from './endgame_cred_manipulation_detected.json';
-import rule60 from './endgame_cred_manipulation_prevented.json';
-import rule61 from './endgame_exploit_detected.json';
-import rule62 from './endgame_exploit_prevented.json';
-import rule63 from './endgame_malware_detected.json';
-import rule64 from './endgame_malware_prevented.json';
-import rule65 from './endgame_permission_theft_detected.json';
-import rule66 from './endgame_permission_theft_prevented.json';
-import rule67 from './endgame_process_injection_detected.json';
-import rule68 from './endgame_process_injection_prevented.json';
-import rule69 from './endgame_ransomware_detected.json';
-import rule70 from './endgame_ransomware_prevented.json';
-import rule71 from './execution_command_prompt_connecting_to_the_internet.json';
-import rule72 from './execution_command_shell_started_by_powershell.json';
-import rule73 from './execution_command_shell_started_by_svchost.json';
-import rule74 from './execution_html_help_executable_program_connecting_to_the_internet.json';
-import rule75 from './execution_psexec_lateral_movement_command.json';
-import rule76 from './execution_register_server_program_connecting_to_the_internet.json';
-import rule77 from './execution_via_compiled_html_file.json';
-import rule78 from './impact_volume_shadow_copy_deletion_via_vssadmin.json';
-import rule79 from './initial_access_rdp_remote_desktop_protocol_to_the_internet.json';
-import rule80 from './initial_access_rpc_remote_procedure_call_from_the_internet.json';
-import rule81 from './initial_access_rpc_remote_procedure_call_to_the_internet.json';
-import rule82 from './initial_access_script_executing_powershell.json';
-import rule83 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json';
-import rule84 from './initial_access_suspicious_ms_office_child_process.json';
-import rule85 from './initial_access_suspicious_ms_outlook_child_process.json';
-import rule86 from './lateral_movement_direct_outbound_smb_connection.json';
-import rule87 from './lateral_movement_local_service_commands.json';
-import rule88 from './linux_hping_activity.json';
-import rule89 from './linux_iodine_activity.json';
-import rule90 from './linux_mknod_activity.json';
-import rule91 from './linux_netcat_network_connection.json';
-import rule92 from './linux_nmap_activity.json';
-import rule93 from './linux_nping_activity.json';
-import rule94 from './linux_process_started_in_temp_directory.json';
-import rule95 from './linux_socat_activity.json';
-import rule96 from './linux_strace_activity.json';
-import rule97 from './persistence_adobe_hijack_persistence.json';
-import rule98 from './persistence_kernel_module_activity.json';
-import rule99 from './persistence_local_scheduled_task_commands.json';
-import rule100 from './persistence_priv_escalation_via_accessibility_features.json';
-import rule101 from './persistence_shell_activity_by_web_server.json';
-import rule102 from './persistence_system_shells_via_services.json';
-import rule103 from './persistence_user_account_creation.json';
-import rule104 from './persistence_via_application_shimming.json';
-import rule105 from './privilege_escalation_unusual_parentchild_relationship.json';
-import rule106 from './defense_evasion_modification_of_boot_config.json';
-import rule107 from './privilege_escalation_uac_bypass_event_viewer.json';
-import rule108 from './defense_evasion_msxsl_network.json';
-import rule109 from './discovery_net_command_system_account.json';
-import rule110 from './command_and_control_certutil_network_connection.json';
-import rule111 from './defense_evasion_cve_2020_0601.json';
-import rule112 from './credential_access_credential_dumping_msbuild.json';
-import rule113 from './defense_evasion_execution_msbuild_started_by_office_app.json';
-import rule114 from './defense_evasion_execution_msbuild_started_by_script.json';
-import rule115 from './defense_evasion_execution_msbuild_started_by_system_process.json';
-import rule116 from './defense_evasion_execution_msbuild_started_renamed.json';
-import rule117 from './defense_evasion_execution_msbuild_started_unusal_process.json';
-import rule118 from './defense_evasion_injection_msbuild.json';
-import rule119 from './execution_via_net_com_assemblies.json';
-import rule120 from './ml_linux_anomalous_network_activity.json';
-import rule121 from './ml_linux_anomalous_network_port_activity.json';
-import rule122 from './ml_linux_anomalous_network_service.json';
-import rule123 from './ml_linux_anomalous_network_url_activity.json';
-import rule124 from './ml_linux_anomalous_process_all_hosts.json';
-import rule125 from './ml_linux_anomalous_user_name.json';
-import rule126 from './ml_packetbeat_dns_tunneling.json';
-import rule127 from './ml_packetbeat_rare_dns_question.json';
-import rule128 from './ml_packetbeat_rare_server_domain.json';
-import rule129 from './ml_packetbeat_rare_urls.json';
-import rule130 from './ml_packetbeat_rare_user_agent.json';
-import rule131 from './ml_rare_process_by_host_linux.json';
-import rule132 from './ml_rare_process_by_host_windows.json';
-import rule133 from './ml_suspicious_login_activity.json';
-import rule134 from './ml_windows_anomalous_network_activity.json';
-import rule135 from './ml_windows_anomalous_path_activity.json';
-import rule136 from './ml_windows_anomalous_process_all_hosts.json';
-import rule137 from './ml_windows_anomalous_process_creation.json';
-import rule138 from './ml_windows_anomalous_script.json';
-import rule139 from './ml_windows_anomalous_service.json';
-import rule140 from './ml_windows_anomalous_user_name.json';
-import rule141 from './ml_windows_rare_user_runas_event.json';
-import rule142 from './ml_windows_rare_user_type10_remote_login.json';
-import rule143 from './execution_suspicious_pdf_reader.json';
-import rule144 from './privilege_escalation_sudoers_file_mod.json';
-import rule145 from './defense_evasion_iis_httplogging_disabled.json';
-import rule146 from './execution_python_tty_shell.json';
-import rule147 from './execution_perl_tty_shell.json';
-import rule148 from './defense_evasion_base16_or_base32_encoding_or_decoding_activity.json';
-import rule149 from './defense_evasion_base64_encoding_or_decoding_activity.json';
-import rule150 from './defense_evasion_hex_encoding_or_decoding_activity.json';
-import rule151 from './defense_evasion_file_mod_writable_dir.json';
-import rule152 from './defense_evasion_disable_selinux_attempt.json';
-import rule153 from './discovery_kernel_module_enumeration.json';
-import rule154 from './lateral_movement_telnet_network_activity_external.json';
-import rule155 from './lateral_movement_telnet_network_activity_internal.json';
-import rule156 from './privilege_escalation_setuid_setgid_bit_set_via_chmod.json';
-import rule157 from './defense_evasion_attempt_to_disable_iptables_or_firewall.json';
-import rule158 from './defense_evasion_kernel_module_removal.json';
-import rule159 from './defense_evasion_attempt_to_disable_syslog_service.json';
-import rule160 from './defense_evasion_file_deletion_via_shred.json';
-import rule161 from './discovery_virtual_machine_fingerprinting.json';
-import rule162 from './defense_evasion_hidden_file_dir_tmp.json';
-import rule163 from './defense_evasion_deletion_of_bash_command_line_history.json';
-import rule164 from './impact_cloudwatch_log_group_deletion.json';
-import rule165 from './impact_cloudwatch_log_stream_deletion.json';
-import rule166 from './impact_rds_instance_cluster_stoppage.json';
-import rule167 from './persistence_attempt_to_deactivate_mfa_for_okta_user_account.json';
-import rule168 from './persistence_rds_cluster_creation.json';
-import rule169 from './credential_access_attempted_bypass_of_okta_mfa.json';
-import rule170 from './defense_evasion_waf_acl_deletion.json';
-import rule171 from './impact_attempt_to_revoke_okta_api_token.json';
-import rule172 from './impact_iam_group_deletion.json';
-import rule173 from './impact_possible_okta_dos_attack.json';
-import rule174 from './impact_rds_cluster_deletion.json';
-import rule175 from './initial_access_suspicious_activity_reported_by_okta_user.json';
-import rule176 from './okta_attempt_to_deactivate_okta_policy.json';
-import rule177 from './okta_attempt_to_deactivate_okta_policy_rule.json';
-import rule178 from './okta_attempt_to_modify_okta_network_zone.json';
-import rule179 from './okta_attempt_to_modify_okta_policy.json';
-import rule180 from './okta_attempt_to_modify_okta_policy_rule.json';
-import rule181 from './okta_threat_detected_by_okta_threatinsight.json';
-import rule182 from './persistence_administrator_privileges_assigned_to_okta_group.json';
-import rule183 from './persistence_attempt_to_create_okta_api_token.json';
-import rule184 from './persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json';
-import rule185 from './defense_evasion_cloudtrail_logging_deleted.json';
-import rule186 from './defense_evasion_ec2_network_acl_deletion.json';
-import rule187 from './impact_iam_deactivate_mfa_device.json';
-import rule188 from './defense_evasion_s3_bucket_configuration_deletion.json';
-import rule189 from './defense_evasion_guardduty_detector_deletion.json';
-import rule190 from './okta_attempt_to_delete_okta_policy.json';
-import rule191 from './credential_access_iam_user_addition_to_group.json';
-import rule192 from './persistence_ec2_network_acl_creation.json';
-import rule193 from './impact_ec2_disable_ebs_encryption.json';
-import rule194 from './persistence_iam_group_creation.json';
-import rule195 from './defense_evasion_waf_rule_or_rule_group_deletion.json';
-import rule196 from './collection_cloudtrail_logging_created.json';
-import rule197 from './defense_evasion_cloudtrail_logging_suspended.json';
-import rule198 from './impact_cloudtrail_logging_updated.json';
-import rule199 from './initial_access_console_login_root.json';
-import rule200 from './defense_evasion_cloudwatch_alarm_deletion.json';
-import rule201 from './defense_evasion_ec2_flow_log_deletion.json';
-import rule202 from './defense_evasion_configuration_recorder_stopped.json';
-import rule203 from './exfiltration_ec2_snapshot_change_activity.json';
-import rule204 from './defense_evasion_config_service_rule_deletion.json';
-import rule205 from './okta_attempt_to_modify_or_delete_application_sign_on_policy.json';
-import rule206 from './command_and_control_download_rar_powershell_from_internet.json';
-import rule207 from './initial_access_password_recovery.json';
-import rule208 from './command_and_control_cobalt_strike_beacon.json';
-import rule209 from './command_and_control_fin7_c2_behavior.json';
-import rule210 from './command_and_control_halfbaked_beacon.json';
-import rule211 from './credential_access_secretsmanager_getsecretvalue.json';
-import rule212 from './initial_access_via_system_manager.json';
-import rule213 from './privilege_escalation_root_login_without_mfa.json';
-import rule214 from './privilege_escalation_updateassumerolepolicy.json';
-import rule215 from './impact_hosts_file_modified.json';
-import rule216 from './elastic_endpoint_security.json';
-import rule217 from './external_alerts.json';
-import rule218 from './initial_access_login_failures.json';
-import rule219 from './initial_access_login_location.json';
-import rule220 from './initial_access_login_sessions.json';
-import rule221 from './initial_access_login_time.json';
-import rule222 from './ml_cloudtrail_error_message_spike.json';
-import rule223 from './ml_cloudtrail_rare_error_code.json';
-import rule224 from './ml_cloudtrail_rare_method_by_city.json';
-import rule225 from './ml_cloudtrail_rare_method_by_country.json';
-import rule226 from './ml_cloudtrail_rare_method_by_user.json';
-import rule227 from './credential_access_aws_iam_assume_role_brute_force.json';
-import rule228 from './credential_access_okta_brute_force_or_password_spraying.json';
-import rule229 from './initial_access_unusual_dns_service_children.json';
-import rule230 from './initial_access_unusual_dns_service_file_writes.json';
-import rule231 from './lateral_movement_dns_server_overflow.json';
-import rule232 from './credential_access_root_console_failure_brute_force.json';
-import rule233 from './initial_access_unsecure_elasticsearch_node.json';
-import rule234 from './credential_access_domain_backup_dpapi_private_keys.json';
-import rule235 from './persistence_gpo_schtask_service_creation.json';
-import rule236 from './credential_access_credentials_keychains.json';
-import rule237 from './credential_access_kerberosdump_kcc.json';
-import rule238 from './defense_evasion_attempt_del_quarantine_attrib.json';
-import rule239 from './execution_suspicious_psexesvc.json';
-import rule240 from './execution_via_xp_cmdshell_mssql_stored_procedure.json';
-import rule241 from './privilege_escalation_printspooler_service_suspicious_file.json';
-import rule242 from './privilege_escalation_printspooler_suspicious_spl_file.json';
-import rule243 from './defense_evasion_azure_diagnostic_settings_deletion.json';
-import rule244 from './execution_command_virtual_machine.json';
-import rule245 from './execution_via_hidden_shell_conhost.json';
-import rule246 from './impact_resource_group_deletion.json';
-import rule247 from './persistence_via_telemetrycontroller_scheduledtask_hijack.json';
-import rule248 from './persistence_via_update_orchestrator_service_hijack.json';
-import rule249 from './collection_update_event_hub_auth_rule.json';
-import rule250 from './credential_access_iis_apppoolsa_pwd_appcmd.json';
-import rule251 from './credential_access_iis_connectionstrings_dumping.json';
-import rule252 from './defense_evasion_event_hub_deletion.json';
-import rule253 from './defense_evasion_firewall_policy_deletion.json';
-import rule254 from './defense_evasion_sdelete_like_filename_rename.json';
-import rule255 from './lateral_movement_remote_ssh_login_enabled.json';
-import rule256 from './persistence_azure_automation_account_created.json';
-import rule257 from './persistence_azure_automation_runbook_created_or_modified.json';
-import rule258 from './persistence_azure_automation_webhook_created.json';
-import rule259 from './privilege_escalation_uac_bypass_diskcleanup_hijack.json';
-import rule260 from './credential_access_attempts_to_brute_force_okta_user_account.json';
-import rule261 from './credential_access_storage_account_key_regenerated.json';
-import rule262 from './defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json';
-import rule263 from './defense_evasion_system_critical_proc_abnormal_file_activity.json';
-import rule264 from './defense_evasion_unusual_system_vp_child_program.json';
-import rule265 from './discovery_blob_container_access_mod.json';
-import rule266 from './persistence_mfa_disabled_for_azure_user.json';
-import rule267 from './persistence_user_added_as_owner_for_azure_application.json';
-import rule268 from './persistence_user_added_as_owner_for_azure_service_principal.json';
-import rule269 from './defense_evasion_dotnet_compiler_parent_process.json';
-import rule270 from './defense_evasion_suspicious_managedcode_host_process.json';
-import rule271 from './execution_command_shell_started_by_unusual_process.json';
-import rule272 from './defense_evasion_masquerading_as_elastic_endpoint_process.json';
-import rule273 from './defense_evasion_masquerading_suspicious_werfault_childproc.json';
-import rule274 from './defense_evasion_masquerading_werfault.json';
-import rule275 from './credential_access_key_vault_modified.json';
-import rule276 from './credential_access_mimikatz_memssp_default_logs.json';
-import rule277 from './defense_evasion_code_injection_conhost.json';
-import rule278 from './defense_evasion_network_watcher_deletion.json';
-import rule279 from './initial_access_external_guest_user_invite.json';
-import rule280 from './defense_evasion_masquerading_renamed_autoit.json';
-import rule281 from './impact_azure_automation_runbook_deleted.json';
-import rule282 from './initial_access_consent_grant_attack_via_azure_registered_application.json';
-import rule283 from './persistence_azure_conditional_access_policy_modified.json';
-import rule284 from './persistence_azure_privileged_identity_management_role_modified.json';
-import rule285 from './command_and_control_teamviewer_remote_file_copy.json';
-import rule286 from './defense_evasion_installutil_beacon.json';
-import rule287 from './defense_evasion_mshta_beacon.json';
-import rule288 from './defense_evasion_network_connection_from_windows_binary.json';
-import rule289 from './defense_evasion_rundll32_no_arguments.json';
-import rule290 from './defense_evasion_suspicious_scrobj_load.json';
-import rule291 from './defense_evasion_suspicious_wmi_script.json';
-import rule292 from './execution_ms_office_written_file.json';
-import rule293 from './execution_pdf_written_file.json';
-import rule294 from './lateral_movement_cmd_service.json';
-import rule295 from './persistence_app_compat_shim.json';
-import rule296 from './command_and_control_remote_file_copy_desktopimgdownldr.json';
-import rule297 from './command_and_control_remote_file_copy_mpcmdrun.json';
-import rule298 from './defense_evasion_execution_suspicious_explorer_winword.json';
-import rule299 from './defense_evasion_suspicious_zoom_child_process.json';
-import rule300 from './ml_linux_anomalous_compiler_activity.json';
-import rule301 from './ml_linux_anomalous_kernel_module_arguments.json';
-import rule302 from './ml_linux_anomalous_sudo_activity.json';
-import rule303 from './ml_linux_system_information_discovery.json';
-import rule304 from './ml_linux_system_network_configuration_discovery.json';
-import rule305 from './ml_linux_system_network_connection_discovery.json';
-import rule306 from './ml_linux_system_process_discovery.json';
-import rule307 from './ml_linux_system_user_discovery.json';
-import rule308 from './discovery_post_exploitation_public_ip_reconnaissance.json';
-import rule309 from './initial_access_zoom_meeting_with_no_passcode.json';
-import rule310 from './defense_evasion_gcp_logging_sink_deletion.json';
-import rule311 from './defense_evasion_gcp_pub_sub_topic_deletion.json';
-import rule312 from './defense_evasion_gcp_firewall_rule_created.json';
-import rule313 from './defense_evasion_gcp_firewall_rule_deleted.json';
-import rule314 from './defense_evasion_gcp_firewall_rule_modified.json';
-import rule315 from './defense_evasion_gcp_logging_bucket_deletion.json';
-import rule316 from './defense_evasion_gcp_storage_bucket_permissions_modified.json';
-import rule317 from './impact_gcp_storage_bucket_deleted.json';
-import rule318 from './initial_access_gcp_iam_custom_role_creation.json';
-import rule319 from './persistence_gcp_iam_service_account_key_deletion.json';
-import rule320 from './persistence_gcp_key_created_for_service_account.json';
-import rule321 from './defense_evasion_gcp_storage_bucket_configuration_modified.json';
-import rule322 from './exfiltration_gcp_logging_sink_modification.json';
-import rule323 from './impact_gcp_iam_role_deletion.json';
-import rule324 from './impact_gcp_service_account_deleted.json';
-import rule325 from './impact_gcp_service_account_disabled.json';
-import rule326 from './impact_gcp_virtual_private_cloud_network_deleted.json';
-import rule327 from './impact_gcp_virtual_private_cloud_route_created.json';
-import rule328 from './impact_gcp_virtual_private_cloud_route_deleted.json';
-import rule329 from './ml_linux_anomalous_metadata_process.json';
-import rule330 from './ml_linux_anomalous_metadata_user.json';
-import rule331 from './ml_windows_anomalous_metadata_process.json';
-import rule332 from './ml_windows_anomalous_metadata_user.json';
-import rule333 from './persistence_gcp_service_account_created.json';
-import rule334 from './collection_gcp_pub_sub_subscription_creation.json';
-import rule335 from './collection_gcp_pub_sub_topic_creation.json';
-import rule336 from './defense_evasion_gcp_pub_sub_subscription_deletion.json';
-import rule337 from './persistence_azure_pim_user_added_global_admin.json';
-import rule338 from './command_and_control_cobalt_strike_default_teamserver_cert.json';
-import rule339 from './defense_evasion_enable_inbound_rdp_with_netsh.json';
-import rule340 from './defense_evasion_execution_lolbas_wuauclt.json';
-import rule341 from './privilege_escalation_unusual_svchost_childproc_childless.json';
-import rule342 from './lateral_movement_rdp_tunnel_plink.json';
-import rule343 from './privilege_escalation_uac_bypass_winfw_mmc_hijack.json';
-import rule344 from './persistence_ms_office_addins_file.json';
-import rule345 from './discovery_adfind_command_activity.json';
-import rule346 from './discovery_security_software_wmic.json';
-import rule347 from './execution_command_shell_via_rundll32.json';
-import rule348 from './execution_suspicious_cmd_wmi.json';
-import rule349 from './lateral_movement_via_startup_folder_rdp_smb.json';
-import rule350 from './privilege_escalation_uac_bypass_com_interface_icmluautil.json';
-import rule351 from './privilege_escalation_uac_bypass_mock_windir.json';
-import rule352 from './defense_evasion_potential_processherpaderping.json';
-import rule353 from './privilege_escalation_uac_bypass_dll_sideloading.json';
-import rule354 from './execution_shared_modules_local_sxs_dll.json';
-import rule355 from './privilege_escalation_uac_bypass_com_clipup.json';
-import rule356 from './initial_access_via_explorer_suspicious_child_parent_args.json';
-import rule357 from './execution_from_unusual_directory.json';
-import rule358 from './execution_from_unusual_path_cmdline.json';
-import rule359 from './credential_access_kerberoasting_unusual_process.json';
-import rule360 from './discovery_peripheral_device.json';
-import rule361 from './lateral_movement_mount_hidden_or_webdav_share_net.json';
-import rule362 from './defense_evasion_deleting_websvr_access_logs.json';
-import rule363 from './defense_evasion_log_files_deleted.json';
-import rule364 from './defense_evasion_timestomp_touch.json';
-import rule365 from './lateral_movement_dcom_hta.json';
-import rule366 from './lateral_movement_execution_via_file_shares_sequence.json';
-import rule367 from './privilege_escalation_uac_bypass_com_ieinstal.json';
-import rule368 from './command_and_control_common_webservices.json';
-import rule369 from './command_and_control_encrypted_channel_freesslcert.json';
-import rule370 from './defense_evasion_process_termination_followed_by_deletion.json';
-import rule371 from './lateral_movement_remote_file_copy_hidden_share.json';
-import rule372 from './attempt_to_deactivate_okta_network_zone.json';
-import rule373 from './attempt_to_delete_okta_network_zone.json';
-import rule374 from './lateral_movement_dcom_mmc20.json';
-import rule375 from './lateral_movement_dcom_shellwindow_shellbrowserwindow.json';
-import rule376 from './okta_attempt_to_deactivate_okta_application.json';
-import rule377 from './okta_attempt_to_delete_okta_application.json';
-import rule378 from './okta_attempt_to_delete_okta_policy_rule.json';
-import rule379 from './okta_attempt_to_modify_okta_application.json';
-import rule380 from './persistence_administrator_role_assigned_to_okta_user.json';
-import rule381 from './lateral_movement_executable_tool_transfer_smb.json';
-import rule382 from './command_and_control_dns_tunneling_nslookup.json';
-import rule383 from './lateral_movement_execution_from_tsclient_mup.json';
-import rule384 from './lateral_movement_rdp_sharprdp_target.json';
-import rule385 from './defense_evasion_clearing_windows_security_logs.json';
-import rule386 from './persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json';
-import rule387 from './execution_suspicious_short_program_name.json';
-import rule388 from './lateral_movement_incoming_wmi.json';
-import rule389 from './persistence_via_hidden_run_key_valuename.json';
-import rule390 from './credential_access_potential_ssh_bruteforce.json';
-import rule391 from './credential_access_promt_for_pwd_via_osascript.json';
-import rule392 from './lateral_movement_remote_services.json';
-import rule393 from './application_added_to_google_workspace_domain.json';
-import rule394 from './domain_added_to_google_workspace_trusted_domains.json';
-import rule395 from './execution_suspicious_image_load_wmi_ms_office.json';
-import rule396 from './execution_suspicious_powershell_imgload.json';
-import rule397 from './google_workspace_admin_role_deletion.json';
-import rule398 from './google_workspace_mfa_enforcement_disabled.json';
-import rule399 from './google_workspace_policy_modified.json';
-import rule400 from './mfa_disabled_for_google_workspace_organization.json';
-import rule401 from './persistence_evasion_registry_ifeo_injection.json';
-import rule402 from './persistence_google_workspace_admin_role_assigned_to_user.json';
-import rule403 from './persistence_google_workspace_custom_admin_role_created.json';
-import rule404 from './persistence_google_workspace_role_modified.json';
-import rule405 from './persistence_suspicious_image_load_scheduled_task_ms_office.json';
-import rule406 from './defense_evasion_masquerading_trusted_directory.json';
-import rule407 from './exfiltration_microsoft_365_exchange_transport_rule_creation.json';
-import rule408 from './initial_access_microsoft_365_exchange_safelinks_disabled.json';
-import rule409 from './microsoft_365_exchange_dkim_signing_config_disabled.json';
-import rule410 from './persistence_appcertdlls_registry.json';
-import rule411 from './persistence_appinitdlls_registry.json';
-import rule412 from './persistence_registry_uncommon.json';
-import rule413 from './persistence_run_key_and_startup_broad.json';
-import rule414 from './persistence_services_registry.json';
-import rule415 from './persistence_startup_folder_file_written_by_suspicious_process.json';
-import rule416 from './persistence_startup_folder_scripts.json';
-import rule417 from './persistence_suspicious_com_hijack_registry.json';
-import rule418 from './persistence_via_lsa_security_support_provider_registry.json';
-import rule419 from './defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json';
-import rule420 from './defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json';
-import rule421 from './defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json';
-import rule422 from './exfiltration_microsoft_365_exchange_transport_rule_mod.json';
-import rule423 from './initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json';
-import rule424 from './initial_access_microsoft_365_exchange_anti_phish_rule_mod.json';
-import rule425 from './lateral_movement_suspicious_rdp_client_imageload.json';
-import rule426 from './persistence_runtime_run_key_startup_susp_procs.json';
-import rule427 from './persistence_suspicious_scheduled_task_runtime.json';
-import rule428 from './defense_evasion_microsoft_365_exchange_dlp_policy_removed.json';
-import rule429 from './lateral_movement_scheduled_task_target.json';
-import rule430 from './persistence_microsoft_365_exchange_management_role_assignment.json';
-import rule431 from './persistence_microsoft_365_teams_guest_access_enabled.json';
-import rule432 from './credential_access_dump_registry_hives.json';
-import rule433 from './defense_evasion_scheduledjobs_at_protocol_enabled.json';
-import rule434 from './persistence_ms_outlook_vba_template.json';
-import rule435 from './persistence_suspicious_service_created_registry.json';
-import rule436 from './privilege_escalation_named_pipe_impersonation.json';
-import rule437 from './credential_access_cmdline_dump_tool.json';
-import rule438 from './credential_access_copy_ntds_sam_volshadowcp_cmdline.json';
-import rule439 from './credential_access_lsass_memdump_file_created.json';
-import rule440 from './lateral_movement_incoming_winrm_shell_execution.json';
-import rule441 from './lateral_movement_powershell_remoting_target.json';
-import rule442 from './defense_evasion_hide_encoded_executable_registry.json';
-import rule443 from './defense_evasion_port_forwarding_added_registry.json';
-import rule444 from './lateral_movement_rdp_enabled_registry.json';
-import rule445 from './privilege_escalation_printspooler_registry_copyfiles.json';
-import rule446 from './privilege_escalation_rogue_windir_environment_var.json';
-import rule447 from './initial_access_scripts_process_started_via_wmi.json';
-import rule448 from './command_and_control_iexplore_via_com.json';
-import rule449 from './command_and_control_remote_file_copy_scripts.json';
-import rule450 from './persistence_local_scheduled_task_scripting.json';
-import rule451 from './persistence_startup_folder_file_written_by_unsigned_process.json';
-import rule452 from './command_and_control_remote_file_copy_powershell.json';
-import rule453 from './credential_access_microsoft_365_brute_force_user_account_attempt.json';
-import rule454 from './microsoft_365_teams_custom_app_interaction_allowed.json';
-import rule455 from './persistence_microsoft_365_teams_external_access_enabled.json';
-import rule456 from './credential_access_microsoft_365_potential_password_spraying_attack.json';
-import rule457 from './defense_evasion_stop_process_service_threshold.json';
-import rule458 from './collection_winrar_encryption.json';
-import rule459 from './defense_evasion_unusual_dir_ads.json';
-import rule460 from './discovery_admin_recon.json';
-import rule461 from './discovery_file_dir_discovery.json';
-import rule462 from './discovery_net_view.json';
-import rule463 from './discovery_query_registry_via_reg.json';
-import rule464 from './discovery_remote_system_discovery_commands_windows.json';
-import rule465 from './persistence_via_windows_management_instrumentation_event_subscription.json';
-import rule466 from './execution_scripting_osascript_exec_followed_by_netcon.json';
-import rule467 from './execution_shell_execution_via_apple_scripting.json';
-import rule468 from './persistence_creation_change_launch_agents_file.json';
-import rule469 from './persistence_creation_modif_launch_deamon_sequence.json';
-import rule470 from './persistence_folder_action_scripts_runtime.json';
-import rule471 from './persistence_login_logout_hooks_defaults.json';
-import rule472 from './privilege_escalation_explicit_creds_via_scripting.json';
-import rule473 from './command_and_control_sunburst_c2_activity_detected.json';
-import rule474 from './defense_evasion_azure_application_credential_modification.json';
-import rule475 from './defense_evasion_azure_service_principal_addition.json';
-import rule476 from './defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json';
-import rule477 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.json';
-import rule478 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json';
-import rule479 from './initial_access_azure_active_directory_powershell_signin.json';
-import rule480 from './collection_email_powershell_exchange_mailbox.json';
-import rule481 from './collection_persistence_powershell_exch_mailbox_activesync_add_device.json';
-import rule482 from './execution_scheduled_task_powershell_source.json';
-import rule483 from './persistence_docker_shortcuts_plist_modification.json';
-import rule484 from './persistence_evasion_hidden_local_account_creation.json';
-import rule485 from './persistence_finder_sync_plugin_pluginkit.json';
-import rule486 from './discovery_security_software_grep.json';
-import rule487 from './credential_access_cookies_chromium_browsers_debugging.json';
-import rule488 from './credential_access_ssh_backdoor_log.json';
-import rule489 from './persistence_credential_access_modify_auth_module_or_config.json';
-import rule490 from './persistence_credential_access_modify_ssh_binaries.json';
-import rule491 from './credential_access_collection_sensitive_files.json';
-import rule492 from './persistence_ssh_authorized_keys_modification.json';
-import rule493 from './defense_evasion_defender_disabled_via_registry.json';
-import rule494 from './defense_evasion_privacy_controls_tcc_database_modification.json';
-import rule495 from './execution_initial_access_suspicious_browser_childproc.json';
-import rule496 from './execution_script_via_automator_workflows.json';
-import rule497 from './persistence_modification_sublime_app_plugin_or_script.json';
-import rule498 from './privilege_escalation_applescript_with_admin_privs.json';
-import rule499 from './credential_access_dumping_keychain_security.json';
-import rule500 from './initial_access_azure_active_directory_high_risk_signin.json';
-import rule501 from './initial_access_suspicious_mac_ms_office_child_process.json';
-import rule502 from './credential_access_mitm_localhost_webproxy.json';
-import rule503 from './persistence_kde_autostart_modification.json';
-import rule504 from './persistence_user_account_added_to_privileged_group_ad.json';
-import rule505 from './defense_evasion_attempt_to_disable_gatekeeper.json';
-import rule506 from './defense_evasion_sandboxed_office_app_suspicious_zip_file.json';
-import rule507 from './persistence_emond_rules_file_creation.json';
-import rule508 from './persistence_emond_rules_process_execution.json';
-import rule509 from './discovery_users_domain_built_in_commands.json';
-import rule510 from './execution_pentest_eggshell_remote_admin_tool.json';
-import rule511 from './defense_evasion_install_root_certificate.json';
-import rule512 from './persistence_credential_access_authorization_plugin_creation.json';
-import rule513 from './persistence_directory_services_plugins_modification.json';
-import rule514 from './defense_evasion_modify_environment_launchctl.json';
-import rule515 from './defense_evasion_safari_config_change.json';
-import rule516 from './defense_evasion_apple_softupdates_modification.json';
-import rule517 from './persistence_cron_jobs_creation_and_runtime.json';
-import rule518 from './credential_access_mod_wdigest_security_provider.json';
-import rule519 from './credential_access_saved_creds_vaultcmd.json';
-import rule520 from './defense_evasion_file_creation_mult_extension.json';
-import rule521 from './execution_enumeration_via_wmiprvse.json';
-import rule522 from './execution_suspicious_jar_child_process.json';
-import rule523 from './persistence_shell_profile_modification.json';
-import rule524 from './persistence_suspicious_calendar_modification.json';
-import rule525 from './persistence_time_provider_mod.json';
-import rule526 from './privilege_escalation_exploit_adobe_acrobat_updater.json';
-import rule527 from './defense_evasion_sip_provider_mod.json';
-import rule528 from './execution_com_object_xwizard.json';
-import rule529 from './privilege_escalation_disable_uac_registry.json';
-import rule530 from './defense_evasion_unusual_ads_file_creation.json';
-import rule531 from './persistence_loginwindow_plist_modification.json';
-import rule532 from './persistence_periodic_tasks_file_mdofiy.json';
-import rule533 from './persistence_via_atom_init_file_modification.json';
-import rule534 from './privilege_escalation_lsa_auth_package.json';
-import rule535 from './privilege_escalation_port_monitor_print_pocessor_abuse.json';
-import rule536 from './credential_access_dumping_hashes_bi_cmds.json';
-import rule537 from './lateral_movement_mounting_smb_share.json';
-import rule538 from './privilege_escalation_echo_nopasswd_sudoers.json';
-import rule539 from './privilege_escalation_ld_preload_shared_object_modif.json';
-import rule540 from './privilege_escalation_root_crontab_filemod.json';
-import rule541 from './defense_evasion_create_mod_root_certificate.json';
-import rule542 from './privilege_escalation_sudo_buffer_overflow.json';
-import rule543 from './execution_installer_spawned_network_event.json';
-import rule544 from './initial_access_suspicious_ms_exchange_files.json';
-import rule545 from './initial_access_suspicious_ms_exchange_process.json';
-import rule546 from './initial_access_suspicious_ms_exchange_worker_child_process.json';
+import rule23 from './command_and_control_nat_traversal_port_activity.json';
+import rule24 from './command_and_control_port_26_activity.json';
+import rule25 from './command_and_control_rdp_remote_desktop_protocol_from_the_internet.json';
+import rule26 from './command_and_control_telnet_port_activity.json';
+import rule27 from './command_and_control_vnc_virtual_network_computing_from_the_internet.json';
+import rule28 from './command_and_control_vnc_virtual_network_computing_to_the_internet.json';
+import rule29 from './defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json';
+import rule30 from './defense_evasion_clearing_windows_event_logs.json';
+import rule31 from './defense_evasion_delete_volume_usn_journal_with_fsutil.json';
+import rule32 from './defense_evasion_deleting_backup_catalogs_with_wbadmin.json';
+import rule33 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json';
+import rule34 from './defense_evasion_encoding_or_decoding_files_via_certutil.json';
+import rule35 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json';
+import rule36 from './defense_evasion_msbuild_making_network_connections.json';
+import rule37 from './defense_evasion_unusual_network_connection_via_rundll32.json';
+import rule38 from './defense_evasion_unusual_process_network_connection.json';
+import rule39 from './defense_evasion_via_filter_manager.json';
+import rule40 from './defense_evasion_volume_shadow_copy_deletion_via_wmic.json';
+import rule41 from './discovery_whoami_command_activity.json';
+import rule42 from './endgame_adversary_behavior_detected.json';
+import rule43 from './endgame_cred_dumping_detected.json';
+import rule44 from './endgame_cred_dumping_prevented.json';
+import rule45 from './endgame_cred_manipulation_detected.json';
+import rule46 from './endgame_cred_manipulation_prevented.json';
+import rule47 from './endgame_exploit_detected.json';
+import rule48 from './endgame_exploit_prevented.json';
+import rule49 from './endgame_malware_detected.json';
+import rule50 from './endgame_malware_prevented.json';
+import rule51 from './endgame_permission_theft_detected.json';
+import rule52 from './endgame_permission_theft_prevented.json';
+import rule53 from './endgame_process_injection_detected.json';
+import rule54 from './endgame_process_injection_prevented.json';
+import rule55 from './endgame_ransomware_detected.json';
+import rule56 from './endgame_ransomware_prevented.json';
+import rule57 from './execution_command_prompt_connecting_to_the_internet.json';
+import rule58 from './execution_command_shell_started_by_svchost.json';
+import rule59 from './execution_html_help_executable_program_connecting_to_the_internet.json';
+import rule60 from './execution_psexec_lateral_movement_command.json';
+import rule61 from './execution_register_server_program_connecting_to_the_internet.json';
+import rule62 from './execution_via_compiled_html_file.json';
+import rule63 from './impact_volume_shadow_copy_deletion_via_vssadmin.json';
+import rule64 from './initial_access_rpc_remote_procedure_call_from_the_internet.json';
+import rule65 from './initial_access_rpc_remote_procedure_call_to_the_internet.json';
+import rule66 from './initial_access_script_executing_powershell.json';
+import rule67 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json';
+import rule68 from './initial_access_suspicious_ms_office_child_process.json';
+import rule69 from './initial_access_suspicious_ms_outlook_child_process.json';
+import rule70 from './lateral_movement_direct_outbound_smb_connection.json';
+import rule71 from './lateral_movement_service_control_spawned_script_int.json';
+import rule72 from './linux_hping_activity.json';
+import rule73 from './linux_iodine_activity.json';
+import rule74 from './linux_netcat_network_connection.json';
+import rule75 from './linux_nping_activity.json';
+import rule76 from './linux_process_started_in_temp_directory.json';
+import rule77 from './linux_strace_activity.json';
+import rule78 from './persistence_adobe_hijack_persistence.json';
+import rule79 from './persistence_local_scheduled_task_creation.json';
+import rule80 from './persistence_priv_escalation_via_accessibility_features.json';
+import rule81 from './persistence_shell_activity_by_web_server.json';
+import rule82 from './persistence_system_shells_via_services.json';
+import rule83 from './persistence_user_account_creation.json';
+import rule84 from './persistence_via_application_shimming.json';
+import rule85 from './privilege_escalation_unusual_parentchild_relationship.json';
+import rule86 from './defense_evasion_modification_of_boot_config.json';
+import rule87 from './privilege_escalation_uac_bypass_event_viewer.json';
+import rule88 from './defense_evasion_msxsl_network.json';
+import rule89 from './discovery_net_command_system_account.json';
+import rule90 from './command_and_control_certutil_network_connection.json';
+import rule91 from './defense_evasion_cve_2020_0601.json';
+import rule92 from './credential_access_credential_dumping_msbuild.json';
+import rule93 from './defense_evasion_execution_msbuild_started_by_office_app.json';
+import rule94 from './defense_evasion_execution_msbuild_started_by_script.json';
+import rule95 from './defense_evasion_execution_msbuild_started_by_system_process.json';
+import rule96 from './defense_evasion_execution_msbuild_started_renamed.json';
+import rule97 from './defense_evasion_execution_msbuild_started_unusal_process.json';
+import rule98 from './defense_evasion_injection_msbuild.json';
+import rule99 from './ml_linux_anomalous_network_activity.json';
+import rule100 from './ml_linux_anomalous_network_port_activity.json';
+import rule101 from './ml_linux_anomalous_network_service.json';
+import rule102 from './ml_linux_anomalous_network_url_activity.json';
+import rule103 from './ml_linux_anomalous_process_all_hosts.json';
+import rule104 from './ml_linux_anomalous_user_name.json';
+import rule105 from './ml_packetbeat_dns_tunneling.json';
+import rule106 from './ml_packetbeat_rare_dns_question.json';
+import rule107 from './ml_packetbeat_rare_server_domain.json';
+import rule108 from './ml_packetbeat_rare_urls.json';
+import rule109 from './ml_packetbeat_rare_user_agent.json';
+import rule110 from './ml_rare_process_by_host_linux.json';
+import rule111 from './ml_rare_process_by_host_windows.json';
+import rule112 from './ml_suspicious_login_activity.json';
+import rule113 from './ml_windows_anomalous_network_activity.json';
+import rule114 from './ml_windows_anomalous_path_activity.json';
+import rule115 from './ml_windows_anomalous_process_all_hosts.json';
+import rule116 from './ml_windows_anomalous_process_creation.json';
+import rule117 from './ml_windows_anomalous_script.json';
+import rule118 from './ml_windows_anomalous_service.json';
+import rule119 from './ml_windows_anomalous_user_name.json';
+import rule120 from './ml_windows_rare_user_runas_event.json';
+import rule121 from './ml_windows_rare_user_type10_remote_login.json';
+import rule122 from './execution_suspicious_pdf_reader.json';
+import rule123 from './privilege_escalation_sudoers_file_mod.json';
+import rule124 from './defense_evasion_iis_httplogging_disabled.json';
+import rule125 from './execution_python_tty_shell.json';
+import rule126 from './execution_perl_tty_shell.json';
+import rule127 from './defense_evasion_base16_or_base32_encoding_or_decoding_activity.json';
+import rule128 from './defense_evasion_file_mod_writable_dir.json';
+import rule129 from './defense_evasion_disable_selinux_attempt.json';
+import rule130 from './discovery_kernel_module_enumeration.json';
+import rule131 from './lateral_movement_telnet_network_activity_external.json';
+import rule132 from './lateral_movement_telnet_network_activity_internal.json';
+import rule133 from './privilege_escalation_setuid_setgid_bit_set_via_chmod.json';
+import rule134 from './defense_evasion_attempt_to_disable_iptables_or_firewall.json';
+import rule135 from './defense_evasion_kernel_module_removal.json';
+import rule136 from './defense_evasion_attempt_to_disable_syslog_service.json';
+import rule137 from './defense_evasion_file_deletion_via_shred.json';
+import rule138 from './discovery_virtual_machine_fingerprinting.json';
+import rule139 from './defense_evasion_hidden_file_dir_tmp.json';
+import rule140 from './defense_evasion_deletion_of_bash_command_line_history.json';
+import rule141 from './impact_cloudwatch_log_group_deletion.json';
+import rule142 from './impact_cloudwatch_log_stream_deletion.json';
+import rule143 from './impact_rds_instance_cluster_stoppage.json';
+import rule144 from './persistence_attempt_to_deactivate_mfa_for_okta_user_account.json';
+import rule145 from './persistence_rds_cluster_creation.json';
+import rule146 from './credential_access_attempted_bypass_of_okta_mfa.json';
+import rule147 from './defense_evasion_waf_acl_deletion.json';
+import rule148 from './impact_attempt_to_revoke_okta_api_token.json';
+import rule149 from './impact_iam_group_deletion.json';
+import rule150 from './impact_possible_okta_dos_attack.json';
+import rule151 from './impact_rds_cluster_deletion.json';
+import rule152 from './initial_access_suspicious_activity_reported_by_okta_user.json';
+import rule153 from './okta_attempt_to_deactivate_okta_policy.json';
+import rule154 from './okta_attempt_to_deactivate_okta_policy_rule.json';
+import rule155 from './okta_attempt_to_modify_okta_network_zone.json';
+import rule156 from './okta_attempt_to_modify_okta_policy.json';
+import rule157 from './okta_attempt_to_modify_okta_policy_rule.json';
+import rule158 from './okta_threat_detected_by_okta_threatinsight.json';
+import rule159 from './persistence_administrator_privileges_assigned_to_okta_group.json';
+import rule160 from './persistence_attempt_to_create_okta_api_token.json';
+import rule161 from './persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json';
+import rule162 from './defense_evasion_cloudtrail_logging_deleted.json';
+import rule163 from './defense_evasion_ec2_network_acl_deletion.json';
+import rule164 from './impact_iam_deactivate_mfa_device.json';
+import rule165 from './defense_evasion_s3_bucket_configuration_deletion.json';
+import rule166 from './defense_evasion_guardduty_detector_deletion.json';
+import rule167 from './okta_attempt_to_delete_okta_policy.json';
+import rule168 from './credential_access_iam_user_addition_to_group.json';
+import rule169 from './persistence_ec2_network_acl_creation.json';
+import rule170 from './impact_ec2_disable_ebs_encryption.json';
+import rule171 from './persistence_iam_group_creation.json';
+import rule172 from './defense_evasion_waf_rule_or_rule_group_deletion.json';
+import rule173 from './collection_cloudtrail_logging_created.json';
+import rule174 from './defense_evasion_cloudtrail_logging_suspended.json';
+import rule175 from './impact_cloudtrail_logging_updated.json';
+import rule176 from './initial_access_console_login_root.json';
+import rule177 from './defense_evasion_cloudwatch_alarm_deletion.json';
+import rule178 from './defense_evasion_ec2_flow_log_deletion.json';
+import rule179 from './defense_evasion_configuration_recorder_stopped.json';
+import rule180 from './exfiltration_ec2_snapshot_change_activity.json';
+import rule181 from './defense_evasion_config_service_rule_deletion.json';
+import rule182 from './okta_attempt_to_modify_or_delete_application_sign_on_policy.json';
+import rule183 from './command_and_control_download_rar_powershell_from_internet.json';
+import rule184 from './initial_access_password_recovery.json';
+import rule185 from './command_and_control_cobalt_strike_beacon.json';
+import rule186 from './command_and_control_fin7_c2_behavior.json';
+import rule187 from './command_and_control_halfbaked_beacon.json';
+import rule188 from './credential_access_secretsmanager_getsecretvalue.json';
+import rule189 from './initial_access_via_system_manager.json';
+import rule190 from './privilege_escalation_root_login_without_mfa.json';
+import rule191 from './privilege_escalation_updateassumerolepolicy.json';
+import rule192 from './impact_hosts_file_modified.json';
+import rule193 from './elastic_endpoint_security.json';
+import rule194 from './external_alerts.json';
+import rule195 from './initial_access_login_failures.json';
+import rule196 from './initial_access_login_location.json';
+import rule197 from './initial_access_login_sessions.json';
+import rule198 from './initial_access_login_time.json';
+import rule199 from './ml_cloudtrail_error_message_spike.json';
+import rule200 from './ml_cloudtrail_rare_error_code.json';
+import rule201 from './ml_cloudtrail_rare_method_by_city.json';
+import rule202 from './ml_cloudtrail_rare_method_by_country.json';
+import rule203 from './ml_cloudtrail_rare_method_by_user.json';
+import rule204 from './credential_access_aws_iam_assume_role_brute_force.json';
+import rule205 from './credential_access_okta_brute_force_or_password_spraying.json';
+import rule206 from './initial_access_unusual_dns_service_children.json';
+import rule207 from './initial_access_unusual_dns_service_file_writes.json';
+import rule208 from './lateral_movement_dns_server_overflow.json';
+import rule209 from './credential_access_root_console_failure_brute_force.json';
+import rule210 from './initial_access_unsecure_elasticsearch_node.json';
+import rule211 from './credential_access_domain_backup_dpapi_private_keys.json';
+import rule212 from './persistence_gpo_schtask_service_creation.json';
+import rule213 from './credential_access_credentials_keychains.json';
+import rule214 from './credential_access_kerberosdump_kcc.json';
+import rule215 from './defense_evasion_attempt_del_quarantine_attrib.json';
+import rule216 from './execution_suspicious_psexesvc.json';
+import rule217 from './execution_via_xp_cmdshell_mssql_stored_procedure.json';
+import rule218 from './privilege_escalation_printspooler_service_suspicious_file.json';
+import rule219 from './privilege_escalation_printspooler_suspicious_spl_file.json';
+import rule220 from './defense_evasion_azure_diagnostic_settings_deletion.json';
+import rule221 from './execution_command_virtual_machine.json';
+import rule222 from './execution_via_hidden_shell_conhost.json';
+import rule223 from './impact_resource_group_deletion.json';
+import rule224 from './persistence_via_telemetrycontroller_scheduledtask_hijack.json';
+import rule225 from './persistence_via_update_orchestrator_service_hijack.json';
+import rule226 from './collection_update_event_hub_auth_rule.json';
+import rule227 from './credential_access_iis_apppoolsa_pwd_appcmd.json';
+import rule228 from './credential_access_iis_connectionstrings_dumping.json';
+import rule229 from './defense_evasion_event_hub_deletion.json';
+import rule230 from './defense_evasion_firewall_policy_deletion.json';
+import rule231 from './defense_evasion_sdelete_like_filename_rename.json';
+import rule232 from './lateral_movement_remote_ssh_login_enabled.json';
+import rule233 from './persistence_azure_automation_account_created.json';
+import rule234 from './persistence_azure_automation_runbook_created_or_modified.json';
+import rule235 from './persistence_azure_automation_webhook_created.json';
+import rule236 from './privilege_escalation_uac_bypass_diskcleanup_hijack.json';
+import rule237 from './credential_access_attempts_to_brute_force_okta_user_account.json';
+import rule238 from './credential_access_storage_account_key_regenerated.json';
+import rule239 from './defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json';
+import rule240 from './defense_evasion_system_critical_proc_abnormal_file_activity.json';
+import rule241 from './defense_evasion_unusual_system_vp_child_program.json';
+import rule242 from './discovery_blob_container_access_mod.json';
+import rule243 from './persistence_mfa_disabled_for_azure_user.json';
+import rule244 from './persistence_user_added_as_owner_for_azure_application.json';
+import rule245 from './persistence_user_added_as_owner_for_azure_service_principal.json';
+import rule246 from './defense_evasion_dotnet_compiler_parent_process.json';
+import rule247 from './defense_evasion_suspicious_managedcode_host_process.json';
+import rule248 from './execution_command_shell_started_by_unusual_process.json';
+import rule249 from './defense_evasion_masquerading_as_elastic_endpoint_process.json';
+import rule250 from './defense_evasion_masquerading_suspicious_werfault_childproc.json';
+import rule251 from './defense_evasion_masquerading_werfault.json';
+import rule252 from './credential_access_key_vault_modified.json';
+import rule253 from './credential_access_mimikatz_memssp_default_logs.json';
+import rule254 from './defense_evasion_code_injection_conhost.json';
+import rule255 from './defense_evasion_network_watcher_deletion.json';
+import rule256 from './initial_access_external_guest_user_invite.json';
+import rule257 from './defense_evasion_masquerading_renamed_autoit.json';
+import rule258 from './impact_azure_automation_runbook_deleted.json';
+import rule259 from './initial_access_consent_grant_attack_via_azure_registered_application.json';
+import rule260 from './persistence_azure_conditional_access_policy_modified.json';
+import rule261 from './persistence_azure_privileged_identity_management_role_modified.json';
+import rule262 from './command_and_control_teamviewer_remote_file_copy.json';
+import rule263 from './defense_evasion_installutil_beacon.json';
+import rule264 from './defense_evasion_mshta_beacon.json';
+import rule265 from './defense_evasion_network_connection_from_windows_binary.json';
+import rule266 from './defense_evasion_rundll32_no_arguments.json';
+import rule267 from './defense_evasion_suspicious_scrobj_load.json';
+import rule268 from './defense_evasion_suspicious_wmi_script.json';
+import rule269 from './execution_ms_office_written_file.json';
+import rule270 from './execution_pdf_written_file.json';
+import rule271 from './lateral_movement_cmd_service.json';
+import rule272 from './persistence_app_compat_shim.json';
+import rule273 from './command_and_control_remote_file_copy_desktopimgdownldr.json';
+import rule274 from './command_and_control_remote_file_copy_mpcmdrun.json';
+import rule275 from './defense_evasion_execution_suspicious_explorer_winword.json';
+import rule276 from './defense_evasion_suspicious_zoom_child_process.json';
+import rule277 from './ml_linux_anomalous_compiler_activity.json';
+import rule278 from './ml_linux_anomalous_kernel_module_arguments.json';
+import rule279 from './ml_linux_anomalous_sudo_activity.json';
+import rule280 from './ml_linux_system_information_discovery.json';
+import rule281 from './ml_linux_system_network_configuration_discovery.json';
+import rule282 from './ml_linux_system_network_connection_discovery.json';
+import rule283 from './ml_linux_system_process_discovery.json';
+import rule284 from './ml_linux_system_user_discovery.json';
+import rule285 from './discovery_post_exploitation_external_ip_lookup.json';
+import rule286 from './initial_access_zoom_meeting_with_no_passcode.json';
+import rule287 from './defense_evasion_gcp_logging_sink_deletion.json';
+import rule288 from './defense_evasion_gcp_pub_sub_topic_deletion.json';
+import rule289 from './defense_evasion_gcp_firewall_rule_created.json';
+import rule290 from './defense_evasion_gcp_firewall_rule_deleted.json';
+import rule291 from './defense_evasion_gcp_firewall_rule_modified.json';
+import rule292 from './defense_evasion_gcp_logging_bucket_deletion.json';
+import rule293 from './defense_evasion_gcp_storage_bucket_permissions_modified.json';
+import rule294 from './impact_gcp_storage_bucket_deleted.json';
+import rule295 from './initial_access_gcp_iam_custom_role_creation.json';
+import rule296 from './persistence_gcp_iam_service_account_key_deletion.json';
+import rule297 from './persistence_gcp_key_created_for_service_account.json';
+import rule298 from './defense_evasion_gcp_storage_bucket_configuration_modified.json';
+import rule299 from './exfiltration_gcp_logging_sink_modification.json';
+import rule300 from './impact_gcp_iam_role_deletion.json';
+import rule301 from './impact_gcp_service_account_deleted.json';
+import rule302 from './impact_gcp_service_account_disabled.json';
+import rule303 from './impact_gcp_virtual_private_cloud_network_deleted.json';
+import rule304 from './impact_gcp_virtual_private_cloud_route_created.json';
+import rule305 from './impact_gcp_virtual_private_cloud_route_deleted.json';
+import rule306 from './ml_linux_anomalous_metadata_process.json';
+import rule307 from './ml_linux_anomalous_metadata_user.json';
+import rule308 from './ml_windows_anomalous_metadata_process.json';
+import rule309 from './ml_windows_anomalous_metadata_user.json';
+import rule310 from './persistence_gcp_service_account_created.json';
+import rule311 from './collection_gcp_pub_sub_subscription_creation.json';
+import rule312 from './collection_gcp_pub_sub_topic_creation.json';
+import rule313 from './defense_evasion_gcp_pub_sub_subscription_deletion.json';
+import rule314 from './persistence_azure_pim_user_added_global_admin.json';
+import rule315 from './command_and_control_cobalt_strike_default_teamserver_cert.json';
+import rule316 from './defense_evasion_enable_inbound_rdp_with_netsh.json';
+import rule317 from './defense_evasion_execution_lolbas_wuauclt.json';
+import rule318 from './privilege_escalation_unusual_svchost_childproc_childless.json';
+import rule319 from './lateral_movement_rdp_tunnel_plink.json';
+import rule320 from './privilege_escalation_uac_bypass_winfw_mmc_hijack.json';
+import rule321 from './persistence_ms_office_addins_file.json';
+import rule322 from './discovery_adfind_command_activity.json';
+import rule323 from './discovery_security_software_wmic.json';
+import rule324 from './execution_command_shell_via_rundll32.json';
+import rule325 from './execution_suspicious_cmd_wmi.json';
+import rule326 from './lateral_movement_via_startup_folder_rdp_smb.json';
+import rule327 from './privilege_escalation_uac_bypass_com_interface_icmluautil.json';
+import rule328 from './privilege_escalation_uac_bypass_mock_windir.json';
+import rule329 from './defense_evasion_potential_processherpaderping.json';
+import rule330 from './privilege_escalation_uac_bypass_dll_sideloading.json';
+import rule331 from './execution_shared_modules_local_sxs_dll.json';
+import rule332 from './privilege_escalation_uac_bypass_com_clipup.json';
+import rule333 from './initial_access_via_explorer_suspicious_child_parent_args.json';
+import rule334 from './execution_from_unusual_directory.json';
+import rule335 from './execution_from_unusual_path_cmdline.json';
+import rule336 from './credential_access_kerberoasting_unusual_process.json';
+import rule337 from './discovery_peripheral_device.json';
+import rule338 from './lateral_movement_mount_hidden_or_webdav_share_net.json';
+import rule339 from './defense_evasion_deleting_websvr_access_logs.json';
+import rule340 from './defense_evasion_log_files_deleted.json';
+import rule341 from './defense_evasion_timestomp_touch.json';
+import rule342 from './lateral_movement_dcom_hta.json';
+import rule343 from './lateral_movement_execution_via_file_shares_sequence.json';
+import rule344 from './privilege_escalation_uac_bypass_com_ieinstal.json';
+import rule345 from './command_and_control_common_webservices.json';
+import rule346 from './command_and_control_encrypted_channel_freesslcert.json';
+import rule347 from './defense_evasion_process_termination_followed_by_deletion.json';
+import rule348 from './lateral_movement_remote_file_copy_hidden_share.json';
+import rule349 from './attempt_to_deactivate_okta_network_zone.json';
+import rule350 from './attempt_to_delete_okta_network_zone.json';
+import rule351 from './lateral_movement_dcom_mmc20.json';
+import rule352 from './lateral_movement_dcom_shellwindow_shellbrowserwindow.json';
+import rule353 from './okta_attempt_to_deactivate_okta_application.json';
+import rule354 from './okta_attempt_to_delete_okta_application.json';
+import rule355 from './okta_attempt_to_delete_okta_policy_rule.json';
+import rule356 from './okta_attempt_to_modify_okta_application.json';
+import rule357 from './persistence_administrator_role_assigned_to_okta_user.json';
+import rule358 from './lateral_movement_executable_tool_transfer_smb.json';
+import rule359 from './command_and_control_dns_tunneling_nslookup.json';
+import rule360 from './lateral_movement_execution_from_tsclient_mup.json';
+import rule361 from './lateral_movement_rdp_sharprdp_target.json';
+import rule362 from './defense_evasion_clearing_windows_security_logs.json';
+import rule363 from './persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json';
+import rule364 from './execution_suspicious_short_program_name.json';
+import rule365 from './lateral_movement_incoming_wmi.json';
+import rule366 from './persistence_via_hidden_run_key_valuename.json';
+import rule367 from './credential_access_potential_ssh_bruteforce.json';
+import rule368 from './credential_access_promt_for_pwd_via_osascript.json';
+import rule369 from './lateral_movement_remote_services.json';
+import rule370 from './application_added_to_google_workspace_domain.json';
+import rule371 from './domain_added_to_google_workspace_trusted_domains.json';
+import rule372 from './execution_suspicious_image_load_wmi_ms_office.json';
+import rule373 from './execution_suspicious_powershell_imgload.json';
+import rule374 from './google_workspace_admin_role_deletion.json';
+import rule375 from './google_workspace_mfa_enforcement_disabled.json';
+import rule376 from './google_workspace_policy_modified.json';
+import rule377 from './mfa_disabled_for_google_workspace_organization.json';
+import rule378 from './persistence_evasion_registry_ifeo_injection.json';
+import rule379 from './persistence_google_workspace_admin_role_assigned_to_user.json';
+import rule380 from './persistence_google_workspace_custom_admin_role_created.json';
+import rule381 from './persistence_google_workspace_role_modified.json';
+import rule382 from './persistence_suspicious_image_load_scheduled_task_ms_office.json';
+import rule383 from './defense_evasion_masquerading_trusted_directory.json';
+import rule384 from './exfiltration_microsoft_365_exchange_transport_rule_creation.json';
+import rule385 from './initial_access_microsoft_365_exchange_safelinks_disabled.json';
+import rule386 from './microsoft_365_exchange_dkim_signing_config_disabled.json';
+import rule387 from './persistence_appcertdlls_registry.json';
+import rule388 from './persistence_appinitdlls_registry.json';
+import rule389 from './persistence_registry_uncommon.json';
+import rule390 from './persistence_run_key_and_startup_broad.json';
+import rule391 from './persistence_services_registry.json';
+import rule392 from './persistence_startup_folder_file_written_by_suspicious_process.json';
+import rule393 from './persistence_startup_folder_scripts.json';
+import rule394 from './persistence_suspicious_com_hijack_registry.json';
+import rule395 from './persistence_via_lsa_security_support_provider_registry.json';
+import rule396 from './defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json';
+import rule397 from './defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json';
+import rule398 from './defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json';
+import rule399 from './exfiltration_microsoft_365_exchange_transport_rule_mod.json';
+import rule400 from './initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json';
+import rule401 from './initial_access_microsoft_365_exchange_anti_phish_rule_mod.json';
+import rule402 from './lateral_movement_suspicious_rdp_client_imageload.json';
+import rule403 from './persistence_runtime_run_key_startup_susp_procs.json';
+import rule404 from './persistence_suspicious_scheduled_task_runtime.json';
+import rule405 from './defense_evasion_microsoft_365_exchange_dlp_policy_removed.json';
+import rule406 from './lateral_movement_scheduled_task_target.json';
+import rule407 from './persistence_microsoft_365_exchange_management_role_assignment.json';
+import rule408 from './persistence_microsoft_365_teams_guest_access_enabled.json';
+import rule409 from './credential_access_dump_registry_hives.json';
+import rule410 from './defense_evasion_scheduledjobs_at_protocol_enabled.json';
+import rule411 from './persistence_ms_outlook_vba_template.json';
+import rule412 from './persistence_suspicious_service_created_registry.json';
+import rule413 from './privilege_escalation_named_pipe_impersonation.json';
+import rule414 from './credential_access_cmdline_dump_tool.json';
+import rule415 from './credential_access_copy_ntds_sam_volshadowcp_cmdline.json';
+import rule416 from './credential_access_lsass_memdump_file_created.json';
+import rule417 from './lateral_movement_incoming_winrm_shell_execution.json';
+import rule418 from './lateral_movement_powershell_remoting_target.json';
+import rule419 from './defense_evasion_hide_encoded_executable_registry.json';
+import rule420 from './defense_evasion_port_forwarding_added_registry.json';
+import rule421 from './lateral_movement_rdp_enabled_registry.json';
+import rule422 from './privilege_escalation_printspooler_registry_copyfiles.json';
+import rule423 from './privilege_escalation_rogue_windir_environment_var.json';
+import rule424 from './initial_access_scripts_process_started_via_wmi.json';
+import rule425 from './command_and_control_iexplore_via_com.json';
+import rule426 from './command_and_control_remote_file_copy_scripts.json';
+import rule427 from './persistence_local_scheduled_task_scripting.json';
+import rule428 from './persistence_startup_folder_file_written_by_unsigned_process.json';
+import rule429 from './command_and_control_remote_file_copy_powershell.json';
+import rule430 from './credential_access_microsoft_365_brute_force_user_account_attempt.json';
+import rule431 from './microsoft_365_teams_custom_app_interaction_allowed.json';
+import rule432 from './persistence_microsoft_365_teams_external_access_enabled.json';
+import rule433 from './credential_access_microsoft_365_potential_password_spraying_attack.json';
+import rule434 from './defense_evasion_stop_process_service_threshold.json';
+import rule435 from './collection_winrar_encryption.json';
+import rule436 from './defense_evasion_unusual_dir_ads.json';
+import rule437 from './discovery_admin_recon.json';
+import rule438 from './discovery_file_dir_discovery.json';
+import rule439 from './discovery_net_view.json';
+import rule440 from './discovery_remote_system_discovery_commands_windows.json';
+import rule441 from './persistence_via_windows_management_instrumentation_event_subscription.json';
+import rule442 from './execution_scripting_osascript_exec_followed_by_netcon.json';
+import rule443 from './execution_shell_execution_via_apple_scripting.json';
+import rule444 from './persistence_creation_change_launch_agents_file.json';
+import rule445 from './persistence_creation_modif_launch_deamon_sequence.json';
+import rule446 from './persistence_folder_action_scripts_runtime.json';
+import rule447 from './persistence_login_logout_hooks_defaults.json';
+import rule448 from './privilege_escalation_explicit_creds_via_scripting.json';
+import rule449 from './command_and_control_sunburst_c2_activity_detected.json';
+import rule450 from './defense_evasion_azure_application_credential_modification.json';
+import rule451 from './defense_evasion_azure_service_principal_addition.json';
+import rule452 from './defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json';
+import rule453 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.json';
+import rule454 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json';
+import rule455 from './initial_access_azure_active_directory_powershell_signin.json';
+import rule456 from './collection_email_powershell_exchange_mailbox.json';
+import rule457 from './collection_persistence_powershell_exch_mailbox_activesync_add_device.json';
+import rule458 from './execution_scheduled_task_powershell_source.json';
+import rule459 from './persistence_docker_shortcuts_plist_modification.json';
+import rule460 from './persistence_evasion_hidden_local_account_creation.json';
+import rule461 from './persistence_finder_sync_plugin_pluginkit.json';
+import rule462 from './discovery_security_software_grep.json';
+import rule463 from './credential_access_cookies_chromium_browsers_debugging.json';
+import rule464 from './credential_access_ssh_backdoor_log.json';
+import rule465 from './persistence_credential_access_modify_auth_module_or_config.json';
+import rule466 from './persistence_credential_access_modify_ssh_binaries.json';
+import rule467 from './credential_access_collection_sensitive_files.json';
+import rule468 from './persistence_ssh_authorized_keys_modification.json';
+import rule469 from './defense_evasion_defender_disabled_via_registry.json';
+import rule470 from './defense_evasion_privacy_controls_tcc_database_modification.json';
+import rule471 from './execution_initial_access_suspicious_browser_childproc.json';
+import rule472 from './execution_script_via_automator_workflows.json';
+import rule473 from './persistence_modification_sublime_app_plugin_or_script.json';
+import rule474 from './privilege_escalation_applescript_with_admin_privs.json';
+import rule475 from './credential_access_dumping_keychain_security.json';
+import rule476 from './initial_access_azure_active_directory_high_risk_signin.json';
+import rule477 from './initial_access_suspicious_mac_ms_office_child_process.json';
+import rule478 from './credential_access_mitm_localhost_webproxy.json';
+import rule479 from './persistence_kde_autostart_modification.json';
+import rule480 from './persistence_user_account_added_to_privileged_group_ad.json';
+import rule481 from './defense_evasion_attempt_to_disable_gatekeeper.json';
+import rule482 from './defense_evasion_sandboxed_office_app_suspicious_zip_file.json';
+import rule483 from './persistence_emond_rules_file_creation.json';
+import rule484 from './persistence_emond_rules_process_execution.json';
+import rule485 from './discovery_users_domain_built_in_commands.json';
+import rule486 from './execution_pentest_eggshell_remote_admin_tool.json';
+import rule487 from './defense_evasion_install_root_certificate.json';
+import rule488 from './persistence_credential_access_authorization_plugin_creation.json';
+import rule489 from './persistence_directory_services_plugins_modification.json';
+import rule490 from './defense_evasion_modify_environment_launchctl.json';
+import rule491 from './defense_evasion_safari_config_change.json';
+import rule492 from './defense_evasion_apple_softupdates_modification.json';
+import rule493 from './credential_access_mod_wdigest_security_provider.json';
+import rule494 from './credential_access_saved_creds_vaultcmd.json';
+import rule495 from './defense_evasion_file_creation_mult_extension.json';
+import rule496 from './execution_enumeration_via_wmiprvse.json';
+import rule497 from './execution_suspicious_jar_child_process.json';
+import rule498 from './persistence_shell_profile_modification.json';
+import rule499 from './persistence_suspicious_calendar_modification.json';
+import rule500 from './persistence_time_provider_mod.json';
+import rule501 from './privilege_escalation_exploit_adobe_acrobat_updater.json';
+import rule502 from './defense_evasion_sip_provider_mod.json';
+import rule503 from './execution_com_object_xwizard.json';
+import rule504 from './privilege_escalation_disable_uac_registry.json';
+import rule505 from './defense_evasion_unusual_ads_file_creation.json';
+import rule506 from './persistence_loginwindow_plist_modification.json';
+import rule507 from './persistence_periodic_tasks_file_mdofiy.json';
+import rule508 from './persistence_via_atom_init_file_modification.json';
+import rule509 from './privilege_escalation_lsa_auth_package.json';
+import rule510 from './privilege_escalation_port_monitor_print_pocessor_abuse.json';
+import rule511 from './credential_access_dumping_hashes_bi_cmds.json';
+import rule512 from './lateral_movement_mounting_smb_share.json';
+import rule513 from './privilege_escalation_echo_nopasswd_sudoers.json';
+import rule514 from './privilege_escalation_ld_preload_shared_object_modif.json';
+import rule515 from './privilege_escalation_root_crontab_filemod.json';
+import rule516 from './defense_evasion_create_mod_root_certificate.json';
+import rule517 from './privilege_escalation_sudo_buffer_overflow.json';
+import rule518 from './execution_installer_spawned_network_event.json';
+import rule519 from './initial_access_suspicious_ms_exchange_files.json';
+import rule520 from './initial_access_suspicious_ms_exchange_process.json';
+import rule521 from './initial_access_suspicious_ms_exchange_worker_child_process.json';
+import rule522 from './persistence_evasion_registry_startup_shell_folder_modified.json';
+import rule523 from './persistence_local_scheduled_job_creation.json';
+import rule524 from './persistence_via_wmi_stdregprov_run_services.json';
+import rule525 from './credential_access_persistence_network_logon_provider_modification.json';
+import rule526 from './lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json';
+import rule527 from './collection_microsoft_365_new_inbox_rule.json';
+import rule528 from './ml_high_count_network_denies.json';
+import rule529 from './ml_high_count_network_events.json';
+import rule530 from './ml_rare_destination_country.json';
+import rule531 from './ml_spike_in_traffic_to_a_country.json';
+import rule532 from './command_and_control_tunneling_via_earthworm.json';
+import rule533 from './lateral_movement_evasion_rdp_shadowing.json';
+import rule534 from './threat_intel_module_match.json';
+import rule535 from './persistence_via_bits_job_notify_command.json';
export const rawRules = [
rule1,
@@ -1093,15 +1082,4 @@ export const rawRules = [
rule533,
rule534,
rule535,
- rule536,
- rule537,
- rule538,
- rule539,
- rule540,
- rule541,
- rule542,
- rule543,
- rule544,
- rule545,
- rule546,
];
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json
index 48796255ac6bb..c0884cf809e77 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS Management Console Root Login",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:ConsoleLogin and event.dataset:aws.cloudtrail and event.provider:signin.amazonaws.com and aws.cloudtrail.user_identity.type:Root and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:signin.amazonaws.com and event.action:ConsoleLogin and aws.cloudtrail.user_identity.type:Root and event.outcome:success",
"references": [
"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html"
],
@@ -65,5 +65,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json
index 667d2eff5fb05..902abb51a6f99 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS IAM Password Recovery Requested",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:PasswordRecoveryRequested and event.provider:signin.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:signin.amazonaws.com and event.action:PasswordRecoveryRequested and event.outcome:success",
"references": [
"https://www.cadosecurity.com/2020/06/11/an-ongoing-aws-phishing-campaign/"
],
@@ -50,5 +50,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rdp_remote_desktop_protocol_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rdp_remote_desktop_protocol_to_the_internet.json
deleted file mode 100644
index d58db96e4b1ba..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rdp_remote_desktop_protocol_to_the_internet.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "This rule detects network events that may indicate the use of RDP traffic to the Internet. RDP is commonly used by system administrators to remotely control a system for maintenance or to use shared resources. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or back-door vector.",
- "false_positives": [
- "RDP connections may be made directly to Internet destinations in order to access Windows cloud server instances but such connections are usually made only by engineers. In such cases, only RDP gateways, bastions or jump servers may be expected Internet destinations and can be exempted from this rule. RDP may be required by some work-flows such as remote access and support for specialized software products and servers. Such work-flows are usually known and not unexpected. Usage that is unfamiliar to server or network owners can be unexpected and suspicious."
- ],
- "from": "now-9m",
- "index": [
- "filebeat-*",
- "packetbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "RDP (Remote Desktop Protocol) to the Internet",
- "query": "event.category:(network or network_traffic) and network.transport:tcp and (destination.port:3389 or event.dataset:zeek.rdp) and source.ip:( 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 ) and not destination.ip:( 10.0.0.0/8 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.168.0.0/16 or 224.0.0.0/4 or \"::1\" or \"FE80::/10\" or \"FF00::/8\" )",
- "risk_score": 21,
- "rule_id": "e56993d2-759c-4120-984c-9ec9bb940fd5",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Network",
- "Threat Detection",
- "Initial Access"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0001",
- "name": "Initial Access",
- "reference": "https://attack.mitre.org/tactics/TA0001/"
- },
- "technique": [
- {
- "id": "T1190",
- "name": "Exploit Public-Facing Application",
- "reference": "https://attack.mitre.org/techniques/T1190/"
- }
- ]
- },
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0010",
- "name": "Exfiltration",
- "reference": "https://attack.mitre.org/tactics/TA0010/"
- },
- "technique": [
- {
- "id": "T1048",
- "name": "Exfiltration Over Alternative Protocol",
- "reference": "https://attack.mitre.org/techniques/T1048/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json
index 561ac14994efb..4950066d307ff 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Windows Script Executing PowerShell",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:(cscript.exe or wscript.exe) and process.name:powershell.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : (\"cscript.exe\", \"wscript.exe\") and process.name : \"powershell.exe\"\n",
"risk_score": 21,
"rule_id": "f545ff26-3c94-4fd0-bd33-3c7f95a3a0fc",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json
index 8796a6b4f291f..73b0718e0f27d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json
@@ -10,7 +10,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Suspicious macOS MS Office Child Process",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name:(\"Microsoft Word\", \"Microsoft PowerPoint\", \"Microsoft Excel\") and\n process.name:\n (\n \"bash\", \n \"dash\", \n \"sh\", \n \"tcsh\", \n \"csh\", \n \"zsh\", \n \"ksh\", \n \"fish\", \n \"python*\", \n \"perl*\", \n \"php*\", \n \"osascript\",\n \"pwsh\", \n \"curl\", \n \"wget\", \n \"cp\", \n \"mv\", \n \"base64\", \n \"launchctl\"\n )\n",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name:(\"Microsoft Word\", \"Microsoft PowerPoint\", \"Microsoft Excel\") and\n process.name:\n (\n \"bash\", \n \"dash\", \n \"sh\", \n \"tcsh\", \n \"csh\", \n \"zsh\", \n \"ksh\", \n \"fish\", \n \"python*\", \n \"perl*\", \n \"php*\", \n \"osascript\",\n \"pwsh\", \n \"curl\", \n \"wget\", \n \"cp\", \n \"mv\", \n \"base64\", \n \"launchctl\"\n ) and\n /* noisy false positives related to product version discovery and office errors reporting */\n not process.args:\n (\n \"ProductVersion\",\n \"hw.model\",\n \"ioreg\",\n \"ProductName\",\n \"ProductUserVisibleVersion\",\n \"ProductBuildVersion\",\n \"/Library/Application Support/Microsoft/MERP*/Microsoft Error Reporting.app/Contents/MacOS/Microsoft Error Reporting\"\n )\n",
"references": [
"https://blog.malwarebytes.com/cybercrime/2017/02/microsoft-office-macro-malware-targets-macs/"
],
@@ -50,5 +50,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json
index a999e05a66d5b..bd3e6129fa3ab 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json
@@ -5,7 +5,8 @@
],
"description": "Identifies suspicious files being written by the Microsoft Exchange Server Unified Messaging (UM) service. This activity has been observed exploiting CVE-2021-26858.",
"false_positives": [
- "Files generated during installation will generate a lot of noise, so the rule should only be enabled after the fact."
+ "Files generated during installation will generate a lot of noise, so the rule should only be enabled after the fact.",
+ "This rule was tuned using the following baseline: https://raw.githubusercontent.com/microsoft/CSS-Exchange/main/Security/Baselines/baseline_15.2.792.5.csv from Microsoft. Depending on version, consult https://github.com/microsoft/CSS-Exchange/tree/main/Security/Baselines to help determine normalcy."
],
"from": "now-9m",
"index": [
@@ -16,7 +17,8 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Microsoft Exchange Server UM Writing Suspicious Files",
- "query": "file where event.type == \"creation\" and\n process.parent.name : (\"UMWorkerProcess.exe\", \"umservice.exe\") and\n file.extension : (\"php\", \"jsp\", \"js\", \"aspx\", \"asmx\", \"asax\", \"cfm\", \"shtml\") and\n (\n file.path : (\"C:\\\\inetpub\\\\wwwroot\\\\aspnet_client\\\\*\",\n \"C:\\\\*\\\\FrontEnd\\\\HttpProxy\\\\owa\\\\auth\\\\*\") or\n (file.path : \"C:\\\\*\\\\FrontEnd\\\\HttpProxy\\\\ecp\\\\auth\\\\*\" and not file.name : \"TimeoutLogoff.aspx\")\n )\n",
+ "note": "## Triage and analysis\nPositive hits can be checked against the established Microsoft [baselines](https://github.com/microsoft/CSS-Exchange/tree/main/Security/Baselines).\n\nMicrosoft highly recommends that the best course of action is patching, but this may not protect already compromised systems\nfrom existing intrusions. Other tools for detecting and mitigating can be found within their Exchange support\n[repository](https://github.com/microsoft/CSS-Exchange/tree/main/Security)\n",
+ "query": "file where event.type == \"creation\" and\n process.name : (\"UMWorkerProcess.exe\", \"umservice.exe\") and\n file.extension : (\"php\", \"jsp\", \"js\", \"aspx\", \"asmx\", \"asax\", \"cfm\", \"shtml\") and\n (\n file.path : \"?:\\\\inetpub\\\\wwwroot\\\\aspnet_client\\\\*\" or\n\n (file.path : \"?:\\\\*\\\\Microsoft\\\\Exchange Server*\\\\FrontEnd\\\\HttpProxy\\\\owa\\\\auth\\\\*\" and\n not (file.path : \"?:\\\\*\\\\Microsoft\\\\Exchange Server*\\\\FrontEnd\\\\HttpProxy\\\\owa\\\\auth\\\\version\\\\*\" or\n file.name : (\"errorFE.aspx\", \"expiredpassword.aspx\", \"frowny.aspx\", \"GetIdToken.htm\", \"logoff.aspx\",\n \"logon.aspx\", \"OutlookCN.aspx\", \"RedirSuiteServiceProxy.aspx\", \"signout.aspx\"))) or\n\n (file.path : \"?:\\\\*\\\\Microsoft\\\\Exchange Server*\\\\FrontEnd\\\\HttpProxy\\\\ecp\\\\auth\\\\*\" and\n not file.name : \"TimeoutLogoff.aspx\")\n )\n",
"references": [
"https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers",
"https://www.volexity.com/blog/2021/03/02/active-exploitation-of-microsoft-exchange-zero-day-vulnerabilities"
@@ -50,5 +52,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json
index 1e5aa4e3950ab..baba3386b048e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious MS Outlook Child Process",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:outlook.exe and process.name:(Microsoft.Workflow.Compiler.exe or arp.exe or atbroker.exe or bginfo.exe or bitsadmin.exe or cdb.exe or certutil.exe or cmd.exe or cmstp.exe or cscript.exe or csi.exe or dnx.exe or dsget.exe or dsquery.exe or forfiles.exe or fsi.exe or ftp.exe or gpresult.exe or hostname.exe or ieexec.exe or iexpress.exe or installutil.exe or ipconfig.exe or mshta.exe or msxsl.exe or nbtstat.exe or net.exe or net1.exe or netsh.exe or netstat.exe or nltest.exe or odbcconf.exe or ping.exe or powershell.exe or pwsh.exe or qprocess.exe or quser.exe or qwinsta.exe or rcsi.exe or reg.exe or regasm.exe or regsvcs.exe or regsvr32.exe or sc.exe or schtasks.exe or systeminfo.exe or tasklist.exe or tracert.exe or whoami.exe or wmic.exe or wscript.exe or xwizard.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"outlook.exe\" and\n process.name : (\"Microsoft.Workflow.Compiler.exe\", \"arp.exe\", \"atbroker.exe\", \"bginfo.exe\", \"bitsadmin.exe\",\n \"cdb.exe\", \"certutil.exe\", \"cmd.exe\", \"cmstp.exe\", \"cscript.exe\", \"csi.exe\", \"dnx.exe\", \"dsget.exe\",\n \"dsquery.exe\", \"forfiles.exe\", \"fsi.exe\", \"ftp.exe\", \"gpresult.exe\", \"hostname.exe\", \"ieexec.exe\",\n \"iexpress.exe\", \"installutil.exe\", \"ipconfig.exe\", \"mshta.exe\", \"msxsl.exe\", \"nbtstat.exe\", \"net.exe\",\n \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"odbcconf.exe\", \"ping.exe\", \"powershell.exe\",\n \"pwsh.exe\", \"qprocess.exe\", \"quser.exe\", \"qwinsta.exe\", \"rcsi.exe\", \"reg.exe\", \"regasm.exe\",\n \"regsvcs.exe\", \"regsvr32.exe\", \"sc.exe\", \"schtasks.exe\", \"systeminfo.exe\", \"tasklist.exe\",\n \"tracert.exe\", \"whoami.exe\", \"wmic.exe\", \"wscript.exe\", \"xwizard.exe\")\n",
"risk_score": 21,
"rule_id": "32f4675e-6c49-4ace-80f9-97c9259dca2e",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json
index bfc9002ee4f54..736090dd66003 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json
@@ -12,11 +12,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Unusual Child Process of dns.exe",
"note": "### Investigating Unusual Child Process\nDetection alerts from this rule indicate potential suspicious child processes spawned after exploitation from CVE-2020-1350 (SigRed) has occurred. Here are some possible avenues of investigation:\n- Any suspicious or abnormal child process spawned from dns.exe should be reviewed and investigated with care. It's impossible to predict what an adversary may deploy as the follow-on process after the exploit, but built-in discovery/enumeration utilities should be top of mind (whoami.exe, netstat.exe, systeminfo.exe, tasklist.exe).\n- Built-in Windows programs that contain capabilities used to download and execute additional payloads should also be considered. This is not an exhaustive list, but ideal candidates to start out would be: mshta.exe, powershell.exe, regsvr32.exe, rundll32.exe, wscript.exe, wmic.exe.\n- If the DoS exploit is successful and DNS Server service crashes, be mindful of potential child processes related to werfault.exe occurring.\n- Any subsequent activity following the child process spawned related to execution/network activity should be thoroughly reviewed from the endpoint.",
- "query": "event.category:process and event.type:start and process.parent.name:dns.exe and not process.name:conhost.exe",
+ "query": "process where event.type == \"start\" and process.parent.name : \"dns.exe\" and\n not process.name : \"conhost.exe\"\n",
"references": [
"https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/",
"https://msrc-blog.microsoft.com/2020/07/14/july-2020-security-update-cve-2020-1350-vulnerability-in-windows-domain-name-system-dns-server/",
@@ -50,6 +50,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json
index a1fdf6cc2749b..495f4885f2145 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json
@@ -9,11 +9,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Unusual File Modification by dns.exe",
"note": "### Investigating Unusual File Write\nDetection alerts from this rule indicate potential unusual/abnormal file writes from the DNS Server service process (`dns.exe`) after exploitation from CVE-2020-1350 (SigRed) has occurred. Here are some possible avenues of investigation:\n- Post-exploitation, adversaries may write additional files or payloads to the system as additional discovery/exploitation/persistence mechanisms.\n- Any suspicious or abnormal files written from `dns.exe` should be reviewed and investigated with care.",
- "query": "event.category:file and process.name:dns.exe and event.type:(creation or deletion or change) and not file.name:dns.log",
+ "query": "file where process.name : \"dns.exe\" and event.type in (\"creation\", \"deletion\", \"change\") and\n not file.name : \"dns.log\"\n",
"references": [
"https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/",
"https://msrc-blog.microsoft.com/2020/07/14/july-2020-security-update-cve-2020-1350-vulnerability-in-windows-domain-name-system-dns-server/"
@@ -46,6 +46,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json
index 3ee2c01444ba2..23e8d3b43faf5 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Suspicious Explorer Child Process",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : (\"cscript.exe\", \"wscript.exe\", \"powershell.exe\", \"rundll32.exe\", \"cmd.exe\", \"mshta.exe\", \"regsvr32.exe\") and\n /* Explorer started via DCOM */\n process.parent.name : \"explorer.exe\" and process.parent.args : \"-Embedding\"\n",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n (\n process.name : (\"cscript.exe\", \"wscript.exe\", \"powershell.exe\", \"rundll32.exe\", \"cmd.exe\", \"mshta.exe\", \"regsvr32.exe\") or\n process.pe.original_file_name in (\"cscript.exe\", \"wscript.exe\", \"PowerShell.EXE\", \"RUNDLL32.EXE\", \"Cmd.Exe\", \"MSHTA.EXE\", \"REGSVR32.EXE\")\n ) and\n /* Explorer started via DCOM */\n process.parent.name : \"explorer.exe\" and process.parent.args : \"-Embedding\" and\n not process.parent.args:\n (\n /* Noisy CLSID_SeparateSingleProcessExplorerHost Explorer COM Class IDs */\n \"/factory,{5BD95610-9434-43C2-886C-57852CC8A120}\",\n \"/factory,{ceff45ee-c862-41de-aee2-a022c81eda92}\"\n )\n",
"risk_score": 47,
"rule_id": "9a5b4e31-6cde-4295-9ff7-6be1b8567e1b",
"severity": "medium",
@@ -54,5 +54,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json
new file mode 100644
index 0000000000000..1ccabf42237ef
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json
@@ -0,0 +1,57 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies NullSessionPipe registry modifications that specify which pipes can be accessed anonymously. This could be indicative of adversary lateral movement preparation by making the added pipe available to everyone.",
+ "from": "now-9m",
+ "index": [
+ "logs-endpoint.events.*",
+ "winlogbeat-*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "NullSessionPipe Registry Modification",
+ "query": "registry where\nregistry.path : \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\services\\\\LanmanServer\\\\Parameters\\\\NullSessionPipes\" and\nregistry.data.strings != null\n",
+ "references": [
+ "https://www.welivesecurity.com/2019/05/29/turla-powershell-usage/",
+ "https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-access-restrict-anonymous-access-to-named-pipes-and-shares"
+ ],
+ "risk_score": 47,
+ "rule_id": "ddab1f5f-7089-44f5-9fda-de5b11322e77",
+ "severity": "medium",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Lateral Movement"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0008",
+ "name": "Lateral Movement",
+ "reference": "https://attack.mitre.org/tactics/TA0008/"
+ },
+ "technique": [
+ {
+ "id": "T1021",
+ "name": "Remote Services",
+ "reference": "https://attack.mitre.org/techniques/T1021/",
+ "subtechnique": [
+ {
+ "id": "T1021.002",
+ "name": "SMB/Windows Admin Shares",
+ "reference": "https://attack.mitre.org/techniques/T1021/002/"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json
new file mode 100644
index 0000000000000..8656bd4a0712e
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json
@@ -0,0 +1,50 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies the modification of the Remote Desktop Protocol (RDP) Shadow registry or the execution of processes indicative of an active RDP shadowing session. An adversary may abuse the RDP Shadowing feature to spy on or control other users active RDP sessions.",
+ "from": "now-9m",
+ "index": [
+ "logs-endpoint.events.*",
+ "winlogbeat-*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Potential Remote Desktop Shadowing Activity",
+ "query": "/* Identifies the modification of RDP Shadow registry or\n the execution of processes indicative of active shadow RDP session */\n\nany where \n (event.category == \"registry\" and\n registry.path : \"HKLM\\\\Software\\\\Policies\\\\Microsoft\\\\Windows NT\\\\Terminal Services\\\\Shadow\"\n ) or\n (event.category == \"process\" and \n (process.name : (\"RdpSaUacHelper.exe\", \"RdpSaProxy.exe\") and process.parent.name : \"svchost.exe\") or\n (process.pe.original_file_name : \"mstsc.exe\" and process.args : \"/shadow:*\")\n )\n",
+ "references": [
+ "https://bitsadm.in/blog/spying-on-users-using-rdp-shadowing",
+ "https://swarm.ptsecurity.com/remote-desktop-services-shadowing/"
+ ],
+ "risk_score": 73,
+ "rule_id": "c57f8579-e2a5-4804-847f-f2732edc5156",
+ "severity": "high",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Lateral Movement"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0008",
+ "name": "Lateral Movement",
+ "reference": "https://attack.mitre.org/tactics/TA0008/"
+ },
+ "technique": [
+ {
+ "id": "T1021",
+ "name": "Remote Services",
+ "reference": "https://attack.mitre.org/techniques/T1021/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json
deleted file mode 100644
index 5f92e2cb3dfc0..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_local_service_commands.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies use of sc.exe to create, modify, or start services on remote hosts. This could be indicative of adversary lateral movement but will be noisy if commonly done by admins.",
- "from": "now-9m",
- "index": [
- "winlogbeat-*",
- "logs-endpoint.events.*",
- "logs-windows.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Local Service Commands",
- "query": "event.category:process and event.type:(start or process_started) and process.name:sc.exe and process.args:(config or create or failure or start)",
- "risk_score": 21,
- "rule_id": "e8571d5f-bea1-46c2-9f56-998de2d3ed95",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Windows",
- "Threat Detection",
- "Lateral Movement"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0008",
- "name": "Lateral Movement",
- "reference": "https://attack.mitre.org/tactics/TA0008/"
- },
- "technique": [
- {
- "id": "T1021",
- "name": "Remote Services",
- "reference": "https://attack.mitre.org/techniques/T1021/"
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json
new file mode 100644
index 0000000000000..61234f392158f
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json
@@ -0,0 +1,46 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies Service Control (sc.exe) spawning from script interpreter processes to create, modify, or start services. This could be indicative of adversary lateral movement but will be noisy if commonly done by admins.",
+ "from": "now-9m",
+ "index": [
+ "winlogbeat-*",
+ "logs-endpoint.events.*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Service Control Spawned via Script Interpreter",
+ "query": "process where event.type == \"start\" and\n (process.name : \"sc.exe\" or process.pe.original_file_name == \"sc.exe\") and\n process.parent.name : (\"cmd.exe\", \"wscript.exe\", \"rundll32.exe\", \"regsvr32.exe\",\n \"wmic.exe\", \"mshta.exe\",\"powershell.exe\", \"pwsh.exe\") and\n process.args:(\"config\", \"create\", \"start\", \"delete\", \"stop\", \"pause\") and\n /* exclude SYSTEM SID - look for service creations by non-SYSTEM user */\n not user.id : \"S-1-5-18\"\n",
+ "risk_score": 21,
+ "rule_id": "e8571d5f-bea1-46c2-9f56-998de2d3ed95",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Lateral Movement"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0008",
+ "name": "Lateral Movement",
+ "reference": "https://attack.mitre.org/tactics/TA0008/"
+ },
+ "technique": [
+ {
+ "id": "T1021",
+ "name": "Remote Services",
+ "reference": "https://attack.mitre.org/techniques/T1021/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 9
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
deleted file mode 100644
index 664a7ccd3b9d1..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "The Linux mknod program is sometimes used in the command payload of a remote command injection (RCI) and other exploits. It is used to export a command shell when the traditional version of netcat is not available to the payload.",
- "false_positives": [
- "Mknod is a Linux system program. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Mknod Process Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:mknod",
- "references": [
- "https://web.archive.org/web/20191218024607/https://pen-testing.sans.org/blog/2013/05/06/netcat-without-e-no-problem/"
- ],
- "risk_score": 21,
- "rule_id": "61c31c14-507f-4627-8c31-072556b89a9c",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection"
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
deleted file mode 100644
index 023b580adb483..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Nmap was executed on a Linux host. Nmap is a FOSS tool for network scanning and security testing. It can map and discover networks, and identify listening services and operating systems. It is sometimes used to gather information in support of exploitation, execution or lateral movement.",
- "false_positives": [
- "Security testing tools and frameworks may run `Nmap` in the course of security auditing. Some normal use of this command may originate from security engineers and network or server administrators. Use of nmap by ordinary users is uncommon."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Nmap Process Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:nmap",
- "references": [
- "https://en.wikipedia.org/wiki/Nmap"
- ],
- "risk_score": 21,
- "rule_id": "c87fca17-b3a9-4e83-b545-f30746c53920",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection"
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
deleted file mode 100644
index fdf50bb9bf452..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "A Socat process is running on a Linux host. Socat is often used as a persistence mechanism by exporting a reverse shell, or by serving a shell on a listening port. Socat is also sometimes used for lateral movement.",
- "false_positives": [
- "Socat is a dual-use tool that can be used for benign or malicious activity. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Socat Process Activity",
- "query": "event.category:process and event.type:(start or process_started) and process.name:socat and not process.args:-V",
- "references": [
- "https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/#method-2-using-socat"
- ],
- "risk_score": 47,
- "rule_id": "cd4d5754-07e1-41d4-b9a5-ef4ea6a0a126",
- "severity": "medium",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection"
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json
index 87822b480cbbb..4cd3583fa681f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json
@@ -7,7 +7,7 @@
"false_positives": [
"Rare and unusual errors may indicate an impending service failure state. Rare and unusual user error activity can also be due to manual troubleshooting or reconfiguration attempts by insufficiently privileged users, bugs in cloud automation scripts or workflows, or changes to IAM privileges."
],
- "from": "now-60m",
+ "from": "now-2h",
"interval": "15m",
"license": "Elastic License v2",
"machine_learning_job_id": "rare_error_code",
@@ -26,5 +26,5 @@
"ML"
],
"type": "machine_learning",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json
index c259d5a6b5599..c516ae87e9be8 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json
@@ -7,7 +7,7 @@
"false_positives": [
"New or unusual command and user geolocation activity can be due to manual troubleshooting or reconfiguration; changes in cloud automation scripts or workflows; adoption of new services; expansion into new regions; increased adoption of work from home policies; or users who travel frequently."
],
- "from": "now-60m",
+ "from": "now-2h",
"interval": "15m",
"license": "Elastic License v2",
"machine_learning_job_id": "rare_method_for_a_city",
@@ -26,5 +26,5 @@
"ML"
],
"type": "machine_learning",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json
index bb469c725aed6..8263b06cb6b2e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json
@@ -7,7 +7,7 @@
"false_positives": [
"New or unusual command and user geolocation activity can be due to manual troubleshooting or reconfiguration; changes in cloud automation scripts or workflows; adoption of new services; expansion into new regions; increased adoption of work from home policies; or users who travel frequently."
],
- "from": "now-60m",
+ "from": "now-2h",
"interval": "15m",
"license": "Elastic License v2",
"machine_learning_job_id": "rare_method_for_a_country",
@@ -26,5 +26,5 @@
"ML"
],
"type": "machine_learning",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json
index c8e995d592e39..3228031911147 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json
@@ -7,7 +7,7 @@
"false_positives": [
"New or unusual user command activity can be due to manual troubleshooting or reconfiguration; changes in cloud automation scripts or workflows; adoption of new services; or changes in the way services are used."
],
- "from": "now-60m",
+ "from": "now-2h",
"interval": "15m",
"license": "Elastic License v2",
"machine_learning_job_id": "rare_method_for_a_username",
@@ -26,5 +26,5 @@
"ML"
],
"type": "machine_learning",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json
new file mode 100644
index 0000000000000..7856d13b8d66f
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json
@@ -0,0 +1,29 @@
+{
+ "anomaly_threshold": 75,
+ "author": [
+ "Elastic"
+ ],
+ "description": "A machine learning job detected an unusually large spike in network traffic that was denied by network access control lists (ACLs) or firewall rules. Such a burst of denied traffic is usually caused by either 1) a mis-configured application or firewall or 2) suspicious or malicious activity. Unsuccessful attempts at network transit, in order to connect to command-and-control (C2), or engage in data exfiltration, may produce a burst of failed connections. This could also be due to unusually large amounts of reconnaissance or enumeration traffic. Denial-of-service attacks or traffic floods may also produce such a surge in traffic.",
+ "false_positives": [
+ "A misconfgured network application or firewall may trigger this alert. Security scans or test cycles may trigger this alert."
+ ],
+ "from": "now-30m",
+ "interval": "15m",
+ "license": "Elastic License",
+ "machine_learning_job_id": "high-count-network-denies",
+ "name": "Spike in Firewall Denies",
+ "references": [
+ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "eaa77d63-9679-4ce3-be25-3ba8b795e5fa",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Network",
+ "Threat Detection",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json
new file mode 100644
index 0000000000000..14aec268cc13b
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json
@@ -0,0 +1,29 @@
+{
+ "anomaly_threshold": 75,
+ "author": [
+ "Elastic"
+ ],
+ "description": "A machine learning job detected an unusually large spike in network traffic. Such a burst of traffic, if not caused by a surge in business activity, can be due to suspicious or malicious activity. Large-scale data exfiltration may produce a burst of network traffic; this could also be due to unusually large amounts of reconnaissance or enumeration traffic. Denial-of-service attacks or traffic floods may also produce such a surge in traffic.",
+ "false_positives": [
+ "Business workflows that occur very occasionally, and involve an unsual surge in network trafic, can trigger this alert. A new business workflow or a surge in business activity may trigger this alert. A misconfigured network application or firewall may trigger this alert."
+ ],
+ "from": "now-30m",
+ "interval": "15m",
+ "license": "Elastic License",
+ "machine_learning_job_id": "high-count-network-events",
+ "name": "Spike in Network Traffic",
+ "references": [
+ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "b240bfb8-26b7-4e5e-924e-218144a3fa71",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Network",
+ "Threat Detection",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json
new file mode 100644
index 0000000000000..571c7e0d0d32c
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json
@@ -0,0 +1,29 @@
+{
+ "anomaly_threshold": 75,
+ "author": [
+ "Elastic"
+ ],
+ "description": "A machine learning job detected a rare destination country name in the network logs. This can be due to initial access, persistence, command-and-control, or exfiltration activity. For example, when a user clicks on a link in a phishing email or opens a malicious document, a request may be sent to download and run a payload from a server in a country which does not normally appear in network traffic or business work-flows. Malware instances and persistence mechanisms may communicate with command-and-control (C2) infrastructure in their country of origin, which may be an unusual destination country for the source network.",
+ "false_positives": [
+ "Business workflows that occur very occasionally, and involve a business relationship with an organization in a country that does not routinely appear in network events, can trigger this alert. A new business workflow with an organization in a country with which no workflows previously existed may trigger this alert - although the model will learn that the new destination country is no longer anomalous as the activity becomes ongoing. Business travelers who roam to many countries for brief periods may trigger this alert."
+ ],
+ "from": "now-30m",
+ "interval": "15m",
+ "license": "Elastic License",
+ "machine_learning_job_id": "rare-destination-country",
+ "name": "Network Traffic to Rare Destination Country",
+ "references": [
+ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "35f86980-1fb1-4dff-b311-3be941549c8d",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Network",
+ "Threat Detection",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json
new file mode 100644
index 0000000000000..e1e571bbd1c99
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json
@@ -0,0 +1,29 @@
+{
+ "anomaly_threshold": 75,
+ "author": [
+ "Elastic"
+ ],
+ "description": "A machine learning job detected an unusually large spike in network activity to one destination country in the network logs. This could be due to unusually large amounts of reconnaissance or enumeration traffic. Data exfiltration activity may also produce such a surge in traffic to a destination country which does not normally appear in network traffic or business work-flows. Malware instances and persistence mechanisms may communicate with command-and-control (C2) infrastructure in their country of origin, which may be an unusual destination country for the source network.",
+ "false_positives": [
+ "Business workflows that occur very occasionally, and involve an unusual surge in network traffic to one destination country, can trigger this alert. A new business workflow or a surge in business activity in a particular country may trigger this alert. Business travelers who roam to many countries for brief periods may trigger this alert if they engage in volumetric network activity."
+ ],
+ "from": "now-30m",
+ "interval": "15m",
+ "license": "Elastic License",
+ "machine_learning_job_id": "high-count-by-destination-country",
+ "name": "Spike in Network Traffic To a Country",
+ "references": [
+ "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"
+ ],
+ "risk_score": 21,
+ "rule_id": "c7db5533-ca2a-41f6-a8b0-ee98abe0f573",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Network",
+ "Threat Detection",
+ "ML"
+ ],
+ "type": "machine_learning",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json
index c42c48560c32f..66580e65df4a9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Adobe Hijack Persistence",
- "query": "event.category:file and event.type:creation and file.path:(\"C:\\Program Files (x86)\\Adobe\\Acrobat Reader DC\\Reader\\AcroCEF\\RdrCEF.exe\" or \"C:\\Program Files\\Adobe\\Acrobat Reader DC\\Reader\\AcroCEF\\RdrCEF.exe\") and not process.name:msiexec.exe",
+ "query": "file where event.type == \"creation\" and\n file.path : (\"?:\\\\Program Files (x86)\\\\Adobe\\\\Acrobat Reader DC\\\\Reader\\\\AcroCEF\\\\RdrCEF.exe\",\n \"?:\\\\Program Files\\\\Adobe\\\\Acrobat Reader DC\\\\Reader\\\\AcroCEF\\\\RdrCEF.exe\") and\n not process.name : \"msiexec.exe\"\n",
"risk_score": 21,
"rule_id": "2bf78aa2-9c56-48de-b139-f169bf99cf86",
"severity": "low",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json
index d8faa12add9fa..f13f108cbd7a5 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json
@@ -31,7 +31,6 @@
"Configuration Audit"
],
"timestamp_override": "event.ingested",
- "to": "now-25m",
"type": "query",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json
index 7895594743de8..e1d8c05438b81 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json
@@ -14,7 +14,7 @@
"language": "kuery",
"license": "Elastic License v2",
"name": "Modification of Standard Authentication Module or Configuration",
- "query": "event.category:file and event.type:change and (file.name:pam_*.so or file.path:(/etc/pam.d/* or /private/etc/pam.d/*)) and process.executable: (* and not ( /bin/yum or \"/usr/sbin/pam-auth-update\" or /usr/libexec/packagekitd or /usr/bin/dpkg or /usr/bin/vim or /usr/libexec/xpcproxy or /usr/bin/bsdtar or /usr/local/bin/brew ) )",
+ "query": "event.category:file and event.type:change and (file.name:pam_*.so or file.path:(/etc/pam.d/* or /private/etc/pam.d/*)) and process.executable: (* and not ( /bin/yum or \"/usr/sbin/pam-auth-update\" or /usr/libexec/packagekitd or /usr/bin/dpkg or /usr/bin/vim or /usr/libexec/xpcproxy or /usr/bin/bsdtar or /usr/local/bin/brew or /usr/bin/rsync or /usr/bin/yum or /var/lib/docker/*/bin/yum or /var/lib/docker/*/bin/dpkg or ./merged/var/lib/docker/*/bin/dpkg or \"/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service\" ) ) and not file.path: ( /tmp/snap.rootfs_*/pam_*.so or /tmp/newroot/lib/*/pam_*.so or /private/var/folders/*/T/com.apple.fileprovider.ArchiveService/TemporaryItems/*/lib/security/pam_*.so or /tmp/newroot/usr/lib64/security/pam_*.so )",
"references": [
"https://github.com/zephrax/linux-pam-backdoor",
"https://github.com/eurialo/pambd",
@@ -67,5 +67,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 1
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_cron_jobs_creation_and_runtime.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_cron_jobs_creation_and_runtime.json
deleted file mode 100644
index 982f3b505c8f5..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_cron_jobs_creation_and_runtime.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies the creation or execution of a cron job. Adversaries may abuse cron jobs to perform task scheduling for initial or recurring execution of malicious code.",
- "false_positives": [
- "Legitimate software or scripts using cron jobs for recurring tasks."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Potential Persistence via Cron Job",
- "query": "event.category:process and event.type:(start or process_started or info) and not user.name:root and ((process.name:crontab and not process.args:(\"-l\" or \"-r\" or \"-e\" or \"-help\" or \"-h\")) or (process.parent.name:cron and not process.name:\"running job\" and not process.executable:(/Applications/Docker.app/Contents/Resources/bin/docker or /usr/bin/killall or /usr/sbin/sendmail or /usr/bin/env or /usr/bin/timeshift or /bin/rm)))",
- "references": [
- "https://archive.f-secure.com/weblog/archives/00002576.html",
- "https://ss64.com/osx/crontab.html"
- ],
- "risk_score": 21,
- "rule_id": "b1c14366-f4f8-49a0-bcbb-51d2de8b0bb8",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "macOS",
- "Threat Detection",
- "Persistence"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0003",
- "name": "Persistence",
- "reference": "https://attack.mitre.org/tactics/TA0003/"
- },
- "technique": [
- {
- "id": "T1053",
- "name": "Scheduled Task/Job",
- "reference": "https://attack.mitre.org/techniques/T1053/",
- "subtechnique": [
- {
- "id": "T1053.003",
- "name": "Cron",
- "reference": "https://attack.mitre.org/techniques/T1053/003/"
- }
- ]
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 1
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json
index 2cd50efc59fb1..f1ece4525079a 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS EC2 Network Access Control List Creation",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(CreateNetworkAcl or CreateNetworkAclEntry) and event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:ec2.amazonaws.com and event.action:(CreateNetworkAcl or CreateNetworkAclEntry) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/create-network-acl.html",
"https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkAcl.html",
@@ -53,5 +53,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json
new file mode 100644
index 0000000000000..ec985807b3137
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json
@@ -0,0 +1,54 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies suspicious startup shell folder modifications to change the default Startup directory in order to bypass detections monitoring file creation in the Windows Startup folder.",
+ "from": "now-9m",
+ "index": [
+ "winlogbeat-*",
+ "logs-endpoint.events.*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Suspicious Startup Shell Folder Modification",
+ "note": "Verify file creation events in the new Windows Startup folder location.",
+ "query": "registry where\n registry.path : (\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Common Startup\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Common Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Startup\"\n ) and\n registry.data.strings != null and\n /* Normal Startup Folder Paths */\n not registry.data.strings : (\n \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%ProgramData%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%USERPROFILE%\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"C:\\\\Users\\\\*\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\"\n )\n",
+ "risk_score": 73,
+ "rule_id": "c8b150f0-0164-475b-a75e-74b47800a9ff",
+ "severity": "high",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Persistence"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0003",
+ "name": "Persistence",
+ "reference": "https://attack.mitre.org/tactics/TA0003/"
+ },
+ "technique": [
+ {
+ "id": "T1547",
+ "name": "Boot or Logon Autostart Execution",
+ "reference": "https://attack.mitre.org/techniques/T1547/",
+ "subtechnique": [
+ {
+ "id": "T1547.001",
+ "name": "Registry Run Keys / Startup Folder",
+ "reference": "https://attack.mitre.org/techniques/T1547/001/"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json
index 042e42fdbecd6..86b1cd3e71eaf 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Creation or Modification of a new GPO Scheduled Task or Service",
- "query": "event.category:file and not event.type:deletion and file.path:(C\\:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\ScheduledTasks\\\\ScheduledTasks.xml or C\\:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\Preferences\\\\Services\\\\Services.xml) and not process.name:dfsrs.exe",
+ "query": "file where event.type != \"deletion\" and\n file.path : (\"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\ScheduledTasks\\\\ScheduledTasks.xml\",\n \"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\Preferences\\\\Services\\\\Services.xml\") and\n not process.name : \"dfsrs.exe\"\n",
"risk_score": 21,
"rule_id": "c0429aa8-9974-42da-bfb6-53a0a515a145",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json
index ceff8cc41dc91..155be18fe8add 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS IAM Group Creation",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:CreateGroup and event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:iam.amazonaws.com and event.action:CreateGroup and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-group.html",
"https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateGroup.html"
@@ -58,5 +58,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json
deleted file mode 100644
index 5a453faa1fafc..0000000000000
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": [
- "Elastic"
- ],
- "description": "Identifies loadable kernel module errors, which are often indicative of potential persistence attempts.",
- "false_positives": [
- "Security tools and device drivers may run these programs in order to load legitimate kernel modules. Use of these programs by ordinary users is uncommon."
- ],
- "from": "now-9m",
- "index": [
- "auditbeat-*",
- "logs-endpoint.events.*"
- ],
- "language": "kuery",
- "license": "Elastic License v2",
- "name": "Persistence via Kernel Module Modification",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(insmod or kmod or modprobe or rmod)",
- "references": [
- "https://www.hackers-arise.com/single-post/2017/11/03/Linux-for-Hackers-Part-10-Loadable-Kernel-Modules-LKM"
- ],
- "risk_score": 21,
- "rule_id": "81cc58f5-8062-49a2-ba84-5cc4b4d31c40",
- "severity": "low",
- "tags": [
- "Elastic",
- "Host",
- "Linux",
- "Threat Detection",
- "Persistence"
- ],
- "threat": [
- {
- "framework": "MITRE ATT&CK",
- "tactic": {
- "id": "TA0003",
- "name": "Persistence",
- "reference": "https://attack.mitre.org/tactics/TA0003/"
- },
- "technique": [
- {
- "id": "T1547",
- "name": "Boot or Logon Autostart Execution",
- "reference": "https://attack.mitre.org/techniques/T1547/",
- "subtechnique": [
- {
- "id": "T1547.006",
- "name": "Kernel Modules and Extensions",
- "reference": "https://attack.mitre.org/techniques/T1547/006/"
- }
- ]
- }
- ]
- }
- ],
- "timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
-}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json
similarity index 53%
rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json
rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json
index 769aba1ad647c..6e656209fd055 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json
@@ -2,9 +2,9 @@
"author": [
"Elastic"
],
- "description": "A scheduled task can be used by an adversary to establish persistence, move laterally, and/or escalate privileges.",
+ "description": "A job can be used to schedule programs or scripts to be executed at a specified date and time. Adversaries may abuse task scheduling functionality to facilitate initial or recurring execution of malicious code.",
"false_positives": [
- "Legitimate scheduled tasks may be created during installation of new software."
+ "Legitimate scheduled jobs may be created during installation of new software."
],
"from": "now-9m",
"index": [
@@ -12,13 +12,13 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
- "name": "Local Scheduled Task Commands",
- "query": "event.category:process and event.type:(start or process_started) and process.name:schtasks.exe and process.args:(-change or -create or -run or -s or /S or /change or /create or /run)",
- "risk_score": 21,
- "rule_id": "afcce5ad-65de-4ed2-8516-5e093d3ac99a",
- "severity": "low",
+ "name": "Persistence via Scheduled Job Creation",
+ "query": "file where event.type != \"deletion\" and\n file.path : \"?:\\\\Windows\\\\Tasks\\\\*\" and file.extension : \"job\"\n",
+ "risk_score": 47,
+ "rule_id": "1327384f-00f3-44d5-9a8c-2373ba071e92",
+ "severity": "medium",
"tags": [
"Elastic",
"Host",
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 1
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json
new file mode 100644
index 0000000000000..8b6fa370f4ab9
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json
@@ -0,0 +1,56 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "A scheduled task can be used by an adversary to establish persistence, move laterally, and/or escalate privileges.",
+ "false_positives": [
+ "Legitimate scheduled tasks may be created during installation of new software."
+ ],
+ "from": "now-9m",
+ "index": [
+ "winlogbeat-*",
+ "logs-endpoint.events.*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Local Scheduled Task Creation",
+ "query": "sequence with maxspan=1m\n [process where event.type != \"end\" and\n ((process.name : (\"cmd.exe\", \"wscript.exe\", \"rundll32.exe\", \"regsvr32.exe\", \"wmic.exe\", \"mshta.exe\",\n \"powershell.exe\", \"pwsh.exe\", \"WmiPrvSe.exe\", \"wsmprovhost.exe\", \"winrshost.exe\") or\n process.pe.original_file_name : (\"cmd.exe\", \"wscript.exe\", \"rundll32.exe\", \"regsvr32.exe\", \"wmic.exe\", \"mshta.exe\",\n \"powershell.exe\", \"pwsh.exe\", \"WmiPrvSe.exe\", \"wsmprovhost.exe\",\n \"winrshost.exe\")) or\n process.code_signature.trusted == false)] by process.entity_id\n [process where event.type == \"start\" and\n (process.name : \"schtasks.exe\" or process.pe.original_file_name == \"schtasks.exe\") and\n process.args : (\"/create\", \"-create\") and process.args : (\"/RU\", \"/SC\", \"/TN\", \"/TR\", \"/F\", \"/XML\") and\n /* exclude SYSTEM SIDs - look for task creations by non-SYSTEM user */\n not user.id : (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\")] by process.parent.entity_id\n",
+ "risk_score": 21,
+ "rule_id": "afcce5ad-65de-4ed2-8516-5e093d3ac99a",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Persistence"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0003",
+ "name": "Persistence",
+ "reference": "https://attack.mitre.org/tactics/TA0003/"
+ },
+ "technique": [
+ {
+ "id": "T1053",
+ "name": "Scheduled Task/Job",
+ "reference": "https://attack.mitre.org/techniques/T1053/",
+ "subtechnique": [
+ {
+ "id": "T1053.005",
+ "name": "Scheduled Task",
+ "reference": "https://attack.mitre.org/techniques/T1053/005/"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 8
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json
index 662ea6678a195..ade4f76e3c0dc 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json
@@ -11,7 +11,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Persistence via Login or Logout Hook",
- "query": "process where event.type in (\"start\", \"process_started\") and\n process.name == \"defaults\" and process.args == \"write\" and process.args in (\"LoginHook\", \"LogoutHook\")\n",
+ "query": "process where event.type == \"start\" and\n process.name == \"defaults\" and process.args == \"write\" and process.args in (\"LoginHook\", \"LogoutHook\") and\n not process.args :\n (\n \"Support/JAMF/ManagementFrameworkScripts/logouthook.sh\",\n \"Support/JAMF/ManagementFrameworkScripts/loginhook.sh\",\n \"/Library/Application Support/JAMF/ManagementFrameworkScripts/logouthook.sh\",\n \"/Library/Application Support/JAMF/ManagementFrameworkScripts/loginhook.sh\"\n )\n",
"references": [
"https://www.virusbulletin.com/uploads/pdf/conference_slides/2014/Wardle-VB2014.pdf",
"https://www.manpagez.com/man/1/defaults/"
@@ -45,5 +45,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json
index a7ea7424721a5..d0d3200d00058 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json
@@ -16,7 +16,7 @@
"license": "Elastic License v2",
"name": "AWS RDS Cluster Creation",
"note": "The AWS Filebeat module must be enabled to use this rule.",
- "query": "event.action:(CreateDBCluster or CreateGlobalCluster) and event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.outcome:success",
+ "query": "event.dataset:aws.cloudtrail and event.provider:rds.amazonaws.com and event.action:(CreateDBCluster or CreateGlobalCluster) and event.outcome:success",
"references": [
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/create-db-cluster.html",
"https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBCluster.html",
@@ -62,5 +62,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 5
+ "version": 6
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json
index 690afcf5a8025..46bbeb00f4d05 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Startup or Run Key Registry Modification",
- "query": "/* uncomment length once stable */\nregistry where /* length(registry.data.strings) > 0 and */\n registry.path : (\n /* Machine Hive */\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\", \n /* Users Hive */\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\"\n ) and\n /* add here common legit changes without making too restrictive as this is one of the most abused AESPs */\n not registry.data.strings : \"ctfmon.exe /n\" and\n not (registry.value : \"Application Restart #*\" and process.name : \"csrss.exe\") and\n user.domain != \"NT AUTHORITY\" and\n not registry.data.strings : (\"C:\\\\Program Files\\\\*.exe\", \"C:\\\\Program Files (x86)\\\\*.exe\") and\n not process.executable : (\"C:\\\\Windows\\\\System32\\\\msiexec.exe\", \"C:\\\\Windows\\\\SysWOW64\\\\msiexec.exe\")\n",
+ "query": "registry where registry.data.strings != null and\n registry.path : (\n /* Machine Hive */\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\", \n \"HKLM\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\", \n /* Users Hive */\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\", \n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\"\n ) and\n /* add common legitimate changes without being too restrictive as this is one of the most abused AESPs */\n not registry.data.strings : \"ctfmon.exe /n\" and\n not (registry.value : \"Application Restart #*\" and process.name : \"csrss.exe\") and\n user.id not in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and\n not registry.data.strings : (\"?:\\\\Program Files\\\\*.exe\", \"?:\\\\Program Files (x86)\\\\*.exe\") and\n not process.executable : (\"?:\\\\Windows\\\\System32\\\\msiexec.exe\", \"?:\\\\Windows\\\\SysWOW64\\\\msiexec.exe\") and\n not (process.name : \"OneDriveSetup.exe\" and\n registry.value : (\"Delete Cached Standalone Update Binary\", \"Delete Cached Update Binary\", \"amd64\", \"Uninstall *\") and\n registry.data.strings : \"?:\\\\Windows\\\\system32\\\\cmd.exe /q /c * \\\"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\OneDrive\\\\*\\\"\")\n",
"risk_score": 21,
"rule_id": "97fc44d3-8dae-4019-ae83-298c3015600f",
"severity": "low",
@@ -49,5 +49,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json
index 8ad7ef7a22c9b..64b9aba81551d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "Unusual Persistence via Services Registry",
- "query": "registry where registry.path : (\"HKLM\\\\SYSTEM\\\\ControlSet*\\\\Services\\\\*\\\\ServiceDLL\", \"HKLM\\\\SYSTEM\\\\ControlSet*\\\\Services\\\\*\\\\ImagePath\") and\n not registry.data.strings : (\"C:\\\\windows\\\\system32\\\\Drivers\\\\*.sys\", \n \"\\\\SystemRoot\\\\System32\\\\drivers\\\\*.sys\", \n \"system32\\\\DRIVERS\\\\USBSTOR\") and\n not (process.name : \"procexp??.exe\" and registry.data.strings : \"C:\\\\*\\\\procexp*.sys\") and\n not process.executable : (\"C:\\\\Program Files*\\\\*.exe\", \n \"C:\\\\Windows\\\\System32\\\\svchost.exe\", \n \"C:\\\\Windows\\\\winsxs\\\\*\\\\TiWorker.exe\", \n \"C:\\\\Windows\\\\System32\\\\drvinst.exe\", \n \"C:\\\\Windows\\\\System32\\\\services.exe\", \n \"C:\\\\Windows\\\\System32\\\\msiexec.exe\", \n \"C:\\\\Windows\\\\System32\\\\regsvr32.exe\")\n",
+ "query": "registry where registry.path : (\"HKLM\\\\SYSTEM\\\\ControlSet*\\\\Services\\\\*\\\\ServiceDLL\", \"HKLM\\\\SYSTEM\\\\ControlSet*\\\\Services\\\\*\\\\ImagePath\") and\n not registry.data.strings : (\"?:\\\\windows\\\\system32\\\\Drivers\\\\*.sys\",\n \"\\\\SystemRoot\\\\System32\\\\drivers\\\\*.sys\",\n \"\\\\??\\\\?:\\\\Windows\\\\system32\\\\Drivers\\\\*.SYS\",\n \"system32\\\\DRIVERS\\\\USBSTOR\") and\n not (process.name : \"procexp??.exe\" and registry.data.strings : \"?:\\\\*\\\\procexp*.sys\") and\n not process.executable : (\"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\svchost.exe\",\n \"?:\\\\Windows\\\\winsxs\\\\*\\\\TiWorker.exe\",\n \"?:\\\\Windows\\\\System32\\\\drvinst.exe\",\n \"?:\\\\Windows\\\\System32\\\\services.exe\",\n \"?:\\\\Windows\\\\System32\\\\msiexec.exe\",\n \"?:\\\\Windows\\\\System32\\\\regsvr32.exe\")\n",
"risk_score": 21,
"rule_id": "403ef0d3-8259-40c9-a5b6-d48354712e49",
"severity": "low",
@@ -49,5 +49,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 3
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json
index 8c26a67c65a64..709396a5eaf2f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "System Shells via Services",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:services.exe and process.name:(cmd.exe or powershell.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"services.exe\" and\n process.name : (\"cmd.exe\", \"powershell.exe\") and\n \n /* Third party FP's */\n not process.args : \"NVDisplay.ContainerLocalSystem\"\n",
"risk_score": 47,
"rule_id": "0022d47d-39c7-4f69-a232-4fe9dc7a3acd",
"severity": "medium",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 8
+ "type": "eql",
+ "version": 9
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json
index 875745e0d161a..c63d96b106a01 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json
@@ -7,19 +7,18 @@
"from": "now-9m",
"index": [
"winlogbeat-*",
- "logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "User Added to Privileged Group in Active Directory",
- "query": "event.category:iam and event.action:\"added-member-to-group\" and group.name:(Administrators or \"Local Administrators\" or \"Domain Admins\" or \"Enterprise Admins\" or \"Backup Admins\" or \"Schema Admins\" or \"DnsAdmins\")",
+ "query": "iam where event.action == \"added-member-to-group\" and\n group.name : (\"Admin*\",\n \"Local Administrators\",\n \"Domain Admins\",\n \"Enterprise Admins\",\n \"Backup Admins\",\n \"Schema Admins\",\n \"DnsAdmins\",\n \"Exchange Organization Administrators\")\n",
"references": [
"https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-b--privileged-accounts-and-groups-in-active-directory"
],
- "risk_score": 21,
+ "risk_score": 47,
"rule_id": "5cd8e1f7-0050-4afc-b2df-904e40b2f5ae",
- "severity": "low",
+ "severity": "medium",
"tags": [
"Elastic",
"Host",
@@ -52,6 +51,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 1
+ "type": "eql",
+ "version": 2
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json
index 21a297c3fd8ef..0e2b01a1967d2 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "User Account Creation",
- "query": "event.category:process and event.type:(start or process_started) and process.name:(net.exe or net1.exe) and not process.parent.name:net.exe and process.args:(user and (/ad or /add))",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.name : (\"net.exe\", \"net1.exe\") and\n not process.parent.name : \"net.exe\" and\n (process.args : \"user\" and process.args : (\"/ad\", \"/add\"))\n",
"risk_score": 21,
"rule_id": "1aa9181a-492b-4c01-8b16-fa0735786b2b",
"severity": "low",
@@ -41,6 +41,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json
index 2143dd2743240..13c8829869c8d 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Potential Application Shimming via Sdbinst",
- "query": "event.category:process and event.type:(start or process_started) and process.name:sdbinst.exe",
+ "query": "process where event.type in (\"start\", \"process_started\") and process.name : \"sdbinst.exe\"\n",
"risk_score": 21,
"rule_id": "fd4a992d-6130-4802-9ff8-829b89ae801f",
"severity": "low",
@@ -70,6 +70,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json
new file mode 100644
index 0000000000000..6cd322d20d4e8
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json
@@ -0,0 +1,52 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "An adversary can use the Background Intelligent Transfer Service (BITS) SetNotifyCmdLine method to execute a program that runs after a job finishes transferring data or after a job enters a specified state in order to persist on a system.",
+ "from": "now-9m",
+ "index": [
+ "logs-endpoint.events.*",
+ "winlogbeat-*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Persistence via BITS Job Notify Cmdline",
+ "query": "process where event.type == \"start\" and\n process.parent.name : \"svchost.exe\" and process.parent.args : \"BITS\" and\n not process.executable :\n (\"?:\\\\Windows\\\\System32\\\\WerFaultSecure.exe\",\n \"?:\\\\Windows\\\\System32\\\\WerFault.exe\",\n \"?:\\\\Windows\\\\System32\\\\wermgr.exe\",\n \"?:\\\\WINDOWS\\\\system32\\\\directxdatabaseupdater.exe\")\n",
+ "references": [
+ "https://pentestlab.blog/2019/10/30/persistence-bits-jobs/",
+ "https://docs.microsoft.com/en-us/windows/win32/api/bits1_5/nf-bits1_5-ibackgroundcopyjob2-setnotifycmdline",
+ "https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin-setnotifycmdline",
+ "https://www.elastic.co/blog/hunting-for-persistence-using-elastic-security-part-2"
+ ],
+ "risk_score": 47,
+ "rule_id": "c3b915e0-22f3-4bf7-991d-b643513c722f",
+ "severity": "medium",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Persistence"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0003",
+ "name": "Persistence",
+ "reference": "https://attack.mitre.org/tactics/TA0003/"
+ },
+ "technique": [
+ {
+ "id": "T1197",
+ "name": "BITS Jobs",
+ "reference": "https://attack.mitre.org/techniques/T1197/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json
index 51b7f34fdc7b9..dca20728b40fa 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Persistence via TelemetryController Scheduled Task Hijack",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:(CompatTelRunner.exe or compattelrunner.exe) and process.args:-cv* and not process.name:(conhost.exe or DeviceCensus.exe or devicecensus.exe or CompatTelRunner.exe or compattelrunner.exe or DismHost.exe or dismhost.exe or rundll32.exe or powershell.exe)",
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"CompatTelRunner.exe\" and process.args : \"-cv*\" and\n not process.name : (\"conhost.exe\",\n \"DeviceCensus.exe\",\n \"CompatTelRunner.exe\",\n \"DismHost.exe\",\n \"rundll32.exe\",\n \"powershell.exe\")\n",
"references": [
"https://www.trustedsec.com/blog/abusing-windows-telemetry-for-persistence/?utm_content=131234033&utm_medium=social&utm_source=twitter&hss_channel=tw-403811306"
],
@@ -44,6 +44,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 4
+ "type": "eql",
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json
new file mode 100644
index 0000000000000..3fdb1e1ebc96d
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json
@@ -0,0 +1,83 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "Identifies use of the Windows Management Instrumentation StdRegProv (registry provider) to modify commonly abused registry locations for persistence.",
+ "from": "now-9m",
+ "index": [
+ "logs-endpoint.events.*",
+ "winlogbeat-*",
+ "logs-windows.*"
+ ],
+ "language": "eql",
+ "license": "Elastic License v2",
+ "name": "Persistence via WMI Standard Registry Provider",
+ "query": "registry where \n registry.data.strings != null and process.name : \"WmiPrvSe.exe\" and\n registry.path : (\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\WOW6432Node\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\Services\\\\*\\\\ServiceDLL\",\n \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\Services\\\\*\\\\ImagePath\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\", \n \"HKEY_USERS\\\\*\\\\Environment\\\\UserInitMprLogonScript\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Windows\\\\Load\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\System\\\\Shell\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\System\\\\Scripts\\\\Logoff\\\\Script\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\System\\\\Scripts\\\\Logon\\\\Script\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\System\\\\Scripts\\\\Shutdown\\\\Script\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\System\\\\Scripts\\\\Startup\\\\Script\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Ctf\\\\LangBarAddin\\\\*\\\\FilePath\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Internet Explorer\\\\Extensions\\\\*\\\\Exec\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Internet Explorer\\\\Extensions\\\\*\\\\Script\", \n \"HKEY_USERS\\\\*\\\\SOFTWARE\\\\Microsoft\\\\Command Processor\\\\Autorun\"\n )\n",
+ "references": [
+ "https://docs.microsoft.com/en-us/previous-versions/windows/desktop/regprov/stdregprov"
+ ],
+ "risk_score": 73,
+ "rule_id": "70d12c9c-0dbd-4a1a-bc44-1467502c9cf6",
+ "severity": "high",
+ "tags": [
+ "Elastic",
+ "Host",
+ "Windows",
+ "Threat Detection",
+ "Persistence"
+ ],
+ "threat": [
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0003",
+ "name": "Persistence",
+ "reference": "https://attack.mitre.org/tactics/TA0003/"
+ },
+ "technique": [
+ {
+ "id": "T1547",
+ "name": "Boot or Logon Autostart Execution",
+ "reference": "https://attack.mitre.org/techniques/T1547/",
+ "subtechnique": [
+ {
+ "id": "T1547.001",
+ "name": "Registry Run Keys / Startup Folder",
+ "reference": "https://attack.mitre.org/techniques/T1547/001/"
+ }
+ ]
+ },
+ {
+ "id": "T1543",
+ "name": "Create or Modify System Process",
+ "reference": "https://attack.mitre.org/techniques/T1543/",
+ "subtechnique": [
+ {
+ "id": "T1543.003",
+ "name": "Windows Service",
+ "reference": "https://attack.mitre.org/techniques/T1543/003/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "framework": "MITRE ATT&CK",
+ "tactic": {
+ "id": "TA0002",
+ "name": "Execution",
+ "reference": "https://attack.mitre.org/tactics/TA0002/"
+ },
+ "technique": [
+ {
+ "id": "T1047",
+ "name": "Windows Management Instrumentation",
+ "reference": "https://attack.mitre.org/techniques/T1047/"
+ }
+ ]
+ }
+ ],
+ "timestamp_override": "event.ingested",
+ "type": "eql",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json
index ac6e8c470ef2f..7197c7f979a38 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json
@@ -9,10 +9,10 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious PrintSpooler Service Executable File Creation",
- "query": "event.category:file and not event.type:deletion and process.name:spoolsv.exe and file.extension:(exe or dll) and not file.path:(C\\:\\\\Windows\\\\System32\\\\spool\\\\* or C\\:\\\\Windows\\\\Temp\\\\* or C\\:\\\\Users\\\\*)",
+ "query": "file where event.type != \"deletion\" and process.name : \"spoolsv.exe\" and\n file.extension : (\"exe\", \"dll\") and\n not file.path : (\"?:\\\\Windows\\\\System32\\\\spool\\\\*\", \"?:\\\\Windows\\\\Temp\\\\*\", \"?:\\\\Users\\\\*\")\n",
"references": [
"https://voidsec.com/cve-2020-1337-printdemon-is-dead-long-live-printdemon/",
"https://www.thezdi.com/blog/2020/7/8/cve-2020-1300-remote-code-execution-through-microsoft-windows-cab-files"
@@ -45,6 +45,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json
index 964206f86d9cf..52a835b3d6fd9 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json
@@ -9,11 +9,11 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Suspicious PrintSpooler SPL File Created",
"note": "Refer to CVEs, CVE-2020-1048 and CVE-2020-1337 for further information on the vulnerability and exploit. Verify that the relevant system is patched.",
- "query": "event.category:file and not event.type:deletion and file.extension:(spl or SPL) and file.path:C\\:\\\\Windows\\\\System32\\\\spool\\\\PRINTERS\\\\* and not process.name:(spoolsv.exe or printfilterpipelinesvc.exe or PrintIsolationHost.exe or splwow64.exe or msiexec.exe or poqexec.exe)",
+ "query": "file where event.type != \"deletion\" and\n file.extension : \"spl\" and\n file.path : \"?:\\\\Windows\\\\System32\\\\spool\\\\PRINTERS\\\\*\" and\n not process.name : (\"spoolsv.exe\",\n \"printfilterpipelinesvc.exe\",\n \"PrintIsolationHost.exe\",\n \"splwow64.exe\",\n \"msiexec.exe\",\n \"poqexec.exe\")\n",
"references": [
"https://safebreach.com/Post/How-we-bypassed-CVE-2020-1048-Patch-and-got-CVE-2020-1337"
],
@@ -45,6 +45,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 3
+ "type": "eql",
+ "version": 4
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json
index 844fa83e20fff..67633985221e3 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json
@@ -12,7 +12,7 @@
"license": "Elastic License v2",
"max_signals": 33,
"name": "Setuid / Setgid Bit Set via chmod",
- "query": "event.category:process AND event.type:(start OR process_started) AND process.name:chmod AND process.args:(\"+s\" OR \"u+s\" OR /4[0-9]{3}/ OR g+s OR /2[0-9]{3}/)",
+ "query": "event.category:process AND event.type:(start OR process_started) AND process.name:chmod AND process.args:(\"+s\" OR \"u+s\" OR /4[0-9]{3}/ OR g+s OR /2[0-9]{3}/) AND NOT process.args: ( /.*\\/Applications\\/VirtualBox.app\\/.+/ OR /\\/usr\\/local\\/lib\\/python.+/ OR /\\/var\\/folders\\/.+\\/FP.*nstallHelper/ OR /\\/Library\\/Filesystems\\/.+/ OR /\\/usr\\/lib\\/virtualbox\\/.+/ OR /\\/Library\\/Application.*/ OR \"/run/postgresql\" OR \"/var/crash\" OR \"/var/run/postgresql\" OR /\\/usr\\/bin\\/.+/ OR /\\/usr\\/local\\/share\\/.+/ OR /\\/Applications\\/.+/ OR /\\/usr\\/libexec\\/.+/ OR \"/var/metrics\" OR /\\/var\\/lib\\/dpkg\\/.+/ OR /\\/run\\/log\\/journal\\/.*/ OR \\/Users\\/*\\/.minikube\\/bin\\/docker-machine-driver-hyperkit ) AND NOT process.parent.executable: ( /\\/var\\/lib\\/docker\\/.+/ OR \"/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service\" OR \"/var/lib/dpkg/info/whoopsie.postinst\" )",
"risk_score": 21,
"rule_id": "8a1b0278-0f9a-487d-96bd-d4833298e87a",
"severity": "low",
@@ -59,5 +59,5 @@
],
"timestamp_override": "event.ingested",
"type": "query",
- "version": 7
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json
index c127302c2e086..9bdd9375b89b4 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json
@@ -12,7 +12,7 @@
"language": "eql",
"license": "Elastic License v2",
"name": "UAC Bypass via DiskCleanup Scheduled Task Hijack",
- "query": "process where event.type in (\"start\", \"process_started\") and\nprocess.args:\"/autoclean\" and process.args:\"/d\" and\nnot process.executable : (\"C:\\\\Windows\\\\System32\\\\cleanmgr.exe\", \"C:\\\\Windows\\\\SysWOW64\\\\cleanmgr.exe\")\n",
+ "query": "process where event.type == \"start\" and\n process.args : \"/autoclean\" and process.args : \"/d\" and\n not process.executable : (\"C:\\\\Windows\\\\System32\\\\cleanmgr.exe\",\n \"C:\\\\Windows\\\\SysWOW64\\\\cleanmgr.exe\",\n \"C:\\\\Windows\\\\System32\\\\taskhostw.exe\")\n",
"risk_score": 47,
"rule_id": "1dcc51f6-ba26-49e7-9ef4-2655abb2361e",
"severity": "medium",
@@ -49,5 +49,5 @@
],
"timestamp_override": "event.ingested",
"type": "eql",
- "version": 4
+ "version": 5
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json
index fe6f6ff854ab4..08ebede619793 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json
@@ -9,13 +9,13 @@
"logs-endpoint.events.*",
"logs-windows.*"
],
- "language": "kuery",
+ "language": "eql",
"license": "Elastic License v2",
"name": "Bypass UAC via Event Viewer",
- "query": "event.category:process and event.type:(start or process_started) and process.parent.name:eventvwr.exe and not process.executable:(\"C:\\Windows\\SysWOW64\\mmc.exe\" or \"C:\\Windows\\System32\\mmc.exe\")",
- "risk_score": 21,
+ "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"eventvwr.exe\" and\n not process.executable : \n (\"?:\\\\Windows\\\\SysWOW64\\\\mmc.exe\", \n \"?:\\\\Windows\\\\System32\\\\mmc.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\WerFault.exe\",\n \"?:\\\\Windows\\\\System32\\\\WerFault.exe\")\n",
+ "risk_score": 73,
"rule_id": "31b4c719-f2b4-41f6-a9bd-fce93c2eaf62",
- "severity": "low",
+ "severity": "high",
"tags": [
"Elastic",
"Host",
@@ -48,6 +48,6 @@
}
],
"timestamp_override": "event.ingested",
- "type": "query",
- "version": 7
+ "type": "eql",
+ "version": 8
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json
new file mode 100644
index 0000000000000..ab99f9c69c847
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_module_match.json
@@ -0,0 +1,198 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "This rule is triggered when indicators from the Threat Intel Filebeat module has a match against local file or network observations.",
+ "from": "now-10m",
+ "index": [
+ "auditbeat-*",
+ "endgame-*",
+ "filebeat-*",
+ "logs-*",
+ "packetbeat-*",
+ "winlogbeat-*"
+ ],
+ "interval": "9m",
+ "language": "kuery",
+ "license": "Elastic License v2",
+ "name": "Threat Intel Filebeat Module Indicator Match",
+ "note": "## Triage and Analysis\nIf an indicator matches a local observation, the following enriched fields will be generated to identify the indicator, field, and type matched.\n\n- `threatintel.indicator.matched.atomic` - this identifies the atomic indicator that matched the local observation\n- `threatintel.indicator.matched.field` - this identifies the indicator field that matched the local observation\n- `threatintel.indicator.matched.type` - this identifies the indicator type that matched the local observation\n",
+ "query": "file.hash.*:* or file.pe.imphash:* or source.ip:* or destination.ip:* or url.full:* or registry.path:*",
+ "references": [
+ "https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-threatintel.html"
+ ],
+ "risk_score": 99,
+ "rule_id": "dc672cb7-d5df-4d1f-a6d7-0841b1caafb9",
+ "severity": "critical",
+ "tags": [
+ "Elastic",
+ "Windows",
+ "Elastic Endgame",
+ "Network",
+ "Continuous Monitoring",
+ "SecOps",
+ "Monitoring"
+ ],
+ "threat_filters": [
+ {
+ "$state": {
+ "store": "appState"
+ },
+ "meta": {
+ "disabled": false,
+ "key": "event.module",
+ "negate": false,
+ "params": {
+ "query": "threatintel"
+ },
+ "type": "phrase"
+ },
+ "query": {
+ "match_phrase": {
+ "event.module": "threatintel"
+ }
+ }
+ },
+ {
+ "$state": {
+ "store": "appState"
+ },
+ "meta": {
+ "disabled": false,
+ "key": "event.category",
+ "negate": false,
+ "params": {
+ "query": "threat"
+ },
+ "type": "phrase"
+ },
+ "query": {
+ "match_phrase": {
+ "event.category": "threat"
+ }
+ }
+ },
+ {
+ "$state": {
+ "store": "appState"
+ },
+ "meta": {
+ "disabled": false,
+ "key": "event.kind",
+ "negate": false,
+ "params": {
+ "query": "enrichment"
+ },
+ "type": "phrase"
+ },
+ "query": {
+ "match_phrase": {
+ "event.kind": "enrichment"
+ }
+ }
+ },
+ {
+ "$state": {
+ "store": "appState"
+ },
+ "meta": {
+ "disabled": false,
+ "key": "event.type",
+ "negate": false,
+ "params": {
+ "query": "indicator"
+ },
+ "type": "phrase"
+ },
+ "query": {
+ "match_phrase": {
+ "event.type": "indicator"
+ }
+ }
+ }
+ ],
+ "threat_index": [
+ "filebeat-*"
+ ],
+ "threat_indicator_path": "",
+ "threat_language": "kuery",
+ "threat_mapping": [
+ {
+ "entries": [
+ {
+ "field": "file.hash.md5",
+ "type": "mapping",
+ "value": "threatintel.indicator.file.hash.md5"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "file.hash.sha1",
+ "type": "mapping",
+ "value": "threatintel.indicator.file.hash.sha1"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "file.hash.sha256",
+ "type": "mapping",
+ "value": "threatintel.indicator.file.hash.sha256"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "file.pe.imphash",
+ "type": "mapping",
+ "value": "threatintel.indicator.file.pe.imphash"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "source.ip",
+ "type": "mapping",
+ "value": "threatintel.indicator.ip"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "destination.ip",
+ "type": "mapping",
+ "value": "threatintel.indicator.ip"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "url.full",
+ "type": "mapping",
+ "value": "threatintel.indicator.url.full"
+ }
+ ]
+ },
+ {
+ "entries": [
+ {
+ "field": "registry.path",
+ "type": "mapping",
+ "value": "threatintel.indicator.registry.path"
+ }
+ ]
+ }
+ ],
+ "threat_query": "event.module:threatintel and (threatintel.indicator.file.hash.*:* or threatintel.indicator.file.pe.imphash:* or threatintel.indicator.ip:* or threatintel.indicator.registry.path:* or threatintel.indicator.url.full:*)",
+ "timeline_id": "495ad7a7-316e-4544-8a0f-9c098daee76e",
+ "timeline_title": "Generic Threat Match Timeline",
+ "type": "threat_match",
+ "version": 1
+}
From 0401d2f5c8e3fec9291af632de54ead46ff08106 Mon Sep 17 00:00:00 2001
From: Nicolas Chaulet
Date: Mon, 3 May 2021 15:45:01 -0400
Subject: [PATCH 23/81] [Fleet] Remove Agent events saved object and unused
types (#98739)
---
.../plugins/fleet/common/constants/agent.ts | 3 -
.../plugins/fleet/common/constants/routes.ts | 1 -
.../openapi/components/schemas/agent.yaml | 5 -
.../paths/agents@{agent_id}@events.yaml | 11 --
.../services/is_agent_upgradeable.test.ts | 1 -
.../plugins/fleet/common/services/routes.ts | 1 -
.../fleet/common/types/models/agent.ts | 34 -----
.../fleet/common/types/rest_spec/agent.ts | 74 +--------
.../applications/fleet/constants/index.ts | 1 -
.../fleet/hooks/use_request/agents.ts | 15 --
.../agents/components/agent_health.tsx | 3 -
.../public/applications/fleet/types/index.ts | 3 -
.../plugins/fleet/server/constants/index.ts | 1 -
x-pack/plugins/fleet/server/plugin.ts | 2 -
.../fleet/server/routes/agent/handlers.ts | 35 -----
.../fleet/server/routes/agent/index.ts | 12 --
.../fleet/server/saved_objects/index.ts | 29 ----
.../saved_objects/migrations/to_v7_10_0.ts | 13 --
.../fleet/server/services/agents/events.ts | 48 ------
.../fleet/server/services/agents/helpers.ts | 1 -
.../fleet/server/services/agents/index.ts | 1 -
.../server/services/agents/saved_objects.ts | 3 -
.../fleet/server/services/agents/status.ts | 20 +--
x-pack/plugins/fleet/server/types/index.tsx | 3 -
.../fleet/server/types/models/agent.ts | 49 ------
.../fleet/server/types/rest_spec/agent.ts | 143 ------------------
.../common/endpoint/index_data.ts | 25 ++-
.../server/usage/endpoints/endpoint.mocks.ts | 12 +-
.../server/usage/endpoints/endpoint.test.ts | 5 +-
.../usage/endpoints/fleet_saved_objects.ts | 25 ++-
.../server/usage/endpoints/index.ts | 8 +-
31 files changed, 36 insertions(+), 551 deletions(-)
delete mode 100644 x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@events.yaml
delete mode 100644 x-pack/plugins/fleet/server/services/agents/events.ts
diff --git a/x-pack/plugins/fleet/common/constants/agent.ts b/x-pack/plugins/fleet/common/constants/agent.ts
index 92e24256c7a2b..6d85f658f2240 100644
--- a/x-pack/plugins/fleet/common/constants/agent.ts
+++ b/x-pack/plugins/fleet/common/constants/agent.ts
@@ -6,9 +6,6 @@
*/
export const AGENT_SAVED_OBJECT_TYPE = 'fleet-agents';
-// TODO: Remove this saved object type. Core will drop any saved objects of
-// this type during migrations. See https://github.com/elastic/kibana/issues/91869
-export const AGENT_EVENT_SAVED_OBJECT_TYPE = 'fleet-agent-events';
export const AGENT_ACTION_SAVED_OBJECT_TYPE = 'fleet-agent-actions';
export const AGENT_TYPE_PERMANENT = 'PERMANENT';
diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts
index 377cb8d8bd871..037c0ee506a05 100644
--- a/x-pack/plugins/fleet/common/constants/routes.ts
+++ b/x-pack/plugins/fleet/common/constants/routes.ts
@@ -85,7 +85,6 @@ export const AGENT_API_ROUTES = {
INFO_PATTERN: `${API_ROOT}/agents/{agentId}`,
UPDATE_PATTERN: `${API_ROOT}/agents/{agentId}`,
DELETE_PATTERN: `${API_ROOT}/agents/{agentId}`,
- EVENTS_PATTERN: `${API_ROOT}/agents/{agentId}/events`,
CHECKIN_PATTERN: `${API_ROOT}/agents/{agentId}/checkin`,
ACKS_PATTERN: `${API_ROOT}/agents/{agentId}/acks`,
ACTIONS_PATTERN: `${API_ROOT}/agents/{agentId}/actions`,
diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml
index a2647b71c70cc..c21651ca7f8be 100644
--- a/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml
+++ b/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml
@@ -30,10 +30,6 @@ properties:
$ref: ./agent_metadata.yaml
id:
type: string
- current_error_events:
- type: array
- items:
- $ref: ./agent_event.yaml
access_api_key:
type: string
status:
@@ -45,5 +41,4 @@ required:
- active
- enrolled_at
- id
- - current_error_events
- status
diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@events.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@events.yaml
deleted file mode 100644
index db8d28f72b5a2..0000000000000
--- a/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@events.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-parameters:
- - schema:
- type: string
- name: agentId
- in: path
- required: true
-get:
- summary: Fleet - Agent - Events
- tags: []
- responses: {}
- operationId: get-fleet-agents-agentId-events
diff --git a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.test.ts b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.test.ts
index f6656b881c598..1346628758a49 100644
--- a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.test.ts
+++ b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.test.ts
@@ -83,7 +83,6 @@ const getAgent = ({
policy_revision: 1,
packages: ['system'],
last_checkin: '2020-10-01T14:43:27.255Z',
- current_error_events: [],
status: 'online',
};
if (upgradeable) {
diff --git a/x-pack/plugins/fleet/common/services/routes.ts b/x-pack/plugins/fleet/common/services/routes.ts
index 6156decf8641d..1e51f2d6163cc 100644
--- a/x-pack/plugins/fleet/common/services/routes.ts
+++ b/x-pack/plugins/fleet/common/services/routes.ts
@@ -134,7 +134,6 @@ export const fleetSetupRouteService = {
export const agentRouteService = {
getInfoPath: (agentId: string) => AGENT_API_ROUTES.INFO_PATTERN.replace('{agentId}', agentId),
getUpdatePath: (agentId: string) => AGENT_API_ROUTES.UPDATE_PATTERN.replace('{agentId}', agentId),
- getEventsPath: (agentId: string) => AGENT_API_ROUTES.EVENTS_PATTERN.replace('{agentId}', agentId),
getUnenrollPath: (agentId: string) =>
AGENT_API_ROUTES.UNENROLL_PATTERN.replace('{agentId}', agentId),
getBulkUnenrollPath: () => AGENT_API_ROUTES.BULK_UNENROLL_PATTERN,
diff --git a/x-pack/plugins/fleet/common/types/models/agent.ts b/x-pack/plugins/fleet/common/types/models/agent.ts
index 0629a67f0d8d3..de00f623b829b 100644
--- a/x-pack/plugins/fleet/common/types/models/agent.ts
+++ b/x-pack/plugins/fleet/common/types/models/agent.ts
@@ -93,38 +93,6 @@ export type AgentPolicyActionSOAttributes = CommonAgentActionSOAttributes & {
};
export type BaseAgentActionSOAttributes = AgentActionSOAttributes | AgentPolicyActionSOAttributes;
-export interface NewAgentEvent {
- type: 'STATE' | 'ERROR' | 'ACTION_RESULT' | 'ACTION';
- subtype: // State
- | 'RUNNING'
- | 'STARTING'
- | 'IN_PROGRESS'
- | 'CONFIG'
- | 'FAILED'
- | 'STOPPING'
- | 'STOPPED'
- | 'DEGRADED'
- | 'UPDATING'
- // Action results
- | 'DATA_DUMP'
- // Actions
- | 'ACKNOWLEDGED'
- | 'UNKNOWN';
- timestamp: string;
- message: string;
- payload?: any;
- agent_id: string;
- action_id?: string;
- policy_id?: string;
- stream_id?: string;
-}
-
-export interface AgentEvent extends NewAgentEvent {
- id: string;
-}
-
-export type AgentEventSOAttributes = NewAgentEvent;
-
export interface AgentMetadata {
[x: string]: any;
}
@@ -149,14 +117,12 @@ interface AgentBase {
export interface Agent extends AgentBase {
id: string;
- current_error_events: AgentEvent[];
access_api_key?: string;
status?: string;
packages: string[];
}
export interface AgentSOAttributes extends AgentBase {
- current_error_events?: string;
packages?: string[];
}
diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
index 47f9112d4ab59..e6da9d4498ce2 100644
--- a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
+++ b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
@@ -5,15 +5,7 @@
* 2.0.
*/
-import type {
- Agent,
- AgentAction,
- NewAgentAction,
- NewAgentEvent,
- AgentEvent,
- AgentStatus,
- AgentType,
-} from '../models';
+import type { Agent, AgentAction, NewAgentAction } from '../models';
export interface GetAgentsRequest {
query: {
@@ -43,52 +35,6 @@ export interface GetOneAgentResponse {
item: Agent;
}
-export interface PostAgentCheckinRequest {
- params: {
- agentId: string;
- };
- body: {
- status?: 'online' | 'error' | 'degraded';
- local_metadata?: Record;
- events?: NewAgentEvent[];
- };
-}
-
-export interface PostAgentCheckinResponse {
- action: string;
-
- actions: AgentAction[];
-}
-
-export interface PostAgentEnrollRequest {
- body: {
- type: AgentType;
- metadata: {
- local: Record;
- user_provided: Record;
- };
- };
-}
-
-export interface PostAgentEnrollResponse {
- action: string;
-
- item: Agent & { status: AgentStatus };
-}
-
-export interface PostAgentAcksRequest {
- body: {
- events: AgentEvent[];
- };
- params: {
- agentId: string;
- };
-}
-
-export interface PostAgentAcksResponse {
- action: string;
-}
-
export interface PostNewAgentActionRequest {
body: {
action: NewAgentAction;
@@ -185,24 +131,6 @@ export type PostBulkAgentReassignResponse = Record<
}
>;
-export interface GetOneAgentEventsRequest {
- params: {
- agentId: string;
- };
- query: {
- page: number;
- perPage: number;
- kuery?: string;
- };
-}
-
-export interface GetOneAgentEventsResponse {
- list: AgentEvent[];
- total: number;
- page: number;
- perPage: number;
-}
-
export interface DeleteAgentRequest {
params: {
agentId: string;
diff --git a/x-pack/plugins/fleet/public/applications/fleet/constants/index.ts b/x-pack/plugins/fleet/public/applications/fleet/constants/index.ts
index 539e7d38f4015..bbf14dcae45fc 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/constants/index.ts
+++ b/x-pack/plugins/fleet/public/applications/fleet/constants/index.ts
@@ -11,7 +11,6 @@ export {
AGENT_API_ROUTES,
SO_SEARCH_LIMIT,
AGENT_POLICY_SAVED_OBJECT_TYPE,
- AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
PACKAGE_POLICY_SAVED_OBJECT_TYPE,
diff --git a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/agents.ts b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/agents.ts
index 90ca762173a80..0fbe59f3f48ee 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/agents.ts
+++ b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_request/agents.ts
@@ -9,8 +9,6 @@ import { agentRouteService } from '../../services';
import type {
GetOneAgentResponse,
- GetOneAgentEventsResponse,
- GetOneAgentEventsRequest,
PostAgentUnenrollRequest,
PostBulkAgentUnenrollRequest,
PostBulkAgentUnenrollResponse,
@@ -44,19 +42,6 @@ export function useGetOneAgent(agentId: string, options?: RequestOptions) {
});
}
-export function useGetOneAgentEvents(
- agentId: string,
- query: GetOneAgentEventsRequest['query'],
- options?: RequestOptions
-) {
- return useRequest({
- path: agentRouteService.getEventsPath(agentId),
- method: 'get',
- query,
- ...options,
- });
-}
-
export function useGetAgents(query: GetAgentsRequest['query'], options?: RequestOptions) {
return useRequest({
method: 'get',
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx
index eb693775a65c9..f597d2c6758a8 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx
@@ -82,9 +82,6 @@ export const AgentHealth: React.FunctionComponent = ({ agent }) => {
lastCheckIn: ,
}}
/>
- {agent.current_error_events.map((event, idx) => (
- {event.message}
- ))}
>
) : (
,
- TypeOf
-> = async (context, request, response) => {
- const soClient = context.core.savedObjects.client;
- try {
- const { page, perPage, kuery } = request.query;
- const { items, total } = await AgentService.getAgentEvents(soClient, request.params.agentId, {
- page,
- perPage,
- kuery,
- });
-
- const body: GetOneAgentEventsResponse = {
- list: items,
- total,
- page,
- perPage,
- };
-
- return response.ok({
- body,
- });
- } catch (error) {
- if (error.isBoom && error.output.statusCode === 404) {
- return response.notFound({
- body: { message: `Agent ${request.params.agentId} not found` },
- });
- }
- return defaultIngestErrorHandler({ error, response });
- }
-};
-
export const deleteAgentHandler: RequestHandler<
TypeOf
> = async (context, request, response) => {
diff --git a/x-pack/plugins/fleet/server/routes/agent/index.ts b/x-pack/plugins/fleet/server/routes/agent/index.ts
index 9b33443d0dca3..db5b01b319e00 100644
--- a/x-pack/plugins/fleet/server/routes/agent/index.ts
+++ b/x-pack/plugins/fleet/server/routes/agent/index.ts
@@ -11,7 +11,6 @@ import { PLUGIN_ID, AGENT_API_ROUTES } from '../../constants';
import {
GetAgentsRequestSchema,
GetOneAgentRequestSchema,
- GetOneAgentEventsRequestSchema,
UpdateAgentRequestSchema,
DeleteAgentRequestSchema,
PostAgentUnenrollRequestSchema,
@@ -31,7 +30,6 @@ import {
getAgentHandler,
updateAgentHandler,
deleteAgentHandler,
- getAgentEventsHandler,
getAgentStatusForAgentPolicyHandler,
putAgentsReassignHandler,
postBulkAgentsReassignHandler,
@@ -109,16 +107,6 @@ export const registerAPIRoutes = (router: IRouter, config: FleetConfigType) => {
putAgentsReassignHandler
);
- // Get agent events
- router.get(
- {
- path: AGENT_API_ROUTES.EVENTS_PATTERN,
- validate: GetOneAgentEventsRequestSchema,
- options: { tags: [`access:${PLUGIN_ID}-read`] },
- },
- getAgentEventsHandler
- );
-
// Get agent status for policy
router.get(
{
diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts
index bc9b2d9f9dc86..e2e33f1ee6c26 100644
--- a/x-pack/plugins/fleet/server/saved_objects/index.ts
+++ b/x-pack/plugins/fleet/server/saved_objects/index.ts
@@ -15,7 +15,6 @@ import {
PACKAGES_SAVED_OBJECT_TYPE,
ASSETS_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
- AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_ACTION_SAVED_OBJECT_TYPE,
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
GLOBAL_SETTINGS_SAVED_OBJECT_TYPE,
@@ -24,7 +23,6 @@ import {
import {
migrateAgentActionToV7100,
- migrateAgentEventToV7100,
migrateAgentPolicyToV7100,
migrateAgentToV7100,
migrateEnrollmentApiKeysToV7100,
@@ -133,33 +131,6 @@ const getSavedObjectTypes = (
'7.10.0': migrateAgentActionToV7100(encryptedSavedObjects),
},
},
- // TODO: Remove this saved object type. Core will drop any saved objects of
- // this type during migrations. See https://github.com/elastic/kibana/issues/91869
- [AGENT_EVENT_SAVED_OBJECT_TYPE]: {
- name: AGENT_EVENT_SAVED_OBJECT_TYPE,
- hidden: false,
- namespaceType: 'agnostic',
- management: {
- importableAndExportable: false,
- },
- mappings: {
- properties: {
- type: { type: 'keyword' },
- subtype: { type: 'keyword' },
- agent_id: { type: 'keyword' },
- action_id: { type: 'keyword' },
- policy_id: { type: 'keyword' },
- stream_id: { type: 'keyword' },
- timestamp: { type: 'date' },
- message: { type: 'text' },
- payload: { type: 'text' },
- data: { type: 'text' },
- },
- },
- migrations: {
- '7.10.0': migrateAgentEventToV7100,
- },
- },
[AGENT_POLICY_SAVED_OBJECT_TYPE]: {
name: AGENT_POLICY_SAVED_OBJECT_TYPE,
hidden: false,
diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts
index f3f6050a8cde2..50780f168c459 100644
--- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts
+++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts
@@ -10,7 +10,6 @@ import type { SavedObjectMigrationFn, SavedObjectUnsanitizedDoc } from 'kibana/s
import type { EncryptedSavedObjectsPluginSetup } from '../../../../encrypted_saved_objects/server';
import type {
Agent,
- AgentEvent,
AgentPolicy,
PackagePolicy,
EnrollmentAPIKey,
@@ -35,18 +34,6 @@ export const migrateAgentToV7100: SavedObjectMigrationFn<
return agentDoc;
};
-export const migrateAgentEventToV7100: SavedObjectMigrationFn<
- Exclude & {
- config_id?: string;
- },
- AgentEvent
-> = (agentEventDoc) => {
- agentEventDoc.attributes.policy_id = agentEventDoc.attributes.config_id;
- delete agentEventDoc.attributes.config_id;
-
- return agentEventDoc;
-};
-
export const migrateAgentPolicyToV7100: SavedObjectMigrationFn<
Exclude & {
package_configs: string[] | PackagePolicy[];
diff --git a/x-pack/plugins/fleet/server/services/agents/events.ts b/x-pack/plugins/fleet/server/services/agents/events.ts
deleted file mode 100644
index e61ce04f1b640..0000000000000
--- a/x-pack/plugins/fleet/server/services/agents/events.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 { SavedObjectsClientContract } from 'src/core/server';
-
-import { AGENT_EVENT_SAVED_OBJECT_TYPE } from '../../constants';
-import type { AgentEventSOAttributes, AgentEvent } from '../../types';
-import { normalizeKuery } from '../saved_object';
-
-export async function getAgentEvents(
- soClient: SavedObjectsClientContract,
- agentId: string,
- options: {
- kuery?: string;
- page: number;
- perPage: number;
- }
-) {
- const { page, perPage, kuery } = options;
-
- // eslint-disable-next-line @typescript-eslint/naming-convention
- const { total, saved_objects } = await soClient.find({
- type: AGENT_EVENT_SAVED_OBJECT_TYPE,
- filter:
- kuery && kuery !== '' ? normalizeKuery(AGENT_EVENT_SAVED_OBJECT_TYPE, kuery) : undefined,
- perPage,
- page,
- sortField: 'timestamp',
- sortOrder: 'desc',
- defaultSearchOperator: 'AND',
- search: agentId,
- searchFields: ['agent_id'],
- });
-
- const items: AgentEvent[] = saved_objects.map((so) => {
- return {
- id: so.id,
- ...so.attributes,
- payload: so.attributes.payload ? JSON.parse(so.attributes.payload) : undefined,
- };
- });
-
- return { items, total };
-}
diff --git a/x-pack/plugins/fleet/server/services/agents/helpers.ts b/x-pack/plugins/fleet/server/services/agents/helpers.ts
index c003d3d546e83..c4273a57ddffd 100644
--- a/x-pack/plugins/fleet/server/services/agents/helpers.ts
+++ b/x-pack/plugins/fleet/server/services/agents/helpers.ts
@@ -21,7 +21,6 @@ export function searchHitToAgent(hit: FleetServerAgentESResponse): Agent {
id: hit._id,
...hit._source,
policy_revision: hit._source?.policy_revision_idx,
- current_error_events: [],
access_api_key: undefined,
status: undefined,
packages: hit._source?.packages ?? [],
diff --git a/x-pack/plugins/fleet/server/services/agents/index.ts b/x-pack/plugins/fleet/server/services/agents/index.ts
index 66303514c4fe7..ede548c6fd60d 100644
--- a/x-pack/plugins/fleet/server/services/agents/index.ts
+++ b/x-pack/plugins/fleet/server/services/agents/index.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-export * from './events';
export * from './unenroll';
export * from './upgrade';
export * from './status';
diff --git a/x-pack/plugins/fleet/server/services/agents/saved_objects.ts b/x-pack/plugins/fleet/server/services/agents/saved_objects.ts
index 8438048f12a87..eec9c9c7c16ff 100644
--- a/x-pack/plugins/fleet/server/services/agents/saved_objects.ts
+++ b/x-pack/plugins/fleet/server/services/agents/saved_objects.ts
@@ -26,9 +26,6 @@ export function savedObjectToAgent(so: SavedObject): Agent {
return {
id: so.id,
...so.attributes,
- current_error_events: so.attributes.current_error_events
- ? JSON.parse(so.attributes.current_error_events)
- : [],
local_metadata: so.attributes.local_metadata,
user_provided_metadata: so.attributes.user_provided_metadata,
access_api_key: undefined,
diff --git a/x-pack/plugins/fleet/server/services/agents/status.ts b/x-pack/plugins/fleet/server/services/agents/status.ts
index 737b6874a8133..a0338aced65ff 100644
--- a/x-pack/plugins/fleet/server/services/agents/status.ts
+++ b/x-pack/plugins/fleet/server/services/agents/status.ts
@@ -8,7 +8,7 @@
import type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server';
import pMap from 'p-map';
-import { AGENT_EVENT_SAVED_OBJECT_TYPE, AGENT_SAVED_OBJECT_TYPE } from '../../constants';
+import { AGENT_SAVED_OBJECT_TYPE } from '../../constants';
import type { AgentStatus } from '../../types';
import { AgentStatusKueryHelper } from '../../../common/services';
import { esKuery } from '../../../../../../src/plugins/data/server';
@@ -84,7 +84,6 @@ export async function getAgentStatusForAgentPolicy(
);
return {
- events: await getEventsCount(soClient, agentPolicyId),
total: allActive.total,
inactive: all.total - allActive.total,
online: online.total,
@@ -92,20 +91,7 @@ export async function getAgentStatusForAgentPolicy(
offline: offline.total,
updating: updating.total,
other: all.total - online.total - error.total - offline.total,
+ /* @deprecated Agent events do not exists anymore */
+ events: 0,
};
}
-
-async function getEventsCount(soClient: SavedObjectsClientContract, agentPolicyId?: string) {
- const { total } = await soClient.find({
- type: AGENT_EVENT_SAVED_OBJECT_TYPE,
- searchFields: ['policy_id'],
- search: agentPolicyId,
- perPage: 0,
- page: 1,
- sortField: 'timestamp',
- sortOrder: 'desc',
- defaultSearchOperator: 'AND',
- });
-
- return total;
-}
diff --git a/x-pack/plugins/fleet/server/types/index.tsx b/x-pack/plugins/fleet/server/types/index.tsx
index 87808e03fe70b..886b4a26b833b 100644
--- a/x-pack/plugins/fleet/server/types/index.tsx
+++ b/x-pack/plugins/fleet/server/types/index.tsx
@@ -12,9 +12,6 @@ export {
AgentSOAttributes,
AgentStatus,
AgentType,
- NewAgentEvent,
- AgentEvent,
- AgentEventSOAttributes,
AgentAction,
AgentPolicyAction,
AgentPolicyActionV7_9,
diff --git a/x-pack/plugins/fleet/server/types/models/agent.ts b/x-pack/plugins/fleet/server/types/models/agent.ts
index 192bb83a88718..aef0dfb8b2f83 100644
--- a/x-pack/plugins/fleet/server/types/models/agent.ts
+++ b/x-pack/plugins/fleet/server/types/models/agent.ts
@@ -15,55 +15,6 @@ export const AgentTypeSchema = schema.oneOf([
schema.literal(AGENT_TYPE_TEMPORARY),
]);
-const AgentEventBase = {
- type: schema.oneOf([
- schema.literal('STATE'),
- schema.literal('ERROR'),
- schema.literal('ACTION_RESULT'),
- schema.literal('ACTION'),
- ]),
- subtype: schema.oneOf([
- // State
- schema.oneOf([
- schema.literal('RUNNING'),
- schema.literal('STARTING'),
- schema.literal('IN_PROGRESS'),
- schema.literal('CONFIG'),
- schema.literal('FAILED'),
- schema.literal('STOPPING'),
- schema.literal('STOPPED'),
- schema.literal('DEGRADED'),
- schema.literal('UPDATING'),
- ]),
- // Action results
- schema.literal('DATA_DUMP'),
- // Actions
- schema.literal('ACKNOWLEDGED'),
- schema.literal('UNKNOWN'),
- ]),
- timestamp: schema.string(),
- message: schema.string(),
- payload: schema.maybe(schema.any()),
- agent_id: schema.string(),
- action_id: schema.maybe(schema.string()),
- policy_id: schema.maybe(schema.string()),
- stream_id: schema.maybe(schema.string()),
-};
-
-export const AckEventSchema = schema.object({
- ...AgentEventBase,
- ...{ action_id: schema.string() },
-});
-
-export const NewAgentEventSchema = schema.object({
- ...AgentEventBase,
-});
-
-export const AgentEventSchema = schema.object({
- ...AgentEventBase,
- id: schema.string(),
-});
-
export const NewAgentActionSchema = schema.oneOf([
schema.object({
type: schema.oneOf([
diff --git a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
index a58849ee4ab4b..3f66c8159562a 100644
--- a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
+++ b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
@@ -25,138 +25,6 @@ export const GetOneAgentRequestSchema = {
}),
};
-export const PostAgentCheckinRequestParamsJSONSchema = {
- type: 'object',
- properties: {
- agentId: { type: 'string' },
- },
- required: ['agentId'],
-};
-
-export const PostAgentCheckinRequestBodyJSONSchema = {
- type: 'object',
- properties: {
- status: { type: 'string', enum: ['online', 'error', 'degraded'] },
- local_metadata: {
- additionalProperties: {
- anyOf: [{ type: 'string' }, { type: 'number' }, { type: 'object' }],
- },
- },
- events: {
- type: 'array',
- items: {
- type: 'object',
- properties: {
- type: { type: 'string', enum: ['STATE', 'ERROR', 'ACTION_RESULT', 'ACTION'] },
- subtype: {
- type: 'string',
- enum: [
- 'RUNNING',
- 'STARTING',
- 'IN_PROGRESS',
- 'CONFIG',
- 'FAILED',
- 'STOPPING',
- 'STOPPED',
- 'DEGRADED',
- 'DATA_DUMP',
- 'ACKNOWLEDGED',
- 'UPDATING',
- 'UNKNOWN',
- ],
- },
- timestamp: { type: 'string' },
- message: { type: 'string' },
- payload: { type: 'object', additionalProperties: true },
- agent_id: { type: 'string' },
- action_id: { type: 'string' },
- policy_id: { type: 'string' },
- stream_id: { type: 'string' },
- },
- required: ['type', 'subtype', 'timestamp', 'message', 'agent_id'],
- additionalProperties: false,
- },
- },
- },
- additionalProperties: false,
-};
-
-export const PostAgentEnrollRequestBodyJSONSchema = {
- type: 'object',
- properties: {
- type: { type: 'string', enum: ['EPHEMERAL', 'PERMANENT', 'TEMPORARY'] },
- // TODO deprecated should be removed in 8.0.0
- shared_id: { type: 'string' },
- metadata: {
- type: 'object',
- properties: {
- local: {
- type: 'object',
- additionalProperties: true,
- },
- user_provided: {
- type: 'object',
- additionalProperties: true,
- },
- },
- additionalProperties: false,
- required: ['local', 'user_provided'],
- },
- },
- additionalProperties: false,
- required: ['type', 'metadata'],
-};
-
-export const PostAgentAcksRequestParamsJSONSchema = {
- type: 'object',
- properties: {
- agentId: { type: 'string' },
- },
- required: ['agentId'],
-};
-
-export const PostAgentAcksRequestBodyJSONSchema = {
- type: 'object',
- properties: {
- events: {
- type: 'array',
- item: {
- type: 'object',
- properties: {
- type: { type: 'string', enum: ['STATE', 'ERROR', 'ACTION_RESULT', 'ACTION'] },
- subtype: {
- type: 'string',
- enum: [
- 'RUNNING',
- 'STARTING',
- 'IN_PROGRESS',
- 'CONFIG',
- 'FAILED',
- 'STOPPING',
- 'STOPPED',
- 'DEGRADED',
- 'DATA_DUMP',
- 'ACKNOWLEDGED',
- 'UNKNOWN',
- ],
- },
- timestamp: { type: 'string' },
- message: { type: 'string' },
- payload: { type: 'object', additionalProperties: true },
- agent_id: { type: 'string' },
- action_id: { type: 'string' },
- policy_id: { type: 'string' },
- stream_id: { type: 'string' },
- },
- required: ['type', 'subtype', 'timestamp', 'message', 'agent_id', 'action_id'],
- additionalProperties: false,
- },
- },
- },
- additionalProperties: false,
- required: ['events'],
-};
-
export const PostNewAgentActionRequestSchema = {
body: schema.object({
action: NewAgentActionSchema,
@@ -222,17 +90,6 @@ export const PostBulkAgentReassignRequestSchema = {
}),
};
-export const GetOneAgentEventsRequestSchema = {
- params: schema.object({
- agentId: schema.string(),
- }),
- query: schema.object({
- page: schema.number({ defaultValue: 1 }),
- perPage: schema.number({ defaultValue: 20 }),
- kuery: schema.maybe(schema.string()),
- }),
-};
-
export const DeleteAgentRequestSchema = {
params: schema.object({
agentId: schema.string(),
diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts
index b35504fc88659..fd26a2d95c9b4 100644
--- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts
@@ -18,7 +18,6 @@ import {
CreatePackagePolicyRequest,
CreatePackagePolicyResponse,
GetPackagesResponse,
- PostAgentEnrollRequest,
AGENT_API_ROUTES,
AGENT_POLICY_API_ROUTES,
EPM_API_ROUTES,
@@ -26,11 +25,7 @@ import {
ENROLLMENT_API_KEY_ROUTES,
GetEnrollmentAPIKeysResponse,
GetOneEnrollmentAPIKeyResponse,
- PostAgentEnrollResponse,
- PostAgentCheckinRequest,
- PostAgentCheckinResponse,
- PostAgentAcksResponse,
- PostAgentAcksRequest,
+ Agent,
} from '../../../fleet/common';
import { policyFactory as policyConfigFactory } from './models/policy_config';
import { HostMetadata } from './types';
@@ -114,7 +109,7 @@ async function indexHostDocs({
const timestamp = new Date().getTime();
let hostMetadata: HostMetadata;
let wasAgentEnrolled = false;
- let enrolledAgent: undefined | PostAgentEnrollResponse['item'];
+ let enrolledAgent: undefined | Agent;
for (let j = 0; j < numDocs; j++) {
generator.updateHostData();
@@ -304,7 +299,7 @@ const fleetEnrollAgentForHost = async (
kbnClient: KbnClientWithApiKeySupport,
endpointHost: HostMetadata,
agentPolicyId: string
-): Promise => {
+): Promise => {
// Get Enrollement key for host's applied policy
const enrollmentApiKey = await kbnClient
.request({
@@ -360,7 +355,7 @@ const fleetEnrollAgentForHost = async (
};
// Enroll an agent for the Host
- const body: PostAgentEnrollRequest['body'] = {
+ const body = {
type: 'PERMANENT',
metadata: {
local: {
@@ -401,7 +396,7 @@ const fleetEnrollAgentForHost = async (
});
if (res) {
- const enrollObj: PostAgentEnrollResponse = await res.json();
+ const enrollObj = await res.json();
if (!res.ok) {
// eslint-disable-next-line no-console
console.error('unable to enroll agent', enrollObj);
@@ -409,7 +404,7 @@ const fleetEnrollAgentForHost = async (
}
// ------------------------------------------------
// now check the agent in so that it can complete enrollment
- const checkinBody: PostAgentCheckinRequest['body'] = {
+ const checkinBody = {
events: [
{
type: 'STATE',
@@ -447,7 +442,7 @@ const fleetEnrollAgentForHost = async (
return;
}
- const checkinObj: PostAgentCheckinResponse = await checkinRes.json();
+ const checkinObj = await checkinRes.json();
if (!checkinRes.ok) {
// eslint-disable-next-line no-console
console.error(
@@ -459,9 +454,9 @@ const fleetEnrollAgentForHost = async (
// ------------------------------------------------
// If we have an action to ack(), then do it now
if (checkinObj.actions.length) {
- const ackActionBody: PostAgentAcksRequest['body'] = {
+ const ackActionBody = {
// @ts-ignore
- events: checkinObj.actions.map((action) => {
+ events: checkinObj.actions.map((action) => {
return {
action_id: action.id,
type: 'ACTION_RESULT',
@@ -486,7 +481,7 @@ const fleetEnrollAgentForHost = async (
}
);
- const ackActionObj: PostAgentAcksResponse = await ackActionResp.json();
+ const ackActionObj = await ackActionResp.json();
if (!ackActionResp.ok) {
// eslint-disable-next-line no-console
console.error(
diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts
index caa4549fbf31d..e0cc62e294406 100644
--- a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts
+++ b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts
@@ -6,10 +6,12 @@
*/
import { SavedObjectsFindResponse } from 'src/core/server';
-import { AgentEventSOAttributes } from './../../../../fleet/common/types/models/agent';
-import { AGENT_EVENT_SAVED_OBJECT_TYPE } from '../../../../fleet/common/constants/agent';
+
import { Agent } from '../../../../fleet/common';
-import { FLEET_ENDPOINT_PACKAGE_CONSTANT } from './fleet_saved_objects';
+import {
+ FLEET_ENDPOINT_PACKAGE_CONSTANT,
+ AGENT_EVENT_SAVED_OBJECT_TYPE,
+} from './fleet_saved_objects';
const testAgentId = 'testAgentId';
const testAgentPolicyId = 'testAgentPolicyId';
@@ -45,7 +47,6 @@ export const mockFleetObjectsResponse = (
type: 'PERMANENT',
user_provided_metadata: {},
enrolled_at: lastCheckIn,
- current_error_events: [],
local_metadata: {
elastic: {
agent: {
@@ -74,7 +75,6 @@ export const mockFleetObjectsResponse = (
type: 'PERMANENT',
user_provided_metadata: {},
enrolled_at: lastCheckIn,
- current_error_events: [],
local_metadata: {
elastic: {
agent: {
@@ -215,7 +215,7 @@ export const mockFleetEventsObjectsResponse = (
updatedDate = new Date().toISOString(),
policyStatus: 'success' | 'failure' = running ? 'success' : 'failure',
policyMode: 'prevent' | 'detect' | 'off' = 'prevent'
-): SavedObjectsFindResponse => {
+): SavedObjectsFindResponse => {
return {
page: 1,
per_page: 20,
diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts
index 1541cb128f60c..11e16c2f9e781 100644
--- a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts
+++ b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts
@@ -14,7 +14,6 @@ import {
MockOSVersion,
} from './endpoint.mocks';
import { SavedObjectsClientContract, SavedObjectsFindResponse } from 'src/core/server';
-import { AgentEventSOAttributes } from '../../../../fleet/common/types/models/agent';
import { Agent } from '../../../../fleet/common';
import * as endpointTelemetry from './index';
import * as fleetSavedObjects from './fleet_saved_objects';
@@ -28,9 +27,7 @@ describe('test security solution endpoint telemetry', () => {
let getEndpointIntegratedFleetMetadataSpy: jest.SpyInstance<
Promise<{ agents: Agent[]; total: number; page: number; perPage: number } | undefined>
>;
- let getLatestFleetEndpointEventSpy: jest.SpyInstance<
- Promise>
- >;
+ let getLatestFleetEndpointEventSpy: jest.SpyInstance>;
beforeAll(() => {
getLatestFleetEndpointEventSpy = jest.spyOn(fleetSavedObjects, 'getLatestFleetEndpointEvent');
diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts b/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts
index 7e3620ec0ae04..f5b4c6c0fdba9 100644
--- a/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts
+++ b/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts
@@ -5,14 +5,18 @@
* 2.0.
*/
-import { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server';
+import {
+ ElasticsearchClient,
+ SavedObjectsClientContract,
+ SavedObjectsFindResponse,
+} from 'src/core/server';
import { AgentService } from '../../../../fleet/server';
-import { AgentEventSOAttributes } from './../../../../fleet/common/types/models/agent';
-import { AGENT_EVENT_SAVED_OBJECT_TYPE } from './../../../../fleet/common/constants/agent';
import { defaultPackages as FleetDefaultPackages } from '../../../../fleet/common';
export const FLEET_ENDPOINT_PACKAGE_CONSTANT = FleetDefaultPackages.Endpoint;
+export const AGENT_EVENT_SAVED_OBJECT_TYPE = 'donotexistsanymore-since-7.13';
+
export const getEndpointIntegratedFleetMetadata = async (
agentService: AgentService | undefined,
esClient: ElasticsearchClient
@@ -36,15 +40,6 @@ export const getEndpointIntegratedFleetMetadata = async (
export const getLatestFleetEndpointEvent = async (
savedObjectsClient: SavedObjectsClientContract,
agentId: string
-) =>
- savedObjectsClient.find({
- // Get the most recent endpoint event.
- type: AGENT_EVENT_SAVED_OBJECT_TYPE,
- fields: ['agent_id', 'subtype', 'payload'],
- filter: `${AGENT_EVENT_SAVED_OBJECT_TYPE}.attributes.message: "${FLEET_ENDPOINT_PACKAGE_CONSTANT}"`,
- perPage: 1,
- sortField: 'timestamp',
- sortOrder: 'desc',
- search: agentId,
- searchFields: ['agent_id'],
- });
+): Promise =>
+ // Agent events saved object do not exists in Fleet anymore
+ ({ total: 0, saved_objects: [], page: 0, per_page: 0 });
diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts
index 94ff168ffffc8..ed8db14e46605 100644
--- a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts
+++ b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts
@@ -8,7 +8,7 @@
import { cloneDeep } from 'lodash';
import { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server';
import { SavedObject } from './../../../../../../src/core/types/saved_objects';
-import { Agent, NewAgentEvent } from './../../../../fleet/common/types/models/agent';
+import { Agent } from './../../../../fleet/common/types/models/agent';
import { AgentMetadata } from '../../../../fleet/common/types/models/agent';
import {
getEndpointIntegratedFleetMetadata,
@@ -112,7 +112,8 @@ export const updateEndpointOSTelemetry = (
* the same time span.
*/
export const updateEndpointDailyActiveCount = (
- latestEndpointEvent: SavedObject, // TODO: This information will be lost in 7.13, need to find an alternative route.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ latestEndpointEvent: SavedObject, // TODO: This information will be lost in 7.13, need to find an alternative route.
lastAgentCheckin: Agent['last_checkin'],
currentCount: number
) => {
@@ -130,7 +131,8 @@ export const updateEndpointDailyActiveCount = (
* to populate the success of it's application. The policy is provided in the agent health checks.
*/
export const updateEndpointPolicyTelemetry = (
- latestEndpointEvent: SavedObject,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ latestEndpointEvent: SavedObject,
policiesTracker: PoliciesTelemetry
): PoliciesTelemetry => {
const policyHostTypeToPolicyType = {
From ae2e0766f9bc109a9200c75d055e095f7324cc4b Mon Sep 17 00:00:00 2001
From: Yara Tercero
Date: Mon, 3 May 2021 13:34:16 -0700
Subject: [PATCH 24/81] [Security Solution][Timeline] - update flakey timeline
cypress tests (#99097)
###Summary
Removes some anti-patterns I introduced in my last PR and makes use of Cypress' chainable pattern that will hopefully help with the flakiness.
---
.../integration/timelines/notes_tab.spec.ts | 22 ++++++++----
.../timelines/open_timeline.spec.ts | 7 ++--
.../cypress/tasks/timeline.ts | 35 ++++++++++++-------
3 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/notes_tab.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/notes_tab.spec.ts
index 72f82aa54b7d5..fdc003039afbc 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timelines/notes_tab.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timelines/notes_tab.spec.ts
@@ -26,12 +26,22 @@ describe('Timeline notes tab', () => {
loginAndWaitForPageWithoutDateRange(TIMELINES_URL);
waitForTimelinesPanelToBeLoaded();
- createTimeline(timeline).then((response) => {
- timelineId = response.body.data.persistTimeline.timeline.savedObjectId;
- waitForTimelinesPanelToBeLoaded();
- openTimelineById(timelineId!);
- addNotesToTimeline(timeline.notes);
- });
+ createTimeline(timeline)
+ .then((response) => {
+ if (response.body.data.persistTimeline.timeline.savedObjectId == null) {
+ cy.log('"createTimeline" did not return expected response');
+ }
+ timelineId = response.body.data.persistTimeline.timeline.savedObjectId;
+ waitForTimelinesPanelToBeLoaded();
+ })
+ .then(() => {
+ // TODO: It would be great to add response validation to avoid such things like
+ // the bang below and to more easily understand where failures are coming from -
+ // client vs server side
+ openTimelineById(timelineId!).then(() => {
+ addNotesToTimeline(timeline.notes);
+ });
+ });
});
after(() => {
diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/open_timeline.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/open_timeline.spec.ts
index 93c8d7265478e..7bf0409d91039 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timelines/open_timeline.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timelines/open_timeline.spec.ts
@@ -48,9 +48,10 @@ describe('Open timeline', () => {
addNoteToTimeline(note, timelineId!).should((response) => {
expect(response.status).to.equal(200);
waitForTimelinesPanelToBeLoaded();
- openTimelineById(timelineId!);
- pinFirstEvent();
- markAsFavorite();
+ openTimelineById(timelineId!).then(() => {
+ pinFirstEvent();
+ markAsFavorite();
+ });
});
});
});
diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts
index 1474098b76281..a7842a7d98e83 100644
--- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts
+++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts
@@ -89,13 +89,14 @@ export const addNameAndDescriptionToTimeline = (timeline: Timeline) => {
cy.get(TIMELINE_TITLE_INPUT).should('not.exist');
};
-export const goToNotesTab = () => {
+export const goToNotesTab = (): Cypress.Chainable> => {
cy.root()
.pipe(($el) => {
$el.find(NOTES_TAB_BUTTON).trigger('click');
return $el.find(NOTES_TEXT_AREA);
})
.should('be.visible');
+ return cy.root().find(NOTES_TAB_BUTTON);
};
export const getNotePreviewByNoteId = (noteId: string) => {
@@ -112,15 +113,16 @@ export const goToQueryTab = () => {
};
export const addNotesToTimeline = (notes: string) => {
- cy.wait(150);
- goToNotesTab();
- cy.get(NOTES_TEXT_AREA).type(notes);
- cy.root()
- .pipe(($el) => {
- $el.find(ADD_NOTE_BUTTON).trigger('click');
- return $el.find(NOTES_TAB_BUTTON).find('.euiBadge');
- })
- .should('have.text', '1');
+ goToNotesTab().then(() => {
+ cy.get(NOTES_TEXT_AREA).type(notes);
+ cy.root()
+ .pipe(($el) => {
+ $el.find(ADD_NOTE_BUTTON).trigger('click');
+ return $el.find(NOTES_TAB_BUTTON).find('.euiBadge');
+ })
+ .should('have.text', '1');
+ });
+
goToQueryTab();
goToNotesTab();
};
@@ -136,7 +138,7 @@ export const addFilter = (filter: TimelineFilter) => {
cy.get(SAVE_FILTER_BTN).click();
};
-export const addDataProvider = (filter: TimelineFilter) => {
+export const addDataProvider = (filter: TimelineFilter): Cypress.Chainable> => {
cy.get(TIMELINE_ADD_FIELD_BUTTON).click();
cy.get(TIMELINE_DATA_PROVIDER_FIELD).type(`${filter.field}{downarrow}{enter}`);
cy.get(TIMELINE_DATA_PROVIDER_OPERATOR).type(filter.operator);
@@ -231,13 +233,22 @@ export const openTimelineTemplateFromSettings = (id: string) => {
cy.get(TIMELINE_TITLE_BY_ID(id)).click({ force: true });
};
-export const openTimelineById = (timelineId: string) => {
+export const openTimelineById = (timelineId: string): Cypress.Chainable> => {
+ // Why are we checking for null if it is typed to 'string'? We don't currently validate the timeline response
+ // so technically we cannot guarantee that we will have the id. Changing the type to 'string | null' results in
+ // a lot of other changes being needed that would be best as part of a cleanup. Added a log, to give a dev a clue
+ // as to whether it's failing client or server side.
+ if (timelineId == null) {
+ cy.log('"timelineId" is null or undefined');
+ }
+
cy.root()
.pipe(($el) => {
$el.find(TIMELINE_TITLE_BY_ID(timelineId)).trigger('click');
return $el.find(QUERY_TAB_BUTTON).find('.euiBadge');
})
.should('be.visible');
+ return cy.root().find(TIMELINE_TITLE_BY_ID(timelineId));
};
export const pinFirstEvent = () => {
From 292b6d2638640db84c308916e7fba34e3a716d07 Mon Sep 17 00:00:00 2001
From: Constance
Date: Mon, 3 May 2021 14:29:36 -0700
Subject: [PATCH 25/81] [Enterprise Search] Refactor shared SchemaAddFieldModal
component (#99096)
* Move SchemaAddFieldModal to its own folder
+ misc test cleanup - remove unnecessary jest.spyOn in individual tests, it's already in the beforeEach
* i18n fixes
- Move constants to subfolder
- Fix various i18n IDs/var names - modal titles is not a fieldNote title
- Fix an i18n string that should be a FormattedMessage (could have grammar issues otherwise)
- Add missing i18n strings - labels (shared, AS will also use these as column headers) & placeholder
- Import order
* Move formatFieldName util to its own file
- simplify leading/trailing trimming regex
- add unit tests - primarily for documenting regexes & providing examples
* Refactor modal form submission
- See https://elastic.github.io/eui/#/layout/modal#forms-in-a-modal for documentation - form should be submitted via ID & EuiModalFooter form={id}
* Misc props cleanup
- Move optional props to bottom of type list
- Remove unnecessary props (default EUI behavior)
- Data test subj cleanup
- Add missing `disabled` passed prop, add unit test for disableForm prop
---
.../schema/add_field_modal/constants.tsx | 44 +++++
.../index.test.tsx} | 31 ++--
.../shared/schema/add_field_modal/index.tsx | 141 ++++++++++++++++
.../schema/add_field_modal/utils.test.ts | 26 +++
.../shared/schema/add_field_modal/utils.ts | 13 ++
.../applications/shared/schema/constants.ts | 39 +----
.../applications/shared/schema/index.ts | 2 +-
.../shared/schema/schema_add_field_modal.tsx | 152 ------------------
.../translations/translations/ja-JP.json | 8 +-
.../translations/translations/zh-CN.json | 8 +-
10 files changed, 257 insertions(+), 207 deletions(-)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/constants.tsx
rename x-pack/plugins/enterprise_search/public/applications/shared/schema/{schema_add_field_modal.test.tsx => add_field_modal/index.test.tsx} (74%)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.test.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.ts
delete mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.tsx
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/constants.tsx
new file mode 100644
index 0000000000000..3cc43532eda73
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/constants.tsx
@@ -0,0 +1,44 @@
+/*
+ * 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 React from 'react';
+
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+
+export const FORM_ID = 'schemaAddFieldForm';
+
+export const ADD_FIELD_MODAL_TITLE = i18n.translate(
+ 'xpack.enterpriseSearch.schema.addFieldModal.title',
+ { defaultMessage: 'Add a new field' }
+);
+export const ADD_FIELD_MODAL_DESCRIPTION = i18n.translate(
+ 'xpack.enterpriseSearch.schema.addFieldModal.description',
+ { defaultMessage: 'Once added, a field cannot be removed from your schema.' }
+);
+export const ADD_FIELD_BUTTON = i18n.translate(
+ 'xpack.enterpriseSearch.schema.addFieldModal.addFieldButtonLabel',
+ { defaultMessage: 'Add field' }
+);
+
+export const FIELD_NAME_PLACEHOLDER = i18n.translate(
+ 'xpack.enterpriseSearch.schema.addFieldModal.fieldNamePlaceholder',
+ { defaultMessage: 'Enter a field name' }
+);
+export const FIELD_NAME_CORRECT_NOTE = i18n.translate(
+ 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.correct',
+ { defaultMessage: 'Field names can only contain lowercase letters, numbers, and underscores' }
+);
+export const FIELD_NAME_CORRECTED_NOTE = (correctedName: string) => (
+ {correctedName},
+ }}
+ />
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.test.tsx
similarity index 74%
rename from x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx
rename to x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.test.tsx
index 12bc61d723919..186560c694d24 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.test.tsx
@@ -9,12 +9,13 @@ import React from 'react';
import { shallow, mount } from 'enzyme';
-import { EuiFieldText, EuiModal } from '@elastic/eui';
+import { EuiForm, EuiFieldText, EuiModal } from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
-import { FIELD_NAME_CORRECTED_PREFIX } from './constants';
-import { SchemaType } from './types';
+import { SchemaFieldTypeSelect } from '../index';
+import { SchemaType } from '../types';
-import { SchemaFieldTypeSelect, SchemaAddFieldModal } from './';
+import { SchemaAddFieldModal } from './';
describe('SchemaAddFieldModal', () => {
const addNewField = jest.fn();
@@ -53,8 +54,15 @@ describe('SchemaAddFieldModal', () => {
expect(setState).toHaveBeenCalledWith(false);
});
+ it('passes disabled state', () => {
+ const wrapper = shallow();
+
+ expect(wrapper.find('[data-test-subj="SchemaAddFieldNameField"]').prop('disabled')).toBe(true);
+ expect(wrapper.find('[data-test-subj="SchemaSelect"]').prop('disabled')).toBe(true);
+ expect(wrapper.find('[data-test-subj="SchemaAddFieldButton"]').prop('disabled')).toBe(true);
+ });
+
it('handles input change - with non-formatted name', () => {
- jest.spyOn(React, 'useState').mockImplementationOnce(setStateMock);
const wrapper = shallow();
const input = wrapper.find(EuiFieldText);
input.simulate('change', { currentTarget: { value: 'foobar' } });
@@ -65,16 +73,14 @@ describe('SchemaAddFieldModal', () => {
});
it('handles input change - with formatted name', () => {
- jest.spyOn(React, 'useState').mockImplementationOnce(setStateMock);
const wrapper = shallow();
const input = wrapper.find(EuiFieldText);
input.simulate('change', { currentTarget: { value: 'foo-bar' } });
- expect(wrapper.find('[data-test-subj="SchemaAddFieldNameRow"]').prop('helpText')).toEqual(
-
- {FIELD_NAME_CORRECTED_PREFIX} foo_bar
-
- );
+ const helpText = wrapper
+ .find('[data-test-subj="SchemaAddFieldNameRow"]')
+ .prop('helpText') as React.ReactElement;
+ expect(helpText.type).toEqual(FormattedMessage);
});
it('handles field type select change', () => {
@@ -87,10 +93,9 @@ describe('SchemaAddFieldModal', () => {
});
it('handles form submission', () => {
- jest.spyOn(React, 'useState').mockImplementationOnce(setStateMock);
const wrapper = shallow();
const preventDefault = jest.fn();
- wrapper.find('form').simulate('submit', { preventDefault });
+ wrapper.find(EuiForm).simulate('submit', { preventDefault });
expect(addNewField).toHaveBeenCalled();
expect(setState).toHaveBeenCalled();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.tsx
new file mode 100644
index 0000000000000..902417d02665e
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/index.tsx
@@ -0,0 +1,141 @@
+/*
+ * 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 React, { ChangeEvent, FormEvent, useEffect, useState } from 'react';
+
+import {
+ EuiButton,
+ EuiButtonEmpty,
+ EuiFieldText,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiForm,
+ EuiFormRow,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiSpacer,
+} from '@elastic/eui';
+
+import { CANCEL_BUTTON_LABEL } from '../../constants';
+import { FIELD_NAME, FIELD_TYPE } from '../constants';
+import { SchemaFieldTypeSelect } from '../index';
+import { SchemaType } from '../types';
+
+import {
+ ADD_FIELD_MODAL_TITLE,
+ ADD_FIELD_MODAL_DESCRIPTION,
+ ADD_FIELD_BUTTON,
+ FORM_ID,
+ FIELD_NAME_PLACEHOLDER,
+ FIELD_NAME_CORRECT_NOTE,
+ FIELD_NAME_CORRECTED_NOTE,
+} from './constants';
+import { formatFieldName } from './utils';
+
+interface Props {
+ addNewField(fieldName: string, newFieldType: string): void;
+ closeAddFieldModal(): void;
+ disableForm?: boolean;
+ addFieldFormErrors?: string[] | null;
+}
+
+export const SchemaAddFieldModal: React.FC = ({
+ addNewField,
+ addFieldFormErrors,
+ closeAddFieldModal,
+ disableForm,
+}) => {
+ const [loading, setLoading] = useState(false);
+ const [newFieldType, updateNewFieldType] = useState(SchemaType.Text);
+ const [formattedFieldName, setFormattedFieldName] = useState('');
+ const [rawFieldName, setRawFieldName] = useState('');
+
+ useEffect(() => {
+ if (addFieldFormErrors) setLoading(false);
+ }, [addFieldFormErrors]);
+
+ const handleChange = ({ currentTarget: { value } }: ChangeEvent) => {
+ setRawFieldName(value);
+ setFormattedFieldName(formatFieldName(value));
+ };
+
+ const submitForm = (e: FormEvent) => {
+ e.preventDefault();
+ addNewField(formattedFieldName, newFieldType);
+ setLoading(true);
+ };
+
+ const fieldNameNote =
+ rawFieldName !== formattedFieldName
+ ? FIELD_NAME_CORRECTED_NOTE(formattedFieldName)
+ : FIELD_NAME_CORRECT_NOTE;
+
+ return (
+
+
+ {ADD_FIELD_MODAL_TITLE}
+
+
+ {ADD_FIELD_MODAL_DESCRIPTION}
+
+
+
+
+
+
+
+
+
+
+ updateNewFieldType(type)}
+ disabled={disableForm}
+ data-test-subj="SchemaSelect"
+ />
+
+
+
+
+
+
+ {CANCEL_BUTTON_LABEL}
+
+ {ADD_FIELD_BUTTON}
+
+
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.test.ts
new file mode 100644
index 0000000000000..917478cd0aa03
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.test.ts
@@ -0,0 +1,26 @@
+/*
+ * 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 { formatFieldName } from './utils';
+
+describe('formatFieldName', () => {
+ it('removes leading and trailing spaces', () => {
+ expect(formatFieldName(' helloworld ')).toEqual('helloworld');
+ });
+
+ it('converts all special characters to underscores', () => {
+ expect(formatFieldName('hello!#@$123---world')).toEqual('hello_123_world');
+ });
+
+ it('strips leading and trailing special characters/underscores', () => {
+ expect(formatFieldName('!!helloworld__')).toEqual('helloworld');
+ });
+
+ it('lowercases any caps', () => {
+ expect(formatFieldName('HELLO_WORLD')).toEqual('hello_world');
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.ts b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.ts
new file mode 100644
index 0000000000000..6242a337871b1
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/add_field_modal/utils.ts
@@ -0,0 +1,13 @@
+/*
+ * 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 formatFieldName = (rawName: string) =>
+ rawName
+ .trim()
+ .replace(/[^a-zA-Z0-9]+/g, '_')
+ .replace(/^(_+)|(_+)$/g, '')
+ .toLowerCase();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/constants.ts b/x-pack/plugins/enterprise_search/public/applications/shared/schema/constants.ts
index 3791626f54398..e85050aa22ef1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/constants.ts
@@ -7,40 +7,13 @@
import { i18n } from '@kbn/i18n';
-export const FIELD_NAME_CORRECT_NOTE = i18n.translate(
- 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.correct',
- {
- defaultMessage: 'Field names can only contain lowercase letters, numbers, and underscores',
- }
-);
-
-export const FIELD_NAME_CORRECTED_PREFIX = i18n.translate(
- 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected',
- {
- defaultMessage: 'The field will be named',
- }
-);
-
-export const FIELD_NAME_MODAL_TITLE = i18n.translate(
- 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.title',
- {
- defaultMessage: 'Add a New Field',
- }
-);
+export const FIELD_NAME = i18n.translate('xpack.enterpriseSearch.schema.fieldNameLabel', {
+ defaultMessage: 'Field name',
+});
-export const FIELD_NAME_MODAL_DESCRIPTION = i18n.translate(
- 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.description',
- {
- defaultMessage: 'Once added, a field cannot be removed from your schema.',
- }
-);
-
-export const FIELD_NAME_MODAL_ADD_FIELD = i18n.translate(
- 'xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.addField',
- {
- defaultMessage: 'Add field',
- }
-);
+export const FIELD_TYPE = i18n.translate('xpack.enterpriseSearch.schema.fieldTypeLabel', {
+ defaultMessage: 'Field type',
+});
export const ERROR_TABLE_ID_HEADER = i18n.translate(
'xpack.enterpriseSearch.schema.errorsTable.heading.id',
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
index b47d7ccabb57e..657ddef64b7ca 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/index.ts
@@ -5,6 +5,6 @@
* 2.0.
*/
-export { SchemaAddFieldModal } from './schema_add_field_modal';
+export { SchemaAddFieldModal } from './add_field_modal';
export { SchemaFieldTypeSelect } from './field_type_select';
export { SchemaErrorsCallout } from './errors_callout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.tsx
deleted file mode 100644
index e6f7bffc2d83f..0000000000000
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.tsx
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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 React, { ChangeEvent, FormEvent, useEffect, useState } from 'react';
-
-import {
- EuiButton,
- EuiButtonEmpty,
- EuiFieldText,
- EuiFlexGroup,
- EuiFlexItem,
- EuiForm,
- EuiFormRow,
- EuiModal,
- EuiModalBody,
- EuiModalFooter,
- EuiModalHeader,
- EuiModalHeaderTitle,
- EuiSpacer,
-} from '@elastic/eui';
-
-import { CANCEL_BUTTON_LABEL } from '../constants';
-
-import {
- FIELD_NAME_CORRECT_NOTE,
- FIELD_NAME_CORRECTED_PREFIX,
- FIELD_NAME_MODAL_TITLE,
- FIELD_NAME_MODAL_DESCRIPTION,
- FIELD_NAME_MODAL_ADD_FIELD,
-} from './constants';
-import { SchemaType } from './types';
-
-import { SchemaFieldTypeSelect } from './';
-
-interface ISchemaAddFieldModalProps {
- disableForm?: boolean;
- addFieldFormErrors?: string[] | null;
- addNewField(fieldName: string, newFieldType: string): void;
- closeAddFieldModal(): void;
-}
-
-export const SchemaAddFieldModal: React.FC = ({
- addNewField,
- addFieldFormErrors,
- closeAddFieldModal,
- disableForm,
-}) => {
- const [loading, setLoading] = useState(false);
- const [newFieldType, updateNewFieldType] = useState(SchemaType.Text);
- const [formattedFieldName, setFormattedFieldName] = useState('');
- const [rawFieldName, setRawFieldName] = useState('');
-
- useEffect(() => {
- if (addFieldFormErrors) setLoading(false);
- }, [addFieldFormErrors]);
-
- const handleChange = ({ currentTarget: { value } }: ChangeEvent) => {
- setRawFieldName(value);
- setFormattedFieldName(formatFieldName(value));
- };
-
- const submitForm = (e: FormEvent) => {
- e.preventDefault();
- addNewField(formattedFieldName, newFieldType);
- setLoading(true);
- };
-
- const fieldNameNote =
- rawFieldName !== formattedFieldName ? (
- <>
- {FIELD_NAME_CORRECTED_PREFIX} {formattedFieldName}
- >
- ) : (
- FIELD_NAME_CORRECT_NOTE
- );
-
- return (
-
-
-
- );
-};
-
-const formatFieldName = (rawName: string) =>
- rawName
- .trim()
- .replace(/[^a-zA-Z0-9]+/g, '_')
- .replace(/^[^a-zA-Z0-9]+/, '')
- .replace(/[^a-zA-Z0-9]+$/, '')
- .toLowerCase();
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index a3fef7f6bbf09..a20cf5a94312a 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -7619,11 +7619,11 @@
"xpack.enterpriseSearch.overview.subheading": "開始する製品を選択します。",
"xpack.enterpriseSearch.productName": "エンタープライズサーチ",
"xpack.enterpriseSearch.readOnlyMode.warning": "エンタープライズ サーチは読み取り専用モードです。作成、編集、削除などの変更を実行できません。",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.addField": "フィールドの追加",
+ "xpack.enterpriseSearch.schema.addFieldModal.addFieldButtonLabel": "フィールドの追加",
+ "xpack.enterpriseSearch.schema.addFieldModal.description": "追加すると、フィールドはスキーマから削除されます。",
+ "xpack.enterpriseSearch.schema.addFieldModal.title": "新しいフィールドを追加",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.correct": "フィールド名には、小文字、数字、アンダースコアのみを使用できます。",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "フィールド名が変更されます",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.description": "追加すると、フィールドはスキーマから削除されます。",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.title": "新しいフィールドを追加",
+ "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "フィールド名が変更されます {correctedName}",
"xpack.enterpriseSearch.schema.errorsCallout.buttonLabel": "エラーを表示",
"xpack.enterpriseSearch.schema.errorsTable.control.review": "見直し",
"xpack.enterpriseSearch.schema.errorsTable.heading.error": "エラー",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 413983c7c8f83..c4c18a18d37e2 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -7689,11 +7689,11 @@
"xpack.enterpriseSearch.overview.subheading": "选择产品开始使用。",
"xpack.enterpriseSearch.productName": "企业搜索",
"xpack.enterpriseSearch.readOnlyMode.warning": "企业搜索处于只读模式。您将无法执行更改,例如创建、编辑或删除。",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.addField": "添加字段",
+ "xpack.enterpriseSearch.schema.addFieldModal.addFieldButtonLabel": "添加字段",
+ "xpack.enterpriseSearch.schema.addFieldModal.description": "字段添加后,将无法从架构中删除。",
+ "xpack.enterpriseSearch.schema.addFieldModal.title": "添加新字段",
"xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.correct": "字段名称只能包含小写字母、数字和下划线",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "该字段将被命名",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.description": "字段添加后,将无法从架构中删除。",
- "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.title": "添加新字段",
+ "xpack.enterpriseSearch.schema.addFieldModal.fieldNameNote.corrected": "该字段将被命名 {correctedName}",
"xpack.enterpriseSearch.schema.errorsCallout.buttonLabel": "查看错误",
"xpack.enterpriseSearch.schema.errorsTable.control.review": "复查",
"xpack.enterpriseSearch.schema.errorsTable.heading.error": "错误",
From 58b3c1bf130c0fcba55ae24a32f211006e6507f0 Mon Sep 17 00:00:00 2001
From: Aaron Caldwell
Date: Mon, 3 May 2021 15:30:19 -0600
Subject: [PATCH 26/81] Fix malformed geo alerts call to `transformResults`
(#98094)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../alert_types/geo_containment/alert_type.ts | 1 +
.../geo_containment/geo_containment.ts | 6 +-
.../tests/es_sample_response.json | 383 +++++++++-------
.../tests/es_sample_response_shapes.json | 428 ++++++++++++++++++
.../es_sample_response_with_nesting.json | 308 ++++++-------
.../tests/geo_containment.test.ts | 315 ++++++++++---
6 files changed, 1068 insertions(+), 373 deletions(-)
create mode 100644 x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_shapes.json
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/alert_type.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/alert_type.ts
index 6015881270405..e3d379f2869b9 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/alert_type.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/alert_type.ts
@@ -120,6 +120,7 @@ export interface GeoContainmentParams extends AlertTypeParams {
export interface GeoContainmentState extends AlertTypeState {
shapesFilters: Record;
shapesIdsNamesMap: Record;
+ prevLocationMap: Record;
}
export interface GeoContainmentInstanceState extends AlertInstanceState {
location: number[];
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/geo_containment.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/geo_containment.ts
index 15a6564395c16..754af920b009e 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/geo_containment.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/geo_containment.ts
@@ -16,6 +16,7 @@ import {
GeoContainmentInstanceState,
GeoContainmentAlertType,
GeoContainmentInstanceContext,
+ GeoContainmentState,
} from './alert_type';
export type LatestEntityLocation = GeoContainmentInstanceState;
@@ -141,7 +142,7 @@ export const getGeoContainmentExecutor = (log: Logger): GeoContainmentAlertType[
params,
alertId,
state,
- }) {
+ }): Promise {
const { shapesFilters, shapesIdsNamesMap } = state.shapesFilters
? state
: await getShapesFilters(
@@ -176,8 +177,7 @@ export const getGeoContainmentExecutor = (log: Logger): GeoContainmentAlertType[
}
const currLocationMap: Map = transformResults(
- // @ts-expect-error body doesn't exist on currentIntervalResults
- currentIntervalResults?.body,
+ currentIntervalResults,
params.dateField,
params.geoField
);
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response.json b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response.json
index 70edbd09aa5a1..b5751e527df4d 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response.json
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response.json
@@ -1,167 +1,246 @@
{
- "took" : 2760,
- "timed_out" : false,
- "_shards" : {
- "total" : 1,
- "successful" : 1,
- "skipped" : 0,
- "failed" : 0
- },
- "hits" : {
- "total" : {
- "value" : 10000,
- "relation" : "gte"
+ "body": {
+ "took":194,
+ "timed_out":false,
+ "_shards":{
+ "total":1,
+ "successful":1,
+ "skipped":0,
+ "failed":0
},
- "max_score" : 0.0,
- "hits" : []
- },
- "aggregations" : {
- "shapes" : {
- "meta" : { },
- "buckets" : {
- "0DrJu3QB6yyY-xQxv6Ip" : {
- "doc_count" : 1047,
- "entitySplit" : {
- "doc_count_error_upper_bound" : 0,
- "sum_other_doc_count" : 957,
- "buckets" : [
- {
- "key" : "936",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "N-ng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "@timestamp" : [
- "2020-09-28T18:01:41.190Z"
- ],
- "location" : [
- "40.62806099653244, -82.8814151789993"
- ],
- "entity_id" : [
- "936"
+ "hits":{
+ "total":{
+ "value":18,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+
+ ]
+ },
+ "aggregations":{
+ "shapes":{
+ "meta":{
+
+ },
+ "buckets":{
+ "k1ATGXkBsFLYN2Tj6AAk":{
+ "doc_count":0,
+ "entitySplit":{
+ "doc_count_error_upper_bound":0,
+ "sum_other_doc_count":0,
+ "buckets":[
+
+ ]
+ }
+ },
+ "kFATGXkBsFLYN2Tj6AAk":{
+ "doc_count":2,
+ "entitySplit":{
+ "doc_count_error_upper_bound":0,
+ "sum_other_doc_count":0,
+ "buckets":[
+ {
+ "key":"0",
+ "doc_count":1,
+ "entityHits":{
+ "hits":{
+ "total":{
+ "value":1,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+ {
+ "_index":"tracks",
+ "_id":"ZVBoGXkBsFLYN2Tj1wmV",
+ "_score":null,
+ "fields":{
+ "@timestamp":[
+ "2021-04-28T16:56:11.923Z"
+ ],
+ "location":[
+ "40.751759740523994, -73.99018926545978"
+ ],
+ "entity_id":[
+ "0"
+ ]
+ },
+ "sort":[
+ 1619628971923
]
- },
- "sort" : [
- 1601316101190
- ]
- }
- ]
+ }
+ ]
+ }
}
- }
- },
- {
- "key" : "AAL2019",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "iOng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "@timestamp" : [
- "2020-09-28T18:01:41.191Z"
- ],
- "location" : [
- "39.006176185794175, -82.22068064846098"
- ],
- "entity_id" : [
- "AAL2019"
+ },
+ {
+ "key":"1",
+ "doc_count":1,
+ "entityHits":{
+ "hits":{
+ "total":{
+ "value":1,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+ {
+ "_index":"tracks",
+ "_id":"ZlBoGXkBsFLYN2Tj1wmV",
+ "_score":null,
+ "fields":{
+ "@timestamp":[
+ "2021-04-28T16:56:11.923Z"
+ ],
+ "location":[
+ "40.75449890457094, -73.99561604484916"
+ ],
+ "entity_id":[
+ "1"
+ ]
+ },
+ "sort":[
+ 1619628971923
]
- },
- "sort" : [
- 1601316101191
- ]
- }
- ]
+ }
+ ]
+ }
}
}
- },
- {
- "key" : "AAL2323",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "n-ng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "@timestamp" : [
- "2020-09-28T18:01:41.191Z"
- ],
- "location" : [
- "41.6677269525826, -84.71324851736426"
- ],
- "entity_id" : [
- "AAL2323"
+ ]
+ }
+ },
+ "kVATGXkBsFLYN2Tj6AAk":{
+ "doc_count":0,
+ "entitySplit":{
+ "doc_count_error_upper_bound":0,
+ "sum_other_doc_count":0,
+ "buckets":[
+
+ ]
+ }
+ },
+ "lVATGXkBsFLYN2Tj6AAk":{
+ "doc_count":0,
+ "entitySplit":{
+ "doc_count_error_upper_bound":0,
+ "sum_other_doc_count":0,
+ "buckets":[
+
+ ]
+ }
+ },
+ "other":{
+ "doc_count":15,
+ "entitySplit":{
+ "doc_count_error_upper_bound":0,
+ "sum_other_doc_count":0,
+ "buckets":[
+ {
+ "key":"2",
+ "doc_count":6,
+ "entityHits":{
+ "hits":{
+ "total":{
+ "value":6,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+ {
+ "_index":"tracks",
+ "_id":"Z1BoGXkBsFLYN2Tj1wmV",
+ "_score":null,
+ "fields":{
+ "@timestamp":[
+ "2021-04-28T16:56:11.923Z"
+ ],
+ "location":[
+ "40.7667087810114, -73.98662586696446"
+ ],
+ "entity_id":[
+ "2"
+ ]
+ },
+ "sort":[
+ 1619628971923
]
- },
- "sort" : [
- 1601316101191
- ]
- }
- ]
+ }
+ ]
+ }
}
- }
- },
- {
- "key" : "ABD5250",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "GOng1XQB6yyY-xQxnGWM",
- "_score" : null,
- "fields" : {
- "@timestamp" : [
- "2020-09-28T18:01:41.192Z"
- ],
- "location" : [
- "39.07997465226799, 6.073727197945118"
- ],
- "entity_id" : [
- "ABD5250"
+ },
+ {
+ "key":"1",
+ "doc_count":5,
+ "entityHits":{
+ "hits":{
+ "total":{
+ "value":5,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+ {
+ "_index":"tracks",
+ "_id":"Y1BoGXkBsFLYN2TjsAlp",
+ "_score":null,
+ "fields":{
+ "@timestamp":[
+ "2021-04-28T16:56:01.896Z"
+ ],
+ "location":[
+ "40.755913141183555, -73.99459345266223"
+ ],
+ "entity_id":[
+ "1"
+ ]
+ },
+ "sort":[
+ 1619628961896
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key":"0",
+ "doc_count":4,
+ "entityHits":{
+ "hits":{
+ "total":{
+ "value":4,
+ "relation":"eq"
+ },
+ "max_score":null,
+ "hits":[
+ {
+ "_index":"tracks",
+ "_id":"YlBoGXkBsFLYN2TjsAlp",
+ "_score":null,
+ "fields":{
+ "@timestamp":[
+ "2021-04-28T16:56:01.896Z"
+ ],
+ "location":[
+ "40.7506317878142, -73.98968475870788"
+ ],
+ "entity_id":[
+ "0"
+ ]
+ },
+ "sort":[
+ 1619628961896
]
- },
- "sort" : [
- 1601316101192
- ]
- }
- ]
+ }
+ ]
+ }
}
}
- }
- ]
+ ]
+ }
}
}
}
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_shapes.json b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_shapes.json
new file mode 100644
index 0000000000000..dfe5a8b7f6ec1
--- /dev/null
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_shapes.json
@@ -0,0 +1,428 @@
+{
+ "body": {
+ "took":1,
+ "timed_out":false,
+ "_shards":{
+ "total":1,
+ "successful":1,
+ "skipped":0,
+ "failed":0
+ },
+ "hits":{
+ "total":{
+ "value":11,
+ "relation":"eq"
+ },
+ "max_score":1,
+ "hits":[
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"waFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.96772861480713,
+ 40.76060200607076
+ ],
+ [
+ -73.96805047988892,
+ 40.7601631739201
+ ],
+ [
+ -73.96732091903687,
+ 40.7598706175435
+ ],
+ [
+ -73.96693468093872,
+ 40.760471982031845
+ ],
+ [
+ -73.96759986877441,
+ 40.76078078870895
+ ],
+ [
+ -73.96772861480713,
+ 40.76060200607076
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"wqFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.97641897201538,
+ 40.75618104606283
+ ],
+ [
+ -73.97865056991577,
+ 40.75371038152863
+ ],
+ [
+ -73.97770643234252,
+ 40.75323899431278
+ ],
+ [
+ -73.9788007736206,
+ 40.75187357799962
+ ],
+ [
+ -73.97671937942503,
+ 40.751060816881505
+ ],
+ [
+ -73.97500276565552,
+ 40.75377540019266
+ ],
+ [
+ -73.97639751434325,
+ 40.75460438258571
+ ],
+ [
+ -73.9755392074585,
+ 40.755985996937774
+ ],
+ [
+ -73.97641897201538,
+ 40.75618104606283
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"w6FXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.98592472076415,
+ 40.75957805987928
+ ],
+ [
+ -73.98695468902588,
+ 40.75566091379097
+ ],
+ [
+ -73.98573160171509,
+ 40.75553088008716
+ ],
+ [
+ -73.98465871810913,
+ 40.75946428710659
+ ],
+ [
+ -73.98592472076415,
+ 40.75957805987928
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"xKFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.9894437789917,
+ 40.75161349552273
+ ],
+ [
+ -73.98914337158203,
+ 40.75206863918968
+ ],
+ [
+ -73.99575233459473,
+ 40.75486445336327
+ ],
+ [
+ -73.99819850921631,
+ 40.75148345390278
+ ],
+ [
+ -73.9914608001709,
+ 40.74881754464601
+ ],
+ [
+ -73.9894437789917,
+ 40.75161349552273
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"xaFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.96914482116699,
+ 40.75874913950493
+ ],
+ [
+ -73.96946668624878,
+ 40.758229027325804
+ ],
+ [
+ -73.96856546401978,
+ 40.75793646243674
+ ],
+ [
+ -73.96824359893799,
+ 40.75845657690492
+ ],
+ [
+ -73.96914482116699,
+ 40.75874913950493
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"xqFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.96953105926514,
+ 40.7581640130173
+ ],
+ [
+ -73.9699387550354,
+ 40.75749761268889
+ ],
+ [
+ -73.96923065185547,
+ 40.75728631362887
+ ],
+ [
+ -73.96862983703613,
+ 40.757920208794026
+ ],
+ [
+ -73.96953105926514,
+ 40.7581640130173
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"x6FXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.97045373916626,
+ 40.75679869785023
+ ],
+ [
+ -73.97079706192015,
+ 40.75629482445485
+ ],
+ [
+ -73.96998167037964,
+ 40.756051013376364
+ ],
+ [
+ -73.96961688995361,
+ 40.756554888619675
+ ],
+ [
+ -73.97045373916626,
+ 40.75679869785023
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"yKFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.98412227630615,
+ 40.75479943576424
+ ],
+ [
+ -73.98498058319092,
+ 40.75351532515499
+ ],
+ [
+ -73.98191213607788,
+ 40.75219867966512
+ ],
+ [
+ -73.9808177947998,
+ 40.75340154200611
+ ],
+ [
+ -73.98412227630615,
+ 40.75479943576424
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"yaFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.99725437164307,
+ 40.74498104863726
+ ],
+ [
+ -74.00386333465576,
+ 40.736136757139285
+ ],
+ [
+ -73.99703979492188,
+ 40.73334015558748
+ ],
+ [
+ -73.9897871017456,
+ 40.74153451605774
+ ],
+ [
+ -73.99725437164307,
+ 40.74498104863726
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"yqFXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.98830652236938,
+ 40.75075196505171
+ ],
+ [
+ -73.9885640144348,
+ 40.74759834321152
+ ],
+ [
+ -73.98761987686157,
+ 40.747582087041366
+ ],
+ [
+ -73.98751258850098,
+ 40.74816730666263
+ ],
+ [
+ -73.98807048797607,
+ 40.74826484276548
+ ],
+ [
+ -73.9875340461731,
+ 40.75075196505171
+ ],
+ [
+ -73.98830652236938,
+ 40.75075196505171
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "_index":"manhattan_boundaries",
+ "_id":"y6FXH3kBi9P-_6qn8c8A",
+ "_score":1,
+ "_source":{
+ "coordinates":{
+ "type":"Polygon",
+ "coordinates":[
+ [
+ [
+ -73.9824914932251,
+ 40.7467692734681
+ ],
+ [
+ -73.98356437683105,
+ 40.7452411570555
+ ],
+ [
+ -73.9813756942749,
+ 40.74446082874893
+ ],
+ [
+ -73.98030281066895,
+ 40.745696344339564
+ ],
+ [
+ -73.9824914932251,
+ 40.7467692734681
+ ]
+ ]
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
+
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_with_nesting.json b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_with_nesting.json
index a4b7b6872b341..9baf58465c38e 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_with_nesting.json
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/es_sample_response_with_nesting.json
@@ -1,167 +1,169 @@
{
- "took" : 2760,
- "timed_out" : false,
- "_shards" : {
- "total" : 1,
- "successful" : 1,
- "skipped" : 0,
- "failed" : 0
- },
- "hits" : {
- "total" : {
- "value" : 10000,
- "relation" : "gte"
+ "body": {
+ "took" : 2760,
+ "timed_out" : false,
+ "_shards" : {
+ "total" : 1,
+ "successful" : 1,
+ "skipped" : 0,
+ "failed" : 0
},
- "max_score" : 0.0,
- "hits" : []
- },
- "aggregations" : {
- "shapes" : {
- "meta" : { },
- "buckets" : {
- "0DrJu3QB6yyY-xQxv6Ip" : {
- "doc_count" : 1047,
- "entitySplit" : {
- "doc_count_error_upper_bound" : 0,
- "sum_other_doc_count" : 957,
- "buckets" : [
- {
- "key" : "936",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "N-ng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "time_data.@timestamp" : [
- "2020-09-28T18:01:41.190Z"
- ],
- "geo.coords.location" : [
- "40.62806099653244, -82.8814151789993"
- ],
- "entity_id" : [
- "936"
+ "hits" : {
+ "total" : {
+ "value" : 10000,
+ "relation" : "gte"
+ },
+ "max_score" : 0.0,
+ "hits" : []
+ },
+ "aggregations" : {
+ "shapes" : {
+ "meta" : { },
+ "buckets" : {
+ "0DrJu3QB6yyY-xQxv6Ip" : {
+ "doc_count" : 1047,
+ "entitySplit" : {
+ "doc_count_error_upper_bound" : 0,
+ "sum_other_doc_count" : 957,
+ "buckets" : [
+ {
+ "key" : "936",
+ "doc_count" : 9,
+ "entityHits" : {
+ "hits" : {
+ "total" : {
+ "value" : 9,
+ "relation" : "eq"
+ },
+ "max_score" : null,
+ "hits" : [
+ {
+ "_index" : "flight_tracks",
+ "_id" : "N-ng1XQB6yyY-xQxnGSM",
+ "_score" : null,
+ "fields" : {
+ "time_data.@timestamp" : [
+ "2020-09-28T18:01:41.190Z"
+ ],
+ "geo.coords.location" : [
+ "40.62806099653244, -82.8814151789993"
+ ],
+ "entity_id" : [
+ "936"
+ ]
+ },
+ "sort" : [
+ 1601316101190
]
- },
- "sort" : [
- 1601316101190
- ]
- }
- ]
+ }
+ ]
+ }
}
- }
- },
- {
- "key" : "AAL2019",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "iOng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "time_data.@timestamp" : [
- "2020-09-28T18:01:41.191Z"
- ],
- "geo.coords.location" : [
- "39.006176185794175, -82.22068064846098"
- ],
- "entity_id" : [
- "AAL2019"
+ },
+ {
+ "key" : "AAL2019",
+ "doc_count" : 9,
+ "entityHits" : {
+ "hits" : {
+ "total" : {
+ "value" : 9,
+ "relation" : "eq"
+ },
+ "max_score" : null,
+ "hits" : [
+ {
+ "_index" : "flight_tracks",
+ "_id" : "iOng1XQB6yyY-xQxnGSM",
+ "_score" : null,
+ "fields" : {
+ "time_data.@timestamp" : [
+ "2020-09-28T18:01:41.191Z"
+ ],
+ "geo.coords.location" : [
+ "39.006176185794175, -82.22068064846098"
+ ],
+ "entity_id" : [
+ "AAL2019"
+ ]
+ },
+ "sort" : [
+ 1601316101191
]
- },
- "sort" : [
- 1601316101191
- ]
- }
- ]
+ }
+ ]
+ }
}
- }
- },
- {
- "key" : "AAL2323",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "n-ng1XQB6yyY-xQxnGSM",
- "_score" : null,
- "fields" : {
- "time_data.@timestamp" : [
- "2020-09-28T18:01:41.191Z"
- ],
- "geo.coords.location" : [
- "41.6677269525826, -84.71324851736426"
- ],
- "entity_id" : [
- "AAL2323"
+ },
+ {
+ "key" : "AAL2323",
+ "doc_count" : 9,
+ "entityHits" : {
+ "hits" : {
+ "total" : {
+ "value" : 9,
+ "relation" : "eq"
+ },
+ "max_score" : null,
+ "hits" : [
+ {
+ "_index" : "flight_tracks",
+ "_id" : "n-ng1XQB6yyY-xQxnGSM",
+ "_score" : null,
+ "fields" : {
+ "time_data.@timestamp" : [
+ "2020-09-28T18:01:41.191Z"
+ ],
+ "geo.coords.location" : [
+ "41.6677269525826, -84.71324851736426"
+ ],
+ "entity_id" : [
+ "AAL2323"
+ ]
+ },
+ "sort" : [
+ 1601316101191
]
- },
- "sort" : [
- 1601316101191
- ]
- }
- ]
+ }
+ ]
+ }
}
- }
- },
- {
- "key" : "ABD5250",
- "doc_count" : 9,
- "entityHits" : {
- "hits" : {
- "total" : {
- "value" : 9,
- "relation" : "eq"
- },
- "max_score" : null,
- "hits" : [
- {
- "_index" : "flight_tracks",
- "_id" : "GOng1XQB6yyY-xQxnGWM",
- "_score" : null,
- "fields" : {
- "time_data.@timestamp" : [
- "2020-09-28T18:01:41.192Z"
- ],
- "geo.coords.location" : [
- "39.07997465226799, 6.073727197945118"
- ],
- "entity_id" : [
- "ABD5250"
+ },
+ {
+ "key" : "ABD5250",
+ "doc_count" : 9,
+ "entityHits" : {
+ "hits" : {
+ "total" : {
+ "value" : 9,
+ "relation" : "eq"
+ },
+ "max_score" : null,
+ "hits" : [
+ {
+ "_index" : "flight_tracks",
+ "_id" : "GOng1XQB6yyY-xQxnGWM",
+ "_score" : null,
+ "fields" : {
+ "time_data.@timestamp" : [
+ "2020-09-28T18:01:41.192Z"
+ ],
+ "geo.coords.location" : [
+ "39.07997465226799, 6.073727197945118"
+ ],
+ "entity_id" : [
+ "ABD5250"
+ ]
+ },
+ "sort" : [
+ 1601316101192
]
- },
- "sort" : [
- 1601316101192
- ]
- }
- ]
+ }
+ ]
+ }
}
}
- }
- ]
+ ]
+ }
}
}
}
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts
index 429331916ea7d..df2e9df4ba189 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts
@@ -6,67 +6,101 @@
*/
import _ from 'lodash';
-import sampleJsonResponse from './es_sample_response.json';
-import sampleJsonResponseWithNesting from './es_sample_response_with_nesting.json';
-import { getActiveEntriesAndGenerateAlerts, transformResults } from '../geo_containment';
+import { loggingSystemMock } from 'src/core/server/mocks';
+import { AlertServicesMock, alertsMock } from '../../../../../alerting/server/mocks';
+import sampleAggsJsonResponse from './es_sample_response.json';
+import sampleShapesJsonResponse from './es_sample_response_shapes.json';
+import sampleAggsJsonResponseWithNesting from './es_sample_response_with_nesting.json';
+import {
+ getActiveEntriesAndGenerateAlerts,
+ transformResults,
+ getGeoContainmentExecutor,
+} from '../geo_containment';
import { OTHER_CATEGORY } from '../es_query_builder';
-import { alertsMock } from '../../../../../alerting/server/mocks';
-import { GeoContainmentInstanceContext, GeoContainmentInstanceState } from '../alert_type';
+import {
+ GeoContainmentInstanceContext,
+ GeoContainmentInstanceState,
+ GeoContainmentParams,
+} from '../alert_type';
import { SearchResponse } from 'elasticsearch';
+const alertInstanceFactory = (contextKeys: unknown[], testAlertActionArr: unknown[]) => (
+ instanceId: string
+) => {
+ const alertInstance = alertsMock.createAlertInstanceFactory<
+ GeoContainmentInstanceState,
+ GeoContainmentInstanceContext
+ >();
+ alertInstance.scheduleActions.mockImplementation(
+ (actionGroupId: string, context?: GeoContainmentInstanceContext) => {
+ // Check subset of alert for comparison to expected results
+ // @ts-ignore
+ const contextSubset = _.pickBy(context, (v, k) => contextKeys.includes(k));
+ testAlertActionArr.push({
+ actionGroupId,
+ instanceId,
+ context: contextSubset,
+ });
+ }
+ );
+ return alertInstance;
+};
+
describe('geo_containment', () => {
describe('transformResults', () => {
const dateField = '@timestamp';
const geoField = 'location';
it('should correctly transform expected results', async () => {
const transformedResults = transformResults(
- (sampleJsonResponse as unknown) as SearchResponse,
+ // @ts-ignore
+ (sampleAggsJsonResponse.body as unknown) as SearchResponse,
dateField,
geoField
);
expect(transformedResults).toEqual(
new Map([
[
- '936',
+ '0',
[
{
- dateInShape: '2020-09-28T18:01:41.190Z',
- docId: 'N-ng1XQB6yyY-xQxnGSM',
- location: [-82.8814151789993, 40.62806099653244],
- shapeLocationId: '0DrJu3QB6yyY-xQxv6Ip',
+ dateInShape: '2021-04-28T16:56:11.923Z',
+ docId: 'ZVBoGXkBsFLYN2Tj1wmV',
+ location: [-73.99018926545978, 40.751759740523994],
+ shapeLocationId: 'kFATGXkBsFLYN2Tj6AAk',
},
- ],
- ],
- [
- 'AAL2019',
- [
{
- dateInShape: '2020-09-28T18:01:41.191Z',
- docId: 'iOng1XQB6yyY-xQxnGSM',
- location: [-82.22068064846098, 39.006176185794175],
- shapeLocationId: '0DrJu3QB6yyY-xQxv6Ip',
+ dateInShape: '2021-04-28T16:56:01.896Z',
+ docId: 'YlBoGXkBsFLYN2TjsAlp',
+ location: [-73.98968475870788, 40.7506317878142],
+ shapeLocationId: 'other',
},
],
],
[
- 'AAL2323',
+ '1',
[
{
- dateInShape: '2020-09-28T18:01:41.191Z',
- docId: 'n-ng1XQB6yyY-xQxnGSM',
- location: [-84.71324851736426, 41.6677269525826],
- shapeLocationId: '0DrJu3QB6yyY-xQxv6Ip',
+ dateInShape: '2021-04-28T16:56:11.923Z',
+ docId: 'ZlBoGXkBsFLYN2Tj1wmV',
+ location: [-73.99561604484916, 40.75449890457094],
+ shapeLocationId: 'kFATGXkBsFLYN2Tj6AAk',
+ },
+ {
+ dateInShape: '2021-04-28T16:56:01.896Z',
+ docId: 'Y1BoGXkBsFLYN2TjsAlp',
+ location: [-73.99459345266223, 40.755913141183555],
+ shapeLocationId: 'other',
},
],
],
[
- 'ABD5250',
+ '2',
[
{
- dateInShape: '2020-09-28T18:01:41.192Z',
- docId: 'GOng1XQB6yyY-xQxnGWM',
- location: [6.073727197945118, 39.07997465226799],
- shapeLocationId: '0DrJu3QB6yyY-xQxv6Ip',
+ dateInShape: '2021-04-28T16:56:11.923Z',
+ docId: 'Z1BoGXkBsFLYN2Tj1wmV',
+ location: [-73.98662586696446, 40.7667087810114],
+ shapeLocationId: 'other',
},
],
],
@@ -78,7 +112,8 @@ describe('geo_containment', () => {
const nestedGeoField = 'geo.coords.location';
it('should correctly transform expected results if fields are nested', async () => {
const transformedResults = transformResults(
- (sampleJsonResponseWithNesting as unknown) as SearchResponse,
+ // @ts-ignore
+ (sampleAggsJsonResponseWithNesting.body as unknown) as SearchResponse,
nestedDateField,
nestedGeoField
);
@@ -181,7 +216,7 @@ describe('geo_containment', () => {
],
]);
- const expectedContext = [
+ const expectedAlertResults = [
{
actionGroupId: 'Tracked entity contained',
context: {
@@ -213,28 +248,9 @@ describe('geo_containment', () => {
instanceId: 'c-789',
},
];
+ const contextKeys = Object.keys(expectedAlertResults[0].context);
const emptyShapesIdsNamesMap = {};
- const alertInstanceFactory = (instanceId: string) => {
- const alertInstance = alertsMock.createAlertInstanceFactory<
- GeoContainmentInstanceState,
- GeoContainmentInstanceContext
- >();
- alertInstance.scheduleActions.mockImplementation(
- (actionGroupId: string, context?: GeoContainmentInstanceContext) => {
- const contextKeys = Object.keys(expectedContext[0].context);
- const contextSubset = _.pickBy(context, (v, k) => contextKeys.includes(k));
- testAlertActionArr.push({
- actionGroupId,
- instanceId,
- context: contextSubset,
- });
- return alertInstance;
- }
- );
- return alertInstance;
- };
-
const currentDateTime = new Date();
it('should use currently active entities if no older entity entries', () => {
@@ -242,13 +258,14 @@ describe('geo_containment', () => {
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
emptyPrevLocationMap,
currLocationMap,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
expect(allActiveEntriesMap).toEqual(currLocationMap);
- expect(testAlertActionArr).toMatchObject(expectedContext);
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
});
+
it('should overwrite older identical entity entries', () => {
const prevLocationMapWithIdenticalEntityEntry = new Map([
[
@@ -266,13 +283,14 @@ describe('geo_containment', () => {
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
prevLocationMapWithIdenticalEntityEntry,
currLocationMap,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
expect(allActiveEntriesMap).toEqual(currLocationMap);
- expect(testAlertActionArr).toMatchObject(expectedContext);
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
});
+
it('should preserve older non-identical entity entries', () => {
const prevLocationMapWithNonIdenticalEntityEntry = new Map([
[
@@ -287,7 +305,7 @@ describe('geo_containment', () => {
],
],
]);
- const expectedContextPlusD = [
+ const expectedAlertResultsPlusD = [
{
actionGroupId: 'Tracked entity contained',
context: {
@@ -298,19 +316,19 @@ describe('geo_containment', () => {
},
instanceId: 'd-999',
},
- ...expectedContext,
+ ...expectedAlertResults,
];
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
prevLocationMapWithNonIdenticalEntityEntry,
currLocationMap,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
expect(allActiveEntriesMap).not.toEqual(currLocationMap);
expect(allActiveEntriesMap.has('d')).toBeTruthy();
- expect(testAlertActionArr).toMatchObject(expectedContextPlusD);
+ expect(testAlertActionArr).toMatchObject(expectedAlertResultsPlusD);
});
it('should remove "other" entries and schedule the expected number of actions', () => {
@@ -327,12 +345,12 @@ describe('geo_containment', () => {
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
emptyPrevLocationMap,
currLocationMapWithOther,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
expect(allActiveEntriesMap).toEqual(currLocationMap);
- expect(testAlertActionArr).toMatchObject(expectedContext);
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
});
it('should generate multiple alerts per entity if found in multiple shapes in interval', () => {
@@ -360,7 +378,7 @@ describe('geo_containment', () => {
getActiveEntriesAndGenerateAlerts(
emptyPrevLocationMap,
currLocationMapWithThreeMore,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
@@ -397,7 +415,7 @@ describe('geo_containment', () => {
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
emptyPrevLocationMap,
currLocationMapWithOther,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
@@ -429,7 +447,7 @@ describe('geo_containment', () => {
const allActiveEntriesMap = getActiveEntriesAndGenerateAlerts(
emptyPrevLocationMap,
currLocationMapWithOther,
- alertInstanceFactory,
+ alertInstanceFactory(contextKeys, testAlertActionArr),
emptyShapesIdsNamesMap,
currentDateTime
);
@@ -445,4 +463,171 @@ describe('geo_containment', () => {
);
});
});
+
+ describe('getGeoContainmentExecutor', () => {
+ // Params needed for all tests
+ const expectedAlertResults = [
+ {
+ actionGroupId: 'Tracked entity contained',
+ context: {
+ containingBoundaryId: 'kFATGXkBsFLYN2Tj6AAk',
+ entityDocumentId: 'ZVBoGXkBsFLYN2Tj1wmV',
+ entityId: '0',
+ entityLocation: 'POINT (-73.99018926545978 40.751759740523994)',
+ },
+ instanceId: '0-kFATGXkBsFLYN2Tj6AAk',
+ },
+ {
+ actionGroupId: 'Tracked entity contained',
+ context: {
+ containingBoundaryId: 'kFATGXkBsFLYN2Tj6AAk',
+ entityDocumentId: 'ZlBoGXkBsFLYN2Tj1wmV',
+ entityId: '1',
+ entityLocation: 'POINT (-73.99561604484916 40.75449890457094)',
+ },
+ instanceId: '1-kFATGXkBsFLYN2Tj6AAk',
+ },
+ ];
+ const testAlertActionArr: unknown[] = [];
+ const mockLogger = loggingSystemMock.createLogger();
+ const previousStartedAt = new Date('2021-04-27T16:56:11.923Z');
+ const startedAt = new Date('2021-04-29T16:56:11.923Z');
+ const geoContainmentParams: GeoContainmentParams = {
+ index: 'testIndex',
+ indexId: 'testIndexId',
+ geoField: 'location',
+ entity: 'testEntity',
+ dateField: '@timestamp',
+ boundaryType: 'testBoundaryType',
+ boundaryIndexTitle: 'testBoundaryIndexTitle',
+ boundaryIndexId: 'testBoundaryIndexId',
+ boundaryGeoField: 'testBoundaryGeoField',
+ };
+ const alertId = 'testAlertId';
+ const geoContainmentState = {
+ shapesFilters: {
+ testShape: 'thisIsAShape',
+ },
+ shapesIdsNamesMap: {},
+ prevLocationMap: {},
+ };
+
+ // Boundary test mocks
+ const boundaryCall = jest.fn();
+ const esAggCall = jest.fn();
+ const contextKeys = Object.keys(expectedAlertResults[0].context);
+ const alertServicesWithSearchMock: AlertServicesMock = {
+ ...alertsMock.createAlertServices(),
+ // @ts-ignore
+ alertInstanceFactory: alertInstanceFactory(contextKeys, testAlertActionArr),
+ scopedClusterClient: {
+ asCurrentUser: {
+ // @ts-ignore
+ search: jest.fn(({ index }: { index: string }) => {
+ if (index === geoContainmentParams.boundaryIndexTitle) {
+ boundaryCall();
+ return sampleShapesJsonResponse;
+ } else {
+ esAggCall();
+ return sampleAggsJsonResponse;
+ }
+ }),
+ },
+ },
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ testAlertActionArr.length = 0;
+ });
+
+ it('should query for shapes if state does not contain shapes', async () => {
+ const executor = await getGeoContainmentExecutor(mockLogger);
+ const executionResult = await executor({
+ previousStartedAt,
+ startedAt,
+ // @ts-ignore
+ services: alertServicesWithSearchMock,
+ params: geoContainmentParams,
+ alertId,
+ // @ts-ignore
+ state: {},
+ });
+ if (executionResult && executionResult.shapesFilters) {
+ expect(boundaryCall.mock.calls.length).toBe(1);
+ expect(esAggCall.mock.calls.length).toBe(1);
+ }
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
+ });
+
+ it('should not query for shapes if state contains shapes', async () => {
+ const executor = await getGeoContainmentExecutor(mockLogger);
+ const executionResult = await executor({
+ previousStartedAt,
+ startedAt,
+ // @ts-ignore
+ services: alertServicesWithSearchMock,
+ params: geoContainmentParams,
+ alertId,
+ state: geoContainmentState,
+ });
+ if (executionResult && executionResult.shapesFilters) {
+ expect(boundaryCall.mock.calls.length).toBe(0);
+ expect(esAggCall.mock.calls.length).toBe(1);
+ }
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
+ });
+
+ it('should carry through shapes filters in state to next call unmodified', async () => {
+ const executor = await getGeoContainmentExecutor(mockLogger);
+ const executionResult = await executor({
+ previousStartedAt,
+ startedAt,
+ // @ts-ignore
+ services: alertServicesWithSearchMock,
+ params: geoContainmentParams,
+ alertId,
+ state: geoContainmentState,
+ });
+ if (executionResult && executionResult.shapesFilters) {
+ expect(executionResult.shapesFilters).toEqual(geoContainmentState.shapesFilters);
+ }
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
+ });
+
+ it('should return previous locations map', async () => {
+ const expectedPrevLocationMap = {
+ '0': [
+ {
+ dateInShape: '2021-04-28T16:56:11.923Z',
+ docId: 'ZVBoGXkBsFLYN2Tj1wmV',
+ location: [-73.99018926545978, 40.751759740523994],
+ shapeLocationId: 'kFATGXkBsFLYN2Tj6AAk',
+ },
+ ],
+ '1': [
+ {
+ dateInShape: '2021-04-28T16:56:11.923Z',
+ docId: 'ZlBoGXkBsFLYN2Tj1wmV',
+ location: [-73.99561604484916, 40.75449890457094],
+ shapeLocationId: 'kFATGXkBsFLYN2Tj6AAk',
+ },
+ ],
+ };
+ const executor = await getGeoContainmentExecutor(mockLogger);
+ const executionResult = await executor({
+ previousStartedAt,
+ startedAt,
+ // @ts-ignore
+ services: alertServicesWithSearchMock,
+ params: geoContainmentParams,
+ alertId,
+ state: geoContainmentState,
+ });
+ if (executionResult && executionResult.prevLocationMap) {
+ expect(executionResult.prevLocationMap).toEqual(expectedPrevLocationMap);
+ }
+ expect(testAlertActionArr).toMatchObject(expectedAlertResults);
+ });
+ });
});
From 4af6e9c6916c2100f7112073f048e8b16e9fa98c Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Mon, 3 May 2021 22:34:53 +0100
Subject: [PATCH 27/81] chore(NA): moving @kbn/analytics into bazel (#98917)
* chore(NA): moving @kbn/analytics into bazel
* chore(NA): fix type check for package migration
* chore(NA): fix type check for package migration
* chore(NA): fix type check for package migration
* chore(NA): separate type generating from server code
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
BUILD.bazel | 1 +
.../monorepo-packages.asciidoc | 1 +
package.json | 2 +-
packages/BUILD.bazel | 1 +
packages/kbn-analytics/BUILD.bazel | 124 ++++++++++++++++++
packages/kbn-analytics/babel.config.js | 21 ---
packages/kbn-analytics/package.json | 9 +-
packages/kbn-analytics/scripts/build.js | 85 ------------
packages/kbn-analytics/tsconfig.browser.json | 18 +++
packages/kbn-analytics/tsconfig.json | 6 +-
packages/kbn-ui-shared-deps/package.json | 1 -
yarn.lock | 2 +-
12 files changed, 152 insertions(+), 119 deletions(-)
create mode 100644 packages/kbn-analytics/BUILD.bazel
delete mode 100644 packages/kbn-analytics/babel.config.js
delete mode 100644 packages/kbn-analytics/scripts/build.js
create mode 100644 packages/kbn-analytics/tsconfig.browser.json
diff --git a/BUILD.bazel b/BUILD.bazel
index 4502daeaacb59..1f6e3030e5d0c 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -3,6 +3,7 @@
exports_files(
[
"tsconfig.base.json",
+ "tsconfig.browser.json",
"tsconfig.json",
"package.json"
],
diff --git a/docs/developer/getting-started/monorepo-packages.asciidoc b/docs/developer/getting-started/monorepo-packages.asciidoc
index 969226df53cb7..02f96f304ec1e 100644
--- a/docs/developer/getting-started/monorepo-packages.asciidoc
+++ b/docs/developer/getting-started/monorepo-packages.asciidoc
@@ -64,6 +64,7 @@ yarn kbn watch-bazel
- @elastic/datemath
- @elastic/eslint-config-kibana
- @elastic/safer-lodash-set
+- @kbn/analytics
- @kbn/apm-config-loader
- @kbn/apm-utils
- @kbn/babel-code-parser
diff --git a/package.json b/package.json
index 04bce960ab1a2..81727c4028610 100644
--- a/package.json
+++ b/package.json
@@ -122,7 +122,7 @@
"@hapi/podium": "^4.1.1",
"@hapi/wreck": "^17.1.0",
"@kbn/ace": "link:packages/kbn-ace",
- "@kbn/analytics": "link:packages/kbn-analytics",
+ "@kbn/analytics": "link:bazel-bin/packages/kbn-analytics/npm_module",
"@kbn/apm-config-loader": "link:bazel-bin/packages/kbn-apm-config-loader/npm_module",
"@kbn/apm-utils": "link:bazel-bin/packages/kbn-apm-utils/npm_module",
"@kbn/config": "link:packages/kbn-config",
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index 39285fb9ea66a..eb93a1055e7b7 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -6,6 +6,7 @@ filegroup(
"//packages/elastic-datemath:build",
"//packages/elastic-eslint-config-kibana:build",
"//packages/elastic-safer-lodash-set:build",
+ "//packages/kbn-analytics:build",
"//packages/kbn-apm-config-loader:build",
"//packages/kbn-apm-utils:build",
"//packages/kbn-babel-code-parser:build",
diff --git a/packages/kbn-analytics/BUILD.bazel b/packages/kbn-analytics/BUILD.bazel
new file mode 100644
index 0000000000000..a5506598baeac
--- /dev/null
+++ b/packages/kbn-analytics/BUILD.bazel
@@ -0,0 +1,124 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm")
+
+PKG_BASE_NAME = "kbn-analytics"
+PKG_REQUIRE_NAME = "@kbn/analytics"
+
+SOURCE_FILES = glob(
+ [
+ "src/**/*.ts",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json"
+]
+
+SRC_DEPS = [
+ "@npm//moment-timezone",
+ "@npm//tslib",
+]
+
+TYPES_DEPS = [
+ "@npm//@types/moment-timezone",
+ "@npm//@types/node",
+]
+
+DEPS = SRC_DEPS + TYPES_DEPS
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//:tsconfig.base.json",
+ ],
+)
+
+ts_config(
+ name = "tsconfig_browser",
+ src = "tsconfig.browser.json",
+ deps = [
+ "//:tsconfig.base.json",
+ "//:tsconfig.browser.json",
+ ],
+)
+
+ts_project(
+ name = "tsc",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = DEPS,
+ declaration = True,
+ declaration_dir = "types",
+ declaration_map = True,
+ incremental = True,
+ out_dir = "node",
+ source_map = True,
+ root_dir = "src",
+ tsconfig = ":tsconfig",
+)
+
+ts_project(
+ name = "tsc_browser",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = DEPS,
+ declaration = False,
+ incremental = True,
+ out_dir = "web",
+ source_map = True,
+ root_dir = "src",
+ tsconfig = ":tsconfig_browser",
+)
+
+filegroup(
+ name = "tsc_types",
+ srcs = [":tsc"],
+ output_group = "types",
+)
+
+filegroup(
+ name = "target_files",
+ srcs = [
+ ":tsc",
+ ":tsc_browser",
+ ":tsc_types",
+ ],
+)
+
+pkg_npm(
+ name = "target",
+ deps = [
+ ":target_files",
+ ],
+)
+
+js_library(
+ name = PKG_BASE_NAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = [":target"] + DEPS,
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [
+ ":%s" % PKG_BASE_NAME,
+ ]
+)
+
+filegroup(
+ name = "build",
+ srcs = [
+ ":npm_module",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/kbn-analytics/babel.config.js b/packages/kbn-analytics/babel.config.js
deleted file mode 100644
index cdbc4feb60176..0000000000000
--- a/packages/kbn-analytics/babel.config.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-// We can't use common Kibana presets here because of babel versions incompatibility
-module.exports = {
- plugins: ['@babel/plugin-proposal-class-properties'],
- env: {
- web: {
- presets: ['@kbn/babel-preset/webpack_preset'],
- },
- node: {
- presets: ['@kbn/babel-preset/node_preset'],
- },
- },
- ignore: ['**/*.test.ts', '**/*.test.tsx'],
-};
diff --git a/packages/kbn-analytics/package.json b/packages/kbn-analytics/package.json
index 2195de578081e..726b62e1c61b8 100644
--- a/packages/kbn-analytics/package.json
+++ b/packages/kbn-analytics/package.json
@@ -4,13 +4,8 @@
"version": "1.0.0",
"description": "Kibana Analytics tool",
"main": "target/node/index.js",
- "browser": "target/web/index.js",
"types": "target/types/index.d.ts",
+ "browser": "target/web/index.js",
"author": "Ahmad Bamieh ",
- "license": "SSPL-1.0 OR Elastic License 2.0",
- "scripts": {
- "build": "node scripts/build",
- "kbn:bootstrap": "node scripts/build --source-maps",
- "kbn:watch": "node scripts/build --source-maps --watch"
- }
+ "license": "SSPL-1.0 OR Elastic License 2.0"
}
\ No newline at end of file
diff --git a/packages/kbn-analytics/scripts/build.js b/packages/kbn-analytics/scripts/build.js
deleted file mode 100644
index b9677d6a07a88..0000000000000
--- a/packages/kbn-analytics/scripts/build.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-const { resolve } = require('path');
-
-const del = require('del');
-const supportsColor = require('supports-color');
-const { run, withProcRunner } = require('@kbn/dev-utils');
-
-const ROOT_DIR = resolve(__dirname, '..');
-const BUILD_DIR = resolve(ROOT_DIR, 'target');
-
-const padRight = (width, str) =>
- str.length >= width ? str : `${str}${' '.repeat(width - str.length)}`;
-
-run(
- async ({ log, flags }) => {
- await withProcRunner(log, async (proc) => {
- log.info('Deleting old output');
- await del(BUILD_DIR);
-
- const cwd = ROOT_DIR;
- const env = { ...process.env };
- if (supportsColor.stdout) {
- env.FORCE_COLOR = 'true';
- }
-
- log.info(`Starting babel and typescript${flags.watch ? ' in watch mode' : ''}`);
- await Promise.all([
- ...['web', 'node'].map((subTask) =>
- proc.run(padRight(10, `babel:${subTask}`), {
- cmd: 'babel',
- args: [
- 'src',
- '--config-file',
- require.resolve('../babel.config.js'),
- '--out-dir',
- resolve(BUILD_DIR, subTask),
- '--extensions',
- '.ts,.js,.tsx',
- ...(flags.watch ? ['--watch'] : ['--quiet']),
- ...(!flags['source-maps'] || !!process.env.CODE_COVERAGE
- ? []
- : ['--source-maps', 'inline']),
- ],
- wait: true,
- env: {
- ...env,
- BABEL_ENV: subTask,
- },
- cwd,
- })
- ),
-
- proc.run(padRight(10, 'tsc'), {
- cmd: 'tsc',
- args: [
- ...(flags.watch ? ['--watch', '--preserveWatchOutput', 'true'] : []),
- ...(flags['source-maps'] ? ['--declarationMap', 'true'] : []),
- ],
- wait: true,
- env,
- cwd,
- }),
- ]);
-
- log.success('Complete');
- });
- },
- {
- description: 'Simple build tool for @kbn/analytics package',
- flags: {
- boolean: ['watch', 'source-maps'],
- help: `
- --watch Run in watch mode
- --source-maps Include sourcemaps
- `,
- },
- }
-);
diff --git a/packages/kbn-analytics/tsconfig.browser.json b/packages/kbn-analytics/tsconfig.browser.json
new file mode 100644
index 0000000000000..12f70b77008e7
--- /dev/null
+++ b/packages/kbn-analytics/tsconfig.browser.json
@@ -0,0 +1,18 @@
+{
+ "extends": "../../tsconfig.browser.json",
+ "compilerOptions": {
+ "incremental": true,
+ "outDir": "./target/web",
+ "stripInternal": true,
+ "declaration": false,
+ "isolatedModules": true,
+ "sourceMap": true,
+ "sourceRoot": "../../../../../packages/kbn-analytics/src",
+ "types": [
+ "node"
+ ]
+ },
+ "include": [
+ "src/**/*"
+ ]
+}
diff --git a/packages/kbn-analytics/tsconfig.json b/packages/kbn-analytics/tsconfig.json
index 80a2255d71805..165a8b695db57 100644
--- a/packages/kbn-analytics/tsconfig.json
+++ b/packages/kbn-analytics/tsconfig.json
@@ -1,10 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
- "incremental": false,
- "outDir": "./target/types",
+ "incremental": true,
+ "declarationDir": "./target/types",
+ "outDir": "./target/node",
"stripInternal": true,
- "emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
"isolatedModules": true,
diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json
index 8b08f64ba0f62..54d983bf1bf44 100644
--- a/packages/kbn-ui-shared-deps/package.json
+++ b/packages/kbn-ui-shared-deps/package.json
@@ -9,7 +9,6 @@
"kbn:watch": "node scripts/build --dev --watch"
},
"dependencies": {
- "@kbn/analytics": "link:../kbn-analytics",
"@kbn/i18n": "link:../kbn-i18n",
"@kbn/monaco": "link:../kbn-monaco"
}
diff --git a/yarn.lock b/yarn.lock
index 39b223b9b00b0..29db5e0d4830a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2587,7 +2587,7 @@
version "0.0.0"
uid ""
-"@kbn/analytics@link:packages/kbn-analytics":
+"@kbn/analytics@link:bazel-bin/packages/kbn-analytics/npm_module":
version "0.0.0"
uid ""
From b2a20fc9af1d0ba765bb59f8cbfee5566b97c907 Mon Sep 17 00:00:00 2001
From: Nicolas Chaulet
Date: Mon, 3 May 2021 17:42:07 -0400
Subject: [PATCH 28/81] [Fleet] Fix fleet server host port during settings
creation (#99084)
---
x-pack/plugins/fleet/server/services/settings.ts | 12 ++++++------
.../fleet_api_integration/apis/settings/update.ts | 12 ++++++++++++
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts
index 6b1a17fc5b060..e493234d1cff8 100644
--- a/x-pack/plugins/fleet/server/services/settings.ts
+++ b/x-pack/plugins/fleet/server/services/settings.ts
@@ -79,14 +79,14 @@ export async function saveSettings(
soClient: SavedObjectsClientContract,
newData: Partial>
): Promise & Pick> {
+ const data = { ...newData };
+ if (data.fleet_server_hosts) {
+ data.fleet_server_hosts = data.fleet_server_hosts.map(normalizeFleetServerHost);
+ }
+
try {
const settings = await getSettings(soClient);
- const data = { ...newData };
- if (data.fleet_server_hosts) {
- data.fleet_server_hosts = data.fleet_server_hosts.map(normalizeFleetServerHost);
- }
-
const res = await soClient.update(
GLOBAL_SETTINGS_SAVED_OBJECT_TYPE,
settings.id,
@@ -102,7 +102,7 @@ export async function saveSettings(
const defaultSettings = createDefaultSettings();
const res = await soClient.create(GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, {
...defaultSettings,
- ...newData,
+ ...data,
});
return {
diff --git a/x-pack/test/fleet_api_integration/apis/settings/update.ts b/x-pack/test/fleet_api_integration/apis/settings/update.ts
index 2c4992b21d71a..31fcb74627915 100644
--- a/x-pack/test/fleet_api_integration/apis/settings/update.ts
+++ b/x-pack/test/fleet_api_integration/apis/settings/update.ts
@@ -38,6 +38,18 @@ export default function (providerContext: FtrProviderContext) {
after(async () => {
await esArchiver.unload('fleet/empty_fleet_server');
});
+
+ it('should explicitly set port on fleet_server_hosts', async function () {
+ await supertest
+ .put(`/api/fleet/settings`)
+ .set('kbn-xsrf', 'xxxx')
+ .send({ fleet_server_hosts: ['https://test.fr'] })
+ .expect(200);
+
+ const { body: getSettingsRes } = await supertest.get(`/api/fleet/settings`).expect(200);
+ expect(getSettingsRes.item.fleet_server_hosts).to.eql(['https://test.fr:443']);
+ });
+
it("should bump all agent policy's revision", async function () {
const { body: testPolicy1PostRes } = await supertest
.post(`/api/fleet/agent_policies`)
From c7977614ed7ab11516dfbaf733da6ef7f8cceebe Mon Sep 17 00:00:00 2001
From: Jonathan Budzenski
Date: Mon, 3 May 2021 17:04:34 -0500
Subject: [PATCH 29/81] [docs/build] Update build dependencies list (#98545)
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
docs/developer/getting-started/building-kibana.asciidoc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/developer/getting-started/building-kibana.asciidoc b/docs/developer/getting-started/building-kibana.asciidoc
index 04771b34bf69f..b015be79abca2 100644
--- a/docs/developer/getting-started/building-kibana.asciidoc
+++ b/docs/developer/getting-started/building-kibana.asciidoc
@@ -18,12 +18,12 @@ yarn build --help
[discrete]
=== Building OS packages
-Packages are built using fpm, dpkg, and rpm. Package building has only been tested on Linux and is not supported on any other platform.
-
+Packages are built using fpm, dpkg, and rpm, and Docker. Package building has only been tested on Linux and is not supported on any other platform.
+Docker installation instructions can be found at https://docs.docker.com/engine/install/[Install Docker Engine].
[source,bash]
----
-apt-get install ruby-dev rpm
+apt-get install ruby ruby-dev rpm dpkg build-essential
gem install fpm -v 1.5.0
yarn build --skip-archives
----
From 7a92ea3e10c88913baa378cb0bce1c61ed12cb43 Mon Sep 17 00:00:00 2001
From: Aaron Caldwell
Date: Mon, 3 May 2021 16:42:01 -0600
Subject: [PATCH 30/81] [Maps][File upload] Add validation check that ensure
index name has been provided (#99118)
---
x-pack/plugins/file_upload/public/validate_index_name.ts | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/x-pack/plugins/file_upload/public/validate_index_name.ts b/x-pack/plugins/file_upload/public/validate_index_name.ts
index cd190188b6a63..c13f09f58ae21 100644
--- a/x-pack/plugins/file_upload/public/validate_index_name.ts
+++ b/x-pack/plugins/file_upload/public/validate_index_name.ts
@@ -23,6 +23,12 @@ export function checkIndexPatternValid(name: string) {
}
export const validateIndexName = async (indexName: string) => {
+ if (!indexName) {
+ return i18n.translate('xpack.fileUpload.indexNameRequired', {
+ defaultMessage: 'Index name required',
+ });
+ }
+
if (!checkIndexPatternValid(indexName)) {
return i18n.translate('xpack.fileUpload.indexNameContainsIllegalCharactersErrorMessage', {
defaultMessage: 'Index name contains illegal characters.',
From 4d3499822d62647536b02be3cf4d79965680c0db Mon Sep 17 00:00:00 2001
From: Liza Katz
Date: Tue, 4 May 2021 01:58:06 +0300
Subject: [PATCH 31/81] [Bug] Fix saved query parsing (#99014)
* Fix saved query parsing
* handle null string
---
.../saved_query/saved_query_service.test.ts | 68 +++++++++++++++++++
.../query/saved_query/saved_query_service.ts | 14 ++--
2 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/src/plugins/data/public/query/saved_query/saved_query_service.test.ts b/src/plugins/data/public/query/saved_query/saved_query_service.test.ts
index 5e566a9ec0135..a74f81b6a046d 100644
--- a/src/plugins/data/public/query/saved_query/saved_query_service.test.ts
+++ b/src/plugins/data/public/query/saved_query/saved_query_service.test.ts
@@ -278,6 +278,74 @@ describe('saved query service', () => {
await getSavedQuery('foo');
expect(mockSavedObjectsClient.get).toHaveBeenCalledWith('query', 'foo');
});
+
+ it('should parse a json query', async () => {
+ mockSavedObjectsClient.get.mockReturnValue({
+ id: 'food',
+ attributes: {
+ title: 'food',
+ description: 'bar',
+ query: {
+ language: 'kuery',
+ query: '{"x": "y"}',
+ },
+ },
+ });
+
+ const response = await getSavedQuery('food');
+ expect(response.attributes.query.query).toEqual({ x: 'y' });
+ });
+
+ it('should handle null string', async () => {
+ mockSavedObjectsClient.get.mockReturnValue({
+ id: 'food',
+ attributes: {
+ title: 'food',
+ description: 'bar',
+ query: {
+ language: 'kuery',
+ query: 'null',
+ },
+ },
+ });
+
+ const response = await getSavedQuery('food');
+ expect(response.attributes.query.query).toEqual('null');
+ });
+
+ it('should handle null quoted string', async () => {
+ mockSavedObjectsClient.get.mockReturnValue({
+ id: 'food',
+ attributes: {
+ title: 'food',
+ description: 'bar',
+ query: {
+ language: 'kuery',
+ query: '"null"',
+ },
+ },
+ });
+
+ const response = await getSavedQuery('food');
+ expect(response.attributes.query.query).toEqual('"null"');
+ });
+
+ it('should not lose quotes', async () => {
+ mockSavedObjectsClient.get.mockReturnValue({
+ id: 'food',
+ attributes: {
+ title: 'food',
+ description: 'bar',
+ query: {
+ language: 'kuery',
+ query: '"Bob"',
+ },
+ },
+ });
+
+ const response = await getSavedQuery('food');
+ expect(response.attributes.query.query).toEqual('"Bob"');
+ });
});
describe('deleteSavedQuery', function () {
diff --git a/src/plugins/data/public/query/saved_query/saved_query_service.ts b/src/plugins/data/public/query/saved_query/saved_query_service.ts
index e29066c8892cf..0f3da8f80a5ec 100644
--- a/src/plugins/data/public/query/saved_query/saved_query_service.ts
+++ b/src/plugins/data/public/query/saved_query/saved_query_service.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import { isObject } from 'lodash';
import { SavedObjectsClientContract, SavedObjectAttributes } from 'src/core/public';
import { SavedQueryAttributes, SavedQuery, SavedQueryService } from './types';
@@ -119,12 +120,15 @@ export const createSavedQueryService = (
id: string;
attributes: SerializedSavedQueryAttributes;
}) => {
- let queryString;
+ let queryString: string | object = savedQuery.attributes.query.query;
+
try {
- queryString = JSON.parse(savedQuery.attributes.query.query);
- } catch (error) {
- queryString = savedQuery.attributes.query.query;
- }
+ const parsedQueryString: object = JSON.parse(savedQuery.attributes.query.query);
+ if (isObject(parsedQueryString)) {
+ queryString = parsedQueryString;
+ }
+ } catch (e) {} // eslint-disable-line no-empty
+
const savedQueryItems: SavedQueryAttributes = {
title: savedQuery.attributes.title || '',
description: savedQuery.attributes.description || '',
From 582c6c7ae3bada799af169cad0a43180e5e6e242 Mon Sep 17 00:00:00 2001
From: ymao1
Date: Mon, 3 May 2021 19:18:13 -0400
Subject: [PATCH 32/81] [Alerting][Docs] Adding query to identify long running
rules to docs (#98773)
* Adding query to identify long running rules to docs
* Wording suggestsion from PR review
* Adding event.provider to query. Allowing copy to console
* Adding note for system privileges
* Adding runtime field to query
* Removing extra dollar sign
* PR fixes
---
.../alerting-troubleshooting.asciidoc | 164 ++++++++++++++++++
1 file changed, 164 insertions(+)
diff --git a/docs/user/alerting/alerting-troubleshooting.asciidoc b/docs/user/alerting/alerting-troubleshooting.asciidoc
index 6d4a0e9375678..b7fd98d1c674e 100644
--- a/docs/user/alerting/alerting-troubleshooting.asciidoc
+++ b/docs/user/alerting/alerting-troubleshooting.asciidoc
@@ -69,3 +69,167 @@ Configuration options are available to specialize connections to TLS servers,
including ignoring server certificate validation, and providing certificate
authority data to verify servers using custom certificates. For more details,
see <>.
+
+[float]
+[[rules-long-execution-time]]
+=== Identify long-running rules
+
+The following query can help you identify rules that are taking a long time to execute and might impact the overall health of your deployment.
+
+[IMPORTANT]
+==============================================
+By default, only users with a `superuser` role can query the {kib} event log because it is a system index. To enable additional users to execute this query, assign `read` privileges to the `.kibana-event-log*` index.
+==============================================
+
+Query for a list of rule ids, bucketed by their execution times:
+
+[source,console]
+--------------------------------------------------
+GET /.kibana-event-log*/_search
+{
+ "size": 0,
+ "query": {
+ "bool": {
+ "filter": [
+ {
+ "range": {
+ "@timestamp": {
+ "gte": "now-1d", <1>
+ "lte": "now"
+ }
+ }
+ },
+ {
+ "term": {
+ "event.action": {
+ "value": "execute"
+ }
+ }
+ },
+ {
+ "term": {
+ "event.provider": {
+ "value": "alerting" <2>
+ }
+ }
+ }
+ ]
+ }
+ },
+ "runtime_mappings": { <3>
+ "event.duration_in_seconds": {
+ "type": "double",
+ "script": {
+ "source": "emit(doc['event.duration'].value / 1E9)"
+ }
+ }
+ },
+ "aggs": {
+ "ruleIdsByExecutionDuration": {
+ "histogram": {
+ "field": "event.duration_in_seconds",
+ "min_doc_count": 1,
+ "interval": 1 <4>
+ },
+ "aggs": {
+ "ruleId": {
+ "nested": {
+ "path": "kibana.saved_objects"
+ },
+ "aggs": {
+ "ruleId": {
+ "terms": {
+ "field": "kibana.saved_objects.id",
+ "size": 10 <5>
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------
+// TEST
+
+<1> This queries for rules executed in the last day. Update the values of `lte` and `gte` to query over a different time range.
+<2> Use `event.provider: actions` to query for long-running action executions.
+<3> Execution durations are stored as nanoseconds. This adds a runtime field to convert that duration into seconds.
+<4> This interval buckets the event.duration_in_seconds runtime field into 1 second intervals. Update this value to change the granularity of the buckets. If you are unable to use runtime fields, make sure this aggregation targets `event.duration` and use nanoseconds for the interval.
+<5> This retrieves the top 10 rule ids for this duration interval. Update this value to retrieve more rule ids.
+
+This query returns the following:
+
+[source,json]
+--------------------------------------------------
+{
+ "took" : 322,
+ "timed_out" : false,
+ "_shards" : {
+ "total" : 1,
+ "successful" : 1,
+ "skipped" : 0,
+ "failed" : 0
+ },
+ "hits" : {
+ "total" : {
+ "value" : 326,
+ "relation" : "eq"
+ },
+ "max_score" : null,
+ "hits" : [ ]
+ },
+ "aggregations" : {
+ "ruleIdsByExecutionDuration" : {
+ "buckets" : [
+ {
+ "key" : 0.0, <1>
+ "doc_count" : 320,
+ "ruleId" : {
+ "doc_count" : 320,
+ "ruleId" : {
+ "doc_count_error_upper_bound" : 0,
+ "sum_other_doc_count" : 0,
+ "buckets" : [
+ {
+ "key" : "1923ada0-a8f3-11eb-a04b-13d723cdfdc5",
+ "doc_count" : 140
+ },
+ {
+ "key" : "15415ecf-cdb0-4fef-950a-f824bd277fe4",
+ "doc_count" : 130
+ },
+ {
+ "key" : "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2",
+ "doc_count" : 50
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key" : 30.0, <2>
+ "doc_count" : 6,
+ "ruleId" : {
+ "doc_count" : 6,
+ "ruleId" : {
+ "doc_count_error_upper_bound" : 0,
+ "sum_other_doc_count" : 0,
+ "buckets" : [
+ {
+ "key" : "41893910-6bca-11eb-9e0d-85d233e3ee35",
+ "doc_count" : 6
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
+--------------------------------------------------
+<1> Most rule execution durations fall within the first bucket (0 - 1 seconds).
+<2> A single rule with id `41893910-6bca-11eb-9e0d-85d233e3ee35` took between 30 and 31 seconds to execute.
+
+Use the <> to retrieve additional information about rules that take a long time to execute.
\ No newline at end of file
From 992ff93a6e3dce29afb43ee5c505ef76f877a6db Mon Sep 17 00:00:00 2001
From: Constance