[8.7] [Security Solution] Analyzer with sysmon via filebeat (#152418) (#152492)

# Backport

This will backport the following commits from `main` to `8.7`:
- [[Security Solution] Analyzer with sysmon via filebeat
(#152418)](https://github.com/elastic/kibana/pull/152418)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Kevin
Qualters","email":"56408403+kqualters-elastic@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-03-01T18:07:05Z","message":"[Security
Solution] Analyzer with sysmon via filebeat (#152418)\n\n##
Summary\r\n\r\nRelated issue:
https://github.com/elastic/kibana/issues/148043\r\n\r\nWith the switch
from beats to elastic agent, analyzer broke for sysmon\r\ndata ingested
via elastic agent, as some fields the code expects to\r\nexist became
slightly different, this pr updates the frontend and server\r\nside api
of analyzer to work with both old winlogbeat style sysmom\r\ningestion
and new elastic agent + filebeat shipping sysmon
generated\r\ndata.\r\n\r\n\r\n\r\nhttps://user-images.githubusercontent.com/56408403/222063497-64b2853e-5d09-4178-b336-1007886c396b.mov\r\n\r\nVideo
with 8.6 agent/fleet + latest main kibana/es + windows 10
w/sysmon\r\nvm\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"a9313eefe0799d032e5176b1de8d3f1608e4e914","branchLabelMapping":{"^v8.8.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Threat
Hunting:Investigations","v8.7.0","v8.8.0"],"number":152418,"url":"https://github.com/elastic/kibana/pull/152418","mergeCommit":{"message":"[Security
Solution] Analyzer with sysmon via filebeat (#152418)\n\n##
Summary\r\n\r\nRelated issue:
https://github.com/elastic/kibana/issues/148043\r\n\r\nWith the switch
from beats to elastic agent, analyzer broke for sysmon\r\ndata ingested
via elastic agent, as some fields the code expects to\r\nexist became
slightly different, this pr updates the frontend and server\r\nside api
of analyzer to work with both old winlogbeat style sysmom\r\ningestion
and new elastic agent + filebeat shipping sysmon
generated\r\ndata.\r\n\r\n\r\n\r\nhttps://user-images.githubusercontent.com/56408403/222063497-64b2853e-5d09-4178-b336-1007886c396b.mov\r\n\r\nVideo
with 8.6 agent/fleet + latest main kibana/es + windows 10
w/sysmon\r\nvm\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"a9313eefe0799d032e5176b1de8d3f1608e4e914"}},"sourceBranch":"main","suggestedTargetBranches":["8.7"],"targetPullRequestStates":[{"branch":"8.7","label":"v8.7.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.8.0","labelRegex":"^v8.8.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/152418","number":152418,"mergeCommit":{"message":"[Security
Solution] Analyzer with sysmon via filebeat (#152418)\n\n##
Summary\r\n\r\nRelated issue:
https://github.com/elastic/kibana/issues/148043\r\n\r\nWith the switch
from beats to elastic agent, analyzer broke for sysmon\r\ndata ingested
via elastic agent, as some fields the code expects to\r\nexist became
slightly different, this pr updates the frontend and server\r\nside api
of analyzer to work with both old winlogbeat style sysmom\r\ningestion
and new elastic agent + filebeat shipping sysmon
generated\r\ndata.\r\n\r\n\r\n\r\nhttps://user-images.githubusercontent.com/56408403/222063497-64b2853e-5d09-4178-b336-1007886c396b.mov\r\n\r\nVideo
with 8.6 agent/fleet + latest main kibana/es + windows 10
w/sysmon\r\nvm\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"a9313eefe0799d032e5176b1de8d3f1608e4e914"}}]}]
BACKPORT-->

Co-authored-by: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2023-03-01 14:56:20 -05:00 committed by GitHub
parent f0ea076397
commit dc508b8ef4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 9 deletions

View file

@ -57,5 +57,27 @@ describe('InvestigateInResolverAction', () => {
expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy();
});
it('returns true for process event from sysmon via filebeat', () => {
const data: Ecs = {
_id: '1',
agent: { type: ['filebeat'] },
event: { dataset: ['windows.sysmon_operational'] },
process: { entity_id: ['always_unique'] },
};
expect(isInvestigateInResolverActionEnabled(data)).toBeTruthy();
});
it('returns false for process event from filebeat but not from sysmon', () => {
const data: Ecs = {
_id: '1',
agent: { type: ['filebeat'] },
event: { dataset: ['windows.not_sysmon'] },
process: { entity_id: ['always_unique'] },
};
expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy();
});
});
});

View file

@ -8,9 +8,20 @@
import { get } from 'lodash/fp';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
export const isInvestigateInResolverActionEnabled = (ecsData?: Ecs) =>
(get(['agent', 'type', 0], ecsData) === 'endpoint' ||
(get(['agent', 'type', 0], ecsData) === 'winlogbeat' &&
get(['event', 'module', 0], ecsData) === 'sysmon')) &&
get(['process', 'entity_id'], ecsData)?.length === 1 &&
get(['process', 'entity_id', 0], ecsData) !== '';
export const isInvestigateInResolverActionEnabled = (ecsData?: Ecs) => {
const agentType = get(['agent', 'type', 0], ecsData);
const processEntityIds = get(['process', 'entity_id'], ecsData);
const firstProcessEntityId = get(['process', 'entity_id', 0], ecsData);
const eventModule = get(['event', 'module', 0], ecsData);
const eventDataStream = get(['event', 'dataset'], ecsData);
const datasetIncludesSysmon =
Array.isArray(eventDataStream) &&
eventDataStream.some((datastream) => datastream.includes('windows.sysmon'));
const agentTypeIsEndpoint = agentType === 'endpoint';
const agentTypeIsWinlogBeat = agentType === 'winlogbeat' && eventModule === 'sysmon';
const isEndpointOrSysmonFromWinlogBeat =
agentTypeIsEndpoint || agentTypeIsWinlogBeat || datasetIncludesSysmon;
const hasProcessEntityId =
processEntityIds != null && processEntityIds.length === 1 && firstProcessEntityId !== '';
return isEndpointOrSysmonFromWinlogBeat && hasProcessEntityId;
};

View file

@ -63,6 +63,24 @@ export const supportedSchemas: SupportedSchema[] = [
name: 'process.name',
},
},
{
name: 'sysmonViaFilebeat',
constraints: [
{
field: 'agent.type',
value: 'filebeat',
},
{
field: 'event.dataset',
value: 'windows.sysmon_operational',
},
],
schema: {
id: 'process.entity_id',
parent: 'process.parent.entity_id',
name: 'process.name',
},
},
];
export function getFieldAsString(doc: unknown, field: string): string | undefined {

View file

@ -86,6 +86,7 @@ export class EventsQuery extends BaseResolverQuery {
return {
body: this.query(filters),
index: this.indexPatterns,
allow_partial_search_results: true,
};
}

View file

@ -61,7 +61,7 @@ describe('Pagination', () => {
const builder = PaginationBuilder.createBuilder(100);
expect(builder.buildQueryFields('a', 'desc').sort).toStrictEqual([
{ '@timestamp': 'desc' },
{ a: 'asc' },
{ a: { order: 'asc', unmapped_type: 'long' } },
]);
});
});

View file

@ -31,7 +31,7 @@ export type SortFields = [
{
'@timestamp': string;
},
{ [x: string]: string }
{ [x: string]: { order: string; unmapped_type?: string } }
];
/**
@ -177,7 +177,10 @@ export class PaginationBuilder {
tiebreaker: string,
timeSort: TimeSortDirection = 'asc'
): PaginationFields {
const sort: SortFields = [{ '@timestamp': timeSort }, { [tiebreaker]: 'asc' }];
const sort: SortFields = [
{ '@timestamp': timeSort },
{ [tiebreaker]: { order: 'asc', unmapped_type: 'long' } },
];
let searchAfter: SearchAfterFields | undefined;
if (this.timestamp && this.eventID) {
searchAfter = [this.timestamp, this.eventID];