mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Security Solution][Endpoint Exceptions] Fixes bug where behavior alerts do not show nested code signatures with subject name and trusted field (#212325)
## Summary When navigating to the endpoint exceptions form from an alert, we pre-populate certain exceptions fields based on the type of alert. There was a bug for behavior alerts where we did not use the proper nested `code_signature` field for windows and mac endpoints. Instead of showing the nested `code_signature` field that has the `subject_name` and `trusted` sub-fields, we only showed non-nested `code_signature subject field. This PR also refactors the code to account for the following behaviors that we want: - [x] If `field.Ext.code_signature` is present, we want to use the nested `code_signature` subject field with the `subject_name` and `trusted` sub-fields for - [x] If `field.Ext.code_signature` is not present, we will default to the non-nested `field.code_signature.subject_name` and `field.code_signature.trusted` field pair. - [x] We will only show non-empty pre-populated values and also only code signature values with the `trusted` field set to `true` - [x] Pre-populated code signature fields are only present in windows and mac OSes. - [x] Behavior, ransomware and default alerts had the code_signature adjustments - [x] Previously the code duplicated a set of the pre-populated fields PER code signature. Now, each pre-populated field is only shown once, followed by all valid code_signatures. - [x] Does not allow duplicate code signatures # SCREENSHOTS Behavior alert w/ nested `process.Ext.code_signature` and non-nested `dll.code_signature` fields  Malware alert w/ nested `file.Ext.code_signature` <img width="1281" alt="image" src="https://github.com/user-attachments/assets/4845c6e5-5567-49df-b66a-1b9a2e6410db" /> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
8d50c08a43
commit
76e256ccff
6 changed files with 1036 additions and 315 deletions
|
@ -7,10 +7,11 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import type { CodeSignature } from '../file';
|
||||
import type { CodeSignature, Ext } from '../file';
|
||||
import type { ProcessPe } from '../process';
|
||||
|
||||
export interface DllEcs {
|
||||
Ext?: Ext;
|
||||
path?: string;
|
||||
code_signature?: CodeSignature;
|
||||
pe?: ProcessPe;
|
||||
|
|
|
@ -14,7 +14,7 @@ interface Original {
|
|||
|
||||
export interface CodeSignature {
|
||||
subject_name: string[];
|
||||
trusted: string[];
|
||||
trusted: boolean;
|
||||
}
|
||||
|
||||
export interface Token {
|
||||
|
@ -72,6 +72,8 @@ export interface FileEcs {
|
|||
|
||||
type?: string[];
|
||||
|
||||
code_signature?: CodeSignature;
|
||||
|
||||
device?: string[];
|
||||
|
||||
inode?: string[];
|
||||
|
|
|
@ -529,6 +529,10 @@ export class EndpointDocGenerator extends BaseDataGenerator {
|
|||
trusted: false,
|
||||
subject_name: 'bad signer',
|
||||
},
|
||||
{
|
||||
trusted: true,
|
||||
subject_name: 'a good signer',
|
||||
},
|
||||
],
|
||||
malware_classification: {
|
||||
identifier: 'endpointpe',
|
||||
|
@ -900,6 +904,10 @@ export class EndpointDocGenerator extends BaseDataGenerator {
|
|||
trusted: false,
|
||||
subject_name: 'bad signer',
|
||||
},
|
||||
{
|
||||
trusted: true,
|
||||
subject_name: 'good signer',
|
||||
},
|
||||
],
|
||||
user: 'SYSTEM',
|
||||
token: {
|
||||
|
@ -921,36 +929,34 @@ export class EndpointDocGenerator extends BaseDataGenerator {
|
|||
* Returns the default DLLs used in alerts
|
||||
*/
|
||||
private getAlertsDefaultDll() {
|
||||
return [
|
||||
{
|
||||
pe: {
|
||||
architecture: 'x64',
|
||||
},
|
||||
code_signature: {
|
||||
subject_name: 'Cybereason Inc',
|
||||
trusted: true,
|
||||
},
|
||||
return {
|
||||
pe: {
|
||||
architecture: 'x64',
|
||||
},
|
||||
code_signature: {
|
||||
subject_name: 'Cybereason Inc',
|
||||
trusted: true,
|
||||
},
|
||||
|
||||
hash: {
|
||||
md5: '1f2d082566b0fc5f2c238a5180db7451',
|
||||
sha1: 'ca85243c0af6a6471bdaa560685c51eefd6dbc0d',
|
||||
sha256: '8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2',
|
||||
},
|
||||
hash: {
|
||||
md5: '1f2d082566b0fc5f2c238a5180db7451',
|
||||
sha1: 'ca85243c0af6a6471bdaa560685c51eefd6dbc0d',
|
||||
sha256: '8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2',
|
||||
},
|
||||
|
||||
path: 'C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe',
|
||||
Ext: {
|
||||
compile_time: 1534424710,
|
||||
mapped_address: 5362483200,
|
||||
mapped_size: 0,
|
||||
malware_classification: {
|
||||
identifier: 'Whitelisted',
|
||||
score: 0,
|
||||
threshold: 0,
|
||||
version: '3.0.0',
|
||||
},
|
||||
path: 'C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe',
|
||||
Ext: {
|
||||
compile_time: 1534424710,
|
||||
mapped_address: 5362483200,
|
||||
mapped_size: 0,
|
||||
malware_classification: {
|
||||
identifier: 'Whitelisted',
|
||||
score: 0,
|
||||
threshold: 0,
|
||||
version: '3.0.0',
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@ import type {
|
|||
UpdateExceptionListItemSchema,
|
||||
ExceptionListSchema,
|
||||
EntriesArray,
|
||||
EntriesArrayOrUndefined,
|
||||
} from '@kbn/securitysolution-io-ts-list-types';
|
||||
import {
|
||||
ListOperatorTypeEnum,
|
||||
|
@ -41,11 +42,17 @@ import type {
|
|||
import { getNewExceptionItem, addIdToEntries } from '@kbn/securitysolution-list-utils';
|
||||
import { removeIdFromExceptionItemsEntries } from '@kbn/securitysolution-list-hooks';
|
||||
|
||||
import type { EcsSecurityExtension as Ecs, CodeSignature } from '@kbn/securitysolution-ecs';
|
||||
import type {
|
||||
EcsSecurityExtension as Ecs,
|
||||
CodeSignature,
|
||||
FileEcs,
|
||||
DllEcs,
|
||||
ProcessEcs,
|
||||
} from '@kbn/securitysolution-ecs';
|
||||
import type { EventSummaryField } from '../../../common/components/event_details/types';
|
||||
import { getHighlightedFieldsToDisplay } from '../../../common/components/event_details/get_alert_summary_rows';
|
||||
import * as i18n from './translations';
|
||||
import type { AlertData, Flattened } from './types';
|
||||
import type { AlertData, Flattened, FlattenedCodeSignature } from './types';
|
||||
|
||||
import { WithCopyToClipboard } from '../../../common/lib/clipboard/with_copy_to_clipboard';
|
||||
import { ALERT_ORIGINAL_EVENT } from '../../../../common/field_maps/field_names';
|
||||
|
@ -292,78 +299,150 @@ export const lowercaseHashValues = (
|
|||
};
|
||||
|
||||
/**
|
||||
* Returns the value for `file.Ext.code_signature` which
|
||||
* can be an object or array of objects
|
||||
* Generic function to get code signature entries from any entity
|
||||
*/
|
||||
export const getFileCodeSignature = (
|
||||
alertData: Flattened<Ecs>
|
||||
): Array<{ subjectName: string; trusted: string }> => {
|
||||
const { file } = alertData;
|
||||
const codeSignature = file && file.Ext && file.Ext.code_signature;
|
||||
export const getEntityCodeSignature = <
|
||||
T extends {
|
||||
Ext?: { code_signature?: Flattened<CodeSignature[] | CodeSignature> };
|
||||
code_signature?: CodeSignature;
|
||||
}
|
||||
>(
|
||||
entity: Flattened<FileEcs | ProcessEcs | DllEcs> | T | undefined,
|
||||
fieldPrefix: string
|
||||
): EntriesArrayOrUndefined => {
|
||||
if (!entity) return undefined;
|
||||
|
||||
return getCodeSignatureValue(codeSignature);
|
||||
// Check Ext.code_signature first
|
||||
if (entity.Ext?.code_signature) {
|
||||
return getCodeSignatureValue(entity.Ext.code_signature, `${fieldPrefix}.Ext.code_signature`);
|
||||
}
|
||||
|
||||
// Then check direct code_signature
|
||||
if (entity.code_signature?.trusted === true) {
|
||||
return [
|
||||
{
|
||||
field: `${fieldPrefix}.code_signature.subject_name`,
|
||||
operator: 'included' as const,
|
||||
type: 'match' as const,
|
||||
value: entity.code_signature?.subject_name.toString() ?? '',
|
||||
},
|
||||
{
|
||||
field: `${fieldPrefix}.code_signature.trusted`,
|
||||
operator: 'included' as const,
|
||||
type: 'match' as const,
|
||||
value: entity.code_signature.trusted.toString(),
|
||||
},
|
||||
];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value for `process.Ext.code_signature` which
|
||||
* can be an object or array of objects
|
||||
* Returns an array of exception entries for either
|
||||
* `file.Ext.code_signature` or 'file.code_signature`
|
||||
* as long as the `trusted` field is `true`.
|
||||
*/
|
||||
export const getProcessCodeSignature = (
|
||||
alertData: Flattened<Ecs>
|
||||
): Array<{ subjectName: string; trusted: string }> => {
|
||||
const { process } = alertData;
|
||||
const codeSignature = process && process.Ext && process.Ext.code_signature;
|
||||
return getCodeSignatureValue(codeSignature);
|
||||
};
|
||||
export const getFileCodeSignature = (alertData: Flattened<Ecs>): EntriesArrayOrUndefined =>
|
||||
getEntityCodeSignature(alertData.file, 'file');
|
||||
|
||||
/**
|
||||
* Returns an array of exception entries for either
|
||||
* `process.Ext.code_signature` or 'process.code_signature`
|
||||
* as long as the `trusted` field is `true`.
|
||||
*/
|
||||
export const getProcessCodeSignature = (alertData: Flattened<Ecs>): EntriesArrayOrUndefined =>
|
||||
getEntityCodeSignature(alertData.process, 'process');
|
||||
|
||||
/**
|
||||
* Returns an array of exception entries for either
|
||||
* `dll.Ext.code_signature` or 'dll.code_signature`
|
||||
* as long as the `trusted` field is `true`.
|
||||
*/
|
||||
export const getDllCodeSignature = (alertData: Flattened<Ecs>): EntriesArrayOrUndefined =>
|
||||
getEntityCodeSignature(alertData.dll, 'dll');
|
||||
|
||||
/**
|
||||
* Pre 7.10 `Ext.code_signature` fields were mistakenly populated as
|
||||
* a single object with subject_name and trusted.
|
||||
*/
|
||||
export const getCodeSignatureValue = (
|
||||
codeSignature: Flattened<CodeSignature> | Flattened<CodeSignature[]> | undefined
|
||||
): Array<{ subjectName: string; trusted: string }> => {
|
||||
codeSignature: Flattened<CodeSignature> | FlattenedCodeSignature[] | undefined,
|
||||
field: string
|
||||
): EntryNested[] | undefined => {
|
||||
if (Array.isArray(codeSignature) && codeSignature.length > 0) {
|
||||
return codeSignature.map((signature) => {
|
||||
return {
|
||||
subjectName: signature?.subject_name ?? '',
|
||||
trusted: signature?.trusted?.toString() ?? '',
|
||||
};
|
||||
});
|
||||
const codeSignatureEntries: EntryNested[] = [];
|
||||
const noDuplicates = new Map<string, boolean>();
|
||||
return codeSignature.reduce((acc, signature) => {
|
||||
if (signature?.trusted === true && !noDuplicates.has(signature?.subject_name)) {
|
||||
noDuplicates.set(signature.subject_name, signature.trusted);
|
||||
acc.push({
|
||||
field,
|
||||
type: 'nested',
|
||||
entries: [
|
||||
{
|
||||
field: 'subject_name',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: signature?.subject_name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'trusted',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: signature.trusted.toString(),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, codeSignatureEntries);
|
||||
} else {
|
||||
const signature: Flattened<CodeSignature> | undefined = !Array.isArray(codeSignature)
|
||||
? codeSignature
|
||||
: undefined;
|
||||
|
||||
return [
|
||||
{
|
||||
subjectName: signature?.subject_name ?? '',
|
||||
trusted: signature?.trusted ?? '',
|
||||
},
|
||||
];
|
||||
if (signature?.trusted === true) {
|
||||
return [
|
||||
{
|
||||
field,
|
||||
type: 'nested',
|
||||
entries: [
|
||||
{
|
||||
field: 'subject_name',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: signature?.subject_name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'trusted',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: signature.trusted.toString(),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// helper type to filter empty-valued exception entries
|
||||
interface ExceptionEntry {
|
||||
value?: string;
|
||||
entries?: ExceptionEntry[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<T extends ExceptionEntry>(entries: T[]): T[] {
|
||||
const finalEntries: T[] = [];
|
||||
|
||||
function filterEmptyExceptionEntries(entries: EntriesArray): EntriesArray {
|
||||
const finalEntries: EntriesArray = [];
|
||||
for (const entry of entries) {
|
||||
if (entry.entries !== undefined) {
|
||||
entry.entries = entry.entries.filter((el) => el.value !== undefined && el.value.length > 0);
|
||||
if ('entries' in entry && entry.entries !== undefined) {
|
||||
entry.entries = entry.entries.filter(
|
||||
(el) => 'value' in el && el.value !== undefined && el.value.length > 0
|
||||
);
|
||||
finalEntries.push(entry);
|
||||
} else if (entry.value !== undefined && entry.value.length > 0) {
|
||||
} else if ('value' in entry && entry?.value?.length > 0) {
|
||||
finalEntries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return finalEntries;
|
||||
}
|
||||
|
||||
|
@ -373,7 +452,6 @@ function filterEmptyExceptionEntries<T extends ExceptionEntry>(entries: T[]): T[
|
|||
export const getPrepopulatedEndpointException = ({
|
||||
listId,
|
||||
name,
|
||||
codeSignature,
|
||||
eventCode,
|
||||
listNamespace = 'agnostic',
|
||||
alertEcsData,
|
||||
|
@ -381,21 +459,16 @@ export const getPrepopulatedEndpointException = ({
|
|||
listId: string;
|
||||
listNamespace?: NamespaceType;
|
||||
name: string;
|
||||
codeSignature: { subjectName: string; trusted: string };
|
||||
eventCode: string;
|
||||
alertEcsData: Flattened<Ecs>;
|
||||
}): ExceptionsBuilderExceptionItem => {
|
||||
const { file, host } = alertEcsData;
|
||||
const fileCodeSignature = getFileCodeSignature(alertEcsData);
|
||||
const filePath = file?.path ?? '';
|
||||
const sha256Hash = file?.hash?.sha256 ?? '';
|
||||
const isLinux = host?.os?.name === 'Linux';
|
||||
|
||||
const commonFields: Array<{
|
||||
field: string;
|
||||
operator: 'excluded' | 'included';
|
||||
type: 'match';
|
||||
value: string;
|
||||
}> = [
|
||||
const commonFields: EntriesArray = [
|
||||
{
|
||||
field: isLinux ? 'file.path' : 'file.path.caseless',
|
||||
operator: 'included',
|
||||
|
@ -416,30 +489,10 @@ export const getPrepopulatedEndpointException = ({
|
|||
},
|
||||
];
|
||||
const entriesToAdd = () => {
|
||||
if (isLinux) {
|
||||
return addIdToEntries(commonFields);
|
||||
if (!isLinux && fileCodeSignature !== undefined) {
|
||||
return addIdToEntries(filterEmptyExceptionEntries(commonFields.concat(fileCodeSignature)));
|
||||
} else {
|
||||
return 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 addIdToEntries(filterEmptyExceptionEntries(commonFields));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -455,7 +508,6 @@ export const getPrepopulatedEndpointException = ({
|
|||
export const getPrepopulatedRansomwareException = ({
|
||||
listId,
|
||||
name,
|
||||
codeSignature,
|
||||
eventCode,
|
||||
listNamespace = 'agnostic',
|
||||
alertEcsData,
|
||||
|
@ -463,60 +515,54 @@ export const getPrepopulatedRansomwareException = ({
|
|||
listId: string;
|
||||
listNamespace?: NamespaceType;
|
||||
name: string;
|
||||
codeSignature: { subjectName: string; trusted: string };
|
||||
eventCode: string;
|
||||
alertEcsData: Flattened<Ecs>;
|
||||
}): ExceptionsBuilderExceptionItem => {
|
||||
const { process, Ransomware } = alertEcsData;
|
||||
const { process, Ransomware, host } = alertEcsData;
|
||||
const processCodeSignature = getProcessCodeSignature(alertEcsData);
|
||||
const sha256Hash = process?.hash?.sha256 ?? '';
|
||||
const executable = process?.executable ?? '';
|
||||
const ransomwareFeature = Ransomware?.feature ?? '';
|
||||
const isLinux = host?.os?.name === 'Linux';
|
||||
|
||||
const commonFields: EntriesArray = [
|
||||
{
|
||||
field: 'process.executable',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: executable ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.hash.sha256',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: sha256Hash ?? '',
|
||||
},
|
||||
{
|
||||
field: 'Ransomware.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: ransomwareFeature ?? '',
|
||||
},
|
||||
{
|
||||
field: 'event.code',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: eventCode ?? '',
|
||||
},
|
||||
];
|
||||
|
||||
const entriesToAdd = () => {
|
||||
if (!isLinux && processCodeSignature !== undefined) {
|
||||
return addIdToEntries(filterEmptyExceptionEntries(commonFields.concat(processCodeSignature)));
|
||||
} else {
|
||||
return addIdToEntries(filterEmptyExceptionEntries(commonFields));
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
...getNewExceptionItem({ listId, namespaceType: listNamespace, name }),
|
||||
entries: 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 ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.hash.sha256',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: sha256Hash ?? '',
|
||||
},
|
||||
{
|
||||
field: 'Ransomware.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: ransomwareFeature ?? '',
|
||||
},
|
||||
{
|
||||
field: 'event.code',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: eventCode ?? '',
|
||||
},
|
||||
]),
|
||||
entries: entriesToAdd(),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -618,6 +664,7 @@ export const getPrepopulatedMemoryShellcodeException = ({
|
|||
};
|
||||
};
|
||||
|
||||
/* eslint complexity: ["error", 21]*/
|
||||
export const getPrepopulatedBehaviorException = ({
|
||||
listId,
|
||||
name,
|
||||
|
@ -631,8 +678,11 @@ export const getPrepopulatedBehaviorException = ({
|
|||
eventCode: string;
|
||||
alertEcsData: Flattened<Ecs>;
|
||||
}): ExceptionsBuilderExceptionItem => {
|
||||
const { process } = alertEcsData;
|
||||
const entries = filterEmptyExceptionEntries([
|
||||
const { process, host } = alertEcsData;
|
||||
const processCodeSignature = getProcessCodeSignature(alertEcsData);
|
||||
const dllCodeSignature = getDllCodeSignature(alertEcsData);
|
||||
const isLinux = host?.os?.name === 'Linux';
|
||||
const commonFields: EntriesArray = [
|
||||
{
|
||||
field: 'rule.id',
|
||||
operator: 'included' as const,
|
||||
|
@ -657,12 +707,6 @@ export const getPrepopulatedBehaviorException = ({
|
|||
type: 'match' as const,
|
||||
value: process?.parent?.executable ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.code_signature.subject_name',
|
||||
operator: 'included' as const,
|
||||
type: 'match' as const,
|
||||
value: process?.code_signature?.subject_name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'file.path',
|
||||
operator: 'included' as const,
|
||||
|
@ -711,12 +755,6 @@ export const getPrepopulatedBehaviorException = ({
|
|||
type: 'match' as const,
|
||||
value: alertEcsData.dll?.path ?? '',
|
||||
},
|
||||
{
|
||||
field: 'dll.code_signature.subject_name',
|
||||
operator: 'included' as const,
|
||||
type: 'match' as const,
|
||||
value: alertEcsData.dll?.code_signature?.subject_name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'dll.pe.original_file_name',
|
||||
operator: 'included' as const,
|
||||
|
@ -741,10 +779,28 @@ export const getPrepopulatedBehaviorException = ({
|
|||
type: 'match' as const,
|
||||
value: alertEcsData.user?.id ?? '',
|
||||
},
|
||||
]);
|
||||
];
|
||||
|
||||
const entriesToAdd = () => {
|
||||
if (!isLinux) {
|
||||
if (processCodeSignature !== undefined && dllCodeSignature !== undefined) {
|
||||
return addIdToEntries(
|
||||
filterEmptyExceptionEntries(commonFields.concat(processCodeSignature, dllCodeSignature))
|
||||
);
|
||||
} else if (processCodeSignature !== undefined) {
|
||||
return addIdToEntries(
|
||||
filterEmptyExceptionEntries(commonFields.concat(processCodeSignature))
|
||||
);
|
||||
} else if (dllCodeSignature !== undefined) {
|
||||
return addIdToEntries(filterEmptyExceptionEntries(commonFields.concat(dllCodeSignature)));
|
||||
}
|
||||
}
|
||||
return addIdToEntries(filterEmptyExceptionEntries(commonFields));
|
||||
};
|
||||
|
||||
return {
|
||||
...getNewExceptionItem({ listId, namespaceType: listNamespace, name }),
|
||||
entries: addIdToEntries(entries),
|
||||
entries: entriesToAdd(),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -757,7 +813,6 @@ export const defaultEndpointExceptionItems = (
|
|||
alertEcsData: Flattened<Ecs> & { 'event.code'?: string }
|
||||
): ExceptionsBuilderExceptionItem[] => {
|
||||
const eventCode = alertEcsData['event.code'] ?? alertEcsData.event?.code;
|
||||
|
||||
switch (eventCode) {
|
||||
case 'behavior':
|
||||
return [
|
||||
|
@ -787,26 +842,24 @@ export const defaultEndpointExceptionItems = (
|
|||
}),
|
||||
];
|
||||
case 'ransomware':
|
||||
return getProcessCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
return [
|
||||
getPrepopulatedRansomwareException({
|
||||
listId,
|
||||
name,
|
||||
eventCode,
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
}),
|
||||
];
|
||||
default:
|
||||
// By default return the standard prepopulated Endpoint Exception fields
|
||||
return getFileCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
return [
|
||||
getPrepopulatedEndpointException({
|
||||
listId,
|
||||
name,
|
||||
eventCode: eventCode ?? '',
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
}),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ export interface ExceptionsPagination {
|
|||
|
||||
export interface FlattenedCodeSignature {
|
||||
subject_name: string;
|
||||
trusted: string;
|
||||
trusted: boolean;
|
||||
}
|
||||
|
||||
export type Flattened<T> = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue