From 8a638a51a12f0488167120a4e39e46e6fed6b1b1 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Tue, 8 Sep 2020 12:27:26 +0100 Subject: [PATCH 1/4] init tests --- .../factory/hosts/details/__mocks__/index.ts | 2370 +++++++++++++++++ .../factory/hosts/details/index.test.tsx | 35 + .../factory/hosts/details/index.ts | 7 +- .../details/query.host_details.dsl.test.ts | 13 + .../hosts/details/query.host_details.dsl.ts | 2 + 5 files changed, 2426 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.test.tsx create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts new file mode 100644 index 000000000000..65343dc721fd --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts @@ -0,0 +1,2370 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; +import { + AuthenticationHit, + Direction, + HostsQueries, + HostAuthenticationsRequestOptions, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: HostAuthenticationsRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.created', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + { + field: 'event.ingested', + format: 'date_time', + }, + { + field: 'event.start', + format: 'date_time', + }, + { + field: 'file.accessed', + format: 'date_time', + }, + { + field: 'file.created', + format: 'date_time', + }, + { + field: 'file.ctime', + format: 'date_time', + }, + { + field: 'file.mtime', + format: 'date_time', + }, + { + field: 'package.installed', + format: 'date_time', + }, + { + field: 'process.parent.start', + format: 'date_time', + }, + { + field: 'process.start', + format: 'date_time', + }, + { + field: 'system.audit.host.boottime', + format: 'date_time', + }, + { + field: 'system.audit.package.installtime', + format: 'date_time', + }, + { + field: 'system.audit.user.password.last_changed', + format: 'date_time', + }, + { + field: 'tls.client.not_after', + format: 'date_time', + }, + { + field: 'tls.client.not_before', + format: 'date_time', + }, + { + field: 'tls.server.not_after', + format: 'date_time', + }, + { + field: 'tls.server.not_before', + format: 'date_time', + }, + { + field: 'aws.cloudtrail.user_identity.session_context.creation_date', + format: 'date_time', + }, + { + field: 'azure.auditlogs.properties.activity_datetime', + format: 'date_time', + }, + { + field: 'azure.enqueued_time', + format: 'date_time', + }, + { + field: 'azure.signinlogs.properties.created_at', + format: 'date_time', + }, + { + field: 'cef.extensions.agentReceiptTime', + format: 'date_time', + }, + { + field: 'cef.extensions.deviceCustomDate1', + format: 'date_time', + }, + { + field: 'cef.extensions.deviceCustomDate2', + format: 'date_time', + }, + { + field: 'cef.extensions.deviceReceiptTime', + format: 'date_time', + }, + { + field: 'cef.extensions.endTime', + format: 'date_time', + }, + { + field: 'cef.extensions.fileCreateTime', + format: 'date_time', + }, + { + field: 'cef.extensions.fileModificationTime', + format: 'date_time', + }, + { + field: 'cef.extensions.flexDate1', + format: 'date_time', + }, + { + field: 'cef.extensions.managerReceiptTime', + format: 'date_time', + }, + { + field: 'cef.extensions.oldFileCreateTime', + format: 'date_time', + }, + { + field: 'cef.extensions.oldFileModificationTime', + format: 'date_time', + }, + { + field: 'cef.extensions.startTime', + format: 'date_time', + }, + { + field: 'checkpoint.subs_exp', + format: 'date_time', + }, + { + field: 'crowdstrike.event.EndTimestamp', + format: 'date_time', + }, + { + field: 'crowdstrike.event.IncidentEndTime', + format: 'date_time', + }, + { + field: 'crowdstrike.event.IncidentStartTime', + format: 'date_time', + }, + { + field: 'crowdstrike.event.ProcessEndTime', + format: 'date_time', + }, + { + field: 'crowdstrike.event.ProcessStartTime', + format: 'date_time', + }, + { + field: 'crowdstrike.event.StartTimestamp', + format: 'date_time', + }, + { + field: 'crowdstrike.event.Timestamp', + format: 'date_time', + }, + { + field: 'crowdstrike.event.UTCTimestamp', + format: 'date_time', + }, + { + field: 'crowdstrike.metadata.eventCreationTime', + format: 'date_time', + }, + { + field: 'gsuite.admin.email.log_search_filter.end_date', + format: 'date_time', + }, + { + field: 'gsuite.admin.email.log_search_filter.start_date', + format: 'date_time', + }, + { + field: 'gsuite.admin.user.birthdate', + format: 'date_time', + }, + { + field: 'kafka.block_timestamp', + format: 'date_time', + }, + { + field: 'microsoft.defender_atp.lastUpdateTime', + format: 'date_time', + }, + { + field: 'microsoft.defender_atp.resolvedTime', + format: 'date_time', + }, + { + field: 'misp.campaign.first_seen', + format: 'date_time', + }, + { + field: 'misp.campaign.last_seen', + format: 'date_time', + }, + { + field: 'misp.intrusion_set.first_seen', + format: 'date_time', + }, + { + field: 'misp.intrusion_set.last_seen', + format: 'date_time', + }, + { + field: 'misp.observed_data.first_observed', + format: 'date_time', + }, + { + field: 'misp.observed_data.last_observed', + format: 'date_time', + }, + { + field: 'misp.report.published', + format: 'date_time', + }, + { + field: 'misp.threat_indicator.valid_from', + format: 'date_time', + }, + { + field: 'misp.threat_indicator.valid_until', + format: 'date_time', + }, + { + field: 'netflow.collection_time_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.exporter.timestamp', + format: 'date_time', + }, + { + field: 'netflow.flow_end_microseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_end_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_end_nanoseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_end_seconds', + format: 'date_time', + }, + { + field: 'netflow.flow_start_microseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_start_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_start_nanoseconds', + format: 'date_time', + }, + { + field: 'netflow.flow_start_seconds', + format: 'date_time', + }, + { + field: 'netflow.max_export_seconds', + format: 'date_time', + }, + { + field: 'netflow.max_flow_end_microseconds', + format: 'date_time', + }, + { + field: 'netflow.max_flow_end_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.max_flow_end_nanoseconds', + format: 'date_time', + }, + { + field: 'netflow.max_flow_end_seconds', + format: 'date_time', + }, + { + field: 'netflow.min_export_seconds', + format: 'date_time', + }, + { + field: 'netflow.min_flow_start_microseconds', + format: 'date_time', + }, + { + field: 'netflow.min_flow_start_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.min_flow_start_nanoseconds', + format: 'date_time', + }, + { + field: 'netflow.min_flow_start_seconds', + format: 'date_time', + }, + { + field: 'netflow.monitoring_interval_end_milli_seconds', + format: 'date_time', + }, + { + field: 'netflow.monitoring_interval_start_milli_seconds', + format: 'date_time', + }, + { + field: 'netflow.observation_time_microseconds', + format: 'date_time', + }, + { + field: 'netflow.observation_time_milliseconds', + format: 'date_time', + }, + { + field: 'netflow.observation_time_nanoseconds', + format: 'date_time', + }, + { + field: 'netflow.observation_time_seconds', + format: 'date_time', + }, + { + field: 'netflow.system_init_time_milliseconds', + format: 'date_time', + }, + { + field: 'rsa.internal.lc_ctime', + format: 'date_time', + }, + { + field: 'rsa.internal.time', + format: 'date_time', + }, + { + field: 'rsa.time.effective_time', + format: 'date_time', + }, + { + field: 'rsa.time.endtime', + format: 'date_time', + }, + { + field: 'rsa.time.event_queue_time', + format: 'date_time', + }, + { + field: 'rsa.time.event_time', + format: 'date_time', + }, + { + field: 'rsa.time.expire_time', + format: 'date_time', + }, + { + field: 'rsa.time.recorded_time', + format: 'date_time', + }, + { + field: 'rsa.time.stamp', + format: 'date_time', + }, + { + field: 'rsa.time.starttime', + format: 'date_time', + }, + { + field: 'sophos.xg.date', + format: 'date_time', + }, + { + field: 'sophos.xg.eventtime', + format: 'date_time', + }, + { + field: 'sophos.xg.start_time', + format: 'date_time', + }, + ], + factoryQueryType: HostsQueries.authentications, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + pagination: { + activePage: 0, + cursorStart: 0, + fakePossibleCount: 50, + querySize: 10, + }, + timerange: { + interval: '12h', + from: '2020-09-02T15:17:13.678Z', + to: '2020-09-03T15:17:13.678Z', + }, + sort: { + direction: Direction.desc, + field: 'success', + }, + params: {}, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 14, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: -1, max_score: 0, hits: [] }, + aggregations: { + group_by_users: { + doc_count_error_upper_bound: -1, + sum_other_doc_count: 408, + buckets: [ + { + key: 'SYSTEM', + doc_count: 281, + failures: { + meta: {}, + doc_count: 0, + lastFailure: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + successes: { + meta: {}, + doc_count: 4, + lastSuccess: { + hits: { + total: 4, + max_score: 0, + hits: [ + { + _index: 'winlogbeat-8.0.0-2020.09.02-000001', + _id: 'zqY7WXQBA6bGZw2uLeKI', + _score: null, + _source: { + process: { + name: 'services.exe', + pid: 564, + executable: 'C:\\Windows\\System32\\services.exe', + }, + agent: { + build_date: '2020-07-16 09:16:27 +0000 UTC ', + name: 'siem-windows', + commit: '4dcbde39492bdc3843034bba8db811c68cb44b97 ', + id: '05e1bff7-d7a8-416a-8554-aa10288fa07d', + type: 'winlogbeat', + ephemeral_id: '655abd6c-6c33-435d-a2eb-79b2a01e6d61', + version: '8.0.0', + user: { name: 'inside_winlogbeat_user' }, + }, + winlog: { + computer_name: 'siem-windows', + process: { pid: 576, thread: { id: 880 } }, + keywords: ['Audit Success'], + logon: { id: '0x3e7', type: 'Service' }, + channel: 'Security', + event_data: { + LogonGuid: '{00000000-0000-0000-0000-000000000000}', + TargetOutboundDomainName: '-', + VirtualAccount: '%%1843', + LogonType: '5', + IpPort: '-', + TransmittedServices: '-', + SubjectLogonId: '0x3e7', + LmPackageName: '-', + TargetOutboundUserName: '-', + KeyLength: '0', + TargetLogonId: '0x3e7', + RestrictedAdminMode: '-', + SubjectUserName: 'SIEM-WINDOWS$', + TargetLinkedLogonId: '0x0', + ElevatedToken: '%%1842', + SubjectDomainName: 'WORKGROUP', + IpAddress: '-', + ImpersonationLevel: '%%1833', + TargetUserName: 'SYSTEM', + LogonProcessName: 'Advapi ', + TargetDomainName: 'NT AUTHORITY', + SubjectUserSid: 'S-1-5-18', + TargetUserSid: 'S-1-5-18', + AuthenticationPackageName: 'Negotiate', + }, + opcode: 'Info', + version: 2, + record_id: 57818, + task: 'Logon', + event_id: 4624, + provider_guid: '{54849625-5478-4994-a5ba-3e3b0328c30d}', + activity_id: '{d2485217-6bac-0000-8fbb-3f7e2571d601}', + api: 'wineventlog', + provider_name: 'Microsoft-Windows-Security-Auditing', + }, + log: { level: 'information' }, + source: { domain: '-' }, + message: + 'An account was successfully logged on.\n\nSubject:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSIEM-WINDOWS$\n\tAccount Domain:\t\tWORKGROUP\n\tLogon ID:\t\t0x3E7\n\nLogon Information:\n\tLogon Type:\t\t5\n\tRestricted Admin Mode:\t-\n\tVirtual Account:\t\tNo\n\tElevated Token:\t\tYes\n\nImpersonation Level:\t\tImpersonation\n\nNew Logon:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSYSTEM\n\tAccount Domain:\t\tNT AUTHORITY\n\tLogon ID:\t\t0x3E7\n\tLinked Logon ID:\t\t0x0\n\tNetwork Account Name:\t-\n\tNetwork Account Domain:\t-\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\n\nProcess Information:\n\tProcess ID:\t\t0x234\n\tProcess Name:\t\tC:\\Windows\\System32\\services.exe\n\nNetwork Information:\n\tWorkstation Name:\t-\n\tSource Network Address:\t-\n\tSource Port:\t\t-\n\nDetailed Authentication Information:\n\tLogon Process:\t\tAdvapi \n\tAuthentication Package:\tNegotiate\n\tTransited Services:\t-\n\tPackage Name (NTLM only):\t-\n\tKey Length:\t\t0\n\nThis event is generated when a logon session is created. It is generated on the computer that was accessed.\n\nThe subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.\n\nThe logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).\n\nThe New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.\n\nThe network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.\n\nThe impersonation level field indicates the extent to which a process in the logon session can impersonate.\n\nThe authentication information fields provide detailed information about this specific logon request.\n\t- Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.\n\t- Transited services indicate which intermediate services have participated in this logon request.\n\t- Package name indicates which sub-protocol was used among the NTLM protocols.\n\t- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.', + cloud: { + availability_zone: 'us-central1-c', + instance: { name: 'siem-windows', id: '9156726559029788564' }, + provider: 'gcp', + machine: { type: 'g1-small' }, + project: { id: 'elastic-siem' }, + }, + '@timestamp': '2020-09-04T13:08:02.532Z', + related: { user: ['SYSTEM', 'SIEM-WINDOWS$'] }, + ecs: { version: '1.5.0' }, + host: { + hostname: 'siem-windows', + os: { + build: '17763.1397', + kernel: '10.0.17763.1397 (WinBuild.160101.0800)', + name: 'Windows Server 2019 Datacenter', + family: 'windows', + version: '10.0', + platform: 'windows', + }, + ip: ['fe80::ecf5:decc:3ec3:767e', '10.200.0.15'], + name: 'siem-windows', + id: 'ce1d3c9b-a815-4643-9641-ada0f2c00609', + mac: ['42:01:0a:c8:00:0f'], + architecture: 'x86_64', + }, + event: { + code: 4624, + provider: 'Microsoft-Windows-Security-Auditing', + created: '2020-09-04T13:08:03.638Z', + kind: 'event', + module: 'security', + action: 'logged-in', + category: 'authentication', + type: 'start', + outcome: 'success', + }, + user: { domain: 'NT AUTHORITY', name: 'SYSTEM', id: 'S-1-5-18' }, + }, + sort: [1599224882532], + }, + ], + }, + }, + }, + }, + { + key: 'tsg', + doc_count: 1, + failures: { + doc_count: 0, + lastFailure: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + successes: { + doc_count: 1, + lastSuccess: { + hits: { + total: 1, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: '9_sfWXQBc39KFIJbIsDh', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 20764 }, + log: { file: { path: '/var/log/auth.log' }, offset: 552463 }, + source: { + geo: { + continent_name: 'Europe', + region_iso_code: 'DE-BE', + city_name: 'Berlin', + country_iso_code: 'DE', + region_name: 'Land Berlin', + location: { lon: 13.3512, lat: 52.5727 }, + }, + as: { number: 6805, organization: { name: 'Telefonica Germany' } }, + port: 57457, + ip: '77.183.42.188', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:49:21.000Z', + system: { + auth: { + ssh: { + method: 'publickey', + signature: 'RSA SHA256:vv64JNLzKZWYA9vonnGWuW7zxWhyZrL/BFxyIGbISx8', + event: 'Accepted', + }, + }, + }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_success', + category: 'authentication', + dataset: 'system.auth', + outcome: 'success', + }, + user: { name: 'tsg' }, + }, + sort: [1599220161000], + }, + ], + }, + }, + }, + }, + { + key: 'admin', + doc_count: 23, + failures: { + doc_count: 23, + lastFailure: { + hits: { + total: 23, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'ZfxZWXQBc39KFIJbLN5U', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 22913 }, + log: { file: { path: '/var/log/auth.log' }, offset: 562910 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'KR-28', + city_name: 'Incheon', + country_iso_code: 'KR', + region_name: 'Incheon', + location: { lon: 126.7288, lat: 37.4562 }, + }, + as: { number: 4766, organization: { name: 'Korea Telecom' } }, + ip: '59.15.3.197', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:40:46.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'admin' }, + }, + sort: [1599226846000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'user', + doc_count: 21, + failures: { + doc_count: 21, + lastFailure: { + hits: { + total: 21, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'M_xLWXQBc39KFIJbY7Cb', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20671 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1028103 }, + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-NY', + city_name: 'New York', + country_iso_code: 'US', + region_name: 'New York', + location: { lon: -74, lat: 40.7157 }, + }, + ip: '64.227.88.245', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:25:43.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['64.227.88.245'], user: ['user'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T13:25:47.034172Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'user' }, + }, + sort: [1599225943000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'ubuntu', + doc_count: 18, + failures: { + doc_count: 18, + lastFailure: { + hits: { + total: 18, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'nPxKWXQBc39KFIJb7q4w', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + type: 'filebeat', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20665 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1027372 }, + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-NY', + city_name: 'New York', + country_iso_code: 'US', + region_name: 'New York', + location: { lon: -74, lat: 40.7157 }, + }, + ip: '64.227.88.245', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:25:07.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['64.227.88.245'], user: ['ubuntu'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T13:25:16.974606Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'ubuntu' }, + }, + sort: [1599225907000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'odoo', + doc_count: 17, + failures: { + doc_count: 17, + lastFailure: { + hits: { + total: 17, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'mPsfWXQBc39KFIJbI8HI', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + type: 'filebeat', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 21506 }, + log: { file: { path: '/var/log/auth.log' }, offset: 556761 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'IN-DL', + city_name: 'New Delhi', + country_iso_code: 'IN', + region_name: 'National Capital Territory of Delhi', + location: { lon: 77.2245, lat: 28.6358 }, + }, + as: { number: 10029, organization: { name: 'SHYAM SPECTRA PVT LTD' } }, + ip: '180.151.228.166', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T12:26:36.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'odoo' }, + }, + sort: [1599222396000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'pi', + doc_count: 17, + failures: { + doc_count: 17, + lastFailure: { + hits: { + total: 17, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'aaToWHQBA6bGZw2uR-St', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20475 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1019218 }, + source: { + geo: { + continent_name: 'Europe', + region_iso_code: 'SE-AB', + city_name: 'Stockholm', + country_iso_code: 'SE', + region_name: 'Stockholm', + location: { lon: 17.7833, lat: 59.25 }, + }, + as: { number: 8473, organization: { name: 'Bahnhof AB' } }, + ip: '178.174.148.58', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:37:22.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['178.174.148.58'], user: ['pi'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T11:37:31.797423Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'pi' }, + }, + sort: [1599219442000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'demo', + doc_count: 14, + failures: { + doc_count: 14, + lastFailure: { + hits: { + total: 14, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'VaP_V3QBA6bGZw2upUbg', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 19849 }, + log: { file: { path: '/var/log/auth.log' }, offset: 981036 }, + source: { + geo: { + continent_name: 'Europe', + country_iso_code: 'HR', + location: { lon: 15.5, lat: 45.1667 }, + }, + as: { + number: 42864, + organization: { name: 'Giganet Internet Szolgaltato Kft' }, + }, + ip: '45.95.168.157', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T07:23:22.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['45.95.168.157'], user: ['demo'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T07:23:26.046346Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'demo' }, + }, + sort: [1599204202000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'git', + doc_count: 13, + failures: { + doc_count: 13, + lastFailure: { + hits: { + total: 13, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'PqYfWXQBA6bGZw2uIhVU', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 20396 }, + log: { file: { path: '/var/log/auth.log' }, offset: 550795 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'CN-BJ', + city_name: 'Beijing', + country_iso_code: 'CN', + region_name: 'Beijing', + location: { lon: 116.3889, lat: 39.9288 }, + }, + as: { + number: 45090, + organization: { + name: 'Shenzhen Tencent Computer Systems Company Limited', + }, + }, + ip: '123.206.30.76', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:20:26.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'git' }, + }, + sort: [1599218426000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'webadmin', + doc_count: 13, + failures: { + doc_count: 13, + lastFailure: { + hits: { + total: 13, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'iMABWHQBB-gskclyitP-', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 19870 }, + log: { file: { path: '/var/log/auth.log' }, offset: 984133 }, + source: { + geo: { + continent_name: 'Europe', + country_iso_code: 'HR', + location: { lon: 15.5, lat: 45.1667 }, + }, + as: { + number: 42864, + organization: { name: 'Giganet Internet Szolgaltato Kft' }, + }, + ip: '45.95.168.157', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T07:25:28.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['45.95.168.157'], user: ['webadmin'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T07:25:30.236651Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'webadmin' }, + }, + sort: [1599204328000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + ], + }, + user_count: { value: 188 }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 14, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: -1, max_score: 0, hits: [] }, + aggregations: { + group_by_users: { + doc_count_error_upper_bound: -1, + sum_other_doc_count: 408, + buckets: [ + { + key: 'SYSTEM', + doc_count: 281, + failures: { + meta: {}, + doc_count: 0, + lastFailure: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + successes: { + meta: {}, + doc_count: 4, + lastSuccess: { + hits: { + total: 4, + max_score: 0, + hits: [ + { + _index: 'winlogbeat-8.0.0-2020.09.02-000001', + _id: 'zqY7WXQBA6bGZw2uLeKI', + _score: null, + _source: { + process: { + name: 'services.exe', + pid: 564, + executable: 'C:\\Windows\\System32\\services.exe', + }, + agent: { + build_date: '2020-07-16 09:16:27 +0000 UTC ', + name: 'siem-windows', + commit: '4dcbde39492bdc3843034bba8db811c68cb44b97 ', + id: '05e1bff7-d7a8-416a-8554-aa10288fa07d', + type: 'winlogbeat', + ephemeral_id: '655abd6c-6c33-435d-a2eb-79b2a01e6d61', + version: '8.0.0', + user: { name: 'inside_winlogbeat_user' }, + }, + winlog: { + computer_name: 'siem-windows', + process: { pid: 576, thread: { id: 880 } }, + keywords: ['Audit Success'], + logon: { id: '0x3e7', type: 'Service' }, + channel: 'Security', + event_data: { + LogonGuid: '{00000000-0000-0000-0000-000000000000}', + TargetOutboundDomainName: '-', + VirtualAccount: '%%1843', + LogonType: '5', + IpPort: '-', + TransmittedServices: '-', + SubjectLogonId: '0x3e7', + LmPackageName: '-', + TargetOutboundUserName: '-', + KeyLength: '0', + TargetLogonId: '0x3e7', + RestrictedAdminMode: '-', + SubjectUserName: 'SIEM-WINDOWS$', + TargetLinkedLogonId: '0x0', + ElevatedToken: '%%1842', + SubjectDomainName: 'WORKGROUP', + IpAddress: '-', + ImpersonationLevel: '%%1833', + TargetUserName: 'SYSTEM', + LogonProcessName: 'Advapi ', + TargetDomainName: 'NT AUTHORITY', + SubjectUserSid: 'S-1-5-18', + TargetUserSid: 'S-1-5-18', + AuthenticationPackageName: 'Negotiate', + }, + opcode: 'Info', + version: 2, + record_id: 57818, + task: 'Logon', + event_id: 4624, + provider_guid: '{54849625-5478-4994-a5ba-3e3b0328c30d}', + activity_id: '{d2485217-6bac-0000-8fbb-3f7e2571d601}', + api: 'wineventlog', + provider_name: 'Microsoft-Windows-Security-Auditing', + }, + log: { level: 'information' }, + source: { domain: '-' }, + message: + 'An account was successfully logged on.\n\nSubject:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSIEM-WINDOWS$\n\tAccount Domain:\t\tWORKGROUP\n\tLogon ID:\t\t0x3E7\n\nLogon Information:\n\tLogon Type:\t\t5\n\tRestricted Admin Mode:\t-\n\tVirtual Account:\t\tNo\n\tElevated Token:\t\tYes\n\nImpersonation Level:\t\tImpersonation\n\nNew Logon:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSYSTEM\n\tAccount Domain:\t\tNT AUTHORITY\n\tLogon ID:\t\t0x3E7\n\tLinked Logon ID:\t\t0x0\n\tNetwork Account Name:\t-\n\tNetwork Account Domain:\t-\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\n\nProcess Information:\n\tProcess ID:\t\t0x234\n\tProcess Name:\t\tC:\\Windows\\System32\\services.exe\n\nNetwork Information:\n\tWorkstation Name:\t-\n\tSource Network Address:\t-\n\tSource Port:\t\t-\n\nDetailed Authentication Information:\n\tLogon Process:\t\tAdvapi \n\tAuthentication Package:\tNegotiate\n\tTransited Services:\t-\n\tPackage Name (NTLM only):\t-\n\tKey Length:\t\t0\n\nThis event is generated when a logon session is created. It is generated on the computer that was accessed.\n\nThe subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.\n\nThe logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).\n\nThe New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.\n\nThe network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.\n\nThe impersonation level field indicates the extent to which a process in the logon session can impersonate.\n\nThe authentication information fields provide detailed information about this specific logon request.\n\t- Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.\n\t- Transited services indicate which intermediate services have participated in this logon request.\n\t- Package name indicates which sub-protocol was used among the NTLM protocols.\n\t- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.', + cloud: { + availability_zone: 'us-central1-c', + instance: { name: 'siem-windows', id: '9156726559029788564' }, + provider: 'gcp', + machine: { type: 'g1-small' }, + project: { id: 'elastic-siem' }, + }, + '@timestamp': '2020-09-04T13:08:02.532Z', + related: { user: ['SYSTEM', 'SIEM-WINDOWS$'] }, + ecs: { version: '1.5.0' }, + host: { + hostname: 'siem-windows', + os: { + build: '17763.1397', + kernel: '10.0.17763.1397 (WinBuild.160101.0800)', + name: 'Windows Server 2019 Datacenter', + family: 'windows', + version: '10.0', + platform: 'windows', + }, + ip: ['fe80::ecf5:decc:3ec3:767e', '10.200.0.15'], + name: 'siem-windows', + id: 'ce1d3c9b-a815-4643-9641-ada0f2c00609', + mac: ['42:01:0a:c8:00:0f'], + architecture: 'x86_64', + }, + event: { + code: 4624, + provider: 'Microsoft-Windows-Security-Auditing', + created: '2020-09-04T13:08:03.638Z', + kind: 'event', + module: 'security', + action: 'logged-in', + category: 'authentication', + type: 'start', + outcome: 'success', + }, + user: { domain: 'NT AUTHORITY', name: 'SYSTEM', id: 'S-1-5-18' }, + }, + sort: [1599224882532], + }, + ], + }, + }, + }, + }, + { + key: 'tsg', + doc_count: 1, + failures: { + doc_count: 0, + lastFailure: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + successes: { + doc_count: 1, + lastSuccess: { + hits: { + total: 1, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: '9_sfWXQBc39KFIJbIsDh', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 20764 }, + log: { file: { path: '/var/log/auth.log' }, offset: 552463 }, + source: { + geo: { + continent_name: 'Europe', + region_iso_code: 'DE-BE', + city_name: 'Berlin', + country_iso_code: 'DE', + region_name: 'Land Berlin', + location: { lon: 13.3512, lat: 52.5727 }, + }, + as: { number: 6805, organization: { name: 'Telefonica Germany' } }, + port: 57457, + ip: '77.183.42.188', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:49:21.000Z', + system: { + auth: { + ssh: { + method: 'publickey', + signature: 'RSA SHA256:vv64JNLzKZWYA9vonnGWuW7zxWhyZrL/BFxyIGbISx8', + event: 'Accepted', + }, + }, + }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_success', + category: 'authentication', + dataset: 'system.auth', + outcome: 'success', + }, + user: { name: 'tsg' }, + }, + sort: [1599220161000], + }, + ], + }, + }, + }, + }, + { + key: 'admin', + doc_count: 23, + failures: { + doc_count: 23, + lastFailure: { + hits: { + total: 23, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'ZfxZWXQBc39KFIJbLN5U', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 22913 }, + log: { file: { path: '/var/log/auth.log' }, offset: 562910 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'KR-28', + city_name: 'Incheon', + country_iso_code: 'KR', + region_name: 'Incheon', + location: { lon: 126.7288, lat: 37.4562 }, + }, + as: { number: 4766, organization: { name: 'Korea Telecom' } }, + ip: '59.15.3.197', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:40:46.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'admin' }, + }, + sort: [1599226846000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'user', + doc_count: 21, + failures: { + doc_count: 21, + lastFailure: { + hits: { + total: 21, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'M_xLWXQBc39KFIJbY7Cb', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20671 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1028103 }, + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-NY', + city_name: 'New York', + country_iso_code: 'US', + region_name: 'New York', + location: { lon: -74, lat: 40.7157 }, + }, + ip: '64.227.88.245', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:25:43.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['64.227.88.245'], user: ['user'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T13:25:47.034172Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'user' }, + }, + sort: [1599225943000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'ubuntu', + doc_count: 18, + failures: { + doc_count: 18, + lastFailure: { + hits: { + total: 18, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'nPxKWXQBc39KFIJb7q4w', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + type: 'filebeat', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20665 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1027372 }, + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-NY', + city_name: 'New York', + country_iso_code: 'US', + region_name: 'New York', + location: { lon: -74, lat: 40.7157 }, + }, + ip: '64.227.88.245', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T13:25:07.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['64.227.88.245'], user: ['ubuntu'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T13:25:16.974606Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'ubuntu' }, + }, + sort: [1599225907000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'odoo', + doc_count: 17, + failures: { + doc_count: 17, + lastFailure: { + hits: { + total: 17, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'mPsfWXQBc39KFIJbI8HI', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + type: 'filebeat', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 21506 }, + log: { file: { path: '/var/log/auth.log' }, offset: 556761 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'IN-DL', + city_name: 'New Delhi', + country_iso_code: 'IN', + region_name: 'National Capital Territory of Delhi', + location: { lon: 77.2245, lat: 28.6358 }, + }, + as: { number: 10029, organization: { name: 'SHYAM SPECTRA PVT LTD' } }, + ip: '180.151.228.166', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T12:26:36.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'odoo' }, + }, + sort: [1599222396000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'pi', + doc_count: 17, + failures: { + doc_count: 17, + lastFailure: { + hits: { + total: 17, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'aaToWHQBA6bGZw2uR-St', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 20475 }, + log: { file: { path: '/var/log/auth.log' }, offset: 1019218 }, + source: { + geo: { + continent_name: 'Europe', + region_iso_code: 'SE-AB', + city_name: 'Stockholm', + country_iso_code: 'SE', + region_name: 'Stockholm', + location: { lon: 17.7833, lat: 59.25 }, + }, + as: { number: 8473, organization: { name: 'Bahnhof AB' } }, + ip: '178.174.148.58', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:37:22.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['178.174.148.58'], user: ['pi'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T11:37:31.797423Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'pi' }, + }, + sort: [1599219442000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'demo', + doc_count: 14, + failures: { + doc_count: 14, + lastFailure: { + hits: { + total: 14, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'VaP_V3QBA6bGZw2upUbg', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 19849 }, + log: { file: { path: '/var/log/auth.log' }, offset: 981036 }, + source: { + geo: { + continent_name: 'Europe', + country_iso_code: 'HR', + location: { lon: 15.5, lat: 45.1667 }, + }, + as: { + number: 42864, + organization: { name: 'Giganet Internet Szolgaltato Kft' }, + }, + ip: '45.95.168.157', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T07:23:22.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['45.95.168.157'], user: ['demo'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T07:23:26.046346Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'demo' }, + }, + sort: [1599204202000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'git', + doc_count: 13, + failures: { + doc_count: 13, + lastFailure: { + hits: { + total: 13, + max_score: 0, + hits: [ + { + _index: '.ds-logs-system.auth-default-000001', + _id: 'PqYfWXQBA6bGZw2uIhVU', + _score: null, + _source: { + agent: { + hostname: 'siem-kibana', + name: 'siem-kibana', + id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', + ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', + type: 'filebeat', + version: '7.9.1', + }, + process: { name: 'sshd', pid: 20396 }, + log: { file: { path: '/var/log/auth.log' }, offset: 550795 }, + source: { + geo: { + continent_name: 'Asia', + region_iso_code: 'CN-BJ', + city_name: 'Beijing', + country_iso_code: 'CN', + region_name: 'Beijing', + location: { lon: 116.3889, lat: 39.9288 }, + }, + as: { + number: 45090, + organization: { + name: 'Shenzhen Tencent Computer Systems Company Limited', + }, + }, + ip: '123.206.30.76', + }, + cloud: { + availability_zone: 'us-east1-b', + instance: { name: 'siem-kibana', id: '5412578377715150143' }, + provider: 'gcp', + machine: { type: 'n1-standard-2' }, + project: { id: 'elastic-beats' }, + }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T11:20:26.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, + host: { + hostname: 'siem-kibana', + os: { + kernel: '4.9.0-8-amd64', + codename: 'stretch', + name: 'Debian GNU/Linux', + family: 'debian', + version: '9 (stretch)', + platform: 'debian', + }, + containerized: false, + ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], + name: 'siem-kibana', + id: 'aa7ca589f1b8220002f2fc61c64cfbf1', + mac: ['42:01:0a:8e:00:07'], + architecture: 'x86_64', + }, + event: { + timezone: '+00:00', + action: 'ssh_login', + type: 'authentication_failure', + category: 'authentication', + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'git' }, + }, + sort: [1599218426000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + { + key: 'webadmin', + doc_count: 13, + failures: { + doc_count: 13, + lastFailure: { + hits: { + total: 13, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'iMABWHQBB-gskclyitP-', + _score: null, + _source: { + agent: { + name: 'bastion00.siem.estc.dev', + id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', + type: 'filebeat', + ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', + version: '8.0.0', + }, + process: { name: 'sshd', pid: 19870 }, + log: { file: { path: '/var/log/auth.log' }, offset: 984133 }, + source: { + geo: { + continent_name: 'Europe', + country_iso_code: 'HR', + location: { lon: 15.5, lat: 45.1667 }, + }, + as: { + number: 42864, + organization: { name: 'Giganet Internet Szolgaltato Kft' }, + }, + ip: '45.95.168.157', + }, + fileset: { name: 'auth' }, + input: { type: 'log' }, + '@timestamp': '2020-09-04T07:25:28.000Z', + system: { auth: { ssh: { event: 'Invalid' } } }, + ecs: { version: '1.5.0' }, + related: { ip: ['45.95.168.157'], user: ['webadmin'] }, + service: { type: 'system' }, + host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, + event: { + ingested: '2020-09-04T07:25:30.236651Z', + timezone: '+00:00', + kind: 'event', + module: 'system', + action: 'ssh_login', + type: ['authentication_failure', 'info'], + category: ['authentication'], + dataset: 'system.auth', + outcome: 'failure', + }, + user: { name: 'webadmin' }, + }, + sort: [1599204328000], + }, + ], + }, + }, + }, + successes: { + doc_count: 0, + lastSuccess: { hits: { total: 0, max_score: 0, hits: [] } }, + }, + }, + ], + }, + user_count: { value: 188 }, + }, + }, + total: 21, + loaded: 21, + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "user_count": {\n "cardinality": {\n "field": "user.name"\n }\n },\n "group_by_users": {\n "terms": {\n "size": 10,\n "field": "user.name",\n "order": [\n {\n "successes.doc_count": "desc"\n },\n {\n "failures.doc_count": "desc"\n }\n ]\n },\n "aggs": {\n "failures": {\n "filter": {\n "term": {\n "event.outcome": "failure"\n }\n },\n "aggs": {\n "lastFailure": {\n "top_hits": {\n "size": 1,\n "_source": [],\n "sort": [\n {\n "@timestamp": {\n "order": "desc"\n }\n }\n ]\n }\n }\n }\n },\n "successes": {\n "filter": {\n "term": {\n "event.outcome": "success"\n }\n },\n "aggs": {\n "lastSuccess": {\n "top_hits": {\n "size": 1,\n "_source": [],\n "sort": [\n {\n "@timestamp": {\n "order": "desc"\n }\n }\n ]\n }\n }\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "term": {\n "event.category": "authentication"\n }\n },\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-02T15:17:13.678Z",\n "lte": "2020-09-03T15:17:13.678Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ]\n }\n },\n "size": 0\n },\n "track_total_hits": false\n}', + ], + }, + edges: [ + { + node: { + failures: 0, + successes: 4, + _id: 'SYSTEM+281', + user: { name: ['SYSTEM'] }, + lastSuccess: { + timestamp: ['2020-09-04T13:08:02.532Z'], + host: { id: ['ce1d3c9b-a815-4643-9641-ada0f2c00609'], name: ['siem-windows'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 0, + successes: 1, + _id: 'tsg+1', + user: { name: ['tsg'] }, + lastSuccess: { + timestamp: ['2020-09-04T11:49:21.000Z'], + source: { ip: ['77.183.42.188'] }, + host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 23, + successes: 0, + _id: 'admin+23', + user: { name: ['admin'] }, + lastFailure: { + timestamp: ['2020-09-04T13:40:46.000Z'], + source: { ip: ['59.15.3.197'] }, + host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 21, + successes: 0, + _id: 'user+21', + user: { name: ['user'] }, + lastFailure: { + timestamp: ['2020-09-04T13:25:43.000Z'], + source: { ip: ['64.227.88.245'] }, + host: { name: ['bastion00.siem.estc.dev'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 18, + successes: 0, + _id: 'ubuntu+18', + user: { name: ['ubuntu'] }, + lastFailure: { + timestamp: ['2020-09-04T13:25:07.000Z'], + source: { ip: ['64.227.88.245'] }, + host: { name: ['bastion00.siem.estc.dev'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 17, + successes: 0, + _id: 'odoo+17', + user: { name: ['odoo'] }, + lastFailure: { + timestamp: ['2020-09-04T12:26:36.000Z'], + source: { ip: ['180.151.228.166'] }, + host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 17, + successes: 0, + _id: 'pi+17', + user: { name: ['pi'] }, + lastFailure: { + timestamp: ['2020-09-04T11:37:22.000Z'], + source: { ip: ['178.174.148.58'] }, + host: { name: ['bastion00.siem.estc.dev'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 14, + successes: 0, + _id: 'demo+14', + user: { name: ['demo'] }, + lastFailure: { + timestamp: ['2020-09-04T07:23:22.000Z'], + source: { ip: ['45.95.168.157'] }, + host: { name: ['bastion00.siem.estc.dev'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 13, + successes: 0, + _id: 'git+13', + user: { name: ['git'] }, + lastFailure: { + timestamp: ['2020-09-04T11:20:26.000Z'], + source: { ip: ['123.206.30.76'] }, + host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + { + node: { + failures: 13, + successes: 0, + _id: 'webadmin+13', + user: { name: ['webadmin'] }, + lastFailure: { + timestamp: ['2020-09-04T07:25:28.000Z'], + source: { ip: ['45.95.168.157'] }, + host: { name: ['bastion00.siem.estc.dev'] }, + }, + }, + cursor: { value: '', tiebreaker: null }, + }, + ], + totalCount: 188, + pageInfo: { activePage: 0, fakeTotalCount: 50, showMorePagesIndicator: true }, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggregations: { + user_count: { cardinality: { field: 'user.name' } }, + group_by_users: { + terms: { + size: 10, + field: 'user.name', + order: [{ 'successes.doc_count': 'desc' }, { 'failures.doc_count': 'desc' }], + }, + aggs: { + failures: { + filter: { term: { 'event.outcome': 'failure' } }, + aggs: { + lastFailure: { + top_hits: { size: 1, _source: [], sort: [{ '@timestamp': { order: 'desc' } }] }, + }, + }, + }, + successes: { + filter: { term: { 'event.outcome': 'success' } }, + aggs: { + lastSuccess: { + top_hits: { size: 1, _source: [], sort: [{ '@timestamp': { order: 'desc' } }] }, + }, + }, + }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { term: { 'event.category': 'authentication' } }, + { + range: { + '@timestamp': { + gte: '2020-09-02T15:17:13.678Z', + lte: '2020-09-03T15:17:13.678Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }, + }, + size: 0, + }, + track_total_hits: false, +}; + +export const mockHit: AuthenticationHit = { + _index: 'index-123', + _type: 'type-123', + _id: 'id-123', + _score: 10, + _source: { + '@timestamp': 'time-1', + }, + cursor: 'cursor-1', + sort: [0], + user: 'Evan', + failures: 10, + successes: 20, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.test.tsx b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.test.tsx new file mode 100644 index 000000000000..816b9b2081c6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.test.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.host_details.dsl'; +import { hostDetails } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('hostDetails search strategy', () => { + const buildHostDetailsQuery = jest.spyOn(buildQuery, 'buildHostDetailsQuery'); + + afterEach(() => { + buildHostDetailsQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + hostDetails.buildDsl(mockOptions); + expect(buildHostDetailsQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await hostDetails.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts index 616e4ed0bac3..2cea136e427c 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts @@ -32,7 +32,12 @@ export const hostDetails: SecuritySolutionFactory = { response: [inspectStringifyObject(response)], }; const formattedHostItem = formatHostItem(aggregations); - + console.log('-------------'); + console.log(JSON.stringify(options)); + console.log('------2-------'); + console.log(JSON.stringify(response)); + console.log('------3-------'); + console.log(JSON.stringify({ ...response, inspect, hostDetails: formattedHostItem })); return { ...response, inspect, hostDetails: formattedHostItem }; }, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts new file mode 100644 index 000000000000..31e4069e458b --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildQuery } from './query.dsl'; +import { mockOptions, expectedDsl } from '../__mocks__/'; + +describe('buildQuery', () => { + test('build query from options correctly', () => { + expect(buildQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts index ade6128f0b05..6d12951c80c5 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts @@ -44,6 +44,8 @@ export const buildHostDetailsQuery = ({ track_total_hits: false, }, }; + console.log('----dsl----'); + console.log(JSON.stringify(dslQuery)); return dslQuery; }; From 79f6dacbe081dfe28fac2668d9545c4078230e83 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 14 Sep 2020 17:50:26 +0100 Subject: [PATCH 2/4] add unit tests for network --- .../factory/hosts/details/__mocks__/index.ts | 12 +- .../factory/hosts/details/index.ts | 6 - .../details/query.host_details.dsl.test.ts | 8 +- .../hosts/details/query.host_details.dsl.ts | 2 - .../network/details/__mocks__/index.ts | 377 ++++++++ .../factory/network/details/index.test.ts | 35 + .../details/query.details_network.dsl.test.ts | 13 + .../factory/network/dns/__mocks__/index.ts | 185 ++++ .../factory/network/dns/index.test.ts | 35 + .../network/dns/query.dns_network.dsl.test.ts | 13 + .../factory/network/http/__mocks__/index.ts | 670 ++++++++++++++ .../factory/network/http/index.test.ts | 35 + .../http/query.http_network.dsl.test.ts | 13 + .../network/http/query.http_network.dsl.ts | 1 + .../factory/network/index.test.ts | 41 + .../network/overview/__mocks__/index.ts | 213 +++++ .../factory/network/overview/index.test.ts | 35 + .../query.overview_network.dsl.test.ts | 13 + .../factory/network/tls/__mocks__/index.ts | 109 +++ .../factory/network/tls/index.test.ts | 35 + .../network/tls/query.tls_network.dsl.test.ts | 13 + .../network/top_countries/__mocks__/index.ts | 109 +++ .../network/top_countries/index.test.ts | 35 + .../factory/network/top_countries/index.ts | 1 - .../query.top_countries_network.dsl.test.ts | 13 + .../network/top_n_flow/__mocks__/index.ts | 847 ++++++++++++++++++ .../factory/network/top_n_flow/index.test.ts | 35 + .../query.top_n_flow_network.dsl.test.ts | 13 + .../factory/network/users/__mocks__/index.ts | 170 ++++ .../factory/network/users/index.test.ts | 51 ++ .../users/query.users_network.dsl.test.ts | 13 + 31 files changed, 3133 insertions(+), 18 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/query.dns_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/query.overview_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network.dsl.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/__mocks__/index.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.test.ts create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.test.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts index 65343dc721fd..d29fcb03b856 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/__mocks__/index.ts @@ -8,10 +8,12 @@ import { AuthenticationHit, Direction, HostsQueries, - HostAuthenticationsRequestOptions, + HostDetailsRequestOptions, + SortField, + HostsFields, } from '../../../../../../../common/search_strategy'; -export const mockOptions: HostAuthenticationsRequestOptions = { +export const mockOptions: HostDetailsRequestOptions = { defaultIndex: [ 'apm-*-transaction*', 'auditbeat-*', @@ -436,12 +438,12 @@ export const mockOptions: HostAuthenticationsRequestOptions = { from: '2020-09-02T15:17:13.678Z', to: '2020-09-03T15:17:13.678Z', }, - sort: { + sort: ({ direction: Direction.desc, field: 'success', - }, + } as unknown) as SortField, params: {}, -}; +} as HostDetailsRequestOptions; export const mockSearchStrategyResponse: IEsSearchResponse = { isPartial: false, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts index 2cea136e427c..8274d20a138e 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts @@ -32,12 +32,6 @@ export const hostDetails: SecuritySolutionFactory = { response: [inspectStringifyObject(response)], }; const formattedHostItem = formatHostItem(aggregations); - console.log('-------------'); - console.log(JSON.stringify(options)); - console.log('------2-------'); - console.log(JSON.stringify(response)); - console.log('------3-------'); - console.log(JSON.stringify({ ...response, inspect, hostDetails: formattedHostItem })); return { ...response, inspect, hostDetails: formattedHostItem }; }, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts index 31e4069e458b..ad1fabd156fa 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.test.ts @@ -3,11 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { buildQuery } from './query.dsl'; -import { mockOptions, expectedDsl } from '../__mocks__/'; +import { buildHostDetailsQuery } from './query.host_details.dsl'; +import { mockOptions, expectedDsl } from './__mocks__/'; -describe('buildQuery', () => { +describe('buildHostDetailsQuery', () => { test('build query from options correctly', () => { - expect(buildQuery(mockOptions)).toEqual(expectedDsl); + expect(buildHostDetailsQuery(mockOptions)).toEqual(expectedDsl); }); }); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts index 6d12951c80c5..ade6128f0b05 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/query.host_details.dsl.ts @@ -44,8 +44,6 @@ export const buildHostDetailsQuery = ({ track_total_hits: false, }, }; - console.log('----dsl----'); - console.log(JSON.stringify(dslQuery)); return dslQuery; }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/__mocks__/index.ts new file mode 100644 index 000000000000..fbe007622005 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/__mocks__/index.ts @@ -0,0 +1,377 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + NetworkDetailsRequestOptions, + NetworkQueries, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkDetailsRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + docValueFields: [ + { field: '@timestamp', format: 'date_time' }, + { field: 'event.created', format: 'date_time' }, + { field: 'event.end', format: 'date_time' }, + { field: 'event.ingested', format: 'date_time' }, + { field: 'event.start', format: 'date_time' }, + { field: 'file.accessed', format: 'date_time' }, + { field: 'file.created', format: 'date_time' }, + { field: 'file.ctime', format: 'date_time' }, + { field: 'file.mtime', format: 'date_time' }, + { field: 'package.installed', format: 'date_time' }, + { field: 'process.parent.start', format: 'date_time' }, + { field: 'process.start', format: 'date_time' }, + { field: 'system.audit.host.boottime', format: 'date_time' }, + { field: 'system.audit.package.installtime', format: 'date_time' }, + { field: 'system.audit.user.password.last_changed', format: 'date_time' }, + { field: 'tls.client.not_after', format: 'date_time' }, + { field: 'tls.client.not_before', format: 'date_time' }, + { field: 'tls.server.not_after', format: 'date_time' }, + { field: 'tls.server.not_before', format: 'date_time' }, + { field: 'aws.cloudtrail.user_identity.session_context.creation_date', format: 'date_time' }, + { field: 'azure.auditlogs.properties.activity_datetime', format: 'date_time' }, + { field: 'azure.enqueued_time', format: 'date_time' }, + { field: 'azure.signinlogs.properties.created_at', format: 'date_time' }, + { field: 'cef.extensions.agentReceiptTime', format: 'date_time' }, + { field: 'cef.extensions.deviceCustomDate1', format: 'date_time' }, + { field: 'cef.extensions.deviceCustomDate2', format: 'date_time' }, + { field: 'cef.extensions.deviceReceiptTime', format: 'date_time' }, + { field: 'cef.extensions.endTime', format: 'date_time' }, + { field: 'cef.extensions.fileCreateTime', format: 'date_time' }, + { field: 'cef.extensions.fileModificationTime', format: 'date_time' }, + { field: 'cef.extensions.flexDate1', format: 'date_time' }, + { field: 'cef.extensions.managerReceiptTime', format: 'date_time' }, + { field: 'cef.extensions.oldFileCreateTime', format: 'date_time' }, + { field: 'cef.extensions.oldFileModificationTime', format: 'date_time' }, + { field: 'cef.extensions.startTime', format: 'date_time' }, + { field: 'checkpoint.subs_exp', format: 'date_time' }, + { field: 'crowdstrike.event.EndTimestamp', format: 'date_time' }, + { field: 'crowdstrike.event.IncidentEndTime', format: 'date_time' }, + { field: 'crowdstrike.event.IncidentStartTime', format: 'date_time' }, + { field: 'crowdstrike.event.ProcessEndTime', format: 'date_time' }, + { field: 'crowdstrike.event.ProcessStartTime', format: 'date_time' }, + { field: 'crowdstrike.event.StartTimestamp', format: 'date_time' }, + { field: 'crowdstrike.event.Timestamp', format: 'date_time' }, + { field: 'crowdstrike.event.UTCTimestamp', format: 'date_time' }, + { field: 'crowdstrike.metadata.eventCreationTime', format: 'date_time' }, + { field: 'gsuite.admin.email.log_search_filter.end_date', format: 'date_time' }, + { field: 'gsuite.admin.email.log_search_filter.start_date', format: 'date_time' }, + { field: 'gsuite.admin.user.birthdate', format: 'date_time' }, + { field: 'kafka.block_timestamp', format: 'date_time' }, + { field: 'microsoft.defender_atp.lastUpdateTime', format: 'date_time' }, + { field: 'microsoft.defender_atp.resolvedTime', format: 'date_time' }, + { field: 'misp.campaign.first_seen', format: 'date_time' }, + { field: 'misp.campaign.last_seen', format: 'date_time' }, + { field: 'misp.intrusion_set.first_seen', format: 'date_time' }, + { field: 'misp.intrusion_set.last_seen', format: 'date_time' }, + { field: 'misp.observed_data.first_observed', format: 'date_time' }, + { field: 'misp.observed_data.last_observed', format: 'date_time' }, + { field: 'misp.report.published', format: 'date_time' }, + { field: 'misp.threat_indicator.valid_from', format: 'date_time' }, + { field: 'misp.threat_indicator.valid_until', format: 'date_time' }, + { field: 'netflow.collection_time_milliseconds', format: 'date_time' }, + { field: 'netflow.exporter.timestamp', format: 'date_time' }, + { field: 'netflow.flow_end_microseconds', format: 'date_time' }, + { field: 'netflow.flow_end_milliseconds', format: 'date_time' }, + { field: 'netflow.flow_end_nanoseconds', format: 'date_time' }, + { field: 'netflow.flow_end_seconds', format: 'date_time' }, + { field: 'netflow.flow_start_microseconds', format: 'date_time' }, + { field: 'netflow.flow_start_milliseconds', format: 'date_time' }, + { field: 'netflow.flow_start_nanoseconds', format: 'date_time' }, + { field: 'netflow.flow_start_seconds', format: 'date_time' }, + { field: 'netflow.max_export_seconds', format: 'date_time' }, + { field: 'netflow.max_flow_end_microseconds', format: 'date_time' }, + { field: 'netflow.max_flow_end_milliseconds', format: 'date_time' }, + { field: 'netflow.max_flow_end_nanoseconds', format: 'date_time' }, + { field: 'netflow.max_flow_end_seconds', format: 'date_time' }, + { field: 'netflow.min_export_seconds', format: 'date_time' }, + { field: 'netflow.min_flow_start_microseconds', format: 'date_time' }, + { field: 'netflow.min_flow_start_milliseconds', format: 'date_time' }, + { field: 'netflow.min_flow_start_nanoseconds', format: 'date_time' }, + { field: 'netflow.min_flow_start_seconds', format: 'date_time' }, + { field: 'netflow.monitoring_interval_end_milli_seconds', format: 'date_time' }, + { field: 'netflow.monitoring_interval_start_milli_seconds', format: 'date_time' }, + { field: 'netflow.observation_time_microseconds', format: 'date_time' }, + { field: 'netflow.observation_time_milliseconds', format: 'date_time' }, + { field: 'netflow.observation_time_nanoseconds', format: 'date_time' }, + { field: 'netflow.observation_time_seconds', format: 'date_time' }, + { field: 'netflow.system_init_time_milliseconds', format: 'date_time' }, + { field: 'rsa.internal.lc_ctime', format: 'date_time' }, + { field: 'rsa.internal.time', format: 'date_time' }, + { field: 'rsa.time.effective_time', format: 'date_time' }, + { field: 'rsa.time.endtime', format: 'date_time' }, + { field: 'rsa.time.event_queue_time', format: 'date_time' }, + { field: 'rsa.time.event_time', format: 'date_time' }, + { field: 'rsa.time.expire_time', format: 'date_time' }, + { field: 'rsa.time.recorded_time', format: 'date_time' }, + { field: 'rsa.time.stamp', format: 'date_time' }, + { field: 'rsa.time.starttime', format: 'date_time' }, + { field: 'sophos.xg.date', format: 'date_time' }, + { field: 'sophos.xg.eventtime', format: 'date_time' }, + { field: 'sophos.xg.start_time', format: 'date_time' }, + ], + factoryQueryType: NetworkQueries.details, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + ip: '35.196.65.164', +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 2620, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: 0, max_score: 0, hits: [] }, + aggregations: { + host: { + doc_count: 0, + results: { hits: { total: { value: 0, relation: 'eq' }, max_score: null, hits: [] } }, + }, + destination: { + meta: {}, + doc_count: 5, + geo: { + meta: {}, + doc_count: 5, + results: { + hits: { + total: { value: 5, relation: 'eq' }, + max_score: null, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1523631609876537', + _score: null, + _source: { + destination: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + }, + sort: [1599703212208], + }, + ], + }, + }, + }, + as: { + meta: {}, + doc_count: 5, + results: { + hits: { + total: { value: 5, relation: 'eq' }, + max_score: null, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1523631609876537', + _score: null, + _source: { + destination: { as: { number: 15169, organization: { name: 'Google LLC' } } }, + }, + sort: [1599703212208], + }, + ], + }, + }, + }, + lastSeen: { value: 1599703212208, value_as_string: '2020-09-10T02:00:12.208Z' }, + firstSeen: { value: 1598802015355, value_as_string: '2020-08-30T15:40:15.355Z' }, + }, + source: { + meta: {}, + doc_count: 5, + geo: { + meta: {}, + doc_count: 5, + results: { + hits: { + total: { value: 5, relation: 'eq' }, + max_score: null, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1523631486500511', + _score: null, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + }, + sort: [1599703214494], + }, + ], + }, + }, + }, + as: { + meta: {}, + doc_count: 5, + results: { + hits: { + total: { value: 5, relation: 'eq' }, + max_score: null, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1523631486500511', + _score: null, + _source: { + source: { as: { number: 15169, organization: { name: 'Google LLC' } } }, + }, + sort: [1599703214494], + }, + ], + }, + }, + }, + lastSeen: { value: 1599703214494, value_as_string: '2020-09-10T02:00:14.494Z' }, + firstSeen: { value: 1598802015107, value_as_string: '2020-08-30T15:40:15.107Z' }, + }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggs": {\n "source": {\n "filter": {\n "term": {\n "source.ip": "35.196.65.164"\n }\n },\n "aggs": {\n "firstSeen": {\n "min": {\n "field": "@timestamp"\n }\n },\n "lastSeen": {\n "max": {\n "field": "@timestamp"\n }\n },\n "as": {\n "filter": {\n "exists": {\n "field": "source.as"\n }\n },\n "aggs": {\n "results": {\n "top_hits": {\n "size": 1,\n "_source": [\n "source.as"\n ],\n "sort": [\n {\n "@timestamp": "desc"\n }\n ]\n }\n }\n }\n },\n "geo": {\n "filter": {\n "exists": {\n "field": "source.geo"\n }\n },\n "aggs": {\n "results": {\n "top_hits": {\n "size": 1,\n "_source": [\n "source.geo"\n ],\n "sort": [\n {\n "@timestamp": "desc"\n }\n ]\n }\n }\n }\n }\n }\n },\n "destination": {\n "filter": {\n "term": {\n "destination.ip": "35.196.65.164"\n }\n },\n "aggs": {\n "firstSeen": {\n "min": {\n "field": "@timestamp"\n }\n },\n "lastSeen": {\n "max": {\n "field": "@timestamp"\n }\n },\n "as": {\n "filter": {\n "exists": {\n "field": "destination.as"\n }\n },\n "aggs": {\n "results": {\n "top_hits": {\n "size": 1,\n "_source": [\n "destination.as"\n ],\n "sort": [\n {\n "@timestamp": "desc"\n }\n ]\n }\n }\n }\n },\n "geo": {\n "filter": {\n "exists": {\n "field": "destination.geo"\n }\n },\n "aggs": {\n "results": {\n "top_hits": {\n "size": 1,\n "_source": [\n "destination.geo"\n ],\n "sort": [\n {\n "@timestamp": "desc"\n }\n ]\n }\n }\n }\n }\n }\n },\n "host": {\n "filter": {\n "term": {\n "host.ip": "35.196.65.164"\n }\n },\n "aggs": {\n "results": {\n "top_hits": {\n "size": 1,\n "_source": [\n "host"\n ],\n "sort": [\n {\n "@timestamp": "desc"\n }\n ]\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "should": []\n }\n },\n "size": 0,\n "track_total_hits": false\n }\n}', + ], + }, + networkDetails: { + source: { + firstSeen: '2020-08-30T15:40:15.107Z', + lastSeen: '2020-09-10T02:00:14.494Z', + autonomousSystem: { number: 15169, organization: { name: 'Google LLC' } }, + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + destination: { + firstSeen: '2020-08-30T15:40:15.355Z', + lastSeen: '2020-09-10T02:00:12.208Z', + autonomousSystem: { number: 15169, organization: { name: 'Google LLC' } }, + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + host: {}, + }, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggs: { + source: { + filter: { term: { 'source.ip': '35.196.65.164' } }, + aggs: { + firstSeen: { min: { field: '@timestamp' } }, + lastSeen: { max: { field: '@timestamp' } }, + as: { + filter: { exists: { field: 'source.as' } }, + aggs: { + results: { + top_hits: { size: 1, _source: ['source.as'], sort: [{ '@timestamp': 'desc' }] }, + }, + }, + }, + geo: { + filter: { exists: { field: 'source.geo' } }, + aggs: { + results: { + top_hits: { size: 1, _source: ['source.geo'], sort: [{ '@timestamp': 'desc' }] }, + }, + }, + }, + }, + }, + destination: { + filter: { term: { 'destination.ip': '35.196.65.164' } }, + aggs: { + firstSeen: { min: { field: '@timestamp' } }, + lastSeen: { max: { field: '@timestamp' } }, + as: { + filter: { exists: { field: 'destination.as' } }, + aggs: { + results: { + top_hits: { + size: 1, + _source: ['destination.as'], + sort: [{ '@timestamp': 'desc' }], + }, + }, + }, + }, + geo: { + filter: { exists: { field: 'destination.geo' } }, + aggs: { + results: { + top_hits: { + size: 1, + _source: ['destination.geo'], + sort: [{ '@timestamp': 'desc' }], + }, + }, + }, + }, + }, + }, + host: { + filter: { term: { 'host.ip': '35.196.65.164' } }, + aggs: { + results: { top_hits: { size: 1, _source: ['host'], sort: [{ '@timestamp': 'desc' }] } }, + }, + }, + }, + query: { bool: { should: [] } }, + size: 0, + track_total_hits: false, + }, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.test.ts new file mode 100644 index 000000000000..6f54097a76fe --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.details_network.dsl'; +import { networkDetails } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkDetails search strategy', () => { + const buildNetworkDetailsQuery = jest.spyOn(buildQuery, 'buildNetworkDetailsQuery'); + + afterEach(() => { + buildNetworkDetailsQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkDetails.buildDsl(mockOptions); + expect(buildNetworkDetailsQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkDetails.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.test.ts new file mode 100644 index 000000000000..93dca8ee0397 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildNetworkDetailsQuery } from './query.details_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildNetworkDetailsQuery', () => { + test('build query from options correctly', () => { + expect(buildNetworkDetailsQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/__mocks__/index.ts new file mode 100644 index 000000000000..f0605c5523fd --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/__mocks__/index.ts @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkDnsFields, + NetworkDnsRequestOptions, + NetworkQueries, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkDnsRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.dns, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + isPtrIncluded: false, + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { field: NetworkDnsFields.uniqueDomains, direction: Direction.desc }, + timerange: { interval: '12h', from: '2020-09-13T09:00:43.249Z', to: '2020-09-14T09:00:43.249Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 28, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { max_score: 0, hits: [], total: 0 }, + aggregations: { + dns_count: { value: 2 }, + dns_name_query_count: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'google.com', + doc_count: 1, + unique_domains: { value: 1 }, + dns_bytes_in: { value: 0 }, + dns_bytes_out: { value: 0 }, + }, + { + key: 'google.internal', + doc_count: 1, + unique_domains: { value: 1 }, + dns_bytes_in: { value: 0 }, + dns_bytes_out: { value: 0 }, + }, + ], + }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 28, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { max_score: 0, hits: [] }, + aggregations: { + dns_count: { value: 2 }, + dns_name_query_count: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'google.com', + doc_count: 1, + unique_domains: { value: 1 }, + dns_bytes_in: { value: 0 }, + dns_bytes_out: { value: 0 }, + }, + { + key: 'google.internal', + doc_count: 1, + unique_domains: { value: 1 }, + dns_bytes_in: { value: 0 }, + dns_bytes_out: { value: 0 }, + }, + ], + }, + }, + }, + total: 21, + loaded: 21, + edges: [ + { + node: { + _id: 'google.com', + dnsBytesIn: 0, + dnsBytesOut: 0, + dnsName: 'google.com', + queryCount: 1, + uniqueDomains: 1, + }, + cursor: { value: 'google.com', tiebreaker: null }, + }, + { + node: { + _id: 'google.internal', + dnsBytesIn: 0, + dnsBytesOut: 0, + dnsName: 'google.internal', + queryCount: 1, + uniqueDomains: 1, + }, + cursor: { value: 'google.internal', tiebreaker: null }, + }, + ], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "dns_count": {\n "cardinality": {\n "field": "dns.question.registered_domain"\n }\n },\n "dns_name_query_count": {\n "terms": {\n "field": "dns.question.registered_domain",\n "size": 10,\n "order": {\n "unique_domains": "desc"\n }\n },\n "aggs": {\n "unique_domains": {\n "cardinality": {\n "field": "dns.question.name"\n }\n },\n "dns_bytes_in": {\n "sum": {\n "field": "source.bytes"\n }\n },\n "dns_bytes_out": {\n "sum": {\n "field": "destination.bytes"\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T09:00:43.249Z",\n "lte": "2020-09-14T09:00:43.249Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ],\n "must_not": [\n {\n "term": {\n "dns.question.type": {\n "value": "PTR"\n }\n }\n }\n ]\n }\n }\n },\n "size": 0,\n "track_total_hits": false\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 2, showMorePagesIndicator: false }, + totalCount: 2, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggregations: { + dns_count: { cardinality: { field: 'dns.question.registered_domain' } }, + dns_name_query_count: { + terms: { + field: 'dns.question.registered_domain', + size: 10, + order: { unique_domains: 'desc' }, + }, + aggs: { + unique_domains: { cardinality: { field: 'dns.question.name' } }, + dns_bytes_in: { sum: { field: 'source.bytes' } }, + dns_bytes_out: { sum: { field: 'destination.bytes' } }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + gte: '2020-09-13T09:00:43.249Z', + lte: '2020-09-14T09:00:43.249Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + must_not: [{ term: { 'dns.question.type': { value: 'PTR' } } }], + }, + }, + }, + size: 0, + track_total_hits: false, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/index.test.ts new file mode 100644 index 000000000000..22906a1ea138 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.dns_network.dsl'; +import { networkDns } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkDns search strategy', () => { + const mockBuildDnsQuery = jest.spyOn(buildQuery, 'buildDnsQuery'); + + afterEach(() => { + mockBuildDnsQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkDns.buildDsl(mockOptions); + expect(mockBuildDnsQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkDns.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/query.dns_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/query.dns_network.dsl.test.ts new file mode 100644 index 000000000000..9e95990d13a4 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/dns/query.dns_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildDnsQuery } from './query.dns_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildDnsQuery', () => { + test('build query from options correctly', () => { + expect(buildDnsQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/__mocks__/index.ts new file mode 100644 index 000000000000..9991d267707b --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/__mocks__/index.ts @@ -0,0 +1,670 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkDnsFields, + NetworkDnsRequestOptions, + NetworkQueries, + SortField, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkDnsRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.http, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { direction: Direction.desc } as SortField, + timerange: { interval: '12h', from: '2020-09-13T09:00:43.249Z', to: '2020-09-14T09:00:43.249Z' }, +} as NetworkDnsRequestOptions; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 422, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { max_score: 0, hits: [], total: 0 }, + aggregations: { + http_count: { value: 1404 }, + url: { + doc_count_error_upper_bound: 1440, + sum_other_doc_count: 98077, + buckets: [ + { + key: '/_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip', + doc_count: 106704, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'GET', doc_count: 106704 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 68983 }, + { key: 'es.siem.estc.dev', doc_count: 37721 }, + ], + }, + source: { + hits: { + total: { value: 106704, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'L4wXh3QBc39KFIJbgXrN', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '67.173.227.94' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 200, doc_count: 72174 }, + { key: 401, doc_count: 34530 }, + ], + }, + }, + { + key: '/_bulk', + doc_count: 76744, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 76744 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 76737 }, + { key: 'es.siem.estc.dev', doc_count: 7 }, + ], + }, + source: { + hits: { + total: { value: 76744, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'tEIXh3QBB-gskclyiT2g', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '35.227.65.114' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 200, doc_count: 75394 }, + { key: 401, doc_count: 1350 }, + ], + }, + }, + { + key: '/.reporting-*/_search', + doc_count: 58746, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 58746 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 56305 }, + { key: 'es.siem.estc.dev', doc_count: 2441 }, + ], + }, + source: { + hits: { + total: { value: 58746, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'MYwXh3QBc39KFIJbgXrN', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '67.173.227.94' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 58746 }], + }, + }, + { + key: + '/.kibana-task-manager-xavier-m/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + doc_count: 28715, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 28715 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'es.siem.estc.dev:9200', doc_count: 28715 }], + }, + source: { + hits: { + total: { value: 28715, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'MIwXh3QBc39KFIJbgXrN', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '24.168.52.229' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 28715 }], + }, + }, + { + key: + '/.kibana-task-manager-andrewg-local-testing-7-9-ff/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + doc_count: 28161, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 28161 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'es.siem.estc.dev:9200', doc_count: 28161 }], + }, + source: { + hits: { + total: { value: 28161, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'MowXh3QBc39KFIJbgXrN', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '67.173.227.94' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 28161 }], + }, + }, + { + key: '/_security/user/_has_privileges', + doc_count: 23283, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 23283 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 21601 }, + { key: 'es.siem.estc.dev', doc_count: 1682 }, + ], + }, + source: { + hits: { + total: { value: 23283, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: '6Ywch3QBc39KFIJbVY_k', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '67.173.227.94' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 23283 }], + }, + }, + { + key: '/_xpack', + doc_count: 20724, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'GET', doc_count: 20724 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 17289 }, + { key: 'es.siem.estc.dev', doc_count: 3435 }, + ], + }, + source: { + hits: { + total: { value: 20724, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'rkIXh3QBB-gskclyiT2g', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '35.226.77.71' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 200, doc_count: 12084 }, + { key: 401, doc_count: 8640 }, + ], + }, + }, + { + key: '/', + doc_count: 18306, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'GET', doc_count: 18274 }, + { key: 'HEAD', doc_count: 29 }, + { key: 'POST', doc_count: 3 }, + ], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 37, + buckets: [ + { key: 'es.siem.estc.dev', doc_count: 8631 }, + { key: 'es.siem.estc.dev:9200', doc_count: 5757 }, + { key: 'es.siem.estc.dev:443', doc_count: 3858 }, + { key: '35.232.239.42', doc_count: 20 }, + ], + }, + source: { + hits: { + total: { value: 18306, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'JEIYh3QBB-gskclyYEfA', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '35.171.72.245' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 3, + buckets: [ + { key: 401, doc_count: 18220 }, + { key: 404, doc_count: 30 }, + { key: 302, doc_count: 27 }, + { key: 200, doc_count: 26 }, + ], + }, + }, + { + key: '/_monitoring/bulk?system_id=kibana&system_api_version=7&interval=10000ms', + doc_count: 18048, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'POST', doc_count: 18048 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'es.siem.estc.dev:9200', doc_count: 17279 }, + { key: 'es.siem.estc.dev', doc_count: 769 }, + ], + }, + source: { + hits: { + total: { value: 18048, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'sUIXh3QBB-gskclyiT2g', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '24.168.52.229' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 18048 }], + }, + }, + { + key: '/s/row-renderer-checking/api/reporting/jobs/count', + doc_count: 14046, + methods: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'GET', doc_count: 14046 }], + }, + domains: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'kibana.siem.estc.dev', doc_count: 14046 }], + }, + source: { + hits: { + total: { value: 14046, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 's0IXh3QBB-gskclyiT2g', + _score: 0, + _source: { + host: { name: 'bastion00.siem.estc.dev' }, + source: { ip: '75.134.244.183' }, + }, + }, + ], + }, + }, + status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 200, doc_count: 14046 }], + }, + }, + ], + }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + edges: [ + { + node: { + _id: '/_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['GET'], + statuses: ['200', '401'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '67.173.227.94', + path: '/_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip', + requestCount: 106704, + }, + cursor: { + value: '/_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip', + tiebreaker: null, + }, + }, + { + node: { + _id: '/_bulk', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['POST'], + statuses: ['200', '401'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '35.227.65.114', + path: '/_bulk', + requestCount: 76744, + }, + cursor: { value: '/_bulk', tiebreaker: null }, + }, + { + node: { + _id: '/.reporting-*/_search', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['POST'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '67.173.227.94', + path: '/.reporting-*/_search', + requestCount: 58746, + }, + cursor: { value: '/.reporting-*/_search', tiebreaker: null }, + }, + { + node: { + _id: + '/.kibana-task-manager-xavier-m/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + domains: ['es.siem.estc.dev:9200'], + methods: ['POST'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '24.168.52.229', + path: + '/.kibana-task-manager-xavier-m/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + requestCount: 28715, + }, + cursor: { + value: + '/.kibana-task-manager-xavier-m/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + tiebreaker: null, + }, + }, + { + node: { + _id: + '/.kibana-task-manager-andrewg-local-testing-7-9-ff/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + domains: ['es.siem.estc.dev:9200'], + methods: ['POST'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '67.173.227.94', + path: + '/.kibana-task-manager-andrewg-local-testing-7-9-ff/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + requestCount: 28161, + }, + cursor: { + value: + '/.kibana-task-manager-andrewg-local-testing-7-9-ff/_update_by_query?ignore_unavailable=true&refresh=true&max_docs=10&conflicts=proceed', + tiebreaker: null, + }, + }, + { + node: { + _id: '/_security/user/_has_privileges', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['POST'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '67.173.227.94', + path: '/_security/user/_has_privileges', + requestCount: 23283, + }, + cursor: { value: '/_security/user/_has_privileges', tiebreaker: null }, + }, + { + node: { + _id: '/_xpack', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['GET'], + statuses: ['200', '401'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '35.226.77.71', + path: '/_xpack', + requestCount: 20724, + }, + cursor: { value: '/_xpack', tiebreaker: null }, + }, + { + node: { + _id: '/', + domains: [ + 'es.siem.estc.dev', + 'es.siem.estc.dev:9200', + 'es.siem.estc.dev:443', + '35.232.239.42', + ], + methods: ['GET', 'HEAD', 'POST'], + statuses: ['401', '404', '302', '200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '35.171.72.245', + path: '/', + requestCount: 18306, + }, + cursor: { value: '/', tiebreaker: null }, + }, + { + node: { + _id: '/_monitoring/bulk?system_id=kibana&system_api_version=7&interval=10000ms', + domains: ['es.siem.estc.dev:9200', 'es.siem.estc.dev'], + methods: ['POST'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '24.168.52.229', + path: '/_monitoring/bulk?system_id=kibana&system_api_version=7&interval=10000ms', + requestCount: 18048, + }, + cursor: { + value: '/_monitoring/bulk?system_id=kibana&system_api_version=7&interval=10000ms', + tiebreaker: null, + }, + }, + { + node: { + _id: '/s/row-renderer-checking/api/reporting/jobs/count', + domains: ['kibana.siem.estc.dev'], + methods: ['GET'], + statuses: ['200'], + lastHost: 'bastion00.siem.estc.dev', + lastSourceIp: '75.134.244.183', + path: '/s/row-renderer-checking/api/reporting/jobs/count', + requestCount: 14046, + }, + cursor: { value: '/s/row-renderer-checking/api/reporting/jobs/count', tiebreaker: null }, + }, + ], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "http_count": {\n "cardinality": {\n "field": "url.path"\n }\n },\n "url": {\n "terms": {\n "field": "url.path",\n "size": 10,\n "order": {\n "_count": "desc"\n }\n },\n "aggs": {\n "methods": {\n "terms": {\n "field": "http.request.method",\n "size": 4\n }\n },\n "domains": {\n "terms": {\n "field": "url.domain",\n "size": 4\n }\n },\n "status": {\n "terms": {\n "field": "http.response.status_code",\n "size": 4\n }\n },\n "source": {\n "top_hits": {\n "size": 1,\n "_source": {\n "includes": [\n "host.name",\n "source.ip"\n ]\n }\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T09:00:43.249Z",\n "lte": "2020-09-14T09:00:43.249Z",\n "format": "strict_date_optional_time"\n }\n }\n },\n {\n "exists": {\n "field": "http.request.method"\n }\n }\n ]\n }\n }\n },\n "size": 0,\n "track_total_hits": false\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 50, showMorePagesIndicator: true }, + totalCount: 1404, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggregations: { + http_count: { cardinality: { field: 'url.path' } }, + url: { + terms: { field: 'url.path', size: 10, order: { _count: 'desc' } }, + aggs: { + methods: { terms: { field: 'http.request.method', size: 4 } }, + domains: { terms: { field: 'url.domain', size: 4 } }, + status: { terms: { field: 'http.response.status_code', size: 4 } }, + source: { top_hits: { size: 1, _source: { includes: ['host.name', 'source.ip'] } } }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + gte: '2020-09-13T09:00:43.249Z', + lte: '2020-09-14T09:00:43.249Z', + format: 'strict_date_optional_time', + }, + }, + }, + { exists: { field: 'http.request.method' } }, + ], + }, + }, + }, + size: 0, + track_total_hits: false, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/index.test.ts new file mode 100644 index 000000000000..47946ee3ed20 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.http_network.dsl'; +import { networkHttp } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkHttp search strategy', () => { + const buildHttpQuery = jest.spyOn(buildQuery, 'buildHttpQuery'); + + afterEach(() => { + buildHttpQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkHttp.buildDsl(mockOptions); + expect(buildHttpQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkHttp.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.test.ts new file mode 100644 index 000000000000..1d10b60374a2 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildHttpQuery } from './query.http_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildHttpQuery', () => { + test('build query from options correctly', () => { + expect(buildHttpQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.ts index feffe7f70afd..dcffa60d8aa3 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/http/query.http_network.dsl.ts @@ -69,6 +69,7 @@ export const buildHttpQuery = ({ size: 0, track_total_hits: false, }; + return dslQuery; }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts new file mode 100644 index 000000000000..f901d9f3dab5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { NetworkQueries } from '../../../../../common/search_strategy/security_solution'; + +import { networkFactory } from '.'; +import { networkDetails } from './details'; +import { networkDns } from './dns'; +import { networkHttp } from './http'; +import { networkOverview } from './overview'; +import { networkTls } from './tls'; +import { networkTopCountries } from './top_countries'; +import { networkTopNFlow } from './top_n_flow'; +import { networkUsers } from './users'; + +jest.mock('./details'); +jest.mock('./dns'); +jest.mock('./http'); +jest.mock('./overview'); +jest.mock('./tls'); +jest.mock('./top_countries'); +jest.mock('./top_n_flow'); +jest.mock('./users'); + +describe('networkFactory', () => { + test('should include correct apis', () => { + const expectedNetworkFactory = { + [NetworkQueries.details]: networkDetails, + [NetworkQueries.dns]: networkDns, + [NetworkQueries.http]: networkHttp, + [NetworkQueries.overview]: networkOverview, + [NetworkQueries.tls]: networkTls, + [NetworkQueries.topCountries]: networkTopCountries, + [NetworkQueries.topNFlow]: networkTopNFlow, + [NetworkQueries.users]: networkUsers, + }; + expect(networkFactory).toEqual(expectedNetworkFactory); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/__mocks__/index.ts new file mode 100644 index 000000000000..8f34d31e49e1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/__mocks__/index.ts @@ -0,0 +1,213 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + NetworkOverviewRequestOptions, + NetworkQueries, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkOverviewRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.overview, + filterQuery: + '{"bool":{"must":[],"filter":[{"match_all":{}},{"bool":{"filter":[{"bool":{"should":[{"bool":{"should":[{"exists":{"field":"source.ip"}}],"minimum_should_match":1}},{"bool":{"should":[{"exists":{"field":"destination.ip"}}],"minimum_should_match":1}}],"minimum_should_match":1}}]}}],"should":[],"must_not":[]}}', + timerange: { interval: '12h', from: '2020-09-13T12:54:24.685Z', to: '2020-09-14T12:54:24.685Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 141, + timed_out: false, + _shards: { + total: 21, + successful: 21, + skipped: 0, + failed: 0, + }, + hits: { + total: 1349108, + max_score: 0, + hits: [], + }, + aggregations: { + unique_zeek_count: { + meta: {}, + doc_count: 0, + }, + unique_packetbeat_count: { + meta: {}, + doc_count: 0, + unique_tls_count: { + meta: {}, + doc_count: 0, + }, + }, + unique_filebeat_count: { + meta: {}, + doc_count: 1278559, + unique_netflow_count: { + doc_count: 0, + }, + unique_cisco_count: { + meta: {}, + doc_count: 0, + }, + unique_panw_count: { + meta: {}, + doc_count: 0, + }, + }, + unique_dns_count: { + meta: {}, + doc_count: 0, + }, + unique_flow_count: { + meta: {}, + doc_count: 0, + }, + unique_socket_count: { + doc_count: 0, + }, + unique_suricata_count: { + meta: {}, + doc_count: 0, + }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "unique_flow_count": {\n "filter": {\n "term": {\n "type": "flow"\n }\n }\n },\n "unique_dns_count": {\n "filter": {\n "term": {\n "type": "dns"\n }\n }\n },\n "unique_suricata_count": {\n "filter": {\n "term": {\n "service.type": "suricata"\n }\n }\n },\n "unique_zeek_count": {\n "filter": {\n "term": {\n "service.type": "zeek"\n }\n }\n },\n "unique_socket_count": {\n "filter": {\n "term": {\n "event.dataset": "socket"\n }\n }\n },\n "unique_filebeat_count": {\n "filter": {\n "term": {\n "agent.type": "filebeat"\n }\n },\n "aggs": {\n "unique_netflow_count": {\n "filter": {\n "term": {\n "input.type": "netflow"\n }\n }\n },\n "unique_panw_count": {\n "filter": {\n "term": {\n "event.module": "panw"\n }\n }\n },\n "unique_cisco_count": {\n "filter": {\n "term": {\n "event.module": "cisco"\n }\n }\n }\n }\n },\n "unique_packetbeat_count": {\n "filter": {\n "term": {\n "agent.type": "packetbeat"\n }\n },\n "aggs": {\n "unique_tls_count": {\n "filter": {\n "term": {\n "network.protocol": "tls"\n }\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}},{\\"bool\\":{\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"bool\\":{\\"should\\":[{\\"exists\\":{\\"field\\":\\"source.ip\\"}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"exists\\":{\\"field\\":\\"destination.ip\\"}}],\\"minimum_should_match\\":1}}],\\"minimum_should_match\\":1}}]}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T12:54:24.685Z",\n "lte": "2020-09-14T12:54:24.685Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ]\n }\n },\n "size": 0,\n "track_total_hits": false\n }\n}', + ], + }, + overviewNetwork: { + auditbeatSocket: 0, + filebeatCisco: 0, + filebeatNetflow: 0, + filebeatPanw: 0, + filebeatSuricata: 0, + filebeatZeek: 0, + packetbeatDNS: 0, + packetbeatFlow: 0, + packetbeatTLS: 0, + }, +}; + +export const expectedDsl = { + allowNoIndices: true, + ignoreUnavailable: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + body: { + aggregations: { + unique_flow_count: { + filter: { + term: { + type: 'flow', + }, + }, + }, + unique_dns_count: { + filter: { + term: { + type: 'dns', + }, + }, + }, + unique_suricata_count: { + filter: { + term: { + 'service.type': 'suricata', + }, + }, + }, + unique_zeek_count: { + filter: { + term: { + 'service.type': 'zeek', + }, + }, + }, + unique_socket_count: { + filter: { + term: { + 'event.dataset': 'socket', + }, + }, + }, + unique_filebeat_count: { + filter: { + term: { + 'agent.type': 'filebeat', + }, + }, + aggs: { + unique_netflow_count: { + filter: { + term: { + 'input.type': 'netflow', + }, + }, + }, + unique_panw_count: { + filter: { + term: { + 'event.module': 'panw', + }, + }, + }, + unique_cisco_count: { + filter: { + term: { + 'event.module': 'cisco', + }, + }, + }, + }, + }, + unique_packetbeat_count: { + filter: { + term: { + 'agent.type': 'packetbeat', + }, + }, + aggs: { + unique_tls_count: { + filter: { + term: { + 'network.protocol': 'tls', + }, + }, + }, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/index.test.ts new file mode 100644 index 000000000000..14b9fb3c7193 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.overview_network.dsl'; +import { networkOverview } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkOverview search strategy', () => { + const buildOverviewNetworkQuery = jest.spyOn(buildQuery, 'buildOverviewNetworkQuery'); + + afterEach(() => { + buildOverviewNetworkQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkOverview.buildDsl(mockOptions); + expect(buildOverviewNetworkQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkOverview.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/query.overview_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/query.overview_network.dsl.test.ts new file mode 100644 index 000000000000..553df2ab80e5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/overview/query.overview_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildOverviewNetworkQuery } from './query.overview_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildOverviewNetworkQuery', () => { + test('build query from options correctly', () => { + expect(buildOverviewNetworkQuery(mockOptions)).toMatchObject(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/__mocks__/index.ts new file mode 100644 index 000000000000..15e2ac3cc0f6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/__mocks__/index.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkTlsFields, + NetworkTlsRequestOptions, + NetworkQueries, + FlowTargetSourceDest, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkTlsRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.tls, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + flowTarget: FlowTargetSourceDest.source, + ip: '', + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { field: NetworkTlsFields._id, direction: Direction.desc }, + timerange: { interval: '12h', from: '2020-09-13T09:58:58.637Z', to: '2020-09-14T09:58:58.637Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 62, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: 0, max_score: 0, hits: [] }, + aggregations: { + sha1: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + count: { value: 0 }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + edges: [], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggs": {\n "count": {\n "cardinality": {\n "field": "tls.server.hash.sha1"\n }\n },\n "sha1": {\n "terms": {\n "field": "tls.server.hash.sha1",\n "size": 10,\n "order": {\n "_key": "desc"\n }\n },\n "aggs": {\n "issuers": {\n "terms": {\n "field": "tls.server.issuer"\n }\n },\n "subjects": {\n "terms": {\n "field": "tls.server.subject"\n }\n },\n "not_after": {\n "terms": {\n "field": "tls.server.not_after"\n }\n },\n "ja3": {\n "terms": {\n "field": "tls.server.ja3s"\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T09:58:58.637Z",\n "lte": "2020-09-14T09:58:58.637Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ]\n }\n },\n "size": 0,\n "track_total_hits": false\n }\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 0, showMorePagesIndicator: false }, + totalCount: 0, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggs: { + count: { cardinality: { field: 'tls.server.hash.sha1' } }, + sha1: { + terms: { field: 'tls.server.hash.sha1', size: 10, order: { _key: 'desc' } }, + aggs: { + issuers: { terms: { field: 'tls.server.issuer' } }, + subjects: { terms: { field: 'tls.server.subject' } }, + not_after: { terms: { field: 'tls.server.not_after' } }, + ja3: { terms: { field: 'tls.server.ja3s' } }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + gte: '2020-09-13T09:58:58.637Z', + lte: '2020-09-14T09:58:58.637Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }, + }, + size: 0, + track_total_hits: false, + }, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.test.ts new file mode 100644 index 000000000000..b8c2be5bc61f --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.tls_network.dsl'; +import { networkTls } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkTls search strategy', () => { + const buildNetworkTlsQuery = jest.spyOn(buildQuery, 'buildNetworkTlsQuery'); + + afterEach(() => { + buildNetworkTlsQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkTls.buildDsl(mockOptions); + expect(buildNetworkTlsQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkTls.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.test.ts new file mode 100644 index 000000000000..39cfcc7ab462 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildNetworkTlsQuery } from './query.tls_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildNetworkTlsQuery', () => { + test('build query from options correctly', () => { + expect(buildNetworkTlsQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/__mocks__/index.ts new file mode 100644 index 000000000000..0578d99accbf --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/__mocks__/index.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkTopCountriesRequestOptions, + NetworkQueries, + FlowTargetSourceDest, + NetworkTopTablesFields, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkTopCountriesRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.topCountries, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + flowTarget: FlowTargetSourceDest.destination, + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { field: NetworkTopTablesFields.bytes_in, direction: Direction.desc }, + timerange: { interval: '12h', from: '2020-09-13T09:58:58.637Z', to: '2020-09-14T09:58:58.637Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 62, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: 0, max_score: 0, hits: [] }, + aggregations: { + sha1: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + count: { value: 0 }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + edges: [], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "top_countries_count": {\n "cardinality": {\n "field": "destination.geo.country_iso_code"\n }\n },\n "destination": {\n "terms": {\n "field": "destination.geo.country_iso_code",\n "size": 10,\n "order": {\n "bytes_in": "desc"\n }\n },\n "aggs": {\n "bytes_in": {\n "sum": {\n "field": "source.bytes"\n }\n },\n "bytes_out": {\n "sum": {\n "field": "destination.bytes"\n }\n },\n "flows": {\n "cardinality": {\n "field": "network.community_id"\n }\n },\n "source_ips": {\n "cardinality": {\n "field": "source.ip"\n }\n },\n "destination_ips": {\n "cardinality": {\n "field": "destination.ip"\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T09:58:58.637Z",\n "lte": "2020-09-14T09:58:58.637Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ]\n }\n }\n },\n "size": 0,\n "track_total_hits": false\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 0, showMorePagesIndicator: false }, + totalCount: 0, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggregations: { + top_countries_count: { cardinality: { field: 'destination.geo.country_iso_code' } }, + destination: { + terms: { field: 'destination.geo.country_iso_code', size: 10, order: { bytes_in: 'desc' } }, + aggs: { + bytes_in: { sum: { field: 'source.bytes' } }, + bytes_out: { sum: { field: 'destination.bytes' } }, + flows: { cardinality: { field: 'network.community_id' } }, + source_ips: { cardinality: { field: 'source.ip' } }, + destination_ips: { cardinality: { field: 'destination.ip' } }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + gte: '2020-09-13T09:58:58.637Z', + lte: '2020-09-14T09:58:58.637Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }, + }, + }, + size: 0, + track_total_hits: false, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.test.ts new file mode 100644 index 000000000000..65d1306b6946 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.top_countries_network.dsl'; +import { networkTopCountries } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkTopCountries search strategy', () => { + const buildTopCountriesQuery = jest.spyOn(buildQuery, 'buildTopCountriesQuery'); + + afterEach(() => { + buildTopCountriesQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkTopCountries.buildDsl(mockOptions); + expect(buildTopCountriesQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkTopCountries.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts index 5b0ced06f2ee..ba4565b068eb 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts @@ -43,7 +43,6 @@ export const networkTopCountries: SecuritySolutionFactory fakeTotalCount; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network.dsl.test.ts new file mode 100644 index 000000000000..cba2988aa240 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildTopCountriesQuery } from './query.top_countries_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildTopCountriesQuery', () => { + test('build query from options correctly', () => { + expect(buildTopCountriesQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/__mocks__/index.ts new file mode 100644 index 000000000000..84c1ca129eca --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/__mocks__/index.ts @@ -0,0 +1,847 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkTopNFlowRequestOptions, + NetworkQueries, + NetworkTopTablesFields, + FlowTargetSourceDest, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkTopNFlowRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.topNFlow, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + flowTarget: FlowTargetSourceDest.source, + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { field: NetworkTopTablesFields.bytes_out, direction: Direction.desc }, + timerange: { interval: '12h', from: '2020-09-13T10:16:46.870Z', to: '2020-09-14T10:16:46.870Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 191, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { max_score: 0, hits: [], total: 0 }, + aggregations: { + source: { + meta: {}, + doc_count_error_upper_bound: -1, + sum_other_doc_count: 500330, + buckets: [ + { + key: '10.142.0.7', + doc_count: 12116, + bytes_out: { value: 2581835370 }, + flows: { value: 1967 }, + bytes_in: { value: 0 }, + domain: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'siem-kibana', + doc_count: 3221, + timestamp: { value: 1600078221017, value_as_string: '2020-09-14T10:10:21.017Z' }, + }, + ], + }, + autonomous_system: { + meta: {}, + doc_count: 0, + top_as: { hits: { total: { value: 0, relation: 'eq' }, max_score: 0, hits: [] } }, + }, + location: { + doc_count: 0, + top_geo: { hits: { total: { value: 0, relation: 'eq' }, max_score: 0, hits: [] } }, + }, + destination_ips: { value: 264 }, + }, + { + key: '35.232.239.42', + doc_count: 2119, + bytes_out: { value: 86968388 }, + flows: { value: 922 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 2119, + top_as: { + hits: { + total: { value: 2119, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526378075029582', + _score: 0, + _source: { + source: { as: { number: 15169, organization: { name: 'Google LLC' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 2119, + top_geo: { + hits: { + total: { value: 2119, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526378075029582', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '151.101.200.204', + doc_count: 2, + bytes_out: { value: 1394839 }, + flows: { value: 2 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 2, + top_as: { + hits: { + total: { value: 2, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1527252060367158', + _score: 0, + _source: { + source: { as: { number: 54113, organization: { name: 'Fastly' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 2, + top_geo: { + hits: { + total: { value: 2, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1527252060367158', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + city_name: 'Ashburn', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.4728, lat: 39.0481 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '91.189.92.39', + doc_count: 1, + bytes_out: { value: 570550 }, + flows: { value: 1 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 1, + top_as: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526971840437636', + _score: 0, + _source: { + source: { + as: { number: 41231, organization: { name: 'Canonical Group Limited' } }, + }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 1, + top_geo: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526971840437636', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'Europe', + region_iso_code: 'GB-ENG', + city_name: 'London', + country_iso_code: 'GB', + region_name: 'England', + location: { lon: -0.0961, lat: 51.5132 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '10.142.0.5', + doc_count: 514, + bytes_out: { value: 565933 }, + flows: { value: 486 }, + bytes_in: { value: 0 }, + domain: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'infraops-docker-data', + doc_count: 514, + timestamp: { value: 1600078218215, value_as_string: '2020-09-14T10:10:18.215Z' }, + }, + ], + }, + autonomous_system: { + doc_count: 0, + top_as: { hits: { total: { value: 0, relation: 'eq' }, max_score: 0, hits: [] } }, + }, + location: { + doc_count: 0, + top_geo: { hits: { total: { value: 0, relation: 'eq' }, max_score: 0, hits: [] } }, + }, + destination_ips: { value: 343 }, + }, + { + key: '151.101.248.204', + doc_count: 6, + bytes_out: { value: 260903 }, + flows: { value: 6 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 6, + top_as: { + hits: { + total: { value: 6, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1527003062069535', + _score: 0, + _source: { + source: { as: { number: 54113, organization: { name: 'Fastly' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 6, + top_geo: { + hits: { + total: { value: 6, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1527003062069535', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + city_name: 'Ashburn', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.539, lat: 39.018 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '35.196.129.83', + doc_count: 1, + bytes_out: { value: 164079 }, + flows: { value: 1 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 1, + top_as: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526557113311472', + _score: 0, + _source: { + source: { as: { number: 15169, organization: { name: 'Google LLC' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 1, + top_geo: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526557113311472', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '151.101.2.217', + doc_count: 24, + bytes_out: { value: 158407 }, + flows: { value: 24 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 24, + top_as: { + hits: { + total: { value: 24, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526379128390241', + _score: 0, + _source: { + source: { as: { number: 54113, organization: { name: 'Fastly' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 24, + top_geo: { + hits: { + total: { value: 24, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526379128390241', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + country_iso_code: 'US', + location: { lon: -97.822, lat: 37.751 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '91.189.91.38', + doc_count: 1, + bytes_out: { value: 89031 }, + flows: { value: 1 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 1, + top_as: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526555996515551', + _score: 0, + _source: { + source: { + as: { number: 41231, organization: { name: 'Canonical Group Limited' } }, + }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 1, + top_geo: { + hits: { + total: { value: 1, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526555996515551', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-MA', + city_name: 'Boston', + country_iso_code: 'US', + region_name: 'Massachusetts', + location: { lon: -71.0631, lat: 42.3562 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 1 }, + }, + { + key: '193.228.91.123', + doc_count: 33, + bytes_out: { value: 32170 }, + flows: { value: 33 }, + bytes_in: { value: 0 }, + domain: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + autonomous_system: { + doc_count: 33, + top_as: { + hits: { + total: { value: 33, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526584379144248', + _score: 0, + _source: { + source: { as: { number: 133766, organization: { name: 'YHSRV.LLC' } } }, + }, + }, + ], + }, + }, + }, + location: { + doc_count: 33, + top_geo: { + hits: { + total: { value: 33, relation: 'eq' }, + max_score: 0, + hits: [ + { + _index: 'filebeat-8.0.0-2020.09.02-000001', + _id: 'dd4fa2d4bd-1526584379144248', + _score: 0, + _source: { + source: { + geo: { + continent_name: 'North America', + country_iso_code: 'US', + location: { lon: -97.822, lat: 37.751 }, + }, + }, + }, + }, + ], + }, + }, + }, + destination_ips: { value: 2 }, + }, + ], + }, + top_n_flow_count: { value: 738 }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + edges: [ + { + node: { + _id: '10.142.0.7', + source: { + domain: ['siem-kibana'], + ip: '10.142.0.7', + location: null, + autonomous_system: null, + flows: 1967, + destination_ips: 264, + }, + network: { bytes_in: 0, bytes_out: 2581835370 }, + }, + cursor: { value: '10.142.0.7', tiebreaker: null }, + }, + { + node: { + _id: '35.232.239.42', + source: { + domain: [], + ip: '35.232.239.42', + location: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 15169, name: 'Google LLC' }, + flows: 922, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 86968388 }, + }, + cursor: { value: '35.232.239.42', tiebreaker: null }, + }, + { + node: { + _id: '151.101.200.204', + source: { + domain: [], + ip: '151.101.200.204', + location: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + city_name: 'Ashburn', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.4728, lat: 39.0481 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 54113, name: 'Fastly' }, + flows: 2, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 1394839 }, + }, + cursor: { value: '151.101.200.204', tiebreaker: null }, + }, + { + node: { + _id: '91.189.92.39', + source: { + domain: [], + ip: '91.189.92.39', + location: { + geo: { + continent_name: 'Europe', + region_iso_code: 'GB-ENG', + city_name: 'London', + country_iso_code: 'GB', + region_name: 'England', + location: { lon: -0.0961, lat: 51.5132 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 41231, name: 'Canonical Group Limited' }, + flows: 1, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 570550 }, + }, + cursor: { value: '91.189.92.39', tiebreaker: null }, + }, + { + node: { + _id: '10.142.0.5', + source: { + domain: ['infraops-docker-data'], + ip: '10.142.0.5', + location: null, + autonomous_system: null, + flows: 486, + destination_ips: 343, + }, + network: { bytes_in: 0, bytes_out: 565933 }, + }, + cursor: { value: '10.142.0.5', tiebreaker: null }, + }, + { + node: { + _id: '151.101.248.204', + source: { + domain: [], + ip: '151.101.248.204', + location: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + city_name: 'Ashburn', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.539, lat: 39.018 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 54113, name: 'Fastly' }, + flows: 6, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 260903 }, + }, + cursor: { value: '151.101.248.204', tiebreaker: null }, + }, + { + node: { + _id: '35.196.129.83', + source: { + domain: [], + ip: '35.196.129.83', + location: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-VA', + country_iso_code: 'US', + region_name: 'Virginia', + location: { lon: -77.2481, lat: 38.6583 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 15169, name: 'Google LLC' }, + flows: 1, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 164079 }, + }, + cursor: { value: '35.196.129.83', tiebreaker: null }, + }, + { + node: { + _id: '151.101.2.217', + source: { + domain: [], + ip: '151.101.2.217', + location: { + geo: { + continent_name: 'North America', + country_iso_code: 'US', + location: { lon: -97.822, lat: 37.751 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 54113, name: 'Fastly' }, + flows: 24, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 158407 }, + }, + cursor: { value: '151.101.2.217', tiebreaker: null }, + }, + { + node: { + _id: '91.189.91.38', + source: { + domain: [], + ip: '91.189.91.38', + location: { + geo: { + continent_name: 'North America', + region_iso_code: 'US-MA', + city_name: 'Boston', + country_iso_code: 'US', + region_name: 'Massachusetts', + location: { lon: -71.0631, lat: 42.3562 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 41231, name: 'Canonical Group Limited' }, + flows: 1, + destination_ips: 1, + }, + network: { bytes_in: 0, bytes_out: 89031 }, + }, + cursor: { value: '91.189.91.38', tiebreaker: null }, + }, + { + node: { + _id: '193.228.91.123', + source: { + domain: [], + ip: '193.228.91.123', + location: { + geo: { + continent_name: 'North America', + country_iso_code: 'US', + location: { lon: -97.822, lat: 37.751 }, + }, + flowTarget: 'source', + }, + autonomous_system: { number: 133766, name: 'YHSRV.LLC' }, + flows: 33, + destination_ips: 2, + }, + network: { bytes_in: 0, bytes_out: 32170 }, + }, + cursor: { value: '193.228.91.123', tiebreaker: null }, + }, + ], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggregations": {\n "top_n_flow_count": {\n "cardinality": {\n "field": "source.ip"\n }\n },\n "source": {\n "terms": {\n "field": "source.ip",\n "size": 10,\n "order": {\n "bytes_out": "desc"\n }\n },\n "aggs": {\n "bytes_in": {\n "sum": {\n "field": "destination.bytes"\n }\n },\n "bytes_out": {\n "sum": {\n "field": "source.bytes"\n }\n },\n "domain": {\n "terms": {\n "field": "source.domain",\n "order": {\n "timestamp": "desc"\n }\n },\n "aggs": {\n "timestamp": {\n "max": {\n "field": "@timestamp"\n }\n }\n }\n },\n "location": {\n "filter": {\n "exists": {\n "field": "source.geo"\n }\n },\n "aggs": {\n "top_geo": {\n "top_hits": {\n "_source": "source.geo.*",\n "size": 1\n }\n }\n }\n },\n "autonomous_system": {\n "filter": {\n "exists": {\n "field": "source.as"\n }\n },\n "aggs": {\n "top_as": {\n "top_hits": {\n "_source": "source.as.*",\n "size": 1\n }\n }\n }\n },\n "flows": {\n "cardinality": {\n "field": "network.community_id"\n }\n },\n "destination_ips": {\n "cardinality": {\n "field": "destination.ip"\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T10:16:46.870Z",\n "lte": "2020-09-14T10:16:46.870Z",\n "format": "strict_date_optional_time"\n }\n }\n }\n ]\n }\n }\n },\n "size": 0,\n "track_total_hits": false\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 50, showMorePagesIndicator: true }, + totalCount: 738, +}; + +export const expectedDsl = { + allowNoIndices: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + ignoreUnavailable: true, + body: { + aggregations: { + top_n_flow_count: { cardinality: { field: 'source.ip' } }, + source: { + terms: { field: 'source.ip', size: 10, order: { bytes_out: 'desc' } }, + aggs: { + bytes_in: { sum: { field: 'destination.bytes' } }, + bytes_out: { sum: { field: 'source.bytes' } }, + domain: { + terms: { field: 'source.domain', order: { timestamp: 'desc' } }, + aggs: { timestamp: { max: { field: '@timestamp' } } }, + }, + location: { + filter: { exists: { field: 'source.geo' } }, + aggs: { top_geo: { top_hits: { _source: 'source.geo.*', size: 1 } } }, + }, + autonomous_system: { + filter: { exists: { field: 'source.as' } }, + aggs: { top_as: { top_hits: { _source: 'source.as.*', size: 1 } } }, + }, + flows: { cardinality: { field: 'network.community_id' } }, + destination_ips: { cardinality: { field: 'destination.ip' } }, + }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + gte: '2020-09-13T10:16:46.870Z', + lte: '2020-09-14T10:16:46.870Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }, + }, + }, + size: 0, + track_total_hits: false, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.test.ts new file mode 100644 index 000000000000..fe3213a4e538 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as buildQuery from './query.top_n_flow_network.dsl'; +import { networkTopNFlow } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkTopNFlow search strategy', () => { + const buildTopNFlowQuery = jest.spyOn(buildQuery, 'buildTopNFlowQuery'); + + afterEach(() => { + buildTopNFlowQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkTopNFlow.buildDsl(mockOptions); + expect(buildTopNFlowQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkTopNFlow.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network.dsl.test.ts new file mode 100644 index 000000000000..902769ae9a30 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildTopNFlowQuery } from './query.top_n_flow_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildTopNFlowQuery', () => { + test('build query from options correctly', () => { + expect(buildTopNFlowQuery(mockOptions)).toEqual(expectedDsl); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/__mocks__/index.ts new file mode 100644 index 000000000000..3f57de7c78d1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/__mocks__/index.ts @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEsSearchResponse } from '../../../../../../../../../../src/plugins/data/common'; + +import { + Direction, + NetworkUsersRequestOptions, + NetworkQueries, + NetworkUsersFields, + FlowTarget, +} from '../../../../../../../common/search_strategy'; + +export const mockOptions: NetworkUsersRequestOptions = { + defaultIndex: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + factoryQueryType: NetworkQueries.users, + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + flowTarget: FlowTarget.source, + ip: '10.142.0.7', + pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, + sort: { field: NetworkUsersFields.name, direction: Direction.asc }, + timerange: { interval: '12h', from: '2020-09-13T10:16:46.870Z', to: '2020-09-14T10:16:46.870Z' }, +}; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + isPartial: false, + isRunning: false, + rawResponse: { + took: 12, + timed_out: false, + _shards: { total: 21, successful: 21, skipped: 0, failed: 0 }, + hits: { total: 0, max_score: 0, hits: [] }, + aggregations: { + user_count: { value: 3 }, + users: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: '_apt', + doc_count: 34, + groupName: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + groupId: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + id: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: '104', doc_count: 34 }], + }, + }, + { + key: 'root', + doc_count: 8852, + groupName: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + groupId: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + id: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: '0', doc_count: 8852 }], + }, + }, + { + key: 'tsg', + doc_count: 16, + groupName: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + groupId: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + id: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: '1005', doc_count: 16 }], + }, + }, + ], + }, + }, + }, + total: 21, + loaded: 21, +}; + +export const formattedSearchStrategyResponse = { + ...mockSearchStrategyResponse, + edges: [ + { + node: { + _id: '_apt', + user: { id: ['104'], name: '_apt', groupId: [], groupName: [], count: 34 }, + }, + cursor: { value: '_apt', tiebreaker: null }, + }, + { + node: { + _id: 'root', + user: { id: ['0'], name: 'root', groupId: [], groupName: [], count: 8852 }, + }, + cursor: { value: 'root', tiebreaker: null }, + }, + { + node: { + _id: 'tsg', + user: { id: ['1005'], name: 'tsg', groupId: [], groupName: [], count: 16 }, + }, + cursor: { value: 'tsg', tiebreaker: null }, + }, + ], + inspect: { + dsl: [ + '{\n "allowNoIndices": true,\n "index": [\n "apm-*-transaction*",\n "auditbeat-*",\n "endgame-*",\n "filebeat-*",\n "logs-*",\n "packetbeat-*",\n "winlogbeat-*"\n ],\n "ignoreUnavailable": true,\n "body": {\n "aggs": {\n "user_count": {\n "cardinality": {\n "field": "user.name"\n }\n },\n "users": {\n "terms": {\n "field": "user.name",\n "size": 10,\n "order": {\n "_key": "asc"\n }\n },\n "aggs": {\n "id": {\n "terms": {\n "field": "user.id"\n }\n },\n "groupId": {\n "terms": {\n "field": "user.group.id"\n }\n },\n "groupName": {\n "terms": {\n "field": "user.group.name"\n }\n }\n }\n }\n },\n "query": {\n "bool": {\n "filter": [\n "{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"match_all\\":{}}],\\"should\\":[],\\"must_not\\":[]}}",\n {\n "range": {\n "@timestamp": {\n "gte": "2020-09-13T10:16:46.870Z",\n "lte": "2020-09-14T10:16:46.870Z",\n "format": "strict_date_optional_time"\n }\n }\n },\n {\n "term": {\n "source.ip": "10.142.0.7"\n }\n }\n ],\n "must_not": [\n {\n "term": {\n "event.category": "authentication"\n }\n }\n ]\n }\n },\n "size": 0,\n "track_total_hits": false\n }\n}', + ], + }, + pageInfo: { activePage: 0, fakeTotalCount: 3, showMorePagesIndicator: false }, + totalCount: 3, +}; + +export const expectedDsl = { + allowNoIndices: true, + body: { + aggs: { + user_count: { cardinality: { field: 'user.name' } }, + users: { + aggs: { + groupId: { terms: { field: 'user.group.id' } }, + groupName: { terms: { field: 'user.group.name' } }, + id: { terms: { field: 'user.id' } }, + }, + terms: { field: 'user.name', order: { _key: 'asc' }, size: 10 }, + }, + }, + query: { + bool: { + filter: [ + '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', + { + range: { + '@timestamp': { + format: 'strict_date_optional_time', + gte: '2020-09-13T10:16:46.870Z', + lte: '2020-09-14T10:16:46.870Z', + }, + }, + }, + { term: { 'source.ip': '10.142.0.7' } }, + ], + must_not: [{ term: { 'event.category': 'authentication' } }], + }, + }, + size: 0, + track_total_hits: false, + }, + ignoreUnavailable: true, + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.test.ts new file mode 100644 index 000000000000..bd98ec0947b3 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.test.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants'; +import { NetworkUsersRequestOptions } from '../../../../../../common/search_strategy/security_solution/network'; + +import * as buildQuery from './query.users_network.dsl'; +import { networkUsers } from '.'; +import { + mockOptions, + mockSearchStrategyResponse, + formattedSearchStrategyResponse, +} from './__mocks__'; + +describe('networkUsers search strategy', () => { + const buildUsersQuery = jest.spyOn(buildQuery, 'buildUsersQuery'); + + afterEach(() => { + buildUsersQuery.mockClear(); + }); + + describe('buildDsl', () => { + test('should build dsl query', () => { + networkUsers.buildDsl(mockOptions); + expect(buildUsersQuery).toHaveBeenCalledWith(mockOptions); + }); + + test('should throw error if query size is greater equal than DEFAULT_MAX_TABLE_QUERY_SIZE ', () => { + const overSizeOptions = { + ...mockOptions, + pagination: { + ...mockOptions.pagination, + querySize: DEFAULT_MAX_TABLE_QUERY_SIZE, + }, + } as NetworkUsersRequestOptions; + + expect(() => { + networkUsers.buildDsl(overSizeOptions); + }).toThrowError(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); + }); + }); + + describe('parse', () => { + test('should parse data correctly', async () => { + const result = await networkUsers.parse(mockOptions, mockSearchStrategyResponse); + expect(result).toMatchObject(formattedSearchStrategyResponse); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.test.ts new file mode 100644 index 000000000000..ce43e1fb49e9 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.test.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ +import { buildUsersQuery } from './query.users_network.dsl'; +import { mockOptions, expectedDsl } from './__mocks__'; + +describe('buildUsersQuery', () => { + test('build query from options correctly', () => { + expect(buildUsersQuery(mockOptions)).toEqual(expectedDsl); + }); +}); From 36e11e9da28a7f1e3f840fe0ccfd94fbbc447109 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 14 Sep 2020 18:03:54 +0100 Subject: [PATCH 3/4] add more tests --- .../factory/network/users/helpers.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.test.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.test.ts new file mode 100644 index 000000000000..19ce687cd3f0 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.test.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getUsersEdges } from './helpers'; +import { mockSearchStrategyResponse, formattedSearchStrategyResponse } from './__mocks__'; + +describe('#getUsers', () => { + test('will format edges correctly', () => { + const edges = getUsersEdges(mockSearchStrategyResponse); + expect(edges).toEqual(formattedSearchStrategyResponse.edges); + }); +}); From 1cf4bbeffc5e19255617b54ea9b3f610cd70d5f9 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 14 Sep 2020 22:59:52 +0100 Subject: [PATCH 4/4] remove reponse from inspect for hostDetails --- .../security_solution/factory/hosts/details/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts index 8274d20a138e..8913f72aad61 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/index.ts @@ -29,7 +29,6 @@ export const hostDetails: SecuritySolutionFactory = { const aggregations: HostAggEsItem = get('aggregations', response.rawResponse) || {}; const inspect = { dsl: [inspectStringifyObject(buildHostDetailsQuery(options))], - response: [inspectStringifyObject(response)], }; const formattedHostItem = formatHostItem(aggregations); return { ...response, inspect, hostDetails: formattedHostItem };