mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[EDR Workflows] Fix small CrowdStrike connector issues (#190689)
This commit is contained in:
parent
5be73216a3
commit
9524bbcdc7
5 changed files with 26 additions and 27 deletions
|
@ -70,9 +70,8 @@ export class CrowdstrikeActionsClient extends ResponseActionsClientImpl {
|
|||
LogsEndpointAction<TParameters, TOutputContent, TMeta & CrowdstrikeActionRequestCommonMeta>
|
||||
> {
|
||||
const agentId = actionRequest.endpoint_ids[0];
|
||||
const eventDetails = await this.getEventDetailsById(agentId);
|
||||
const hostname = await this.getHostNameByAgentId(agentId);
|
||||
|
||||
const hostname = eventDetails.host.name;
|
||||
return super.writeActionRequestToEndpointIndex({
|
||||
...actionRequest,
|
||||
hosts: {
|
||||
|
@ -124,13 +123,12 @@ export class CrowdstrikeActionsClient extends ResponseActionsClientImpl {
|
|||
return actionSendResponse;
|
||||
}
|
||||
|
||||
private async getEventDetailsById(agentId: string): Promise<{
|
||||
host: { name: string };
|
||||
}> {
|
||||
private async getHostNameByAgentId(agentId: string): Promise<string> {
|
||||
const search = {
|
||||
index: ['logs-crowdstrike.fdr*', 'logs-crowdstrike.falcon*'],
|
||||
// Multiple indexes: .falcon, .fdr, .host, .alert
|
||||
index: ['logs-crowdstrike*'],
|
||||
size: 1,
|
||||
_source: ['host.name'],
|
||||
_source: ['host.hostname', 'host.name'],
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -140,13 +138,14 @@ export class CrowdstrikeActionsClient extends ResponseActionsClientImpl {
|
|||
},
|
||||
};
|
||||
try {
|
||||
const result: SearchResponse<{ host: { name: string } }> =
|
||||
await this.options.esClient.search<{ host: { name: string } }>(search, {
|
||||
const result: SearchResponse<{ host: { name: string; hostname: string } }> =
|
||||
await this.options.esClient.search<{ host: { name: string; hostname: string } }>(search, {
|
||||
ignore: [404],
|
||||
});
|
||||
|
||||
// Check if host name exists
|
||||
const hostName = result.hits.hits?.[0]?._source?.host?.name;
|
||||
const host = result.hits.hits?.[0]?._source?.host;
|
||||
const hostName = host?.name || host?.hostname;
|
||||
if (!hostName) {
|
||||
throw new ResponseActionsClientError(
|
||||
`Host name not found in the event document for agentId: ${agentId}`,
|
||||
|
@ -154,7 +153,7 @@ export class CrowdstrikeActionsClient extends ResponseActionsClientImpl {
|
|||
);
|
||||
}
|
||||
|
||||
return result.hits.hits[0]._source as { host: { name: string } };
|
||||
return hostName;
|
||||
} catch (err) {
|
||||
throw new ResponseActionsClientError(
|
||||
`Failed to fetch event document: ${err.message}`,
|
||||
|
|
|
@ -41,7 +41,7 @@ const getMockSearchResponse = (
|
|||
{
|
||||
_id: '1',
|
||||
_index: 'index',
|
||||
fields: { 'crowdstrike.host.id': [agentName] },
|
||||
fields: { 'device.id': [agentName] },
|
||||
inner_hits: {
|
||||
most_recent: {
|
||||
hits: {
|
||||
|
@ -52,11 +52,13 @@ const getMockSearchResponse = (
|
|||
_source: {
|
||||
crowdstrike: {
|
||||
host: {
|
||||
id: !wrongAgentName ? agentName : 'wrongAgentName',
|
||||
last_seen: '2023-01-01',
|
||||
status,
|
||||
},
|
||||
},
|
||||
device: {
|
||||
id: !wrongAgentName ? agentName : 'wrongAgentName',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -72,7 +72,7 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
filter: [
|
||||
{
|
||||
terms: {
|
||||
'crowdstrike.host.id': agentIds,
|
||||
'device.id': agentIds,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -91,8 +91,7 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
size: DEFAULT_MAX_TABLE_QUERY_SIZE,
|
||||
query,
|
||||
collapse: {
|
||||
// TODO: check if we should use crowdstrike.cid instead
|
||||
field: 'crowdstrike.host.id',
|
||||
field: 'device.id',
|
||||
inner_hits: {
|
||||
name: 'most_recent',
|
||||
size: 1,
|
||||
|
@ -123,10 +122,8 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
const mostRecentAgentInfosByAgentId = searchResponse?.hits?.hits?.reduce<
|
||||
Record<string, RawCrowdstrikeInfo>
|
||||
>((acc, hit) => {
|
||||
// TODO TC: check if we should use crowdstrike.cid instead
|
||||
if (hit.fields?.['crowdstrike.host.id'][0]) {
|
||||
acc[hit.fields?.['crowdstrike.host.id'][0]] =
|
||||
hit.inner_hits?.most_recent.hits.hits[0]._source;
|
||||
if (hit.fields?.['device.id'][0]) {
|
||||
acc[hit.fields?.['device.id'][0]] = hit.inner_hits?.most_recent.hits.hits[0]._source;
|
||||
}
|
||||
|
||||
return acc;
|
||||
|
@ -135,7 +132,7 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
const agentStatuses = await this.getAgentStatusFromConnectorAction(agentIds);
|
||||
|
||||
return agentIds.reduce<AgentStatusRecords>((acc, agentId) => {
|
||||
const agentInfo = mostRecentAgentInfosByAgentId[agentId]?.crowdstrike;
|
||||
const { device, crowdstrike } = mostRecentAgentInfosByAgentId[agentId];
|
||||
|
||||
const agentStatus = agentStatuses[agentId];
|
||||
const pendingActions = allPendingActions.find(
|
||||
|
@ -145,12 +142,11 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
acc[agentId] = {
|
||||
agentId,
|
||||
agentType: this.agentType,
|
||||
// TODO: check if we should use crowdstrike.cid instead
|
||||
found: agentInfo?.host.id === agentId,
|
||||
found: device?.id === agentId,
|
||||
isolated:
|
||||
agentInfo?.host.status === CROWDSTRIKE_NETWORK_STATUS.CONTAINED ||
|
||||
agentInfo?.host.status === CROWDSTRIKE_NETWORK_STATUS.LIFT_CONTAINMENT_PENDING,
|
||||
lastSeen: agentInfo?.host.last_seen || '',
|
||||
crowdstrike?.host.status === CROWDSTRIKE_NETWORK_STATUS.CONTAINED ||
|
||||
crowdstrike?.host.status === CROWDSTRIKE_NETWORK_STATUS.LIFT_CONTAINMENT_PENDING,
|
||||
lastSeen: crowdstrike?.host.last_seen || agentStatus?.last_seen || '',
|
||||
status:
|
||||
agentStatus?.state === CROWDSTRIKE_STATUS_RESPONSE.ONLINE
|
||||
? HostStatus.HEALTHY
|
||||
|
@ -162,6 +158,7 @@ export class CrowdstrikeAgentStatusClient extends AgentStatusClient {
|
|||
pendingActions: pendingActions?.pending_actions ?? {},
|
||||
};
|
||||
|
||||
// console.log({ acc });
|
||||
return acc;
|
||||
}, {});
|
||||
} catch (err) {
|
||||
|
|
|
@ -41,6 +41,7 @@ export const CrowdstrikeGetAgentOnlineStatusResponseSchema = schema.object(
|
|||
{
|
||||
state: schema.maybe(schema.string()),
|
||||
id: schema.maybe(schema.string()),
|
||||
last_seen: schema.maybe(schema.string()),
|
||||
},
|
||||
{ unknowns: 'allow' }
|
||||
)
|
||||
|
|
|
@ -154,7 +154,7 @@ export class CrowdstrikeConnector extends SubActionConnector<
|
|||
headers: {
|
||||
accept: 'application/json',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
authorization: 'Basic ' + this.base64encodedToken,
|
||||
authorization: 'Basic ' + CrowdstrikeConnector.base64encodedToken,
|
||||
},
|
||||
responseSchema: CrowdstrikeGetTokenResponseSchema,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue