"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.retrieveAlertOsTypes = exports.prepareExceptionItemsForBulkClose = exports.lowercaseHashValues = exports.isAlertFromEndpointEvent = exports.getProcessCodeSignature = exports.getPrepopulatedRuleExceptionWithHighlightFields = exports.getPrepopulatedRansomwareException = exports.getPrepopulatedMemorySignatureException = exports.getPrepopulatedMemoryShellcodeException = exports.getPrepopulatedEndpointException = exports.getPrepopulatedBehaviorException = exports.getFormattedComments = exports.getFileCodeSignature = exports.getCodeSignatureValue = exports.getAlertHighlightedFields = exports.formatOperatingSystems = exports.formatExceptionItemForUpdate = exports.filterHighlightedFields = exports.enrichSharedExceptions = exports.enrichRuleExceptions = exports.enrichNewExceptionItemsWithName = exports.enrichNewExceptionItemsWithExpireTime = exports.enrichNewExceptionItemsWithComments = exports.enrichExistingExceptionItemWithComments = exports.enrichExceptionItemsWithOS = exports.defaultEndpointExceptionItems = exports.buildRuleExceptionWithConditions = exports.buildGetAlertByIdQuery = exports.buildExceptionEntriesFromAlertFields = void 0; var _react = _interopRequireDefault(require("react")); var _eui = require("@elastic/eui"); var _lodash = require("lodash"); var _moment = _interopRequireDefault(require("moment")); var _securitysolutionIoTsListTypes = require("@kbn/securitysolution-io-ts-list-types"); var _securitysolutionListUtils = require("@kbn/securitysolution-list-utils"); var _securitysolutionListHooks = require("@kbn/securitysolution-list-hooks"); var _get_alert_summary_rows = require("../../../common/components/event_details/get_alert_summary_rows"); var i18n = _interopRequireWildcard(require("./translations")); var _with_copy_to_clipboard = require("../../../common/lib/clipboard/with_copy_to_clipboard"); var _field_names = require("../../../../common/field_maps/field_names"); var _highlighted_fields_config = require("./highlighted_fields_config"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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. */ /** * Formats os value array to a displayable string */ const formatOperatingSystems = osTypes => { return osTypes.filter(os => ['linux', 'macos', 'windows'].includes(os)).map(os => { if (os === 'macos') { return 'macOS'; } return (0, _lodash.capitalize)(os); }).join(', '); }; /** * Formats ExceptionItem.comments into EuiCommentList format * * @param comments ExceptionItem.comments */ exports.formatOperatingSystems = formatOperatingSystems; const getFormattedComments = comments => comments.map(commentItem => ({ username: commentItem.created_by, timestamp: (0, _moment.default)(commentItem.created_at).format('on MMM Do YYYY @ HH:mm:ss'), event: i18n.COMMENT_EVENT, timelineAvatar: /*#__PURE__*/_react.default.createElement(_eui.EuiAvatar, { size: "l", name: commentItem.created_by.toUpperCase() }), children: /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, commentItem.comment), actions: /*#__PURE__*/_react.default.createElement(_with_copy_to_clipboard.WithCopyToClipboard, { "data-test-subj": "copy-to-clipboard", text: commentItem.comment, titleSummary: i18n.ADD_TO_CLIPBOARD }) })); exports.getFormattedComments = getFormattedComments; const formatExceptionItemForUpdate = exceptionItem => { /* eslint-disable @typescript-eslint/naming-convention */ const { created_at, created_by, list_id, tie_breaker_id, updated_at, updated_by, /* eslint-enable @typescript-eslint/naming-convention */ ...fieldsToUpdate } = exceptionItem; return { ...fieldsToUpdate }; }; /** * Maps "event." fields to "signal.original_event.". This is because when a rule is created * the "event" field is copied over to "original_event". When the user creates an exception, * they expect it to match against the original_event's fields, not the signal event's. * @param exceptionItems new or existing ExceptionItem[] */ exports.formatExceptionItemForUpdate = formatExceptionItemForUpdate; const prepareExceptionItemsForBulkClose = exceptionItems => { return exceptionItems.map(item => { if (item.entries !== undefined) { const newEntries = item.entries.map(itemEntry => { const entry = (0, _lodash.omit)(itemEntry, 'id'); return { ...entry, field: entry.field.startsWith('event.') ? entry.field.replace(/^event./, `${_field_names.ALERT_ORIGINAL_EVENT}.`) : entry.field }; }); return { ...item, entries: newEntries, comments: [] // Strips out unneeded comments attribute for bulk close as they are not needed and are throwing type errors }; } else { return { ...item, comments: [] }; } }); }; /** * Adds new and existing comments to all new exceptionItems if not present already * @param exceptionItems new or existing ExceptionItem[] * @param comments new Comment */ exports.prepareExceptionItemsForBulkClose = prepareExceptionItemsForBulkClose; const enrichNewExceptionItemsWithComments = (exceptionItems, comments) => { return exceptionItems.map(item => { return { ...item, comments }; }); }; /** * Adds expireTime to all new exceptionItems if not present already * @param exceptionItems new or existing ExceptionItem[] * @param expireTime new expireTime */ exports.enrichNewExceptionItemsWithComments = enrichNewExceptionItemsWithComments; const enrichNewExceptionItemsWithExpireTime = (exceptionItems, expireTime) => { const expireTimeDateString = expireTime !== undefined ? expireTime.toISOString() : undefined; return exceptionItems.map(item => { return { ...item, expire_time: expireTimeDateString }; }); }; exports.enrichNewExceptionItemsWithExpireTime = enrichNewExceptionItemsWithExpireTime; const buildGetAlertByIdQuery = id => ({ query: { match: { _id: { query: id || '' } } } }); /** * Adds new and existing comments to exceptionItem * @param exceptionItem existing ExceptionItem * @param comments array of comments that can include existing * and new comments */ exports.buildGetAlertByIdQuery = buildGetAlertByIdQuery; const enrichExistingExceptionItemWithComments = (exceptionItem, comments) => { const formattedComments = comments.map(item => { if (_securitysolutionIoTsListTypes.comment.is(item)) { const { id, comment: existingComment } = item; return { id, comment: existingComment }; } else { return { comment: item.comment }; } }); return { ...exceptionItem, comments: formattedComments }; }; /** * Adds provided osTypes to all exceptionItems if not present already * @param exceptionItems new or existing ExceptionItem[] * @param osTypes array of os values */ exports.enrichExistingExceptionItemWithComments = enrichExistingExceptionItemWithComments; const enrichExceptionItemsWithOS = (exceptionItems, osTypes) => { return exceptionItems.map(item => { return { ...item, os_types: osTypes }; }); }; exports.enrichExceptionItemsWithOS = enrichExceptionItemsWithOS; const retrieveAlertOsTypes = alertData => { const osDefaults = ['windows', 'macos']; if (alertData != null) { var _alertData$agent, _alertData$host, _alertData$host$os, _alertData$host$os$na, _alertData$host2, _alertData$host2$os; const os = (alertData === null || alertData === void 0 ? void 0 : (_alertData$agent = alertData.agent) === null || _alertData$agent === void 0 ? void 0 : _alertData$agent.type) === 'endpoint' ? (_alertData$host = alertData.host) === null || _alertData$host === void 0 ? void 0 : (_alertData$host$os = _alertData$host.os) === null || _alertData$host$os === void 0 ? void 0 : (_alertData$host$os$na = _alertData$host$os.name) === null || _alertData$host$os$na === void 0 ? void 0 : _alertData$host$os$na.toLowerCase() : (_alertData$host2 = alertData.host) === null || _alertData$host2 === void 0 ? void 0 : (_alertData$host2$os = _alertData$host2.os) === null || _alertData$host2$os === void 0 ? void 0 : _alertData$host2$os.family; if (os != null) { return _securitysolutionIoTsListTypes.osType.is(os) ? [os] : osDefaults; } } return osDefaults; }; /** * Returns given exceptionItems with all hash-related entries lowercased */ exports.retrieveAlertOsTypes = retrieveAlertOsTypes; const lowercaseHashValues = exceptionItems => { return exceptionItems.map(item => { const newEntries = item.entries.map(itemEntry => { if (itemEntry.field.includes('.hash')) { if (itemEntry.type === 'match') { return { ...itemEntry, value: itemEntry.value.toLowerCase() }; } else if (itemEntry.type === 'match_any') { return { ...itemEntry, value: itemEntry.value.map(val => val.toLowerCase()) }; } } return itemEntry; }); return { ...item, entries: newEntries }; }); }; /** * Returns the value for `file.Ext.code_signature` which * can be an object or array of objects */ exports.lowercaseHashValues = lowercaseHashValues; const getFileCodeSignature = alertData => { const { file } = alertData; const codeSignature = file && file.Ext && file.Ext.code_signature; return getCodeSignatureValue(codeSignature); }; /** * Returns the value for `process.Ext.code_signature` which * can be an object or array of objects */ exports.getFileCodeSignature = getFileCodeSignature; const getProcessCodeSignature = alertData => { const { process } = alertData; const codeSignature = process && process.Ext && process.Ext.code_signature; return getCodeSignatureValue(codeSignature); }; /** * Pre 7.10 `Ext.code_signature` fields were mistakenly populated as * a single object with subject_name and trusted. */ exports.getProcessCodeSignature = getProcessCodeSignature; const getCodeSignatureValue = codeSignature => { if (Array.isArray(codeSignature) && codeSignature.length > 0) { return codeSignature.map(signature => { var _signature$subject_na, _signature$trusted$to, _signature$trusted; return { subjectName: (_signature$subject_na = signature === null || signature === void 0 ? void 0 : signature.subject_name) !== null && _signature$subject_na !== void 0 ? _signature$subject_na : '', trusted: (_signature$trusted$to = signature === null || signature === void 0 ? void 0 : (_signature$trusted = signature.trusted) === null || _signature$trusted === void 0 ? void 0 : _signature$trusted.toString()) !== null && _signature$trusted$to !== void 0 ? _signature$trusted$to : '' }; }); } else { var _signature$subject_na2, _signature$trusted2; const signature = !Array.isArray(codeSignature) ? codeSignature : undefined; return [{ subjectName: (_signature$subject_na2 = signature === null || signature === void 0 ? void 0 : signature.subject_name) !== null && _signature$subject_na2 !== void 0 ? _signature$subject_na2 : '', trusted: (_signature$trusted2 = signature === null || signature === void 0 ? void 0 : signature.trusted) !== null && _signature$trusted2 !== void 0 ? _signature$trusted2 : '' }]; } }; // helper type to filter empty-valued exception entries exports.getCodeSignatureValue = getCodeSignatureValue; /** * Takes an array of Entries and filter out the ones with empty values. * It will also filter out empty values for nested entries. */ function filterEmptyExceptionEntries(entries) { const finalEntries = []; for (const entry of entries) { if (entry.entries !== undefined) { entry.entries = entry.entries.filter(el => el.value !== undefined && el.value.length > 0); finalEntries.push(entry); } else if (entry.value !== undefined && entry.value.length > 0) { finalEntries.push(entry); } } return finalEntries; } /** * Returns the default values from the alert data to autofill new endpoint exceptions */ const getPrepopulatedEndpointException = ({ listId, name, codeSignature, eventCode, listNamespace = 'agnostic', alertEcsData }) => { var _file$path, _file$hash$sha, _file$hash, _host$os; const { file, host } = alertEcsData; const filePath = (_file$path = file === null || file === void 0 ? void 0 : file.path) !== null && _file$path !== void 0 ? _file$path : ''; const sha256Hash = (_file$hash$sha = file === null || file === void 0 ? void 0 : (_file$hash = file.hash) === null || _file$hash === void 0 ? void 0 : _file$hash.sha256) !== null && _file$hash$sha !== void 0 ? _file$hash$sha : ''; const isLinux = (host === null || host === void 0 ? void 0 : (_host$os = host.os) === null || _host$os === void 0 ? void 0 : _host$os.name) === 'Linux'; const commonFields = [{ field: isLinux ? 'file.path' : 'file.path.caseless', operator: 'included', type: 'match', value: filePath !== null && filePath !== void 0 ? filePath : '' }, { field: 'file.hash.sha256', operator: 'included', type: 'match', value: sha256Hash !== null && sha256Hash !== void 0 ? sha256Hash : '' }, { field: 'event.code', operator: 'included', type: 'match', value: eventCode !== null && eventCode !== void 0 ? eventCode : '' }]; const entriesToAdd = () => { if (isLinux) { return (0, _securitysolutionListUtils.addIdToEntries)(commonFields); } else { return (0, _securitysolutionListUtils.addIdToEntries)([{ field: 'file.Ext.code_signature', type: 'nested', entries: [{ field: 'subject_name', operator: 'included', type: 'match', value: codeSignature != null ? codeSignature.subjectName : '' }, { field: 'trusted', operator: 'included', type: 'match', value: codeSignature != null ? codeSignature.trusted : '' }] }, ...commonFields]); } }; return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId, namespaceType: listNamespace, name }), entries: entriesToAdd() }; }; /** * Returns the default values from the alert data to autofill new endpoint exceptions */ exports.getPrepopulatedEndpointException = getPrepopulatedEndpointException; const getPrepopulatedRansomwareException = ({ listId, name, codeSignature, eventCode, listNamespace = 'agnostic', alertEcsData }) => { var _process$hash$sha, _process$hash, _process$executable, _Ransomware$feature; const { process, Ransomware } = alertEcsData; const sha256Hash = (_process$hash$sha = process === null || process === void 0 ? void 0 : (_process$hash = process.hash) === null || _process$hash === void 0 ? void 0 : _process$hash.sha256) !== null && _process$hash$sha !== void 0 ? _process$hash$sha : ''; const executable = (_process$executable = process === null || process === void 0 ? void 0 : process.executable) !== null && _process$executable !== void 0 ? _process$executable : ''; const ransomwareFeature = (_Ransomware$feature = Ransomware === null || Ransomware === void 0 ? void 0 : Ransomware.feature) !== null && _Ransomware$feature !== void 0 ? _Ransomware$feature : ''; return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId, namespaceType: listNamespace, name }), entries: (0, _securitysolutionListUtils.addIdToEntries)([{ field: 'process.Ext.code_signature', type: 'nested', entries: [{ field: 'subject_name', operator: 'included', type: 'match', value: codeSignature != null ? codeSignature.subjectName : '' }, { field: 'trusted', operator: 'included', type: 'match', value: codeSignature != null ? codeSignature.trusted : '' }] }, { field: 'process.executable', operator: 'included', type: 'match', value: executable !== null && executable !== void 0 ? executable : '' }, { field: 'process.hash.sha256', operator: 'included', type: 'match', value: sha256Hash !== null && sha256Hash !== void 0 ? sha256Hash : '' }, { field: 'Ransomware.feature', operator: 'included', type: 'match', value: ransomwareFeature !== null && ransomwareFeature !== void 0 ? ransomwareFeature : '' }, { field: 'event.code', operator: 'included', type: 'match', value: eventCode !== null && eventCode !== void 0 ? eventCode : '' }]) }; }; exports.getPrepopulatedRansomwareException = getPrepopulatedRansomwareException; const getPrepopulatedMemorySignatureException = ({ listId, name, eventCode, listNamespace = 'agnostic', alertEcsData }) => { var _alertEcsData$Memory_, _alertEcsData$Memory_2, _process$executable2, _process$name, _process$hash$sha2, _process$hash2; const { process } = alertEcsData; const entries = filterEmptyExceptionEntries([{ field: 'Memory_protection.feature', operator: 'included', type: 'match', value: (_alertEcsData$Memory_ = (_alertEcsData$Memory_2 = alertEcsData.Memory_protection) === null || _alertEcsData$Memory_2 === void 0 ? void 0 : _alertEcsData$Memory_2.feature) !== null && _alertEcsData$Memory_ !== void 0 ? _alertEcsData$Memory_ : '' }, { field: 'process.executable.caseless', operator: 'included', type: 'match', value: (_process$executable2 = process === null || process === void 0 ? void 0 : process.executable) !== null && _process$executable2 !== void 0 ? _process$executable2 : '' }, { field: 'process.name.caseless', operator: 'included', type: 'match', value: (_process$name = process === null || process === void 0 ? void 0 : process.name) !== null && _process$name !== void 0 ? _process$name : '' }, { field: 'process.hash.sha256', operator: 'included', type: 'match', value: (_process$hash$sha2 = process === null || process === void 0 ? void 0 : (_process$hash2 = process.hash) === null || _process$hash2 === void 0 ? void 0 : _process$hash2.sha256) !== null && _process$hash$sha2 !== void 0 ? _process$hash$sha2 : '' }]); return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId, namespaceType: listNamespace, name }), entries: (0, _securitysolutionListUtils.addIdToEntries)(entries) }; }; exports.getPrepopulatedMemorySignatureException = getPrepopulatedMemorySignatureException; const getPrepopulatedMemoryShellcodeException = ({ listId, name, eventCode, listNamespace = 'agnostic', alertEcsData }) => { var _alertEcsData$Memory_3, _alertEcsData$Memory_4, _String, _alertEcsData$Memory_5, _process$executable3, _process$name2, _process$Ext$token$in, _process$Ext, _process$Ext$token; const { process } = alertEcsData; const entries = filterEmptyExceptionEntries([{ field: 'Memory_protection.feature', operator: 'included', type: 'match', value: (_alertEcsData$Memory_3 = (_alertEcsData$Memory_4 = alertEcsData.Memory_protection) === null || _alertEcsData$Memory_4 === void 0 ? void 0 : _alertEcsData$Memory_4.feature) !== null && _alertEcsData$Memory_3 !== void 0 ? _alertEcsData$Memory_3 : '' }, { field: 'Memory_protection.self_injection', operator: 'included', type: 'match', value: (_String = String((_alertEcsData$Memory_5 = alertEcsData.Memory_protection) === null || _alertEcsData$Memory_5 === void 0 ? void 0 : _alertEcsData$Memory_5.self_injection)) !== null && _String !== void 0 ? _String : '' }, { field: 'process.executable.caseless', operator: 'included', type: 'match', value: (_process$executable3 = process === null || process === void 0 ? void 0 : process.executable) !== null && _process$executable3 !== void 0 ? _process$executable3 : '' }, { field: 'process.name.caseless', operator: 'included', type: 'match', value: (_process$name2 = process === null || process === void 0 ? void 0 : process.name) !== null && _process$name2 !== void 0 ? _process$name2 : '' }, { field: 'process.Ext.token.integrity_level_name', operator: 'included', type: 'match', value: (_process$Ext$token$in = process === null || process === void 0 ? void 0 : (_process$Ext = process.Ext) === null || _process$Ext === void 0 ? void 0 : (_process$Ext$token = _process$Ext.token) === null || _process$Ext$token === void 0 ? void 0 : _process$Ext$token.integrity_level_name) !== null && _process$Ext$token$in !== void 0 ? _process$Ext$token$in : '' }]); return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId, namespaceType: listNamespace, name }), entries: (0, _securitysolutionListUtils.addIdToEntries)(entries) }; }; exports.getPrepopulatedMemoryShellcodeException = getPrepopulatedMemoryShellcodeException; const getPrepopulatedBehaviorException = ({ listId, name, eventCode, listNamespace = 'agnostic', alertEcsData }) => { var _alertEcsData$rule$id, _alertEcsData$rule, _process$executable4, _process$command_line, _process$parent$execu, _process$parent, _process$code_signatu, _process$code_signatu2, _alertEcsData$file$pa, _alertEcsData$file, _alertEcsData$file$na, _alertEcsData$file2, _alertEcsData$source$, _alertEcsData$source, _alertEcsData$destina, _alertEcsData$destina2, _alertEcsData$registr, _alertEcsData$registr2, _alertEcsData$registr3, _alertEcsData$registr4, _alertEcsData$registr5, _alertEcsData$registr6, _alertEcsData$registr7, _alertEcsData$dll$pat, _alertEcsData$dll, _alertEcsData$dll$cod, _alertEcsData$dll2, _alertEcsData$dll2$co, _alertEcsData$dll$pe$, _alertEcsData$dll3, _alertEcsData$dll3$pe, _alertEcsData$dns$que, _alertEcsData$dns, _alertEcsData$dns$que2, _alertEcsData$dns$que3, _alertEcsData$dns2, _alertEcsData$dns2$qu, _alertEcsData$user$id, _alertEcsData$user; const { process } = alertEcsData; const entries = filterEmptyExceptionEntries([{ field: 'rule.id', operator: 'included', type: 'match', value: (_alertEcsData$rule$id = (_alertEcsData$rule = alertEcsData.rule) === null || _alertEcsData$rule === void 0 ? void 0 : _alertEcsData$rule.id) !== null && _alertEcsData$rule$id !== void 0 ? _alertEcsData$rule$id : '' }, { field: 'process.executable.caseless', operator: 'included', type: 'match', value: (_process$executable4 = process === null || process === void 0 ? void 0 : process.executable) !== null && _process$executable4 !== void 0 ? _process$executable4 : '' }, { field: 'process.command_line', operator: 'included', type: 'match', value: (_process$command_line = process === null || process === void 0 ? void 0 : process.command_line) !== null && _process$command_line !== void 0 ? _process$command_line : '' }, { field: 'process.parent.executable', operator: 'included', type: 'match', value: (_process$parent$execu = process === null || process === void 0 ? void 0 : (_process$parent = process.parent) === null || _process$parent === void 0 ? void 0 : _process$parent.executable) !== null && _process$parent$execu !== void 0 ? _process$parent$execu : '' }, { field: 'process.code_signature.subject_name', operator: 'included', type: 'match', value: (_process$code_signatu = process === null || process === void 0 ? void 0 : (_process$code_signatu2 = process.code_signature) === null || _process$code_signatu2 === void 0 ? void 0 : _process$code_signatu2.subject_name) !== null && _process$code_signatu !== void 0 ? _process$code_signatu : '' }, { field: 'file.path', operator: 'included', type: 'match', value: (_alertEcsData$file$pa = (_alertEcsData$file = alertEcsData.file) === null || _alertEcsData$file === void 0 ? void 0 : _alertEcsData$file.path) !== null && _alertEcsData$file$pa !== void 0 ? _alertEcsData$file$pa : '' }, { field: 'file.name', operator: 'included', type: 'match', value: (_alertEcsData$file$na = (_alertEcsData$file2 = alertEcsData.file) === null || _alertEcsData$file2 === void 0 ? void 0 : _alertEcsData$file2.name) !== null && _alertEcsData$file$na !== void 0 ? _alertEcsData$file$na : '' }, { field: 'source.ip', operator: 'included', type: 'match', value: (_alertEcsData$source$ = (_alertEcsData$source = alertEcsData.source) === null || _alertEcsData$source === void 0 ? void 0 : _alertEcsData$source.ip) !== null && _alertEcsData$source$ !== void 0 ? _alertEcsData$source$ : '' }, { field: 'destination.ip', operator: 'included', type: 'match', value: (_alertEcsData$destina = (_alertEcsData$destina2 = alertEcsData.destination) === null || _alertEcsData$destina2 === void 0 ? void 0 : _alertEcsData$destina2.ip) !== null && _alertEcsData$destina !== void 0 ? _alertEcsData$destina : '' }, { field: 'registry.path', operator: 'included', type: 'match', value: (_alertEcsData$registr = (_alertEcsData$registr2 = alertEcsData.registry) === null || _alertEcsData$registr2 === void 0 ? void 0 : _alertEcsData$registr2.path) !== null && _alertEcsData$registr !== void 0 ? _alertEcsData$registr : '' }, { field: 'registry.value', operator: 'included', type: 'match', value: (_alertEcsData$registr3 = (_alertEcsData$registr4 = alertEcsData.registry) === null || _alertEcsData$registr4 === void 0 ? void 0 : _alertEcsData$registr4.value) !== null && _alertEcsData$registr3 !== void 0 ? _alertEcsData$registr3 : '' }, { field: 'registry.data.strings', operator: 'included', type: 'match', value: (_alertEcsData$registr5 = (_alertEcsData$registr6 = alertEcsData.registry) === null || _alertEcsData$registr6 === void 0 ? void 0 : (_alertEcsData$registr7 = _alertEcsData$registr6.data) === null || _alertEcsData$registr7 === void 0 ? void 0 : _alertEcsData$registr7.strings) !== null && _alertEcsData$registr5 !== void 0 ? _alertEcsData$registr5 : '' }, { field: 'dll.path', operator: 'included', type: 'match', value: (_alertEcsData$dll$pat = (_alertEcsData$dll = alertEcsData.dll) === null || _alertEcsData$dll === void 0 ? void 0 : _alertEcsData$dll.path) !== null && _alertEcsData$dll$pat !== void 0 ? _alertEcsData$dll$pat : '' }, { field: 'dll.code_signature.subject_name', operator: 'included', type: 'match', value: (_alertEcsData$dll$cod = (_alertEcsData$dll2 = alertEcsData.dll) === null || _alertEcsData$dll2 === void 0 ? void 0 : (_alertEcsData$dll2$co = _alertEcsData$dll2.code_signature) === null || _alertEcsData$dll2$co === void 0 ? void 0 : _alertEcsData$dll2$co.subject_name) !== null && _alertEcsData$dll$cod !== void 0 ? _alertEcsData$dll$cod : '' }, { field: 'dll.pe.original_file_name', operator: 'included', type: 'match', value: (_alertEcsData$dll$pe$ = (_alertEcsData$dll3 = alertEcsData.dll) === null || _alertEcsData$dll3 === void 0 ? void 0 : (_alertEcsData$dll3$pe = _alertEcsData$dll3.pe) === null || _alertEcsData$dll3$pe === void 0 ? void 0 : _alertEcsData$dll3$pe.original_file_name) !== null && _alertEcsData$dll$pe$ !== void 0 ? _alertEcsData$dll$pe$ : '' }, { field: 'dns.question.name', operator: 'included', type: 'match', value: (_alertEcsData$dns$que = (_alertEcsData$dns = alertEcsData.dns) === null || _alertEcsData$dns === void 0 ? void 0 : (_alertEcsData$dns$que2 = _alertEcsData$dns.question) === null || _alertEcsData$dns$que2 === void 0 ? void 0 : _alertEcsData$dns$que2.name) !== null && _alertEcsData$dns$que !== void 0 ? _alertEcsData$dns$que : '' }, { field: 'dns.question.type', operator: 'included', type: 'match', value: (_alertEcsData$dns$que3 = (_alertEcsData$dns2 = alertEcsData.dns) === null || _alertEcsData$dns2 === void 0 ? void 0 : (_alertEcsData$dns2$qu = _alertEcsData$dns2.question) === null || _alertEcsData$dns2$qu === void 0 ? void 0 : _alertEcsData$dns2$qu.type) !== null && _alertEcsData$dns$que3 !== void 0 ? _alertEcsData$dns$que3 : '' }, { field: 'user.id', operator: 'included', type: 'match', value: (_alertEcsData$user$id = (_alertEcsData$user = alertEcsData.user) === null || _alertEcsData$user === void 0 ? void 0 : _alertEcsData$user.id) !== null && _alertEcsData$user$id !== void 0 ? _alertEcsData$user$id : '' }]); return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId, namespaceType: listNamespace, name }), entries: (0, _securitysolutionListUtils.addIdToEntries)(entries) }; }; /** * Returns the default values from the alert data to autofill new endpoint exceptions */ exports.getPrepopulatedBehaviorException = getPrepopulatedBehaviorException; const defaultEndpointExceptionItems = (listId, name, alertEcsData) => { var _alertEcsData$eventC, _alertEcsData$event; const eventCode = (_alertEcsData$eventC = alertEcsData['event.code']) !== null && _alertEcsData$eventC !== void 0 ? _alertEcsData$eventC : (_alertEcsData$event = alertEcsData.event) === null || _alertEcsData$event === void 0 ? void 0 : _alertEcsData$event.code; switch (eventCode) { case 'behavior': return [getPrepopulatedBehaviorException({ listId, name, eventCode, alertEcsData })]; case 'memory_signature': return [getPrepopulatedMemorySignatureException({ listId, name, eventCode, alertEcsData })]; case 'shellcode_thread': return [getPrepopulatedMemoryShellcodeException({ listId, name, eventCode, alertEcsData })]; case 'ransomware': return getProcessCodeSignature(alertEcsData).map(codeSignature => getPrepopulatedRansomwareException({ listId, name, eventCode, codeSignature, alertEcsData })); default: // By default return the standard prepopulated Endpoint Exception fields return getFileCodeSignature(alertEcsData).map(codeSignature => getPrepopulatedEndpointException({ listId, name, eventCode: eventCode !== null && eventCode !== void 0 ? eventCode : '', codeSignature, alertEcsData })); } }; /** * Adds user defined name to all new exceptionItems * @param exceptionItems new or existing ExceptionItem[] * @param name new exception item name */ exports.defaultEndpointExceptionItems = defaultEndpointExceptionItems; const enrichNewExceptionItemsWithName = (exceptionItems, name) => { return exceptionItems.map(item => { return { ...item, name }; }); }; /** * Modifies exception items to prepare for creating as rule_default * list items * @param exceptionItems new or existing ExceptionItem[] */ exports.enrichNewExceptionItemsWithName = enrichNewExceptionItemsWithName; const enrichRuleExceptions = exceptionItems => { return exceptionItems.map(item => { return { ...(0, _securitysolutionListHooks.removeIdFromExceptionItemsEntries)(item), list_id: undefined, namespace_type: 'single' }; }); }; /** * Prepares items to be added to shared exception lists * @param exceptionItems new or existing ExceptionItem[] * @param lists shared exception lists that were selected to add items to */ exports.enrichRuleExceptions = enrichRuleExceptions; const enrichSharedExceptions = (exceptionItems, lists) => { return lists.flatMap(list => { return exceptionItems.map(item => { return { ...(0, _securitysolutionListHooks.removeIdFromExceptionItemsEntries)(item), list_id: list.list_id, namespace_type: list.namespace_type }; }); }); }; /** * Creates new Rule exception item with passed in entries */ exports.enrichSharedExceptions = enrichSharedExceptions; const buildRuleExceptionWithConditions = ({ name, exceptionEntries }) => { return { ...(0, _securitysolutionListUtils.getNewExceptionItem)({ listId: undefined, namespaceType: 'single', name }), entries: (0, _securitysolutionListUtils.addIdToEntries)(exceptionEntries) }; }; /** Generate exception conditions based on the highlighted fields of the alert that have corresponding values in the alert data. For the initial implementation the nested conditions are not considered Converting a singular value to a string or an array of strings is necessary because the "Match" or "Match any" operators are designed to operate with string value(s). */ exports.buildRuleExceptionWithConditions = buildRuleExceptionWithConditions; const buildExceptionEntriesFromAlertFields = ({ highlightedFields, alertData }) => { return Object.values(highlightedFields).reduce((acc, field) => { var _get; const fieldKey = field.id; const fieldValue = (_get = (0, _lodash.get)(alertData, fieldKey)) !== null && _get !== void 0 ? _get : (0, _lodash.get)(alertData, (0, _highlighted_fields_config.getKibanaAlertIdField)(fieldKey)); if (fieldValue !== null && fieldValue !== undefined) { const listOperatorType = Array.isArray(fieldValue) ? _securitysolutionIoTsListTypes.ListOperatorTypeEnum.MATCH_ANY : _securitysolutionIoTsListTypes.ListOperatorTypeEnum.MATCH; const fieldValueAsString = Array.isArray(fieldValue) ? fieldValue.map(String) : fieldValue.toString(); acc.push({ field: fieldKey, operator: _securitysolutionIoTsListTypes.ListOperatorEnum.INCLUDED, type: listOperatorType, value: fieldValueAsString }); } return acc; }, []); }; /** * Prepopulate the Rule Exception with the highlighted fields from the Alert's Summary. * @param alertData The Alert data object * @param exceptionItemName The name of the Exception Item * @returns A new Rule Exception Item with the highlighted fields as entries, */ exports.buildExceptionEntriesFromAlertFields = buildExceptionEntriesFromAlertFields; const getPrepopulatedRuleExceptionWithHighlightFields = ({ alertData, exceptionItemName, ruleCustomHighlightedFields }) => { const highlightedFields = getAlertHighlightedFields(alertData, ruleCustomHighlightedFields); if (!highlightedFields.length) return null; const exceptionEntries = buildExceptionEntriesFromAlertFields({ highlightedFields, alertData }); if (!exceptionEntries.length) return null; return buildRuleExceptionWithConditions({ name: exceptionItemName, exceptionEntries }); }; /** Filters out the irrelevant highlighted fields for Rule exceptions using 1. The "highlightedFieldsPrefixToExclude" array 2. Agent.id field in case the alert was not generated from Endpoint 3. Threshold Rule */ exports.getPrepopulatedRuleExceptionWithHighlightFields = getPrepopulatedRuleExceptionWithHighlightFields; const filterHighlightedFields = (fields, prefixesToExclude, alertData) => { return fields.filter(({ id }) => { // Exclude agent.id field only if the agent type was not Endpoint if (id === _highlighted_fields_config.AGENT_ID) return isAlertFromEndpointEvent(alertData); return !prefixesToExclude.some(field => id.startsWith(field)); }); }; /** * Retrieve the highlighted fields from the Alert Summary based on the following Alert properties: * * event.category * * event.code * * kibana.alert.rule.type * * Alert field ids filters * @param alertData The Alert data object */ exports.filterHighlightedFields = filterHighlightedFields; const getAlertHighlightedFields = (alertData, ruleCustomHighlightedFields) => { const eventCategory = (0, _lodash.get)(alertData, _highlighted_fields_config.EVENT_CATEGORY); const eventCode = (0, _lodash.get)(alertData, _highlighted_fields_config.EVENT_CODE); const eventRuleType = (0, _lodash.get)(alertData, _highlighted_fields_config.KIBANA_ALERT_RULE_TYPE); const eventCategories = { primaryEventCategory: Array.isArray(eventCategory) ? eventCategory[0] : eventCategory, allEventCategories: [eventCategory] }; const fieldsToDisplay = (0, _get_alert_summary_rows.getEventFieldsToDisplay)({ eventCategories, eventCode, eventRuleType, highlightedFieldsOverride: ruleCustomHighlightedFields }); return filterHighlightedFields(fieldsToDisplay, _highlighted_fields_config.highlightedFieldsPrefixToExclude, alertData); }; /** * Checks to see if the given set of Timeline event detail items includes data that indicates its * an endpoint Alert */ exports.getAlertHighlightedFields = getAlertHighlightedFields; const isAlertFromEndpointEvent = alertData => { // Check to see if a timeline event item is an Alert const isTimelineEventItemAnAlert = (0, _lodash.get)(alertData, _highlighted_fields_config.KIBANA_ALERT_RULE_UUID); if (!isTimelineEventItemAnAlert) return false; const agentTypes = (0, _lodash.get)(alertData, _highlighted_fields_config.AGENT_TYPE); const agentType = Array.isArray(agentTypes) ? agentTypes[0] : agentTypes; return agentType === _highlighted_fields_config.ENDPOINT_ALERT; }; exports.isAlertFromEndpointEvent = isAlertFromEndpointEvent;