[Security Solution] [Timeline] Endpoint row renderers (1st batch) (#89810)
## [Security Solution] [Timeline] Endpoint row renderers (1st batch) This PR implements the 1st batch of Endpoint (`event.module: "endpoint"`) row renderers by updating and enhancing some of the existing "Endgame" (`event.module: "endgame"`) row renderers to use the latest [ECS fields](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html). The following Endpoint events will be rendered via row renderers in Timeline: | event.dataset | event.action | |--------------------------|---------------------| | endpoint.events.file | creation | | endpoint.events.file | deletion | | endpoint.events.process | start | | endpoint.events.process | end | | endpoint.events.network | lookup_requested | | endpoint.events.network | lookup_result | | endpoint.events.network | connection_accepted | | endpoint.events.network | disconnect_received | | endpoint.events.security | log_on | | endpoint.events.security | log_off | ## File (FIM) Creation events Endpoint File (FIM) Creation events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.file and event.action: creation ``` ### Sample rendered File (FIM) Creation event ![endpoint_file_creation](https://user-images.githubusercontent.com/4459398/106036793-ff522f80-6092-11eb-9e3b-c24538129bea.png) Each field with `this formatting` is draggable (to pivot a search) in the row-rendered event: `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` created a file `WimProvider.dll` in `C:\Windows\TEMP\F590BACBAE94\WimProvider.dll` via `MsMpEng.exe` `(2424)` ### Fields in a File (FIM) Creation event `user.name` \ `user.domain` @ `host.name` created a file `file.name` in `file.path` via `process.name` `(process.pid)` ## File (FIM) Deletion events Endpoint File (FIM) Deletion events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.file and event.action: deletion ``` ### Sample rendered File (FIM) Deletion event ![endpoint_file_deletion](https://user-images.githubusercontent.com/4459398/106037520-088fcc00-6094-11eb-985d-ba8cead9fec9.png) `SYSTEM` \ `NT AUTHORITY` @ `windows-endpoint-1` deleted a file `AM_Delta_Patch_1.329.2793.0.exe` in `C:\Windows\SoftwareDistribution\Download\Install\AM_Delta_Patch_1.329.2793.0.exe` via `svchost.exe` `(1728)` ### Fields in a File (FIM) Deletion event `user.name` \ `user.domain` @ `host.name` deleted a file `file.name` in `file.path` via `process.name` `(process.pid)` ## Process Start events Endpoint Process Start events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.process and event.action: start ``` ### Sample rendered Process Start event ![creation-event](https://user-images.githubusercontent.com/4459398/106061579-c7f37b00-60b2-11eb-9bc4-224e671baa4a.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` started process `conhost.exe` (`376`) `C:\Windows\system32\conhost.exe` `0xffffffff` `-ForceV1` via parent process `sshd.exe` (`6460`) `sha256 697334c236cce7d4c9e223146ee683a1219adced9729d4ae771fd6a1502a6b63` `sha1 e19da2c35ba1c38adf12d1a472c1fcf1f1a811a7` `md5 1b0e9b5fcb62de0787235ecca560b610` ### Fields in a Process Start event The following fields will be used to render a Process Start event: `user.name` \ `user.domain` @ `host.name` started process `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) `process.hash.sha256` `process.hash.sha1` `process.hash.md5` ## Process End events Endpoint Process End events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.process and event.action: end ``` ### Sample rendered Process End event ![endpoint_process_end](https://user-images.githubusercontent.com/4459398/106076527-f1b99b80-60cc-11eb-8ff8-2da78a1fcb8f.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` terminated process `svchost.exe` (`10392`) `C:\Windows\System32\svchost.exe` `-k` `netsvcs` `-p` `-s` `NetSetupSvc` with exit code `0` via parent process `services.exe` `(568)` `7fd065bac18c5278777ae44908101cdfed72d26fa741367f0ad4d02020787ab6` `a1385ce20ad79f55df235effd9780c31442aa234` `8a0a29438052faed8a2532da50455756` ### Fields in a Process End event The following fields will be used to render a Process End event: `user.name` \ `user.domain` @ `host.name` terminated process `process.name` (`process.pid`) with exit code `process.exit_code` via parent process `process.parent.name` (`process.parent.pid`) `process.hash.sha256` `process.hash.sha1` `process.hash.md5` ## Network (DNS) Lookup Requested events Endpoint Network (DNS) Lookup Requested events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.network and event.action: lookup_requested ``` ### Runtime matching criteria All Network Lookup Requested events, including Endpoint and non-Endpoint DNS events matching the following criteria will be rendered: ``` dns.question.type: * and dns.question.name: * ``` ### Sample rendered Network Lookup Requested event ![network_lookup_requested](https://user-images.githubusercontent.com/4459398/106191208-cdf76380-6167-11eb-9be7-aaf78e4cfdd3.png) `SYSTEM` \ `NT AUTHORITY` @ `windows-endpoint-1` asked for `logging.googleapis.com` with question type `A` via `google_osconfig_agent.exe` `(4064)` `dns` ### Fields in a Network Lookup Requested event The following fields will be used to render a Network Lookup Request event: `user.name` \ `user.domain` @ `host.name` asked for `dns.question.name` with question type `dns.question.type` via `process.name` `(process.pid)` `network.protocol` ## Network Lookup Result events Endpoint Network (DNS) Lookup Result events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.network and event.action: lookup_result ``` ### Runtime matching criteria All Network Lookup Result events, including Endpoint and non-Endpoint DNS events matching the following criteria will be rendered: ``` dns.question.type: * and dns.question.name: * ``` ### Sample rendered Network Lookup Result event ![network_lookup_result](https://user-images.githubusercontent.com/4459398/106192595-a43f3c00-6169-11eb-95bc-4ebe331f1231.png) `SYSTEM` \ `NT AUTHORITY` @ `windows-endpoint-1` asked for `logging.googleapis.com` with question type `AAAA` via `GCEWindowsAgent.exe` `(684)` `dns` ### Fields in a Network Lookup Result event The following fields will be used to render a Network Lookup Result event: `user.name` \ `user.domain` @ `host.name` asked for `dns.question.name` with question type `dns.question.type` via `process.name` `(process.pid)` `network.protocol` ## Network Connection Accepted events Endpoint Network Connection Accepted events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.network and event.action: connection_accepted ```` ### Sample rendered Network Connection Accepted event ![network_connection_accepted](https://user-images.githubusercontent.com/4459398/106200497-4f54f300-6174-11eb-8879-06b7bfc88edf.png) Network Connection Accepted events, like the one in the screenshot above, are also rendered by the _Netflow_ row renderer, which displays information that includes the directionality of the connection, protocol, and source / destination details. `NETWORK SERVICE` \ `NT AUTHORITY` @ `windows-endpoint-1` accepted a connection via `svchost.exe` `(328)` with result `success` ### Fields in a Network Connection Accepted event `user.name` \ `user.domain` @ `host.name` accepted a connection via `process.name` `(process.pid)` with result `event.outcome` ## Network Disconnect Received events Endpoint Network Disconnect Received events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.network and event.action: disconnect_received ```` ### Sample rendered Network Disconnect Received event ![network_disconnect_received](https://user-images.githubusercontent.com/4459398/106205196-56cbca80-617b-11eb-83d3-26aa9670f114.png) Network Disconnect Received events, like the one in the screenshot above, are also rendered by the _Netflow_ row renderer, which displays information that includes the directionality of the connection, protocol, and source / destination details. `NETWORK SERVICE` \ `NT AUTHORITY` @ `windows-endpoint-1` disconnected via `svchost.exe` `(328)` ### Fields in a Network Disconnect Received event `user.name` \ `user.domain` @ `host.name` disconnected via `process.name` `(process.pid)` ## Security Log On events Endpoint Security Log On events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.security and event.action: log_on ``` ### `event.outcome: "success"` vs `event.outcome: "failure"` The row renderer for Security Log On events uses the `event.outcome` field to display different results for events matching: ``` event.dataset: endpoint.events.security and event.action: log_on and event.outcome: success ``` vs events matching: ``` event.dataset: endpoint.events.security and event.action: log_on and event.outcome: failure ``` ### Sample rendered Security Log On / `event.outcome: "success"` event ![security_log_on_success](https://user-images.githubusercontent.com/4459398/106210917-fcd00280-6184-11eb-9c1c-564cfb375539.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` successfully logged in via `C:\Program Files\OpenSSH-Win64\sshd.exe` ### Fields in an Security Log On / `event.outcome: "success"` event `user.name` \ `user.domain` @ `host.name` successfully logged in via `process.name` (`process.pid`) ### Sample rendered Security Log On / `event.outcome: "failure"` event ![security_log_on_failure](https://user-images.githubusercontent.com/4459398/106211893-b2e81c00-6186-11eb-9c34-43227c15a1f0.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` failed to log in via `C:\Program Files\OpenSSH-Win64\sshd.exe` ### Fields in an Security Log On / `event.outcome: "failure"` event `user.name` \ `user.domain` @ `host.name` failed to log in via `process.name` (`process.pid`) ## Security Log Off events Endpoint Security Log Off events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.security and event.action: log_off ``` ### Sample rendered Security Log Off event ![security_log_off](https://user-images.githubusercontent.com/4459398/106212499-0018bd80-6188-11eb-9e91-971f360ee87a.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint` logged off via `C:\Program Files\OpenSSH-Win64\sshd.exe` ### Fields in a Security Log Off event `user.name` \ `user.domain` @ `host.name` logged off via `process.name` (`process.pid`)
This commit is contained in:
parent
b4248465cd
commit
e202ceab29
|
@ -7,7 +7,9 @@
|
|||
|
||||
export interface ProcessEcs {
|
||||
entity_id?: string[];
|
||||
exit_code?: number[];
|
||||
hash?: ProcessHashData;
|
||||
parent?: ProcessParentData;
|
||||
pid?: number[];
|
||||
name?: string[];
|
||||
ppid?: number[];
|
||||
|
@ -24,6 +26,10 @@ export interface ProcessHashData {
|
|||
sha256?: string[];
|
||||
}
|
||||
|
||||
export interface ProcessParentData {
|
||||
name?: string[];
|
||||
}
|
||||
|
||||
export interface Thread {
|
||||
id?: number[];
|
||||
start?: string[];
|
||||
|
|
|
@ -58,6 +58,121 @@ export const mockEndgameDnsRequest: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointNetworkLookupRequestedEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['network'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-25T16:44:40.788Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['lookup_requested'],
|
||||
type: ['protocol,info'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6FZj'],
|
||||
dataset: ['endpoint.events.network'],
|
||||
},
|
||||
process: {
|
||||
name: ['google_osconfig_agent.exe'],
|
||||
pid: [3272],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTMyNzItMTMyNTUwNzg4NjguNjUzODkxNTAw',
|
||||
],
|
||||
executable: ['C:\\Program Files\\Google\\OSConfig\\google_osconfig_agent.exe'],
|
||||
},
|
||||
dns: {
|
||||
question: {
|
||||
name: ['logging.googleapis.com'],
|
||||
type: ['A'],
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
network: {
|
||||
protocol: ['dns'],
|
||||
},
|
||||
message: [
|
||||
'DNS query is completed for the name logging.googleapis.com, type 1, query options 1073766400 with status 87 Results',
|
||||
],
|
||||
timestamp: '2021-01-25T16:44:40.788Z',
|
||||
_id: 'sUNzOncBPmkOXwyN9VbT',
|
||||
};
|
||||
|
||||
export const mockEndpointNetworkLookupResultEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['network'],
|
||||
kind: ['event'],
|
||||
outcome: ['success'],
|
||||
created: ['2021-01-25T16:44:40.789Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['lookup_result'],
|
||||
type: ['protocol,info'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6FZq'],
|
||||
dataset: ['endpoint.events.network'],
|
||||
},
|
||||
process: {
|
||||
name: ['google_osconfig_agent.exe'],
|
||||
pid: [3272],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTMyNzItMTMyNTUwNzg4NjguNjUzODkxNTAw',
|
||||
],
|
||||
executable: ['C:\\Program Files\\Google\\OSConfig\\google_osconfig_agent.exe'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
dns: {
|
||||
question: {
|
||||
name: ['logging.googleapis.com'],
|
||||
type: ['AAAA'],
|
||||
},
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
network: {
|
||||
protocol: ['dns'],
|
||||
},
|
||||
message: [
|
||||
'DNS query is completed for the name logging.googleapis.com, type 28, query options 2251800887582720 with status 0 Results',
|
||||
],
|
||||
timestamp: '2021-01-25T16:44:40.789Z',
|
||||
_id: 'skNzOncBPmkOXwyN9VbT',
|
||||
};
|
||||
|
||||
export const mockEndgameFileCreateEvent: Ecs = {
|
||||
_id: '98jPcG0BOpWiDweSouzg',
|
||||
user: {
|
||||
|
@ -91,6 +206,59 @@ export const mockEndgameFileCreateEvent: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointFileCreationEvent: Ecs = {
|
||||
file: {
|
||||
path: ['C:\\Windows\\TEMP\\E38FD162-B6E6-4799-B52D-F590BACBAE94\\WimProvider.dll'],
|
||||
extension: ['dll'],
|
||||
name: ['WimProvider.dll'],
|
||||
},
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.9.8.7'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['file'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-25T16:21:56.832Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['creation'],
|
||||
type: ['creation'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6FEM'],
|
||||
dataset: ['endpoint.events.file'],
|
||||
},
|
||||
process: {
|
||||
name: ['MsMpEng.exe'],
|
||||
pid: [2424],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTI0MjQtMTMyNTUwNzg2OTAuNDQ1MzY0NzAw',
|
||||
],
|
||||
executable: [
|
||||
'C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\4.18.2011.6-0\\MsMpEng.exe',
|
||||
],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
message: ['Endpoint file event'],
|
||||
timestamp: '2021-01-25T16:21:56.832Z',
|
||||
_id: 'eSdbOncBLJMagDUQ3YFs',
|
||||
};
|
||||
|
||||
export const mockEndgameFileDeleteEvent: Ecs = {
|
||||
_id: 'OMjPcG0BOpWiDweSeuW9',
|
||||
user: {
|
||||
|
@ -123,6 +291,58 @@ export const mockEndgameFileDeleteEvent: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointFileDeletionEvent: Ecs = {
|
||||
file: {
|
||||
path: ['C:\\Windows\\SoftwareDistribution\\Download\\Install\\AM_Delta_Patch_1.329.2793.0.exe'],
|
||||
extension: ['exe'],
|
||||
name: ['AM_Delta_Patch_1.329.2793.0.exe'],
|
||||
},
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['11:22:33:44:55:66'],
|
||||
name: ['windows-endpoint-1'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['ce6fa3c3-fda1-4984-9bce-f6d602a5bd1a'],
|
||||
},
|
||||
event: {
|
||||
category: ['file'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-25T22:50:36.783Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['deletion'],
|
||||
type: ['deletion'],
|
||||
id: ['Lzty2lsJxA05IUWg++++CBsc'],
|
||||
dataset: ['endpoint.events.file'],
|
||||
},
|
||||
process: {
|
||||
name: ['svchost.exe'],
|
||||
pid: [1728],
|
||||
entity_id: [
|
||||
'YjUwNDNiMTMtYTdjNi0xZGFlLTEyZWQtODQ1ZDlhNTRhZmQyLTE3MjgtMTMyNTQ5ODc2MjYuNjg3OTg0MDAw',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\svchost.exe'],
|
||||
},
|
||||
user: {
|
||||
id: ['S-1-5-18'],
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
message: ['Endpoint file event'],
|
||||
timestamp: '2021-01-25T22:50:36.783Z',
|
||||
_id: 'mnXHO3cBPmkOXwyNlyv_',
|
||||
};
|
||||
|
||||
export const mockEndgameIpv4ConnectionAcceptEvent: Ecs = {
|
||||
_id: 'LsjPcG0BOpWiDweSCNfu',
|
||||
user: {
|
||||
|
@ -213,6 +433,74 @@ export const mockEndgameIpv6ConnectionAcceptEvent: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointNetworkConnectionAcceptedEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['windows-endpoint-1'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['ce6fa3c3-fda1-4984-9bce-f6d602a5bd1a'],
|
||||
},
|
||||
event: {
|
||||
category: ['network'],
|
||||
kind: ['event'],
|
||||
outcome: ['success'],
|
||||
created: ['2021-01-25T16:44:45.048Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['connection_accepted'],
|
||||
type: ['start'],
|
||||
id: ['Lzty2lsJxA05IUWg++++C1CY'],
|
||||
dataset: ['endpoint.events.network'],
|
||||
},
|
||||
process: {
|
||||
name: ['svchost.exe'],
|
||||
pid: [328],
|
||||
entity_id: [
|
||||
'YjUwNDNiMTMtYTdjNi0xZGFlLTEyZWQtODQ1ZDlhNTRhZmQyLTMyOC0xMzI1NDk4NzUwNS45OTYxMjUzMDA=',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\svchost.exe'],
|
||||
},
|
||||
source: {
|
||||
geo: {
|
||||
region_name: ['North Carolina'],
|
||||
region_iso_code: ['US-NC'],
|
||||
city_name: ['Concord'],
|
||||
country_iso_code: ['US'],
|
||||
continent_name: ['North America'],
|
||||
country_name: ['United States'],
|
||||
},
|
||||
ip: ['10.1.2.3'],
|
||||
port: [64557],
|
||||
},
|
||||
destination: {
|
||||
port: [3389],
|
||||
ip: ['10.50.60.70'],
|
||||
},
|
||||
user: {
|
||||
id: ['S-1-5-20'],
|
||||
name: ['NETWORK SERVICE'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
network: {
|
||||
direction: ['incoming'],
|
||||
transport: ['tcp'],
|
||||
},
|
||||
message: ['Endpoint network event'],
|
||||
timestamp: '2021-01-25T16:44:45.048Z',
|
||||
_id: 'tUN0OncBPmkOXwyNOGPV',
|
||||
};
|
||||
|
||||
export const mockEndgameIpv4DisconnectReceivedEvent: Ecs = {
|
||||
_id: 'hMjPcG0BOpWiDweSoOin',
|
||||
user: {
|
||||
|
@ -309,6 +597,75 @@ export const mockEndgameIpv6DisconnectReceivedEvent: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointDisconnectReceivedEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['windows-endpoint-1'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['ce6fa3c3-fda1-4984-9bce-f6d602a5bd1a'],
|
||||
},
|
||||
event: {
|
||||
category: ['network'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-25T16:44:47.004Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['disconnect_received'],
|
||||
type: ['end'],
|
||||
id: ['Lzty2lsJxA05IUWg++++C1Ch'],
|
||||
dataset: ['endpoint.events.network'],
|
||||
},
|
||||
process: {
|
||||
name: ['svchost.exe'],
|
||||
pid: [328],
|
||||
entity_id: [
|
||||
'YjUwNDNiMTMtYTdjNi0xZGFlLTEyZWQtODQ1ZDlhNTRhZmQyLTMyOC0xMzI1NDk4NzUwNS45OTYxMjUzMDA=',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\svchost.exe'],
|
||||
},
|
||||
source: {
|
||||
geo: {
|
||||
region_name: ['North Carolina'],
|
||||
region_iso_code: ['US-NC'],
|
||||
city_name: ['Concord'],
|
||||
country_iso_code: ['US'],
|
||||
continent_name: ['North America'],
|
||||
country_name: ['United States'],
|
||||
},
|
||||
ip: ['10.20.30.40'],
|
||||
port: [64557],
|
||||
bytes: [1192],
|
||||
},
|
||||
destination: {
|
||||
bytes: [1615],
|
||||
port: [3389],
|
||||
ip: ['10.11.12.13'],
|
||||
},
|
||||
user: {
|
||||
id: ['S-1-5-20'],
|
||||
name: ['NETWORK SERVICE'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
network: {
|
||||
direction: ['incoming'],
|
||||
transport: ['tcp'],
|
||||
},
|
||||
message: ['Endpoint network event'],
|
||||
timestamp: '2021-01-25T16:44:47.004Z',
|
||||
_id: 'uUN0OncBPmkOXwyNOGPV',
|
||||
};
|
||||
|
||||
export const mockEndgameUserLogon: Ecs = {
|
||||
_id: 'QsjPcG0BOpWiDweSeuRE',
|
||||
user: {
|
||||
|
@ -357,6 +714,92 @@ export const mockEndgameUserLogon: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointSecurityLogOnSuccessEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['authentication', 'session'],
|
||||
kind: ['event'],
|
||||
outcome: ['success'],
|
||||
created: ['2021-01-25T16:24:51.761Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['log_on'],
|
||||
type: ['start'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6FKC'],
|
||||
dataset: ['endpoint.events.security'],
|
||||
},
|
||||
process: {
|
||||
name: ['C:\\Program Files\\OpenSSH-Win64\\sshd.exe'],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTQzNDQtMTMyNTYwNjU0ODYuMzIwNDI3MDAw',
|
||||
],
|
||||
executable: ['C:\\Program Files\\OpenSSH-Win64\\sshd.exe'],
|
||||
pid: [90210],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
message: ['Endpoint security event'],
|
||||
timestamp: '2021-01-25T16:24:51.761Z',
|
||||
_id: 'eSlgOncBLJMagDUQ-yBL',
|
||||
};
|
||||
|
||||
export const mockEndpointSecurityLogOnFailureEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1637)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1637)'],
|
||||
kernel: ['1809 (10.0.17763.1637)'],
|
||||
platform: ['windows'],
|
||||
family: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
ip: ['10.1.2.3'],
|
||||
name: ['win2019-endpoint'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
architecture: ['x86_64'],
|
||||
},
|
||||
event: {
|
||||
category: ['authentication', 'session'],
|
||||
module: ['endpoint'],
|
||||
kind: ['event'],
|
||||
outcome: ['failure'],
|
||||
action: ['log_on'],
|
||||
created: ['2020-12-28T04:05:01.409Z'],
|
||||
type: ['start'],
|
||||
id: ['Ly1AjdVRChqy2iq3++++3jlX'],
|
||||
dataset: ['endpoint.events.security'],
|
||||
},
|
||||
process: {
|
||||
name: ['C:\\Program Files\\OpenSSH-Win64\\sshd.exe'],
|
||||
pid: [90210],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
message: ['Endpoint security event'],
|
||||
timestamp: '2020-12-28T04:05:01.409Z',
|
||||
_id: 's8GIp3YBN9Y7_e914Upz',
|
||||
};
|
||||
|
||||
export const mockEndgameAdminLogon: Ecs = {
|
||||
_id: 'psjPcG0BOpWiDweSoelR',
|
||||
user: {
|
||||
|
@ -488,6 +931,49 @@ export const mockEndgameUserLogoff: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointSecurityLogOffEvent: Ecs = {
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['authentication,session'],
|
||||
kind: ['event'],
|
||||
outcome: ['success'],
|
||||
created: ['2021-01-26T23:27:27.610Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['log_off'],
|
||||
type: ['end'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6l0y'],
|
||||
dataset: ['endpoint.events.security'],
|
||||
},
|
||||
process: {
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTU4MC0xMzI1NTA3ODY2Ny45MTg5Njc1MDA=',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\lsass.exe'],
|
||||
pid: [90210],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
message: ['Endpoint security event'],
|
||||
timestamp: '2021-01-26T23:27:27.610Z',
|
||||
_id: 'ZesLQXcBPmkOXwyNdT1a',
|
||||
};
|
||||
|
||||
export const mockEndgameCreationEvent: Ecs = {
|
||||
_id: 'BcjPcG0BOpWiDweSou3g',
|
||||
user: {
|
||||
|
@ -537,6 +1023,58 @@ export const mockEndgameCreationEvent: Ecs = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockEndpointProcessStartEvent: Ecs = {
|
||||
process: {
|
||||
hash: {
|
||||
md5: ['1b0e9b5fcb62de0787235ecca560b610'],
|
||||
sha256: ['697334c236cce7d4c9e223146ee683a1219adced9729d4ae771fd6a1502a6b63'],
|
||||
sha1: ['e19da2c35ba1c38adf12d1a472c1fcf1f1a811a7'],
|
||||
},
|
||||
name: ['conhost.exe'],
|
||||
pid: [3636],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTM2MzYtMTMyNTYwODU1OTguMTA3NTA3MDAw',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\conhost.exe'],
|
||||
args: ['C:\\Windows\\system32\\conhost.exe,0xffffffff,-ForceV1'],
|
||||
},
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint-1'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['process'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-25T21:59:58.107Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['start'],
|
||||
type: ['start'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++6Kw+'],
|
||||
dataset: ['endpoint.events.process'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
message: ['Endpoint process event'],
|
||||
timestamp: '2021-01-25T21:59:58.107Z',
|
||||
_id: 't5KSO3cB8l64wN2iQ8V9',
|
||||
};
|
||||
|
||||
export const mockEndgameTerminationEvent: Ecs = {
|
||||
_id: '2MjPcG0BOpWiDweSoutC',
|
||||
user: {
|
||||
|
@ -578,3 +1116,59 @@ export const mockEndgameTerminationEvent: Ecs = {
|
|||
exit_code: [0],
|
||||
},
|
||||
};
|
||||
|
||||
export const mockEndpointProcessEndEvent: Ecs = {
|
||||
process: {
|
||||
hash: {
|
||||
md5: ['8a0a29438052faed8a2532da50455756'],
|
||||
sha256: ['7fd065bac18c5278777ae44908101cdfed72d26fa741367f0ad4d02020787ab6'],
|
||||
sha1: ['a1385ce20ad79f55df235effd9780c31442aa234'],
|
||||
},
|
||||
name: ['svchost.exe'],
|
||||
parent: {
|
||||
name: ['services.exe'],
|
||||
},
|
||||
pid: [10392],
|
||||
entity_id: [
|
||||
'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTEwMzkyLTEzMjU2MjY2OTkwLjcwMzgzMDgwMA==',
|
||||
],
|
||||
executable: ['C:\\Windows\\System32\\svchost.exe'],
|
||||
exit_code: [-1],
|
||||
args: ['C:\\Windows\\System32\\svchost.exe,-k,netsvcs,-p,-s,NetSetupSvc'],
|
||||
},
|
||||
host: {
|
||||
os: {
|
||||
full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'],
|
||||
name: ['Windows'],
|
||||
version: ['1809 (10.0.17763.1697)'],
|
||||
family: ['windows'],
|
||||
kernel: ['1809 (10.0.17763.1697)'],
|
||||
platform: ['windows'],
|
||||
},
|
||||
mac: ['aa:bb:cc:dd:ee:ff'],
|
||||
name: ['win2019-endpoint'],
|
||||
architecture: ['x86_64'],
|
||||
ip: ['10.1.2.3'],
|
||||
id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'],
|
||||
},
|
||||
event: {
|
||||
category: ['process'],
|
||||
kind: ['event'],
|
||||
created: ['2021-01-28T00:24:05.929Z'],
|
||||
module: ['endpoint'],
|
||||
action: ['end'],
|
||||
type: ['end'],
|
||||
id: ['LzzWB9jjGmCwGMvk++++77mE'],
|
||||
dataset: ['endpoint.events.process'],
|
||||
},
|
||||
agent: {
|
||||
type: ['endpoint'],
|
||||
},
|
||||
user: {
|
||||
name: ['SYSTEM'],
|
||||
domain: ['NT AUTHORITY'],
|
||||
},
|
||||
message: ['Endpoint process event'],
|
||||
timestamp: '2021-01-28T00:24:05.929Z',
|
||||
_id: 'quloRncBX5UUcOOYo2ZS',
|
||||
};
|
||||
|
|
|
@ -1,20 +1,31 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ProcessDraggable rendering it renders against shallow snapshot 1`] = `
|
||||
<div>
|
||||
<DraggableBadge
|
||||
contextId="context-123"
|
||||
eventId="event-123"
|
||||
field="process.name"
|
||||
iconType="console"
|
||||
value="process-name-1"
|
||||
/>
|
||||
<DraggableBadge
|
||||
contextId="context-123"
|
||||
eventId="event-123"
|
||||
field="process.pid"
|
||||
queryValue="123"
|
||||
value="(123)"
|
||||
/>
|
||||
</div>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<DraggableBadge
|
||||
contextId="context-123"
|
||||
eventId="event-123"
|
||||
field="process.name"
|
||||
iconType="console"
|
||||
value="process-name-1"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<DraggableBadge
|
||||
contextId="context-123"
|
||||
eventId="event-123"
|
||||
field="process.pid"
|
||||
queryValue="123"
|
||||
value="(123)"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
|
|
@ -42,6 +42,7 @@ export const EndgameSecurityEventDetails = React.memo<Props>(({ data, contextId,
|
|||
const endgameTargetUserName: string | null | undefined = get('endgame.target_user_name[0]', data);
|
||||
const eventAction: string | null | undefined = get('event.action[0]', data);
|
||||
const eventCode: string | null | undefined = get('event.code[0]', data);
|
||||
const eventOutcome: string | null | undefined = get('event.outcome[0]', data);
|
||||
const hostName: string | null | undefined = get('host.name[0]', data);
|
||||
const id = data._id;
|
||||
const processExecutable: string | null | undefined = get('process.executable[0]', data);
|
||||
|
@ -64,6 +65,7 @@ export const EndgameSecurityEventDetails = React.memo<Props>(({ data, contextId,
|
|||
endgameTargetUserName={endgameTargetUserName}
|
||||
eventAction={eventAction}
|
||||
eventCode={eventCode}
|
||||
eventOutcome={eventOutcome}
|
||||
hostName={hostName}
|
||||
id={id}
|
||||
processExecutable={processExecutable}
|
||||
|
|
|
@ -39,6 +39,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="admin_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -69,6 +70,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -99,6 +101,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -129,6 +132,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -159,6 +163,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -189,6 +194,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -219,6 +225,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -249,6 +256,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -279,6 +287,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName={undefined}
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -309,6 +318,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction={undefined}
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -339,6 +349,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode={undefined}
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -369,6 +380,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName={undefined}
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -399,6 +411,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable={undefined}
|
||||
|
@ -429,6 +442,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -459,6 +473,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="explicit_user_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -489,6 +504,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="admin_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -519,6 +535,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="admin_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -549,6 +566,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="admin_logon"
|
||||
eventCode="[eventCode]"
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
@ -579,6 +597,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
|
|||
endgameTargetUserName="[endgameTargetUserName]"
|
||||
eventAction="admin_logon"
|
||||
eventCode={undefined}
|
||||
eventOutcome={undefined}
|
||||
hostName="[hostName]"
|
||||
id="1"
|
||||
processExecutable="[processExecutable]"
|
||||
|
|
|
@ -35,6 +35,7 @@ interface Props {
|
|||
endgameTargetUserName: string | null | undefined;
|
||||
eventAction: string | null | undefined;
|
||||
eventCode: string | null | undefined;
|
||||
eventOutcome: string | null | undefined;
|
||||
hostName: string | null | undefined;
|
||||
id: string;
|
||||
processExecutable: string | null | undefined;
|
||||
|
@ -57,6 +58,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
|
|||
endgameTargetUserName,
|
||||
eventAction,
|
||||
eventCode,
|
||||
eventOutcome,
|
||||
hostName,
|
||||
id,
|
||||
processExecutable,
|
||||
|
@ -67,7 +69,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
|
|||
winlogEventId,
|
||||
}) => {
|
||||
const domain = getTargetUserAndTargetDomain(eventAction) ? endgameTargetDomainName : userDomain;
|
||||
const eventDetails = getEventDetails(eventAction);
|
||||
const eventDetails = getEventDetails({ eventAction, eventOutcome });
|
||||
const hostNameSeparator = getHostNameSeparator(eventAction);
|
||||
const user = getTargetUserAndTargetDomain(eventAction) ? endgameTargetUserName : userName;
|
||||
const userDomainField = getUserDomainField(eventAction);
|
||||
|
|
|
@ -182,28 +182,116 @@ describe('helpers', () => {
|
|||
});
|
||||
|
||||
describe('#getEventDetails', () => {
|
||||
test('it returns successfully logged in when eventAction is undefined', () => {
|
||||
expect(getEventDetails(undefined)).toEqual('successfully logged in');
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is null', () => {
|
||||
expect(getEventDetails(null)).toEqual('successfully logged in');
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is an empty string', () => {
|
||||
expect(getEventDetails('')).toEqual('successfully logged in');
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is a random value', () => {
|
||||
expect(getEventDetails('a random value')).toEqual('successfully logged in');
|
||||
});
|
||||
|
||||
test('it returns an empty string when eventAction is "explicit_user_logon"', () => {
|
||||
expect(getEventDetails('explicit_user_logon')).toEqual('');
|
||||
expect(
|
||||
getEventDetails({ eventAction: 'explicit_user_logon', eventOutcome: undefined })
|
||||
).toEqual('');
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "user_logoff"', () => {
|
||||
expect(getEventDetails('user_logoff')).toEqual('logged off');
|
||||
test('it returns logged off when eventAction is "log_off" and eventOutcome is null', () => {
|
||||
expect(getEventDetails({ eventAction: 'log_off', eventOutcome: null })).toEqual('logged off');
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "log_off" and eventOutcome is undefined', () => {
|
||||
expect(getEventDetails({ eventAction: 'log_off', eventOutcome: undefined })).toEqual(
|
||||
'logged off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log off when eventAction is "log_off" and eventOutcome is failure', () => {
|
||||
expect(getEventDetails({ eventAction: 'log_off', eventOutcome: 'failure' })).toEqual(
|
||||
'failed to log off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log off when eventAction is "log_off" and eventOutcome is fAiLuRe', () => {
|
||||
expect(getEventDetails({ eventAction: 'log_off', eventOutcome: 'fAiLuRe' })).toEqual(
|
||||
'failed to log off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "log_off" and eventOutcome is anything_else', () => {
|
||||
expect(getEventDetails({ eventAction: 'log_off', eventOutcome: 'anything_else' })).toEqual(
|
||||
'logged off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "user_logoff" and eventOutcome is null', () => {
|
||||
expect(getEventDetails({ eventAction: 'user_logoff', eventOutcome: null })).toEqual(
|
||||
'logged off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "user_logoff" and eventOutcome is undefined', () => {
|
||||
expect(getEventDetails({ eventAction: 'user_logoff', eventOutcome: undefined })).toEqual(
|
||||
'logged off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log off when eventAction is "user_logoff" and eventOutcome is failure', () => {
|
||||
expect(getEventDetails({ eventAction: 'user_logoff', eventOutcome: 'failure' })).toEqual(
|
||||
'failed to log off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log off when eventAction is "user_logoff" and eventOutcome is fAiLuRe', () => {
|
||||
expect(getEventDetails({ eventAction: 'user_logoff', eventOutcome: 'fAiLuRe' })).toEqual(
|
||||
'failed to log off'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns logged off when eventAction is "user_logoff" and eventOutcome is anything_else', () => {
|
||||
expect(
|
||||
getEventDetails({ eventAction: 'user_logoff', eventOutcome: 'anything_else' })
|
||||
).toEqual('logged off');
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is null and eventOutcome is undefined', () => {
|
||||
expect(getEventDetails({ eventAction: null, eventOutcome: undefined })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is null and eventOutcome is null', () => {
|
||||
expect(getEventDetails({ eventAction: null, eventOutcome: null })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is undefined and eventOutcome is null', () => {
|
||||
expect(getEventDetails({ eventAction: undefined, eventOutcome: null })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is undefined and eventOutcome is undefined', () => {
|
||||
expect(getEventDetails({ eventAction: undefined, eventOutcome: undefined })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is anything_else and eventOutcome is undefined', () => {
|
||||
expect(getEventDetails({ eventAction: 'anything_else', eventOutcome: undefined })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns successfully logged in when eventAction is anything_else and eventOutcome is null', () => {
|
||||
expect(getEventDetails({ eventAction: 'anything_else', eventOutcome: null })).toEqual(
|
||||
'successfully logged in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log in when eventAction is anything_else and eventOutcome is failure', () => {
|
||||
expect(getEventDetails({ eventAction: 'anything_else', eventOutcome: 'failure' })).toEqual(
|
||||
'failed to log in'
|
||||
);
|
||||
});
|
||||
|
||||
test('it returns failed to log in when eventAction is anything_else and eventOutcome is fAiLuRe', () => {
|
||||
expect(getEventDetails({ eventAction: 'anything_else', eventOutcome: 'fAiLuRe' })).toEqual(
|
||||
'failed to log in'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -50,13 +50,22 @@ export const getUserDomainField = (eventAction: string | null | undefined): stri
|
|||
export const getUserNameField = (eventAction: string | null | undefined): string =>
|
||||
getTargetUserAndTargetDomain(eventAction) ? 'endgame.target_user_name' : 'user.name';
|
||||
|
||||
export const getEventDetails = (eventAction: string | null | undefined): string => {
|
||||
export const getEventDetails = ({
|
||||
eventAction,
|
||||
eventOutcome,
|
||||
}: {
|
||||
eventAction: string | null | undefined;
|
||||
eventOutcome: string | null | undefined;
|
||||
}): string => {
|
||||
switch (eventAction) {
|
||||
case 'explicit_user_logon':
|
||||
return ''; // no details
|
||||
case 'log_off': // fall through
|
||||
case 'user_logoff':
|
||||
return i18n.LOGGED_OFF;
|
||||
return eventOutcome?.toLowerCase() === 'failure' ? i18n.FAILED_TO_LOG_OFF : i18n.LOGGED_OFF;
|
||||
default:
|
||||
return i18n.SUCCESSFULLY_LOGGED_IN;
|
||||
return eventOutcome?.toLowerCase() === 'failure'
|
||||
? i18n.FAILED_TO_LOG_IN
|
||||
: i18n.SUCCESSFULLY_LOGGED_IN;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -21,6 +21,20 @@ export const AS_REQUESTED_BY_SUBJECT = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
export const FAILED_TO_LOG_IN = i18n.translate(
|
||||
'xpack.securitySolution.timeline.body.renderers.endpoint.failedToLogInDescription',
|
||||
{
|
||||
defaultMessage: 'failed to log in',
|
||||
}
|
||||
);
|
||||
|
||||
export const FAILED_TO_LOG_OFF = i18n.translate(
|
||||
'xpack.securitySolution.timeline.body.renderers.endpoint.failedToLogOffDescription',
|
||||
{
|
||||
defaultMessage: 'failed to log off',
|
||||
}
|
||||
);
|
||||
|
||||
export const LOGGED_OFF = i18n.translate(
|
||||
'xpack.securitySolution.timeline.body.renderers.endgame.loggedOffDescription',
|
||||
{
|
||||
|
|
|
@ -25,22 +25,29 @@ jest.mock('@elastic/eui', () => {
|
|||
describe('ExitCodeDraggable', () => {
|
||||
const mount = useMountAppended();
|
||||
|
||||
test('it renders the expected text and exit code, when both text and an endgameExitCode are provided', () => {
|
||||
test('it renders the expected text and exit codes, when text, processExitCode, and an endgameExitCode are provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable contextId="test" endgameExitCode="0" eventId="1" text="with exit code" />
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode="0"
|
||||
eventId="1"
|
||||
processExitCode={-1}
|
||||
text="with exit code"
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('with exit code0');
|
||||
expect(wrapper.text()).toEqual('with exit code-10');
|
||||
});
|
||||
|
||||
test('it returns an empty string when text is provided, but endgameExitCode is undefined', () => {
|
||||
test('it returns an empty string when text is provided, but processExitCode and endgameExitCode are undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode={undefined}
|
||||
eventId="1"
|
||||
processExitCode={undefined}
|
||||
text="with exit code"
|
||||
/>
|
||||
</TestProviders>
|
||||
|
@ -48,13 +55,14 @@ describe('ExitCodeDraggable', () => {
|
|||
expect(wrapper.text()).toEqual('');
|
||||
});
|
||||
|
||||
test('it returns an empty string when text is provided, but endgameExitCode is null', () => {
|
||||
test('it returns an empty string when text is provided, but processExitCode and endgameExitCode are null', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode={null}
|
||||
eventId="1"
|
||||
processExitCode={null}
|
||||
text="with exit code"
|
||||
/>
|
||||
</TestProviders>
|
||||
|
@ -65,36 +73,105 @@ describe('ExitCodeDraggable', () => {
|
|||
test('it returns an empty string when text is provided, but endgameExitCode is an empty string', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable contextId="test" endgameExitCode="" eventId="1" text="with exit code" />
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode=""
|
||||
eventId="1"
|
||||
processExitCode={undefined}
|
||||
text="with exit code"
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('');
|
||||
});
|
||||
|
||||
test('it renders just the exit code when text is undefined', () => {
|
||||
test('it renders just the endgameExitCode code when text is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable contextId="test" endgameExitCode="1" eventId="1" text={undefined} />
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode="1"
|
||||
eventId="1"
|
||||
processExitCode={undefined}
|
||||
text={undefined}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('1');
|
||||
});
|
||||
|
||||
test('it renders just the exit code when text is null', () => {
|
||||
test('it renders just the processExitCode code when text is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable contextId="test" endgameExitCode="1" eventId="1" text={null} />
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode={undefined}
|
||||
eventId="1"
|
||||
processExitCode={-1}
|
||||
text={undefined}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('-1');
|
||||
});
|
||||
|
||||
test('it renders just the endgameExitCode code when text is null', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode="1"
|
||||
eventId="1"
|
||||
processExitCode={undefined}
|
||||
text={null}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('1');
|
||||
});
|
||||
|
||||
test('it renders just the exit code when text is an empty string', () => {
|
||||
test('it renders just the processExitCode code when text is null', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable contextId="test" endgameExitCode="1" eventId="1" text="" />
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode={undefined}
|
||||
eventId="1"
|
||||
processExitCode={-1}
|
||||
text={null}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('-1');
|
||||
});
|
||||
|
||||
test('it renders just the endgameExitCode code when text is an empty string', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode="1"
|
||||
eventId="1"
|
||||
processExitCode={undefined}
|
||||
text=""
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('1');
|
||||
});
|
||||
|
||||
test('it renders just the processExitCode code when text is an empty string', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ExitCodeDraggable
|
||||
contextId="test"
|
||||
endgameExitCode={undefined}
|
||||
eventId="1"
|
||||
processExitCode={-1}
|
||||
text=""
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('-1');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,12 +15,13 @@ interface Props {
|
|||
contextId: string;
|
||||
endgameExitCode: string | null | undefined;
|
||||
eventId: string;
|
||||
processExitCode: number | null | undefined;
|
||||
text: string | null | undefined;
|
||||
}
|
||||
|
||||
export const ExitCodeDraggable = React.memo<Props>(
|
||||
({ contextId, endgameExitCode, eventId, text }) => {
|
||||
if (isNillEmptyOrNotFinite(endgameExitCode)) {
|
||||
({ contextId, endgameExitCode, eventId, processExitCode, text }) => {
|
||||
if (isNillEmptyOrNotFinite(processExitCode) && isNillEmptyOrNotFinite(endgameExitCode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -32,14 +33,27 @@ export const ExitCodeDraggable = React.memo<Props>(
|
|||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.exit_code"
|
||||
value={endgameExitCode}
|
||||
/>
|
||||
</TokensFlexItem>
|
||||
{!isNillEmptyOrNotFinite(processExitCode) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.exit_code"
|
||||
value={`${processExitCode}`}
|
||||
/>
|
||||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
{!isNillEmptyOrNotFinite(endgameExitCode) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.exit_code"
|
||||
value={endgameExitCode}
|
||||
/>
|
||||
</TokensFlexItem>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -51,14 +51,15 @@ export const isFileEvent = ({
|
|||
eventCategory: string | null | undefined;
|
||||
eventDataset: string | null | undefined;
|
||||
}) =>
|
||||
(eventCategory != null && eventCategory.toLowerCase() === 'file') ||
|
||||
(eventDataset != null && eventDataset.toLowerCase() === 'file');
|
||||
eventCategory?.toLowerCase() === 'file' ||
|
||||
eventDataset?.toLowerCase() === 'file' ||
|
||||
eventDataset?.toLowerCase() === 'endpoint.events.file';
|
||||
|
||||
export const isProcessStoppedOrTerminationEvent = (
|
||||
eventAction: string | null | undefined
|
||||
): boolean => ['process_stopped', 'termination_event'].includes(`${eventAction}`.toLowerCase());
|
||||
|
||||
export const showVia = (eventAction: string | null | undefined): boolean =>
|
||||
['file_create_event', 'created', 'file_delete_event', 'deleted'].includes(
|
||||
['file_create_event', 'created', 'creation', 'file_delete_event', 'deleted', 'deletion'].includes(
|
||||
`${eventAction}`.toLowerCase()
|
||||
);
|
||||
|
|
|
@ -25,28 +25,34 @@ jest.mock('@elastic/eui', () => {
|
|||
describe('ParentProcessDraggable', () => {
|
||||
const mount = useMountAppended();
|
||||
|
||||
test('displays the text, endgameParentProcessName, and processPpid when they are all provided', () => {
|
||||
test('displays the text, endgameParentProcessName, processParentName, processParentPid, and processPpid when they are all provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName="[endgameParentProcessName]"
|
||||
eventId="1"
|
||||
processParentName="[processParentName]"
|
||||
processParentPid={789}
|
||||
processPpid={456}
|
||||
text="via parent process"
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('via parent process[endgameParentProcessName](456)');
|
||||
expect(wrapper.text()).toEqual(
|
||||
'via parent process[processParentName][endgameParentProcessName](789)(456)'
|
||||
);
|
||||
});
|
||||
|
||||
test('displays nothing when the text is provided, but endgameParentProcessName and processPpid are both undefined', () => {
|
||||
test('displays nothing when the text is provided, but endgameParentProcessName and processParentName are both undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName={undefined}
|
||||
eventId="1"
|
||||
processParentName={undefined}
|
||||
processParentPid={undefined}
|
||||
processPpid={undefined}
|
||||
text="via parent process"
|
||||
/>
|
||||
|
@ -55,36 +61,6 @@ describe('ParentProcessDraggable', () => {
|
|||
expect(wrapper.text()).toEqual('');
|
||||
});
|
||||
|
||||
test('displays the text and processPpid when endgameParentProcessName is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName={undefined}
|
||||
eventId="1"
|
||||
processPpid={456}
|
||||
text="via parent process"
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('via parent process(456)');
|
||||
});
|
||||
|
||||
test('displays the processPpid when both endgameParentProcessName and text are undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName={undefined}
|
||||
eventId="1"
|
||||
processPpid={456}
|
||||
text={undefined}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('(456)');
|
||||
});
|
||||
|
||||
test('displays the text and endgameParentProcessName when processPpid is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -92,6 +68,8 @@ describe('ParentProcessDraggable', () => {
|
|||
contextId="test"
|
||||
endgameParentProcessName="[endgameParentProcessName]"
|
||||
eventId="1"
|
||||
processParentName={undefined}
|
||||
processParentPid={undefined}
|
||||
processPpid={undefined}
|
||||
text="via parent process"
|
||||
/>
|
||||
|
@ -100,6 +78,23 @@ describe('ParentProcessDraggable', () => {
|
|||
expect(wrapper.text()).toEqual('via parent process[endgameParentProcessName]');
|
||||
});
|
||||
|
||||
test('displays the text and processParentName when processParentPid is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName={undefined}
|
||||
eventId="1"
|
||||
processParentName="[processParentName]"
|
||||
processParentPid={undefined}
|
||||
processPpid={undefined}
|
||||
text="via parent process"
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('via parent process[processParentName]');
|
||||
});
|
||||
|
||||
test('displays the endgameParentProcessName when both processPpid and text are undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -107,6 +102,8 @@ describe('ParentProcessDraggable', () => {
|
|||
contextId="test"
|
||||
endgameParentProcessName="[endgameParentProcessName]"
|
||||
eventId="1"
|
||||
processParentName={undefined}
|
||||
processParentPid={undefined}
|
||||
processPpid={undefined}
|
||||
text={undefined}
|
||||
/>
|
||||
|
@ -114,4 +111,21 @@ describe('ParentProcessDraggable', () => {
|
|||
);
|
||||
expect(wrapper.text()).toEqual('[endgameParentProcessName]');
|
||||
});
|
||||
|
||||
test('displays the processParentName when both processParentPid and text are undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<ParentProcessDraggable
|
||||
contextId="test"
|
||||
endgameParentProcessName={undefined}
|
||||
eventId="1"
|
||||
processParentName="[processParentName]"
|
||||
processParentPid={undefined}
|
||||
processPpid={undefined}
|
||||
text={undefined}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.text()).toEqual('[processParentName]');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,13 +15,26 @@ interface Props {
|
|||
contextId: string;
|
||||
endgameParentProcessName: string | null | undefined;
|
||||
eventId: string;
|
||||
processParentPid: number | null | undefined;
|
||||
processParentName: string | null | undefined;
|
||||
processPpid: number | undefined | null;
|
||||
text: string | null | undefined;
|
||||
}
|
||||
|
||||
export const ParentProcessDraggable = React.memo<Props>(
|
||||
({ contextId, endgameParentProcessName, eventId, processPpid, text }) => {
|
||||
if (isNillEmptyOrNotFinite(endgameParentProcessName) && isNillEmptyOrNotFinite(processPpid)) {
|
||||
({
|
||||
contextId,
|
||||
endgameParentProcessName,
|
||||
eventId,
|
||||
processParentName,
|
||||
processParentPid,
|
||||
processPpid,
|
||||
text,
|
||||
}) => {
|
||||
if (
|
||||
isNillEmptyOrNotFinite(processParentName) &&
|
||||
isNillEmptyOrNotFinite(endgameParentProcessName)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -37,6 +50,17 @@ export const ParentProcessDraggable = React.memo<Props>(
|
|||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
{!isNillEmptyOrNotFinite(processParentName) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.parent.name"
|
||||
value={processParentName}
|
||||
/>
|
||||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
{!isNillEmptyOrNotFinite(endgameParentProcessName) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
|
@ -48,6 +72,18 @@ export const ParentProcessDraggable = React.memo<Props>(
|
|||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
{!isNillEmptyOrNotFinite(processParentPid) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.parent.pid"
|
||||
queryValue={String(processParentPid)}
|
||||
value={`(${String(processParentPid)})`}
|
||||
/>
|
||||
</TokensFlexItem>
|
||||
)}
|
||||
|
||||
{!isNillEmptyOrNotFinite(processPpid) && (
|
||||
<TokensFlexItem grow={false} component="span">
|
||||
<DraggableBadge
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
|
||||
import { DraggableBadge } from '../../../../../common/components/draggables';
|
||||
|
@ -43,51 +44,61 @@ export const ProcessDraggable = React.memo<Props>(
|
|||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="none">
|
||||
{!isNillEmptyOrNotFinite(processName) ? (
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.name"
|
||||
value={processName}
|
||||
iconType="console"
|
||||
/>
|
||||
<EuiFlexItem grow={false}>
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.name"
|
||||
value={processName}
|
||||
iconType="console"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : !isNillEmptyOrNotFinite(processExecutable) ? (
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.executable"
|
||||
value={processExecutable}
|
||||
iconType="console"
|
||||
/>
|
||||
<EuiFlexItem grow={false}>
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.executable"
|
||||
value={processExecutable}
|
||||
iconType="console"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : !isNillEmptyOrNotFinite(endgameProcessName) ? (
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.process_name"
|
||||
value={endgameProcessName}
|
||||
iconType="console"
|
||||
/>
|
||||
<EuiFlexItem grow={false}>
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.process_name"
|
||||
value={endgameProcessName}
|
||||
iconType="console"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
|
||||
{!isNillEmptyOrNotFinite(processPid) ? (
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.pid"
|
||||
queryValue={String(processPid)}
|
||||
value={`(${String(processPid)})`}
|
||||
/>
|
||||
<EuiFlexItem grow={false}>
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="process.pid"
|
||||
queryValue={String(processPid)}
|
||||
value={`(${String(processPid)})`}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : !isNillEmptyOrNotFinite(endgamePid) ? (
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.pid"
|
||||
queryValue={String(endgamePid)}
|
||||
value={`(${String(endgamePid)})`}
|
||||
/>
|
||||
<EuiFlexItem grow={false}>
|
||||
<DraggableBadge
|
||||
contextId={contextId}
|
||||
eventId={eventId}
|
||||
field="endgame.pid"
|
||||
queryValue={String(endgamePid)}
|
||||
value={`(${String(endgamePid)})`}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -48,6 +48,9 @@ interface Props {
|
|||
packageSummary: string | null | undefined;
|
||||
packageVersion: string | null | undefined;
|
||||
processName: string | null | undefined;
|
||||
processParentName: string | null | undefined;
|
||||
processParentPid: number | null | undefined;
|
||||
processExitCode: number | null | undefined;
|
||||
processPid: number | null | undefined;
|
||||
processPpid: number | null | undefined;
|
||||
processExecutable: string | null | undefined;
|
||||
|
@ -82,6 +85,9 @@ export const SystemGenericFileLine = React.memo<Props>(
|
|||
message,
|
||||
outcome,
|
||||
packageName,
|
||||
processParentName,
|
||||
processParentPid,
|
||||
processExitCode,
|
||||
packageSummary,
|
||||
packageVersion,
|
||||
processExecutable,
|
||||
|
@ -142,6 +148,7 @@ export const SystemGenericFileLine = React.memo<Props>(
|
|||
contextId={contextId}
|
||||
endgameExitCode={endgameExitCode}
|
||||
eventId={id}
|
||||
processExitCode={processExitCode}
|
||||
text={i18n.WITH_EXIT_CODE}
|
||||
/>
|
||||
{!isProcessStoppedOrTerminationEvent(eventAction) && (
|
||||
|
@ -149,6 +156,8 @@ export const SystemGenericFileLine = React.memo<Props>(
|
|||
contextId={contextId}
|
||||
endgameParentProcessName={endgameParentProcessName}
|
||||
eventId={id}
|
||||
processParentName={processParentName}
|
||||
processParentPid={processParentPid}
|
||||
processPpid={processPpid}
|
||||
text={i18n.VIA_PARENT_PROCESS}
|
||||
/>
|
||||
|
@ -239,6 +248,9 @@ export const SystemGenericFileDetails = React.memo<GenericDetailsProps>(
|
|||
const packageName: string | null | undefined = get('system.audit.package.name[0]', data);
|
||||
const packageSummary: string | null | undefined = get('system.audit.package.summary[0]', data);
|
||||
const packageVersion: string | null | undefined = get('system.audit.package.version[0]', data);
|
||||
const processExitCode: number | null | undefined = get('process.exit_code[0]', data);
|
||||
const processParentName: string | null | undefined = get('process.parent.name[0]', data);
|
||||
const processParentPid: number | null | undefined = get('process.parent.pid[0]', data);
|
||||
const processHashMd5: string | null | undefined = get('process.hash.md5[0]', data);
|
||||
const processHashSha1: string | null | undefined = get('process.hash.sha1[0]', data);
|
||||
const processHashSha256: string | null | undefined = get('process.hash.sha256[0]', data);
|
||||
|
@ -271,6 +283,9 @@ export const SystemGenericFileDetails = React.memo<GenericDetailsProps>(
|
|||
userDomain={userDomain}
|
||||
userName={userName}
|
||||
message={message}
|
||||
processExitCode={processExitCode}
|
||||
processParentName={processParentName}
|
||||
processParentPid={processParentPid}
|
||||
processTitle={processTitle}
|
||||
workingDirectory={workingDirectory}
|
||||
args={args}
|
||||
|
|
|
@ -36,6 +36,17 @@ import {
|
|||
mockEndgameTerminationEvent,
|
||||
mockEndgameUserLogoff,
|
||||
mockEndgameUserLogon,
|
||||
mockEndpointDisconnectReceivedEvent,
|
||||
mockEndpointFileCreationEvent,
|
||||
mockEndpointFileDeletionEvent,
|
||||
mockEndpointNetworkConnectionAcceptedEvent,
|
||||
mockEndpointNetworkLookupRequestedEvent,
|
||||
mockEndpointNetworkLookupResultEvent,
|
||||
mockEndpointProcessStartEvent,
|
||||
mockEndpointProcessEndEvent,
|
||||
mockEndpointSecurityLogOnSuccessEvent,
|
||||
mockEndpointSecurityLogOnFailureEvent,
|
||||
mockEndpointSecurityLogOffEvent,
|
||||
} from '../../../../../../common/mock/mock_endgame_ecs_data';
|
||||
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
|
||||
import { RowRenderer } from '../row_renderer';
|
||||
|
@ -187,6 +198,31 @@ describe('GenericRowRenderer', () => {
|
|||
});
|
||||
|
||||
describe('#createEndgameProcessRowRenderer', () => {
|
||||
test('it renders an endpoint process start event', () => {
|
||||
const actionName = 'start';
|
||||
const text = i18n.PROCESS_STARTED;
|
||||
|
||||
const endpointProcessStartRowRenderer = createEndgameProcessRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointProcessStartRowRenderer.isInstance(mockEndpointProcessStartEvent) &&
|
||||
endpointProcessStartRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointProcessStartEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpoint-1started processconhost.exe(3636)C:\\Windows\\system32\\conhost.exe,0xffffffff,-ForceV1697334c236cce7d4c9e223146ee683a1219adced9729d4ae771fd6a1502a6b63e19da2c35ba1c38adf12d1a472c1fcf1f1a811a71b0e9b5fcb62de0787235ecca560b610'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endgame process creation_event', () => {
|
||||
const actionName = 'creation_event';
|
||||
const text = i18n.PROCESS_STARTED;
|
||||
|
@ -215,6 +251,31 @@ describe('GenericRowRenderer', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint process end event', () => {
|
||||
const actionName = 'end';
|
||||
const text = i18n.TERMINATED_PROCESS;
|
||||
|
||||
const endpointProcessEndRowRenderer = createEndgameProcessRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointProcessEndRowRenderer.isInstance(mockEndpointProcessEndEvent) &&
|
||||
endpointProcessEndRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointProcessEndEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointterminated processsvchost.exe(10392)C:\\Windows\\System32\\svchost.exe,-k,netsvcs,-p,-s,NetSetupSvcwith exit code-1via parent processservices.exe7fd065bac18c5278777ae44908101cdfed72d26fa741367f0ad4d02020787ab6a1385ce20ad79f55df235effd9780c31442aa2348a0a29438052faed8a2532da50455756'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endgame process termination_event', () => {
|
||||
const actionName = 'termination_event';
|
||||
const text = i18n.TERMINATED_PROCESS;
|
||||
|
@ -331,6 +392,31 @@ describe('GenericRowRenderer', () => {
|
|||
});
|
||||
|
||||
describe('#createFimRowRenderer', () => {
|
||||
test('it renders an endpoint file creation event', () => {
|
||||
const actionName = 'creation';
|
||||
const text = i18n.CREATED_FILE;
|
||||
|
||||
const endpointFileCreationRowRenderer = createFimRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointFileCreationRowRenderer.isInstance(mockEndpointFileCreationEvent) &&
|
||||
endpointFileCreationRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointFileCreationEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointcreated a fileWimProvider.dllinC:\\Windows\\TEMP\\E38FD162-B6E6-4799-B52D-F590BACBAE94\\WimProvider.dllviaMsMpEng.exe(2424)'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endgame file_create_event', () => {
|
||||
const actionName = 'file_create_event';
|
||||
const text = i18n.CREATED_FILE;
|
||||
|
@ -359,6 +445,31 @@ describe('GenericRowRenderer', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint file deletion event', () => {
|
||||
const actionName = 'deletion';
|
||||
const text = i18n.DELETED_FILE;
|
||||
|
||||
const endpointFileDeletionRowRenderer = createFimRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointFileDeletionRowRenderer.isInstance(mockEndpointFileDeletionEvent) &&
|
||||
endpointFileDeletionRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointFileDeletionEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@windows-endpoint-1deleted a fileAM_Delta_Patch_1.329.2793.0.exeinC:\\Windows\\SoftwareDistribution\\Download\\Install\\AM_Delta_Patch_1.329.2793.0.exeviasvchost.exe(1728)'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endgame file_delete_event', () => {
|
||||
const actionName = 'file_delete_event';
|
||||
const text = i18n.DELETED_FILE;
|
||||
|
@ -529,6 +640,33 @@ describe('GenericRowRenderer', () => {
|
|||
});
|
||||
|
||||
describe('#createSocketRowRenderer', () => {
|
||||
test('it renders an Endpoint network connection_accepted event', () => {
|
||||
const actionName = 'connection_accepted';
|
||||
const text = i18n.ACCEPTED_A_CONNECTION_VIA;
|
||||
|
||||
const endpointConnectionAcceptedRowRenderer = createSocketRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointConnectionAcceptedRowRenderer.isInstance(
|
||||
mockEndpointNetworkConnectionAcceptedEvent
|
||||
) &&
|
||||
endpointConnectionAcceptedRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointNetworkConnectionAcceptedEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(removeExternalLinkText(wrapper.text())).toEqual(
|
||||
'NETWORK SERVICE\\NT AUTHORITY@windows-endpoint-1accepted a connection viasvchost.exe(328)with resultsuccessEndpoint network eventincomingtcpSource10.1.2.3:64557North AmericaUnited States🇺🇸USNorth CarolinaConcordDestination10.50.60.70:3389'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an Endgame ipv4_connection_accept_event', () => {
|
||||
const actionName = 'ipv4_connection_accept_event';
|
||||
const text = i18n.ACCEPTED_A_CONNECTION_VIA;
|
||||
|
@ -585,6 +723,31 @@ describe('GenericRowRenderer', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint network disconnect_received event', () => {
|
||||
const actionName = 'disconnect_received';
|
||||
const text = i18n.DISCONNECTED_VIA;
|
||||
|
||||
const endpointDisconnectReceivedRowRenderer = createSocketRowRenderer({
|
||||
actionName,
|
||||
text,
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{endpointDisconnectReceivedRowRenderer.isInstance(mockEndpointDisconnectReceivedEvent) &&
|
||||
endpointDisconnectReceivedRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointDisconnectReceivedEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(removeExternalLinkText(wrapper.text())).toEqual(
|
||||
'NETWORK SERVICE\\NT AUTHORITY@windows-endpoint-1disconnected viasvchost.exe(328)Endpoint network eventincomingtcpSource10.20.30.40:64557North AmericaUnited States🇺🇸USNorth CarolinaConcord(42.47%)1.2KB(57.53%)1.6KBDestination10.11.12.13:3389'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an Endgame ipv4_disconnect_received_event', () => {
|
||||
const actionName = 'ipv4_disconnect_received_event';
|
||||
const text = i18n.DISCONNECTED_VIA;
|
||||
|
@ -725,6 +888,48 @@ describe('GenericRowRenderer', () => {
|
|||
});
|
||||
|
||||
describe('#createSecurityEventRowRenderer', () => {
|
||||
test('it renders an endpoint security log_on event with event.outcome: success', () => {
|
||||
const actionName = 'log_on';
|
||||
|
||||
const securityLogOnRowRenderer = createSecurityEventRowRenderer({ actionName });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{securityLogOnRowRenderer.isInstance(mockEndpointSecurityLogOnSuccessEvent) &&
|
||||
securityLogOnRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointSecurityLogOnSuccessEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointsuccessfully logged inviaC:\\Program Files\\OpenSSH-Win64\\sshd.exe(90210)'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint security log_on event with event.outcome: failure', () => {
|
||||
const actionName = 'log_on';
|
||||
|
||||
const securityLogOnRowRenderer = createSecurityEventRowRenderer({ actionName });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{securityLogOnRowRenderer.isInstance(mockEndpointSecurityLogOnFailureEvent) &&
|
||||
securityLogOnRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointSecurityLogOnFailureEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'win2019-endpointfailed to log inviaC:\\Program Files\\OpenSSH-Win64\\sshd.exe(90210)'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an Endgame user_logon event', () => {
|
||||
const actionName = 'user_logon';
|
||||
const userLogonEvent = {
|
||||
|
@ -797,6 +1002,27 @@ describe('GenericRowRenderer', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint security log_off event', () => {
|
||||
const actionName = 'log_off';
|
||||
|
||||
const securityLogOffRowRenderer = createSecurityEventRowRenderer({ actionName });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{securityLogOffRowRenderer.isInstance(mockEndpointSecurityLogOffEvent) &&
|
||||
securityLogOffRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointSecurityLogOffEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointlogged offviaC:\\Windows\\System32\\lsass.exe(90210)'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an Endgame user_logoff event', () => {
|
||||
const actionName = 'user_logoff';
|
||||
const userLogoffEvent = {
|
||||
|
@ -845,6 +1071,44 @@ describe('GenericRowRenderer', () => {
|
|||
});
|
||||
|
||||
describe('#createDnsRowRenderer', () => {
|
||||
test('it renders an endpoint network lookup_requested event', () => {
|
||||
const dnsRowRenderer = createDnsRowRenderer();
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{dnsRowRenderer.isInstance(mockEndpointNetworkLookupRequestedEvent) &&
|
||||
dnsRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointNetworkLookupRequestedEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointasked forlogging.googleapis.comwith question typeAviagoogle_osconfig_agent.exe(3272)dns'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an endpoint network lookup_result event', () => {
|
||||
const dnsRowRenderer = createDnsRowRenderer();
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
{dnsRowRenderer.isInstance(mockEndpointNetworkLookupResultEvent) &&
|
||||
dnsRowRenderer.renderRow({
|
||||
browserFields: mockBrowserFields,
|
||||
data: mockEndpointNetworkLookupResultEvent,
|
||||
timelineId: 'test',
|
||||
})}
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.text()).toEqual(
|
||||
'SYSTEM\\NT AUTHORITY@win2019-endpointasked forlogging.googleapis.comwith question typeAAAAviagoogle_osconfig_agent.exe(3272)dns'
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders an Endgame DNS request_event', () => {
|
||||
const requestEvent = {
|
||||
...mockEndgameDnsRequest,
|
||||
|
|
|
@ -63,11 +63,11 @@ export const createEndgameProcessRowRenderer = ({
|
|||
isInstance: (ecs) => {
|
||||
const action: string | null | undefined = get('event.action[0]', ecs);
|
||||
const category: string | null | undefined = get('event.category[0]', ecs);
|
||||
const dataset: string | null | undefined = get('event.dataset[0]', ecs);
|
||||
return (
|
||||
category != null &&
|
||||
category.toLowerCase() === 'process' &&
|
||||
action != null &&
|
||||
action.toLowerCase() === actionName
|
||||
(category?.toLowerCase() === 'process' ||
|
||||
dataset?.toLowerCase() === 'endpoint.events.process') &&
|
||||
action?.toLowerCase() === actionName
|
||||
);
|
||||
},
|
||||
renderRow: ({ browserFields, data, timelineId }) => (
|
||||
|
@ -98,8 +98,7 @@ export const createFimRowRenderer = ({
|
|||
const dataset: string | null | undefined = get('event.dataset[0]', ecs);
|
||||
return (
|
||||
isFileEvent({ eventCategory: category, eventDataset: dataset }) &&
|
||||
action != null &&
|
||||
action.toLowerCase() === actionName
|
||||
action?.toLowerCase() === actionName
|
||||
);
|
||||
},
|
||||
renderRow: ({ browserFields, data, timelineId }) => (
|
||||
|
@ -181,11 +180,11 @@ export const createSecurityEventRowRenderer = ({
|
|||
isInstance: (ecs) => {
|
||||
const category: string | null | undefined = get('event.category[0]', ecs);
|
||||
const action: string | null | undefined = get('event.action[0]', ecs);
|
||||
const dataset: string | null | undefined = get('event.dataset[0]', ecs);
|
||||
return (
|
||||
category != null &&
|
||||
category.toLowerCase() === 'authentication' &&
|
||||
action != null &&
|
||||
action.toLowerCase() === actionName
|
||||
(category?.toLowerCase() === 'authentication' ||
|
||||
dataset?.toLowerCase() === 'endpoint.events.security') &&
|
||||
action?.toLowerCase() === actionName
|
||||
);
|
||||
},
|
||||
renderRow: ({ browserFields, data, timelineId }) => (
|
||||
|
@ -234,6 +233,11 @@ const endgameProcessStartedRowRenderer = createEndgameProcessRowRenderer({
|
|||
text: i18n.PROCESS_STARTED,
|
||||
});
|
||||
|
||||
const endpointProcessStartRowRenderer = createEndgameProcessRowRenderer({
|
||||
actionName: 'start',
|
||||
text: i18n.PROCESS_STARTED,
|
||||
});
|
||||
|
||||
const systemProcessStoppedRowRenderer = createGenericFileRowRenderer({
|
||||
actionName: 'process_stopped',
|
||||
text: i18n.PROCESS_STOPPED,
|
||||
|
@ -244,11 +248,21 @@ const endgameProcessTerminationRowRenderer = createEndgameProcessRowRenderer({
|
|||
text: i18n.TERMINATED_PROCESS,
|
||||
});
|
||||
|
||||
const endpointProcessEndRowRenderer = createEndgameProcessRowRenderer({
|
||||
actionName: 'end',
|
||||
text: i18n.TERMINATED_PROCESS,
|
||||
});
|
||||
|
||||
const endgameFileCreateEventRowRenderer = createFimRowRenderer({
|
||||
actionName: 'file_create_event',
|
||||
text: i18n.CREATED_FILE,
|
||||
});
|
||||
|
||||
const endpointFileCreationEventRowRenderer = createFimRowRenderer({
|
||||
actionName: 'creation',
|
||||
text: i18n.CREATED_FILE,
|
||||
});
|
||||
|
||||
const fimFileCreateEventRowRenderer = createFimRowRenderer({
|
||||
actionName: 'created',
|
||||
text: i18n.CREATED_FILE,
|
||||
|
@ -259,6 +273,11 @@ const endgameFileDeleteEventRowRenderer = createFimRowRenderer({
|
|||
text: i18n.DELETED_FILE,
|
||||
});
|
||||
|
||||
const endpointFileDeletionEventRowRenderer = createFimRowRenderer({
|
||||
actionName: 'deletion',
|
||||
text: i18n.DELETED_FILE,
|
||||
});
|
||||
|
||||
const fimFileDeletedEventRowRenderer = createFimRowRenderer({
|
||||
actionName: 'deleted',
|
||||
text: i18n.DELETED_FILE,
|
||||
|
@ -284,6 +303,11 @@ const endgameIpv4ConnectionAcceptEventRowRenderer = createSocketRowRenderer({
|
|||
text: i18n.ACCEPTED_A_CONNECTION_VIA,
|
||||
});
|
||||
|
||||
const endpointConnectionAcceptedEventRowRenderer = createSocketRowRenderer({
|
||||
actionName: 'connection_accepted',
|
||||
text: i18n.ACCEPTED_A_CONNECTION_VIA,
|
||||
});
|
||||
|
||||
const endgameIpv6ConnectionAcceptEventRowRenderer = createSocketRowRenderer({
|
||||
actionName: 'ipv6_connection_accept_event',
|
||||
text: i18n.ACCEPTED_A_CONNECTION_VIA,
|
||||
|
@ -294,6 +318,11 @@ const endgameIpv4DisconnectReceivedEventRowRenderer = createSocketRowRenderer({
|
|||
text: i18n.DISCONNECTED_VIA,
|
||||
});
|
||||
|
||||
const endpointDisconnectReceivedEventRowRenderer = createSocketRowRenderer({
|
||||
actionName: 'disconnect_received',
|
||||
text: i18n.DISCONNECTED_VIA,
|
||||
});
|
||||
|
||||
const endgameIpv6DisconnectReceivedEventRowRenderer = createSocketRowRenderer({
|
||||
actionName: 'ipv6_disconnect_received_event',
|
||||
text: i18n.DISCONNECTED_VIA,
|
||||
|
@ -315,6 +344,10 @@ const endgameUserLogonRowRenderer = createSecurityEventRowRenderer({
|
|||
actionName: 'user_logon',
|
||||
});
|
||||
|
||||
const endpointUserLogOnRowRenderer = createSecurityEventRowRenderer({
|
||||
actionName: 'log_on',
|
||||
});
|
||||
|
||||
const dnsRowRenderer = createDnsRowRenderer();
|
||||
|
||||
const systemExistingUserRowRenderer = createGenericSystemRowRenderer({
|
||||
|
@ -357,6 +390,10 @@ const systemLogoutRowRenderer = createGenericSystemRowRenderer({
|
|||
text: i18n.LOGGED_OUT,
|
||||
});
|
||||
|
||||
const endpointUserLogOffRowRenderer = createSecurityEventRowRenderer({
|
||||
actionName: 'log_off',
|
||||
});
|
||||
|
||||
const systemProcessErrorRowRenderer = createGenericFileRowRenderer({
|
||||
actionName: 'process_error',
|
||||
text: i18n.PROCESS_ERROR,
|
||||
|
@ -408,15 +445,22 @@ export const systemRowRenderers: RowRenderer[] = [
|
|||
endgameAdminLogonRowRenderer,
|
||||
endgameExplicitUserLogonRowRenderer,
|
||||
endgameFileCreateEventRowRenderer,
|
||||
endpointFileCreationEventRowRenderer,
|
||||
endgameFileDeleteEventRowRenderer,
|
||||
endpointFileDeletionEventRowRenderer,
|
||||
endgameIpv4ConnectionAcceptEventRowRenderer,
|
||||
endpointConnectionAcceptedEventRowRenderer,
|
||||
endgameIpv6ConnectionAcceptEventRowRenderer,
|
||||
endgameIpv4DisconnectReceivedEventRowRenderer,
|
||||
endpointDisconnectReceivedEventRowRenderer,
|
||||
endgameIpv6DisconnectReceivedEventRowRenderer,
|
||||
endgameProcessStartedRowRenderer,
|
||||
endpointProcessStartRowRenderer,
|
||||
endgameProcessTerminationRowRenderer,
|
||||
endpointProcessEndRowRenderer,
|
||||
endgameUserLogoffRowRenderer,
|
||||
endgameUserLogonRowRenderer,
|
||||
endpointUserLogOnRowRenderer,
|
||||
fimFileCreateEventRowRenderer,
|
||||
fimFileDeletedEventRowRenderer,
|
||||
systemAcceptedRowRenderer,
|
||||
|
@ -431,6 +475,7 @@ export const systemRowRenderers: RowRenderer[] = [
|
|||
systemInvalidRowRenderer,
|
||||
systemLoginRowRenderer,
|
||||
systemLogoutRowRenderer,
|
||||
endpointUserLogOffRowRenderer,
|
||||
systemPackageInstalledRowRenderer,
|
||||
systemPackageUpdatedRowRenderer,
|
||||
systemPackageRemovedRowRenderer,
|
||||
|
|
|
@ -162,9 +162,12 @@ export const TIMELINE_EVENTS_FIELDS = [
|
|||
'tls.server_certificate.fingerprint.sha1',
|
||||
'user.domain',
|
||||
'winlog.event_id',
|
||||
'process.exit_code',
|
||||
'process.hash.md5',
|
||||
'process.hash.sha1',
|
||||
'process.hash.sha256',
|
||||
'process.parent.name',
|
||||
'process.parent.pid',
|
||||
'process.pid',
|
||||
'process.name',
|
||||
'process.ppid',
|
||||
|
|
Loading…
Reference in a new issue