mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] User can make Exceptions for Memory protection alerts (#102196)
This commit is contained in:
parent
26bc0015ba
commit
a4a7253d30
10 changed files with 644 additions and 50 deletions
|
@ -14,9 +14,42 @@ export interface CodeSignature {
|
|||
subject_name: string[];
|
||||
trusted: string[];
|
||||
}
|
||||
|
||||
export interface Token {
|
||||
integrity_level_name: string;
|
||||
}
|
||||
|
||||
export interface MemoryPe {
|
||||
imphash?: string;
|
||||
}
|
||||
|
||||
export interface StartAddressDetails {
|
||||
allocation_base?: number;
|
||||
allocation_protection?: string;
|
||||
allocation_size?: number;
|
||||
allocation_type?: string;
|
||||
bytes_address?: number;
|
||||
bytes_allocation_offset?: number;
|
||||
bytes_compressed?: string;
|
||||
bytes_compressed_present?: string;
|
||||
mapped_path?: string;
|
||||
mapped_pe_detected?: boolean;
|
||||
memory_pe_detected?: boolean;
|
||||
region_base?: number;
|
||||
region_protection?: string;
|
||||
region_size?: number;
|
||||
region_state?: string;
|
||||
strings?: string;
|
||||
memory_pe?: MemoryPe;
|
||||
}
|
||||
|
||||
export interface Ext {
|
||||
code_signature?: CodeSignature[] | CodeSignature;
|
||||
original?: Original;
|
||||
token?: Token;
|
||||
start_address_allocation_offset?: number;
|
||||
start_address_bytes_disasm_hash?: string;
|
||||
start_address_details?: StartAddressDetails;
|
||||
}
|
||||
export interface Hash {
|
||||
md5?: string[];
|
||||
|
|
|
@ -30,6 +30,8 @@ import { ProcessEcs } from './process';
|
|||
import { SystemEcs } from './system';
|
||||
import { ThreatEcs } from './threat';
|
||||
import { Ransomware } from './ransomware';
|
||||
import { MemoryProtection } from './memory_protection';
|
||||
import { Target } from './target_type';
|
||||
|
||||
export interface Ecs {
|
||||
_id: string;
|
||||
|
@ -63,4 +65,7 @@ export interface Ecs {
|
|||
// This should be temporary
|
||||
eql?: { parentId: string; sequenceNumber: string };
|
||||
Ransomware?: Ransomware;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Memory_protection?: MemoryProtection;
|
||||
Target?: Target;
|
||||
}
|
||||
|
|
|
@ -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 interface MemoryProtection {
|
||||
cross_session?: boolean;
|
||||
feature?: string;
|
||||
parent_to_child?: boolean;
|
||||
self_injection?: boolean;
|
||||
unique_key_v1?: string;
|
||||
}
|
|
@ -37,4 +37,5 @@ export interface ProcessParentData {
|
|||
export interface Thread {
|
||||
id?: number[];
|
||||
start?: string[];
|
||||
Ext?: Ext;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { ProcessEcs } from '../process';
|
||||
|
||||
export interface Target {
|
||||
process: ProcessEcs;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import uuid from 'uuid';
|
||||
import seedrandom from 'seedrandom';
|
||||
import { assertNever } from '@kbn/std';
|
||||
import {
|
||||
AlertEvent,
|
||||
DataStream,
|
||||
|
@ -387,6 +388,12 @@ const eventsDefaultDataStream = {
|
|||
namespace: 'default',
|
||||
};
|
||||
|
||||
enum AlertTypes {
|
||||
MALWARE = 'MALWARE',
|
||||
MEMORY_SIGNATURE = 'MEMORY_SIGNATURE',
|
||||
MEMORY_SHELLCODE = 'MEMORY_SHELLCODE',
|
||||
}
|
||||
|
||||
const alertsDefaultDataStream = {
|
||||
type: 'logs',
|
||||
dataset: 'endpoint.alerts',
|
||||
|
@ -509,16 +516,15 @@ export class EndpointDocGenerator extends BaseDataGenerator {
|
|||
data_stream: metadataDataStream,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an alert from the simulated host represented by this EndpointDocGenerator
|
||||
* Creates a malware alert from the simulated host represented by this EndpointDocGenerator
|
||||
* @param ts - Timestamp to put in the event
|
||||
* @param entityID - entityID of the originating process
|
||||
* @param parentEntityID - optional entityID of the parent process, if it exists
|
||||
* @param ancestry - an array of ancestors for the generated alert
|
||||
* @param alertsDataStream the values to populate the data_stream fields when generating alert documents
|
||||
*/
|
||||
public generateAlert({
|
||||
public generateMalwareAlert({
|
||||
ts = new Date().getTime(),
|
||||
entityID = this.randomString(10),
|
||||
parentEntityID,
|
||||
|
@ -619,37 +625,198 @@ export class EndpointDocGenerator extends BaseDataGenerator {
|
|||
},
|
||||
},
|
||||
},
|
||||
dll: [
|
||||
{
|
||||
pe: {
|
||||
architecture: 'x64',
|
||||
},
|
||||
code_signature: {
|
||||
subject_name: 'Cybereason Inc',
|
||||
trusted: true,
|
||||
},
|
||||
dll: this.getAlertsDefaultDll(),
|
||||
};
|
||||
}
|
||||
|
||||
hash: {
|
||||
md5: '1f2d082566b0fc5f2c238a5180db7451',
|
||||
sha1: 'ca85243c0af6a6471bdaa560685c51eefd6dbc0d',
|
||||
sha256: '8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2',
|
||||
/**
|
||||
* Creates a memory alert from the simulated host represented by this EndpointDocGenerator
|
||||
* @param ts - Timestamp to put in the event
|
||||
* @param entityID - entityID of the originating process
|
||||
* @param parentEntityID - optional entityID of the parent process, if it exists
|
||||
* @param ancestry - an array of ancestors for the generated alert
|
||||
* @param alertsDataStream the values to populate the data_stream fields when generating alert documents
|
||||
*/
|
||||
public generateMemoryAlert({
|
||||
ts = new Date().getTime(),
|
||||
entityID = this.randomString(10),
|
||||
parentEntityID,
|
||||
ancestry = [],
|
||||
alertsDataStream = alertsDefaultDataStream,
|
||||
alertType,
|
||||
}: {
|
||||
ts?: number;
|
||||
entityID?: string;
|
||||
parentEntityID?: string;
|
||||
ancestry?: string[];
|
||||
alertsDataStream?: DataStream;
|
||||
alertType?: AlertTypes;
|
||||
} = {}): AlertEvent {
|
||||
const processName = this.randomProcessName();
|
||||
const isShellcode = alertType === AlertTypes.MEMORY_SHELLCODE;
|
||||
const newAlert: AlertEvent = {
|
||||
...this.commonInfo,
|
||||
data_stream: alertsDataStream,
|
||||
'@timestamp': ts,
|
||||
ecs: {
|
||||
version: '1.6.0',
|
||||
},
|
||||
// disabling naming-convention to accommodate external field
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Memory_protection: {
|
||||
feature: isShellcode ? 'shellcode_thread' : 'signature',
|
||||
self_injection: true,
|
||||
},
|
||||
event: {
|
||||
action: 'start',
|
||||
kind: 'alert',
|
||||
category: 'malware',
|
||||
code: isShellcode ? 'malicious_thread' : 'memory_signature',
|
||||
id: this.seededUUIDv4(),
|
||||
dataset: 'endpoint',
|
||||
module: 'endpoint',
|
||||
type: 'info',
|
||||
sequence: this.sequence++,
|
||||
},
|
||||
file: {},
|
||||
process: {
|
||||
pid: 2,
|
||||
name: processName,
|
||||
start: ts,
|
||||
uptime: 0,
|
||||
entity_id: entityID,
|
||||
executable: `C:/fake/${processName}`,
|
||||
parent: parentEntityID ? { entity_id: parentEntityID, pid: 1 } : undefined,
|
||||
hash: {
|
||||
md5: 'fake md5',
|
||||
sha1: 'fake sha1',
|
||||
sha256: 'fake sha256',
|
||||
},
|
||||
Ext: {
|
||||
ancestry,
|
||||
code_signature: [
|
||||
{
|
||||
trusted: false,
|
||||
subject_name: 'bad signer',
|
||||
},
|
||||
],
|
||||
user: 'SYSTEM',
|
||||
token: {
|
||||
integrity_level_name: 'high',
|
||||
},
|
||||
malware_signature: {
|
||||
all_names: 'Windows.Trojan.FakeAgent',
|
||||
identifier: 'diagnostic-malware-signature-v1-fake',
|
||||
},
|
||||
},
|
||||
},
|
||||
dll: this.getAlertsDefaultDll(),
|
||||
};
|
||||
|
||||
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',
|
||||
// shellcode_thread memory alert have an additional process field
|
||||
if (isShellcode) {
|
||||
newAlert.Target = {
|
||||
process: {
|
||||
thread: {
|
||||
Ext: {
|
||||
start_address_allocation_offset: 0,
|
||||
start_address_bytes_disasm_hash: 'a disam hash',
|
||||
start_address_details: {
|
||||
allocation_type: 'PRIVATE',
|
||||
allocation_size: 4000,
|
||||
region_size: 4000,
|
||||
region_protection: 'RWX',
|
||||
memory_pe: {
|
||||
imphash: 'a hash',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
}
|
||||
return newAlert;
|
||||
}
|
||||
/**
|
||||
* Creates an alert from the simulated host represented by this EndpointDocGenerator
|
||||
* @param ts - Timestamp to put in the event
|
||||
* @param entityID - entityID of the originating process
|
||||
* @param parentEntityID - optional entityID of the parent process, if it exists
|
||||
* @param ancestry - an array of ancestors for the generated alert
|
||||
* @param alertsDataStream the values to populate the data_stream fields when generating alert documents
|
||||
*/
|
||||
public generateAlert({
|
||||
ts = new Date().getTime(),
|
||||
entityID = this.randomString(10),
|
||||
parentEntityID,
|
||||
ancestry = [],
|
||||
alertsDataStream = alertsDefaultDataStream,
|
||||
}: {
|
||||
ts?: number;
|
||||
entityID?: string;
|
||||
parentEntityID?: string;
|
||||
ancestry?: string[];
|
||||
alertsDataStream?: DataStream;
|
||||
} = {}): AlertEvent {
|
||||
const alertType = this.randomChoice(Object.values(AlertTypes));
|
||||
switch (alertType) {
|
||||
case AlertTypes.MALWARE:
|
||||
return this.generateMalwareAlert({
|
||||
ts,
|
||||
entityID,
|
||||
parentEntityID,
|
||||
ancestry,
|
||||
alertsDataStream,
|
||||
});
|
||||
case AlertTypes.MEMORY_SIGNATURE:
|
||||
case AlertTypes.MEMORY_SHELLCODE:
|
||||
return this.generateMemoryAlert({
|
||||
ts,
|
||||
entityID,
|
||||
parentEntityID,
|
||||
ancestry,
|
||||
alertsDataStream,
|
||||
alertType,
|
||||
});
|
||||
default:
|
||||
return assertNever(alertType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default DLLs used in alerts
|
||||
*/
|
||||
private getAlertsDefaultDll() {
|
||||
return [
|
||||
{
|
||||
pe: {
|
||||
architecture: 'x64',
|
||||
},
|
||||
code_signature: {
|
||||
subject_name: 'Cybereason Inc',
|
||||
trusted: true,
|
||||
},
|
||||
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -295,6 +295,31 @@ export type AlertEvent = Partial<{
|
|||
}>;
|
||||
}>;
|
||||
}>;
|
||||
// disabling naming-convention to accommodate external field
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Memory_protection: Partial<{
|
||||
feature: ECSField<string>;
|
||||
self_injection: ECSField<boolean>;
|
||||
}>;
|
||||
Target: Partial<{
|
||||
process: Partial<{
|
||||
thread: Partial<{
|
||||
Ext: Partial<{
|
||||
start_address_allocation_offset: ECSField<number>;
|
||||
start_address_bytes_disasm_hash: ECSField<string>;
|
||||
start_address_details: Partial<{
|
||||
allocation_type: ECSField<string>;
|
||||
allocation_size: ECSField<number>;
|
||||
region_size: ECSField<number>;
|
||||
region_protection: ECSField<string>;
|
||||
memory_pe: Partial<{
|
||||
imphash: ECSField<string>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
process: Partial<{
|
||||
command_line: ECSField<string>;
|
||||
ppid: ECSField<number>;
|
||||
|
@ -328,6 +353,10 @@ export type AlertEvent = Partial<{
|
|||
>;
|
||||
}>;
|
||||
user: ECSField<string>;
|
||||
malware_signature: Partial<{
|
||||
all_names: ECSField<string>;
|
||||
identifier: ECSField<string>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
file: Partial<{
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
"Endpoint.policy.applied.id",
|
||||
"Target.process.Ext.services",
|
||||
"Target.process.Ext.user",
|
||||
"Target.process.executable",
|
||||
"Target.process.hash.md5",
|
||||
"Target.process.hash.sha1",
|
||||
"Target.process.hash.sha256",
|
||||
"Target.process.hash.sha512",
|
||||
"Target.process.name",
|
||||
"Target.process.parent.hash.md5",
|
||||
"Target.process.parent.hash.sha1",
|
||||
"Target.process.parent.hash.sha256",
|
||||
|
@ -17,6 +19,14 @@
|
|||
"Target.process.pe.original_file_name",
|
||||
"Target.process.pe.product",
|
||||
"Target.process.pgid",
|
||||
"Target.process.thread.Ext.start_address_details.allocation_type",
|
||||
"Target.process.thread.Ext.start_address_bytes_disasm_hash",
|
||||
"Target.process.thread.Ext.start_address_allocation_offset",
|
||||
"Target.process.thread.Ext.start_address_details.allocation_size",
|
||||
"Target.process.thread.Ext.start_address_details.region_size",
|
||||
"Target.process.thread.Ext.start_address_details.region_protection",
|
||||
"Target.process.thread.Ext.start_address_details.memory_pe.imphash",
|
||||
"Target.process.thread.Ext.start_address_bytes",
|
||||
"agent.id",
|
||||
"agent.type",
|
||||
"agent.version",
|
||||
|
@ -68,10 +78,13 @@
|
|||
"host.type",
|
||||
"process.Ext.services",
|
||||
"process.Ext.user",
|
||||
"process.Ext.code_signature",
|
||||
"process.executable",
|
||||
"process.hash.md5",
|
||||
"process.hash.sha1",
|
||||
"process.hash.sha256",
|
||||
"process.hash.sha512",
|
||||
"process.name",
|
||||
"process.parent.hash.md5",
|
||||
"process.parent.hash.sha1",
|
||||
"process.parent.hash.sha256",
|
||||
|
@ -88,5 +101,7 @@
|
|||
"user.email",
|
||||
"user.hash",
|
||||
"user.id",
|
||||
"Ransomware.feature"
|
||||
"Ransomware.feature",
|
||||
"Memory_protection.feature",
|
||||
"Memory_protection.self_injection"
|
||||
]
|
||||
|
|
|
@ -928,5 +928,172 @@ describe('Exception helpers', () => {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('it should return pre-populated memory signature items for event code `memory_signature`', () => {
|
||||
const defaultItems = defaultEndpointExceptionItems('list_id', 'my_rule', {
|
||||
_id: '123',
|
||||
process: {
|
||||
name: 'some name',
|
||||
executable: 'some file path',
|
||||
hash: {
|
||||
sha256: 'some hash',
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Memory_protection: {
|
||||
feature: 'signature',
|
||||
},
|
||||
event: {
|
||||
code: 'memory_signature',
|
||||
},
|
||||
});
|
||||
|
||||
expect(defaultItems[0].entries).toEqual([
|
||||
{
|
||||
field: 'Memory_protection.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'signature',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.executable.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'some file path',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.name.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'some name',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.hash.sha256',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'some hash',
|
||||
id: '123',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('it should return pre-populated memory shellcode items for event code `malicious_thread`', () => {
|
||||
const defaultItems = defaultEndpointExceptionItems('list_id', 'my_rule', {
|
||||
_id: '123',
|
||||
process: {
|
||||
name: 'some name',
|
||||
executable: 'some file path',
|
||||
Ext: {
|
||||
token: {
|
||||
integrity_level_name: 'high',
|
||||
},
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Memory_protection: {
|
||||
feature: 'shellcode_thread',
|
||||
self_injection: true,
|
||||
},
|
||||
event: {
|
||||
code: 'malicious_thread',
|
||||
},
|
||||
Target: {
|
||||
process: {
|
||||
thread: {
|
||||
Ext: {
|
||||
start_address_allocation_offset: 0,
|
||||
start_address_bytes_disasm_hash: 'a disam hash',
|
||||
start_address_details: {
|
||||
allocation_type: 'PRIVATE',
|
||||
allocation_size: 4000,
|
||||
region_size: 4000,
|
||||
region_protection: 'RWX',
|
||||
memory_pe: {
|
||||
imphash: 'a hash',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(defaultItems[0].entries).toEqual([
|
||||
{
|
||||
field: 'Memory_protection.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'shellcode_thread',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'Memory_protection.self_injection',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'true',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.executable.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'some file path',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.name.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'some name',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'process.Ext.token.integrity_level_name',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'high',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'Target.process.thread.Ext.start_address_details',
|
||||
type: 'nested',
|
||||
entries: [
|
||||
{
|
||||
field: 'allocation_type',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'PRIVATE',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'allocation_size',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: '4000',
|
||||
id: '123',
|
||||
},
|
||||
{ field: 'region_size', operator: 'included', type: 'match', value: '4000', id: '123' },
|
||||
{
|
||||
field: 'region_protection',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'RWX',
|
||||
id: '123',
|
||||
},
|
||||
{
|
||||
field: 'memory_pe.imphash',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'a hash',
|
||||
id: '123',
|
||||
},
|
||||
],
|
||||
id: '123',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -496,6 +496,139 @@ export const getPrepopulatedRansomwareException = ({
|
|||
};
|
||||
};
|
||||
|
||||
export const getPrepopulatedMemorySignatureException = ({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
listNamespace = 'agnostic',
|
||||
alertEcsData,
|
||||
}: {
|
||||
listId: string;
|
||||
listNamespace?: NamespaceType;
|
||||
ruleName: string;
|
||||
eventCode: string;
|
||||
alertEcsData: Flattened<Ecs>;
|
||||
}): ExceptionsBuilderExceptionItem => {
|
||||
const { process } = alertEcsData;
|
||||
return {
|
||||
...getNewExceptionItem({ listId, namespaceType: listNamespace, ruleName }),
|
||||
entries: addIdToEntries([
|
||||
{
|
||||
field: 'Memory_protection.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: alertEcsData.Memory_protection?.feature ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.executable.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.executable ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.name.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.hash.sha256',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.hash?.sha256 ?? '',
|
||||
},
|
||||
]),
|
||||
};
|
||||
};
|
||||
export const getPrepopulatedMemoryShellcodeException = ({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
listNamespace = 'agnostic',
|
||||
alertEcsData,
|
||||
}: {
|
||||
listId: string;
|
||||
listNamespace?: NamespaceType;
|
||||
ruleName: string;
|
||||
eventCode: string;
|
||||
alertEcsData: Flattened<Ecs>;
|
||||
}): ExceptionsBuilderExceptionItem => {
|
||||
const { process, Target } = alertEcsData;
|
||||
return {
|
||||
...getNewExceptionItem({ listId, namespaceType: listNamespace, ruleName }),
|
||||
entries: addIdToEntries([
|
||||
{
|
||||
field: 'Memory_protection.feature',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: alertEcsData.Memory_protection?.feature ?? '',
|
||||
},
|
||||
{
|
||||
field: 'Memory_protection.self_injection',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: String(alertEcsData.Memory_protection?.self_injection) ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.executable.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.executable ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.name.caseless',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'process.Ext.token.integrity_level_name',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: process?.Ext?.token?.integrity_level_name ?? '',
|
||||
},
|
||||
{
|
||||
field: 'Target.process.thread.Ext.start_address_details',
|
||||
type: 'nested',
|
||||
entries: [
|
||||
{
|
||||
field: 'allocation_type',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: Target?.process?.thread?.Ext?.start_address_details?.allocation_type ?? '',
|
||||
},
|
||||
{
|
||||
field: 'allocation_size',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value:
|
||||
String(Target?.process?.thread?.Ext?.start_address_details?.allocation_size) ?? '',
|
||||
},
|
||||
{
|
||||
field: 'region_size',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: String(Target?.process?.thread?.Ext?.start_address_details?.region_size) ?? '',
|
||||
},
|
||||
{
|
||||
field: 'region_protection',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value:
|
||||
String(Target?.process?.thread?.Ext?.start_address_details?.region_protection) ?? '',
|
||||
},
|
||||
{
|
||||
field: 'memory_pe.imphash',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value:
|
||||
String(Target?.process?.thread?.Ext?.start_address_details?.memory_pe?.imphash) ?? '',
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Determines whether or not any entries within the given exceptionItems contain values not in the specified ECS mapping
|
||||
*/
|
||||
|
@ -537,26 +670,45 @@ export const defaultEndpointExceptionItems = (
|
|||
const { event: alertEvent } = alertEcsData;
|
||||
const eventCode = alertEvent?.code ?? '';
|
||||
|
||||
if (eventCode === 'ransomware') {
|
||||
return getProcessCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
getPrepopulatedRansomwareException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
switch (eventCode) {
|
||||
case 'memory_signature':
|
||||
return [
|
||||
getPrepopulatedMemorySignatureException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
alertEcsData,
|
||||
}),
|
||||
];
|
||||
case 'malicious_thread':
|
||||
return [
|
||||
getPrepopulatedMemoryShellcodeException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
alertEcsData,
|
||||
}),
|
||||
];
|
||||
case 'ransomware':
|
||||
return getProcessCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
getPrepopulatedRansomwareException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
default:
|
||||
// By default return the standard prepopulated Endpoint Exception fields
|
||||
return getFileCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
getPrepopulatedEndpointException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// By default return the standard prepopulated Endpoint Exception fields
|
||||
return getFileCodeSignature(alertEcsData).map((codeSignature) =>
|
||||
getPrepopulatedEndpointException({
|
||||
listId,
|
||||
ruleName,
|
||||
eventCode,
|
||||
codeSignature,
|
||||
alertEcsData,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue