From f44a70f30b504809457fef8ba7e82ed41ca25db8 Mon Sep 17 00:00:00 2001 From: Andrew Goldstein Date: Wed, 17 Feb 2021 01:06:18 -0700 Subject: [PATCH] [Security Solution] [Timeline] Endpoint row renderers (2nd batch) (#91446) (#91601) ## [Security Solution] [Timeline] Endpoint row renderers (2nd batch) This PR implements the 2nd batch of Endpoint row renderers, **including the new Ransomware alerts**, by adding new row renderers for the following Endpoint alerts and events: | event.dataset | event.type | event.category | event.action | |--------------------------|------------|----------------|-----------------| | endpoint.alerts | denied | file | creation | | endpoint.alerts | allowed | file | creation | | endpoint.alerts | denied | file | files-encrypted | | endpoint.alerts | allowed | file | files-encrypted | | endpoint.alerts | denied | file | modification | | endpoint.alerts | allowed | file | modification | | endpoint.alerts | denied | file | rename | | endpoint.alerts | allowed | file | rename | | endpoint.alerts | denied | process | execution | | endpoint.alerts | allowed | process | execution | | endpoint.events.file | change | file | modification | | endpoint.events.file | change | file | overwrite | | endpoint.events.file | change | file | rename | | endpoint.events.registry | change | registry | modification | | endpoint.events.library | start | library | load | | endpoint.events.network | protocol | network | http_request | | endpoint.events.process | start | process | exec | | endpoint.events.process | start | process | fork | Other updates: - All row renders will now only display the `file.hash.sha256` and `process.hash.sha256`. (The `sha1` and `md5` hashes will no longer be displayed) ## Malware File Creation Prevented alert Malware File Creation Prevented alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: denied and event.category: file and event.action: creation ``` ### Sample Malware File Creation Prevented alert ![malware_file_creation_prevented](https://user-images.githubusercontent.com/4459398/107970084-e4762b00-6f6d-11eb-88c8-c9fd474d2de4.png) `win2019-endpoint-1` was prevented from creating a malicious file `6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmp` in `C:\Users\sean\Downloads\6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmp` via `chrome.exe` (`8944`) `C:\Program Files\Google\Chrome\Application\chrome.exe` via parent process `explorer.exe` (`1008`) with result `success` `7cc42618e580f233fee47e82312cc5c3476cb5de9219ba3f9eb7f99ac0659c30` ### Fields in a Malware File Creation Prevented alert `user.name` \ `user.domain` @ `host.name` was prevented from creating a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Malware File Creation Detected alert Malware File Creation Detected alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: allowed and event.category: file and event.action: creation ``` ### Sample Malware File Creation Detected alert ![malware_file_creation_detected](https://user-images.githubusercontent.com/4459398/107970897-f7d5c600-6f6e-11eb-83a8-7324e34506c1.png) `DESKTOP-1` was detected creating a malicious file `mimikatz_write.exe` in `C:\temp\mimikatz_write.exe` via `python.exe` (`4400`) `C:\Python27\python.exe` `main.py` `-a` `execute` `-p` `c:\temp` via parent process `pythonservice.exe` (`2936`) with result `success` `263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0` ### Fields in a Malware File Creation Detected alert `user.name` \ `user.domain` @ `host.name` was detected creating a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Ransomware Files Encrypted Prevented alert Ransomware Files Encrypted Prevented alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: denied and event.category: file and event.action: files-encrypted ``` ### Sample Ransomware Files Encrypted Prevented alert ![ransomware_files-encrypted_prevented](https://user-images.githubusercontent.com/4459398/107973327-56e90a00-6f72-11eb-8337-8bb15bd24ad2.png) `DESKTOP-1` ransomware was prevented from encrypting files via `powershell.exe` (`6056`) `powershell.exe` `-file` `mock_ransomware_v3.ps1` via parent process `cmd.exe` (`10680`) with result `success` `e9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7` ### Fields in a Ransomware Files Encrypted Prevented alert `user.name` \ `user.domain` @ `host.name` ransomware was prevented from encrypting files via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `process.hash.sha256` ## Ransomware Files Encrypted Detected alert Ransomware Files Encrypted Detected alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: allowed and event.category: file and event.action: files-encrypted ``` ### Sample Ransomware Files Encrypted Detected alert ![ransomware_files-encrypted_detected](https://user-images.githubusercontent.com/4459398/107976086-42a70c00-6f76-11eb-8977-74ad47191d71.png) `DESKTOP-1` ransomware was detected encrypting files via `powershell.exe` (`4684`) `powershell.exe` `-file` `mock_ransomware_v3.ps1` via parent process `cmd.exe` (`8616`) with result `success` `e9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7` ### Fields in a Ransomware Files Encrypted Detected alert `user.name` \ `user.domain` @ `host.name` ransomware was detected encrypting files via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `process.hash.sha256` ## Malware File Modification Prevented alert Malware File Modification Prevented alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: denied and event.category: file and event.action: modification ``` ### Sample Malware File Modification Prevented alert ![malware_file_modification_prevented](https://user-images.githubusercontent.com/4459398/107979686-3a51cf80-6f7c-11eb-92ff-f164536f6c70.png) `win2019-endpoint-1` was prevented from modifying a malicious file `mimikatz - Copy.exe` in `C:\Users\sean\Downloads\mimikatz_trunk (1)\x64\mimikatz - Copy.exe` via `explorer.exe` (`1008`) `C:\Windows\Explorer.EXE` via parent process `C:\Windows\System32\userinit.exe` (`356`) with result `success` `31eb1de7e840a342fd468e558e5ab627bcb4c542a8fe01aec4d5ba01d539a0fc` ### Fields in a Malware File Modification Prevented alert `user.name` \ `user.domain` @ `host.name` was prevented from modifying a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Malware File Modification Detected alert Malware File Modification Detected alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: allowed and event.category: file and event.action: modification ``` ### Sample Malware File Modification Detected alert ![malware_file_modification_detected](https://user-images.githubusercontent.com/4459398/107980920-55bdda00-6f7e-11eb-9d08-2aa02253a958.png) `mac-1.local` was detected modifying a malicious file `aircrack` in `/private/var/root/write_malware/modules/write_malware/aircrack` via `Python` (`5995`) `/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python` `main.py` `-a` `modify` via parent process `Python` (`97`) with result `success` `f0954d9673878b2223b00b7ec770c7b438d876a9bb44ec78457e5c618f31f52b` ### Fields in a Malware File Modification Detected alert `user.name` \ `user.domain` @ `host.name` was detected modifying a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Malware File Rename Prevented alert Malware File Rename Prevented alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: denied and event.category: file and event.action: rename ``` ### Sample Malware File Rename Prevented alert ![malware_file_rename_prevented](https://user-images.githubusercontent.com/4459398/107981991-6e2ef400-6f80-11eb-8d48-3c9aa48c5d72.png) `win2019-endpoint-1` was prevented from renaming a malicious file `23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe` in `C:\Users\sean\Downloads\23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe` via `explorer.exe` (`1008`) `C:\Windows\Explorer.EXE` via parent process `C:\Windows\System32\userinit.exe` (`356`) with result `success` `23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97` ### Fields in a Malware File Rename Prevented alert `user.name` \ `user.domain` @ `host.name` was prevented from renaming a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Malware File Rename Detected alert Malware File Rename Detected alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: allowed and event.category: file and event.action: rename ``` ### Sample Malware File Rename Detected alert ![malware_file_rename_detected](https://user-images.githubusercontent.com/4459398/107983209-ab948100-6f82-11eb-893f-359fa0bd3a19.png) `win2019-endpoint-1` was detected renaming a malicious file `23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe` in `C:\Users\sean\Downloads\23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe` via `explorer.exe` (`1008`) `C:\Windows\Explorer.EXE` via parent process `C:\Windows\System32\userinit.exe` (`356`) with result `success` `23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97` ### Fields in a Malware File Rename Detected alert `user.name` \ `user.domain` @ `host.name` was detected renaming a malicious file `file.name` in `file.path` via `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `file.hash.sha256` ## Malware Process Execution Prevented alert Malware Process Execution Prevented alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: denied and event.category: process and event.action: execution ``` ### Sample Malware Process Execution Prevented alert ![malware_process_execution_prevented](https://user-images.githubusercontent.com/4459398/107986073-8b67c080-6f88-11eb-89a5-95434639631e.png) `win2019-endpoint-1` was prevented from executing a malicious process `C:\Users\sean\Downloads\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe` (`6920`) `C:\Users\sean\Downloads\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe` via parent process `explorer.exe` (`1008`) with result `success` `3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb` ### Fields in a Sample Malware Process Execution Prevented alert `host.name` was prevented from executing a malicious process `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `process.hash.sha256` ## Malware Process Execution Detected alert Malware Process Execution Detected alerts with the following `event.dataset`, `event.type`, `event.category`, and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.alerts and event.type: allowed and event.category: process and event.action: execution ``` ### Sample Malware Process Execution Detected alert ![malware_process_execution_detected](https://user-images.githubusercontent.com/4459398/107986475-590a9300-6f89-11eb-9dbc-373efe005c85.png) `DESKTOP-1` was detected executing a malicious process `mimikatz_write.exe` (`8668`) `c:\temp\mimikatz_write.exe` via parent process `python.exe` (`4400`) with result `success` `263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0` ### Fields in a Sample Malware Process Execution Detected alert `host.name` was detected executing a malicious process `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) with result `event.outcome` `process.hash.sha256` ## File (FIM) Modification events Endpoint File (FIM) Modification 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: modification ``` ### Sample rendered File (FIM) Modification event Each field with `this formatting` is draggable (to pivot a search) in the row-rendered event: ![file_modification](https://user-images.githubusercontent.com/4459398/106680191-641df600-657b-11eb-974e-e2afbc7698a3.png) `admin` @ `test-Mac.local` modified a file `.dat.nosync01a5.6hoWv1` in `/Users/admin/Library/Application Support/CrashReporter/.dat.nosync01a5.6hoWv1` via `diagnostics_agent` `(421)` ### Fields in a File (FIM) Modification event `user.name` \ `user.domain` @ `host.name` modified a file `file.name` in `file.path` via `process.name` `(process.pid)` ## File (FIM) Overwrite events Endpoint File (FIM) Overwrite 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: overwrite ``` ### Sample rendered File (FIM) Overwrite event ![file_overwrite](https://user-images.githubusercontent.com/4459398/106675692-c9b9b480-6572-11eb-9f78-fb0b4bf0b05d.png) `LOCAL SERVICE` \ `NT AUTHORITY` @ `windows-endpoint-1` overwrote a file `lastalive0.dat` in `C:\Windows\ServiceState\EventLog\Data\lastalive0.dat` via `svchost.exe` `(1228)` ### Fields in a File (FIM) Overwrite event `user.name` \ `user.domain` @ `host.name` overwrote a file `file.name` in `file.path` via `process.name` `(process.pid)` ## File (FIM) Rename events Endpoint File (FIM) Rename 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: rename ``` ### Sample rendered File (FIM) Rename event ![file_rename](https://user-images.githubusercontent.com/4459398/106534633-c4e0fc00-64b1-11eb-8213-494b51e8cdf9.png) `LOCAL SERVICE` \ `NT AUTHORITY` @ `windows-endpoint-1` renamed a file `SRU.log` in `C:\Windows\System32\sru\SRU.log` from its original path `C:\Windows\System32\sru\SRUtmp.log` via `svchost.exe` `(1204)` ### Fields in a File (FIM) Rename event `user.name` \ `user.domain` @ `host.name` renamed a file `file.name` in `file.path` from its original path `file.Ext.original.path` via `process.name` `(process.pid)` ## Registry Modification events Registry Modification events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.registry and event.action: modification ``` ### Sample Registry Modification event ![registry_modification](https://user-images.githubusercontent.com/4459398/107091637-56f14900-67bf-11eb-9c8b-7f748e848bac.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint-1` modified registry key `SOFTWARE\WOW6432Node\Google\Update\ClientState\{430FD4D0-B729-4F61-AA34-91526481799D}\CurrentState` with new value `HKLM\SOFTWARE\WOW6432Node\Google\Update\ClientState\{430FD4D0-B729-4F61-AA34-91526481799D}\CurrentState\StateValue` via `GoogleUpdate.exe` `(7408)` ### Fields in a Registry Modification event `user.name` \ `user.domain` @ `host.name` modified registry key `registry.key` with new value `registry.path` via `process.name` `(process.pid)` ## Library Load events Library Load events with the following `event.dataset` and `event.action` will be rendered in Timeline via row renderers: ``` event.dataset: endpoint.events.library and event.action: load ``` ### Sample Library Load event ![library_load](https://user-images.githubusercontent.com/4459398/107261734-ea638d80-69fc-11eb-8b2c-0a4f453b3f95.png) `SYSTEM` \ `NT AUTHORITY` @ `win2019-endpoint-1` loaded library `bcrypt.dll` in `C:\Windows\System32\bcrypt.dll` via `sshd.exe` `(9644)` `e70f5d8f87aab14e3160227d38387889befbe37fa4f8f5adc59eff52804b35fd` `2c4ba5c1482987d50a182bad915f52cd6611ee63` `00439016776de367bad087d739a03797` ### Fields in a Library Load event `user.name` \ `user.domain` @ `host.name` loaded library `file.name` in `file.path` via `process.name` `(process.pid)` `file.hash.sha256` `file.hash.sha1` `file.hash.md5` ## HTTP Request events HTTP Request 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: http_request ``` ### Sample HTTP Request event ![http_request](https://user-images.githubusercontent.com/4459398/107546591-c5505580-6b89-11eb-8081-fe492312cc12.png) Network HTTP Request 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` @ `win2019-endpoint-1` made a http request via `svchost.exe` `(2232)` ### Fields in a HTTP Request event `user.name` \ `user.domain` @ `host.name` made a http request via `process.name` `(process.pid)` ## Process Exec events Endpoint Process Exec 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: exec ``` ### Sample rendered Process Exec event ![process_exec](https://user-images.githubusercontent.com/4459398/107989163-de447680-6f8e-11eb-88e9-d8c72d77bc2d.png) `admin` @ `test-mac.local` executed process `mdworker_shared` (`4454`) `/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared` `-s` `mdworker` `-c` `MDSImporterWorker` `-m` `com.apple.mdworker.shared` via parent process `launchd` (`1`) `4bc018ac461706496302d1faab0a8bb39aad974eb432758665103165f3a2dd2b` ### Fields in a Process Exec event The following fields will be used to render a Process Exec event: `user.name` @ `host.name` executed process `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) `process.hash.sha256` ## Process Fork events Endpoint Process Fork 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: fork ``` ### Sample rendered Process Fork event ![process_fork](https://user-images.githubusercontent.com/4459398/107990678-29ac5400-6f92-11eb-893f-59bafa79cd53.png) `admin` @ `test-mac.local` forked process `zoom.us` (`4042`) `/Applications/zoom.us.app/Contents/MacOS/zoom.us` via parent process `zoom.us` (`3961`) `cbf3d059cc9f9c0adff5ef15bf331b95ab381837fa0adecd965a41b5846f4bd4` ### Fields in a Process Fork event The following fields will be used to render a Process Exec event: `user.name` @ `host.name` forked process `process.name` (`process.pid`) `process.args` via parent process `process.parent.name` (`process.parent.pid`) `process.hash.sha256` --- .../common/ecs/file/index.ts | 10 +- .../security_solution/common/ecs/index.ts | 2 + .../common/ecs/process/index.ts | 1 + .../common/ecs/registry/index.ts | 13 + .../common/types/timeline/index.ts | 3 + .../common/mock/mock_endgame_ecs_data.ts | 879 ++++++++++++++++++ .../public/common/mock/mock_timeline_data.ts | 183 ++++ .../public/graphql/introspection.json | 13 + .../security_solution/public/graphql/types.ts | 3 + .../row_renderers_browser/catalog/index.tsx | 24 + .../catalog/translations.ts | 34 + .../row_renderers_browser/examples/alerts.tsx | 34 + .../row_renderers_browser/examples/index.tsx | 3 + .../examples/library.tsx | 31 + .../examples/registry.tsx | 31 + .../body/renderers/file_draggable.test.tsx | 10 +- .../body/renderers/file_draggable.tsx | 28 +- .../body/renderers/file_hash.test.tsx | 60 ++ .../timeline/body/renderers/file_hash.tsx | 46 + .../timeline/body/renderers/helpers.test.tsx | 14 +- .../timeline/body/renderers/helpers.tsx | 26 +- .../body/renderers/process_hash.test.tsx | 70 +- .../timeline/body/renderers/process_hash.tsx | 70 +- .../registry/registry_event_details.test.tsx | 48 + .../registry/registry_event_details.tsx | 58 ++ .../registry_event_details_line.test.tsx | 135 +++ .../registry/registry_event_details_line.tsx | 133 +++ .../body/renderers/registry/translations.ts | 22 + .../generic_file_details.test.tsx.snap | 2 + .../system/generic_file_details.test.tsx | 244 ++--- .../renderers/system/generic_file_details.tsx | 68 +- .../system/generic_row_renderer.test.tsx | 520 ++++++++++- .../renderers/system/generic_row_renderer.tsx | 235 +++++ .../body/renderers/system/translations.ts | 126 +++ .../timeline/body/renderers/translations.ts | 7 + .../server/graphql/timeline/schema.gql.ts | 3 + .../security_solution/server/graphql/types.ts | 3 + .../timeline/factory/events/all/constants.ts | 3 + 38 files changed, 2905 insertions(+), 290 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/ecs/registry/index.ts create mode 100644 x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/alerts.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/library.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/registry.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/translations.ts diff --git a/x-pack/plugins/security_solution/common/ecs/file/index.ts b/x-pack/plugins/security_solution/common/ecs/file/index.ts index 06abc7fd87541..5e409b1095cf5 100644 --- a/x-pack/plugins/security_solution/common/ecs/file/index.ts +++ b/x-pack/plugins/security_solution/common/ecs/file/index.ts @@ -5,14 +5,22 @@ * 2.0. */ +interface Original { + name?: string[]; + path?: string[]; +} + export interface CodeSignature { subject_name: string[]; trusted: string[]; } export interface Ext { - code_signature: CodeSignature[] | CodeSignature; + code_signature?: CodeSignature[] | CodeSignature; + original?: Original; } export interface Hash { + md5?: string[]; + sha1?: string[]; sha256: string[]; } diff --git a/x-pack/plugins/security_solution/common/ecs/index.ts b/x-pack/plugins/security_solution/common/ecs/index.ts index e3bcd11097cf7..fcd7f7aa33643 100644 --- a/x-pack/plugins/security_solution/common/ecs/index.ts +++ b/x-pack/plugins/security_solution/common/ecs/index.ts @@ -15,6 +15,7 @@ import { FileEcs } from './file'; import { GeoEcs } from './geo'; import { HostEcs } from './host'; import { NetworkEcs } from './network'; +import { RegistryEcs } from './registry'; import { RuleEcs } from './rule'; import { SignalEcs } from './signal'; import { SourceEcs } from './source'; @@ -40,6 +41,7 @@ export interface Ecs { geo?: GeoEcs; host?: HostEcs; network?: NetworkEcs; + registry?: RegistryEcs; rule?: RuleEcs; signal?: SignalEcs; source?: SourceEcs; diff --git a/x-pack/plugins/security_solution/common/ecs/process/index.ts b/x-pack/plugins/security_solution/common/ecs/process/index.ts index 3a8ccc309aecb..931adf2dd70b8 100644 --- a/x-pack/plugins/security_solution/common/ecs/process/index.ts +++ b/x-pack/plugins/security_solution/common/ecs/process/index.ts @@ -28,6 +28,7 @@ export interface ProcessHashData { export interface ProcessParentData { name?: string[]; + pid?: number[]; } export interface Thread { diff --git a/x-pack/plugins/security_solution/common/ecs/registry/index.ts b/x-pack/plugins/security_solution/common/ecs/registry/index.ts new file mode 100644 index 0000000000000..c756fb139199e --- /dev/null +++ b/x-pack/plugins/security_solution/common/ecs/registry/index.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface RegistryEcs { + hive?: string[]; + key?: string[]; + path?: string[]; + value?: string[]; +} diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 58e3b9824d8fd..c954bc1859086 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -180,10 +180,13 @@ export type TimelineStatusLiteralWithNull = runtimeTypes.TypeOf< >; export enum RowRendererId { + alerts = 'alerts', auditd = 'auditd', auditd_file = 'auditd_file', + library = 'library', netflow = 'netflow', plain = 'plain', + registry = 'registry', suricata = 'suricata', system = 'system', system_dns = 'system_dns', diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_endgame_ecs_data.ts b/x-pack/plugins/security_solution/public/common/mock/mock_endgame_ecs_data.ts index 1082b5f9474e5..3400844e671b3 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_endgame_ecs_data.ts +++ b/x-pack/plugins/security_solution/public/common/mock/mock_endgame_ecs_data.ts @@ -343,6 +343,885 @@ export const mockEndpointFileDeletionEvent: Ecs = { _id: 'mnXHO3cBPmkOXwyNlyv_', }; +export const mockEndpointFileCreationMalwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['efca0a88adab8b92e4a333b56db5fbaa'], + sha256: ['8c177f6129dddbd36cae196ef9d9eb71f50cee44640068f24830e83d6a9dd1d0'], + sha1: ['e55e587058112c60d015994424f70a7a8e78afb1'], + }, + parent: { + name: ['explorer.exe'], + pid: [1008], + }, + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTg5NDQtMTMyNDkwNjg0NzIuNzM4OTY4NTAw', + ], + executable: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'], + name: ['chrome.exe'], + pid: [8944], + args: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1518)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1518)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1518)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + name: ['win2019-endpoint-1'], + }, + event: { + category: ['malware', 'intrusion_detection', 'file'], + outcome: ['success'], + code: ['malicious_file'], + action: ['creation'], + id: ['LsuMZVr+sdhvehVM++++Ic8J'], + kind: ['alert'], + module: ['endpoint'], + type: ['info', 'creation', 'denied'], + dataset: ['endpoint.alerts'], + }, + file: { + path: ['C:\\Users\\sean\\Downloads\\6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmp'], + owner: ['sean'], + hash: { + md5: ['c1f8d2b73b4c2488f95e7305f0421bdf'], + sha256: ['7cc42618e580f233fee47e82312cc5c3476cb5de9219ba3f9eb7f99ac0659c30'], + sha1: ['542b2796e9f57a92504f852b6698148bba9ff289'], + }, + name: ['6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmp'], + extension: ['tmp'], + size: [196608], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2020-11-05T16:48:19.923Z', + message: ['Malware Prevention Alert'], + _id: 'dGZQmXUB-o9SpDeMqvln', +}; + +export const mockEndpointFileCreationMalwareDetectionAlert: Ecs = { + process: { + hash: { + md5: ['16d6a536bb2115dcbd16011e6991a9fd'], + sha256: ['6637eca55fedbabc510168f0c4696d41971c89e5d1fb440f2f9391e6ab0e8f54'], + sha1: ['05cc6d37603ca9076f3baf4dc421500c5cf69e4c'], + }, + entity_id: [ + 'Yjk3ZWYwODktNzYyZi00ZTljLTg3OWMtNmQ5MDM1ZjBmYTUzLTQ0MDAtMTMyNDM2MTgwMzIuMjA0MzMxMDA=', + ], + executable: ['C:\\Python27\\python.exe'], + parent: { + name: ['pythonservice.exe'], + pid: [2936], + }, + name: ['python.exe'], + args: ['C:\\Python27\\python.exe', 'main.py', '-a,execute', '-p', 'c:\\temp'], + pid: [4400], + }, + host: { + os: { + full: ['Windows 10 Pro 1903 (10.0.18362.1016)'], + name: ['Windows'], + version: ['1903 (10.0.18362.1016)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1903 (10.0.18362.1016)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + ip: ['10.1.2.3'], + id: ['c85e6c40-d4a1-db21-7458-2565a6b857f3'], + architecture: ['x86_64'], + name: ['DESKTOP-1'], + }, + file: { + path: ['C:\\temp\\mimikatz_write.exe'], + owner: ['Administrators'], + hash: { + md5: ['cc52aebdf82048364119f117f52dbba0'], + sha256: ['263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0'], + sha1: ['c929f6ff2d6d1085ee69625cd8efb92101a0e906'], + }, + name: ['mimikatz_write.exe'], + extension: ['exe'], + size: [1265456], + }, + event: { + id: ['Lp/73XQ38EF48a6i+++++5Ds'], + module: ['endpoint'], + category: ['malware', 'intrusion_detection', 'file'], + outcome: ['success'], + code: ['malicious_file'], + action: ['creation'], + kind: ['signal'], + type: ['info', 'creation', 'allowed'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Malware Detection Alert'], + timestamp: '2020-09-03T15:51:50.209Z', + _id: '51e04f7dad15fe394a3f7ed582ad4528c8ce62948e315571fc3388befd9aa0e6', +}; + +export const mockEndpointFilesEncryptedRansomwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['85bc517e37fe24f909e4378a46a4b567'], + sha256: ['e9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7'], + sha1: ['10a3671c0fbc2bce14fc94891e87e2f4ba07e0df'], + }, + parent: { + name: ['cmd.exe'], + pid: [10680], + }, + entity_id: [ + 'OTI1MTRiMTYtMWJkNi05NzljLWE2MDMtOTgwY2ZkNzQ4M2IwLTYwNTYtMTMyNTczODEzMzYuNzIxNTIxODAw', + ], + name: ['powershell.exe'], + pid: [6056], + args: ['powershell.exe', '-file', 'mock_ransomware_v3.ps1'], + }, + host: { + os: { + full: ['Windows 7 Enterprise Service Pack 1 (6.1.7601)'], + name: ['Windows'], + version: ['Service Pack 1 (6.1.7601)'], + platform: ['windows'], + family: ['windows'], + kernel: ['Service Pack 1 (6.1.7601)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['c6bb2832-d58c-4c57-9d1f-3b102ea74d46'], + name: ['DESKTOP-1'], + }, + event: { + category: ['malware', 'intrusion_detection', 'process', 'file'], + outcome: ['success'], + code: ['ransomware'], + action: ['files-encrypted'], + id: ['M0A1DXHIg6/kaeku+++++1Gv'], + kind: ['alert'], + module: ['endpoint'], + type: ['info', 'start', 'change', 'denied'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2021-02-09T21:55:48.941Z', + message: ['Ransomware Prevention Alert'], + _id: 'BfvLiHcBVXUk10dUK1Pk', +}; + +export const mockEndpointFilesEncryptedRansomwareDetectionAlert: Ecs = { + process: { + hash: { + md5: ['85bc517e37fe24f909e4378a46a4b567'], + sha256: ['e9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7'], + sha1: ['10a3671c0fbc2bce14fc94891e87e2f4ba07e0df'], + }, + parent: { + name: ['cmd.exe'], + pid: [8616], + }, + entity_id: [ + 'MDAwODRkOTAtZDRhOC1kOTZhLWVmYWItZDU1ZWFhNDY1N2M2LTQ2ODQtMTMyNTc0NjE2MzEuNDM3NDUzMDA=', + ], + executable: ['C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'], + name: ['powershell.exe'], + pid: [4684], + args: ['powershell.exe', '-file', 'mock_ransomware_v3.ps1'], + }, + host: { + os: { + full: ['Windows 7 Enterprise Service Pack 1 (6.1.7601)'], + name: ['Windows'], + version: ['Service Pack 1 (6.1.7601)'], + platform: ['windows'], + family: ['windows'], + kernel: ['Service Pack 1 (6.1.7601)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['c6bb2832-d58c-4c57-9d1f-3b102ea74d46'], + name: ['DESKTOP-1'], + }, + event: { + category: ['malware', 'intrusion_detection', 'process', 'file'], + code: ['ransomware'], + action: ['files-encrypted'], + id: ['M0ExfR/BggxoHQ1e+++++1Zv'], + kind: ['alert'], + module: ['endpoint'], + type: ['info', 'start', 'change', 'allowed'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2021-02-10T20:14:03.927Z', + message: ['Ransomware Detection Alert'], + _id: 'enyUjXcBxUk8qlINZEJr', +}; + +export const mockEndpointFileModificationMalwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['47ea9e07b7dbfbeba368bd95a3a2d25b'], + sha256: ['f45557c0b57dec4c000d8cb7d7068c8a4dccf392de740501b1046994460d77ea'], + sha1: ['da714f84a7bbaee2be9f1ca0262aca649657cf3e'], + }, + parent: { + name: ['C:\\Windows\\System32\\userinit.exe'], + pid: [356], + }, + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTEwMDgtMTMyNDc1Njk3ODUuODA0NzQyMDA=', + ], + executable: ['C:\\Windows\\explorer.exe'], + name: ['explorer.exe'], + pid: [1008], + args: ['C:\\Windows\\Explorer.EXE'], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1518)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1518)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1518)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + name: ['win2019-endpoint-1'], + }, + file: { + path: ['C:\\Users\\sean\\Downloads\\mimikatz_trunk (1)\\x64\\mimikatz - Copy.exe'], + owner: ['sean'], + hash: { + md5: ['a3cb3b02a683275f7e0a0f8a9a5c9e07'], + sha256: ['31eb1de7e840a342fd468e558e5ab627bcb4c542a8fe01aec4d5ba01d539a0fc'], + sha1: ['d241df7b9d2ec0b8194751cd5ce153e27cc40fa4'], + }, + name: ['mimikatz - Copy.exe'], + extension: ['exe'], + size: [1309448], + }, + event: { + category: ['malware', 'intrusion_detection', 'file'], + outcome: ['success'], + code: ['malicious_file'], + action: ['modification'], + id: ['LsuMZVr+sdhvehVM++++GvWi'], + kind: ['alert'], + created: ['2020-11-04T22:40:51.724Z'], + module: ['endpoint'], + type: ['info', 'change', 'denied'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2020-11-04T22:40:51.724Z', + message: ['Malware Prevention Alert'], + _id: 'j0RtlXUB-o9SpDeMLdEE', +}; + +export const mockEndpointFileModificationMalwareDetectionAlert: Ecs = { + process: { + hash: { + md5: ['c93876879542fc4710ab1d3b52382d95'], + sha256: ['0ead4d0131ca81aa4820efdcd3c6053eab23179a46c5480c94d7c11eb8451d62'], + sha1: ['def88472b5d92022b6182bfe031c043ddfc5ff0f'], + }, + parent: { + name: ['Python'], + pid: [97], + }, + entity_id: [ + 'ZGQ0NDBhNjMtZjcyNy00NGY4LWI5M2UtNzQzZWEzMDBiYTk2LTU5OTUtMTMyNDM2MTg1MzkuOTUyNjkwMDA=', + ], + executable: [ + '/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python', + ], + name: ['Python'], + args: [ + '/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python', + 'main.py', + '-a', + 'modify', + ], + pid: [5995], + }, + host: { + os: { + full: ['macOS 10.14.1'], + name: ['macOS'], + version: ['10.14.1'], + platform: ['macos'], + family: ['macos'], + kernel: [ + 'Darwin Kernel Version 18.2.0: Fri Oct 5 19:40:55 PDT 2018; root:xnu-4903.221.2~1/RELEASE_X86_64', + ], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + ip: ['10.1.2.3'], + id: ['7d59b1a5-afa1-6531-07ea-691602558230'], + architecture: ['x86_64'], + name: ['mac-1.local'], + }, + file: { + mtime: ['2020-09-03T14:55:42.842Z'], + path: ['/private/var/root/write_malware/modules/write_malware/aircrack'], + owner: ['root'], + hash: { + md5: ['59328cdab10fb4f25a026eb362440422'], + sha256: ['f0954d9673878b2223b00b7ec770c7b438d876a9bb44ec78457e5c618f31f52b'], + sha1: ['f10b043652da8c444e04aede3a9ce4a10ef9028e'], + }, + name: ['aircrack'], + size: [240916], + }, + event: { + id: ['Lp21aufnU2nkG+fO++++++7h'], + module: ['endpoint'], + category: ['malware', 'intrusion_detection', 'file'], + outcome: ['success'], + code: ['malicious_file'], + action: ['modification'], + type: ['info', 'change', 'allowed'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Malware Detection Alert'], + timestamp: '2020-09-03T15:01:19.445Z', + _id: '04d309c7e4cf7c4e54b7e3d93c38399e51797eed2484078487f4d6661f94da2c', +}; + +export const mockEndpointFileRenameMalwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['47ea9e07b7dbfbeba368bd95a3a2d25b'], + sha256: ['f45557c0b57dec4c000d8cb7d7068c8a4dccf392de740501b1046994460d77ea'], + sha1: ['da714f84a7bbaee2be9f1ca0262aca649657cf3e'], + }, + parent: { + name: ['C:\\Windows\\System32\\userinit.exe'], + pid: [356], + }, + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTEwMDgtMTMyNDc1Njk3ODUuODA0NzQyMDA=', + ], + executable: ['C:\\Windows\\explorer.exe'], + name: ['explorer.exe'], + pid: [1008], + args: ['C:\\Windows\\Explorer.EXE'], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1518)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1518)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1518)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + name: ['win2019-endpoint-1'], + }, + file: { + mtime: ['2020-11-04T21:48:47.559Z'], + path: [ + 'C:\\Users\\sean\\Downloads\\23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe', + ], + owner: ['sean'], + hash: { + md5: ['9798063a1fe056ef2f1d6f5217e7b82b'], + sha256: ['23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97'], + sha1: ['ced72fe7fc3835385faea41c657efab7b9f883cd'], + }, + name: ['23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exe'], + extension: ['exe'], + size: [242010], + }, + event: { + category: ['malware', 'intrusion_detection', 'file'], + outcome: ['success'], + code: ['malicious_file'], + action: ['rename'], + id: ['LsuMZVr+sdhvehVM++++GppA'], + kind: ['alert'], + module: ['endpoint'], + type: ['info', 'change', 'denied'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2020-11-04T21:48:57.847Z', + message: ['Malware Prevention Alert'], + _id: 'qtA9lXUBn9bLIbfPj-Tu', +}; + +export const mockEndpointFileRenameMalwareDetectionAlert: Ecs = { + ...mockEndpointFileRenameMalwarePreventionAlert, + event: { + ...mockEndpointFileRenameMalwarePreventionAlert.event, + type: ['info', 'change', 'allowed'], + }, + message: ['Malware Detection Alert'], + _id: 'CD7B6A22-809C-4502-BB94-BC38901EC942', +}; + +// NOTE: see `mock_timeline_data.ts` for the mockEndpointProcessExecutionMalwarePreventionAlert + +export const mockEndpointProcessExecutionMalwareDetectionAlert: Ecs = { + process: { + hash: { + md5: ['cc52aebdf82048364119f117f52dbba0'], + sha256: ['263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0'], + sha1: ['c929f6ff2d6d1085ee69625cd8efb92101a0e906'], + }, + entity_id: [ + 'Yjk3ZWYwODktNzYyZi00ZTljLTg3OWMtNmQ5MDM1ZjBmYTUzLTg2NjgtMTMyNDM2MTgwMzQuODU3Njg5MDA=', + ], + executable: ['C:\\temp\\mimikatz_write.exe'], + parent: { + name: ['python.exe'], + }, + name: ['mimikatz_write.exe'], + args: ['c:\\temp\\mimikatz_write.exe'], + pid: [8668], + }, + host: { + os: { + full: ['Windows 10 Pro 1903 (10.0.18362.1016)'], + name: ['Windows'], + version: ['1903 (10.0.18362.1016)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1903 (10.0.18362.1016)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + ip: ['10.1.2.3'], + id: ['c85e6c40-d4a1-db21-7458-2565a6b857f3'], + architecture: ['x86_64'], + name: ['DESKTOP-1'], + }, + file: { + mtime: ['2020-09-03T14:47:14.647Z'], + path: ['C:\\temp\\mimikatz_write.exe'], + owner: ['Administrators'], + hash: { + md5: ['cc52aebdf82048364119f117f52dbba0'], + sha256: ['263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0'], + sha1: ['c929f6ff2d6d1085ee69625cd8efb92101a0e906'], + }, + name: ['mimikatz_write.exe'], + extension: ['exe'], + size: [1265456], + }, + event: { + id: ['Lp/73XQ38EF48a6i+++++5Do'], + module: ['endpoint'], + category: ['malware', 'intrusion_detection', 'process'], + outcome: ['success'], + code: ['malicious_file'], + action: ['execution'], + kind: ['signal'], + type: ['info', 'start', 'allowed'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Malware Detection Alert'], + timestamp: '2020-09-03T15:51:50.209Z', + _id: '96b3db3079891faaf155f1ada645b7364a03018c65677ce002f18038e7ce1c47', +}; + +export const mockEndpointFileModificationEvent: Ecs = { + file: { + path: ['/Users/admin/Library/Application Support/CrashReporter/.dat.nosync01a5.6hoWv1'], + name: ['.dat.nosync01a5.6hoWv1'], + }, + host: { + os: { + full: ['macOS 10.14.6'], + name: ['macOS'], + version: ['10.14.6'], + family: ['macos'], + kernel: [ + 'Darwin Kernel Version 18.7.0: Mon Aug 31 20:53:32 PDT 2020; root:xnu-4903.278.44~1/RELEASE_X86_64', + ], + platform: ['macos'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + name: ['test-Mac.local'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['fce6b9f1-5c09-d8f0-3d99-9ecb30f995df'], + }, + event: { + category: ['file'], + kind: ['event'], + module: ['endpoint'], + action: ['modification'], + type: ['change'], + dataset: ['endpoint.events.file'], + }, + process: { + name: ['diagnostics_agent'], + pid: [421], + entity_id: ['OTA1ZDkzMTctMjIxOS00ZjQ1LTg4NTMtYzNiYzk1NGU1ZGU4LTQyMS0xMzI0OTEwNTIwOC4w'], + executable: ['/System/Library/CoreServices/diagnostics_agent'], + }, + user: { + id: ['501'], + name: ['admin'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Endpoint file event'], + timestamp: '2021-02-02T18:56:12.871Z', + _id: 'ulkWZHcBGrBB52F2vFf_', +}; + +export const mockEndpointFileOverwriteEvent: Ecs = { + file: { + path: ['C:\\Windows\\ServiceState\\EventLog\\Data\\lastalive0.dat'], + extension: ['dat'], + name: ['lastalive0.dat'], + }, + 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: ['file'], + kind: ['event'], + created: ['2021-02-02T21:40:14.400Z'], + module: ['endpoint'], + action: ['overwrite'], + type: ['change'], + id: ['Lzty2lsJxA05IUWg++++Icrn'], + dataset: ['endpoint.events.file'], + }, + process: { + name: ['svchost.exe'], + pid: [1228], + entity_id: [ + 'YjUwNDNiMTMtYTdjNi0xZGFlLTEyZWQtODQ1ZDlhNTRhZmQyLTEyMjgtMTMyNTQ5ODc1MDcuODc1MTIxNjAw', + ], + executable: ['C:\\Windows\\System32\\svchost.exe'], + }, + user: { + id: ['S-1-5-19'], + name: ['LOCAL SERVICE'], + domain: ['NT AUTHORITY'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Endpoint file event'], + timestamp: '2021-02-02T21:40:14.400Z', + _id: 'LBmxZHcBtgfIO53sCImw', +}; + +export const mockEndpointFileRenameEvent: Ecs = { + file: { + path: ['C:\\Windows\\System32\\sru\\SRU.log'], + Ext: { + original: { + path: ['C:\\Windows\\System32\\sru\\SRUtmp.log'], + name: ['SRUtmp.log'], + }, + }, + extension: ['log'], + name: ['SRU.log'], + }, + 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)'], + }, + 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: ['file'], + kind: ['event'], + created: ['2021-02-01T16:43:00.373Z'], + module: ['endpoint'], + action: ['rename'], + type: ['change'], + id: ['Lzty2lsJxA05IUWg++++I3jv'], + dataset: ['endpoint.events.file'], + }, + process: { + name: ['svchost.exe'], + pid: [1204], + entity_id: [ + 'YjUwNDNiMTMtYTdjNi0xZGFlLTEyZWQtODQ1ZDlhNTRhZmQyLTEyMDQtMTMyNTQ5ODc2NzQuNzQ5MjUzNzAw', + ], + executable: ['C:\\Windows\\System32\\svchost.exe'], + }, + user: { + id: ['S-1-5-19'], + name: ['LOCAL SERVICE'], + domain: ['NT AUTHORITY'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Endpoint file event'], + timestamp: '2021-02-01T16:43:00.373Z', + _id: 'OlJ8XncBGrBB52F2Oga7', +}; + +// NOTE: see `mock_timeline_data.ts` for the mockEndpointRegistryModificationEvent + +// NOTE: see `mock_timeline_data.ts` for the mockEndpointLibraryLoadEvent + +export const mockEndpointNetworkHttpRequestEvent: 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-1'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + }, + event: { + category: ['network'], + kind: ['event'], + module: ['endpoint'], + action: ['http_request'], + type: ['protocol'], + id: ['LzzWB9jjGmCwGMvk++++FD+p'], + dataset: ['endpoint.events.network'], + }, + process: { + name: ['svchost.exe'], + pid: [2232], + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTIyMzItMTMyNTUwNzg2ODkuNTA1NzEzMDA=', + ], + executable: ['C:\\Windows\\System32\\svchost.exe'], + }, + destination: { + geo: { + region_name: ['Arizona'], + continent_name: ['North America'], + city_name: ['Phoenix'], + country_name: ['United States'], + region_iso_code: ['US-AZ'], + country_iso_code: ['US'], + }, + port: [80], + ip: ['10.11.12.13'], + }, + source: { + ip: ['10.1.2.3'], + port: [51570], + }, + http: { + request: { + body: { + content: [ + 'GET /msdownload/update/v3/static/trustedr/en/authrootstl.cab?b3d6249cb8dde683 HTTP/1.1\r\nConnection: Keep-Alive\r\nAccept: */*\r\nIf-Modified-Since: Fri, 15 Jan 2021 00:46:38 GMT\r\nIf-None-Match: "0ebbae1d7ead61:0"\r\nUser-Agent: Microsoft-CryptoAPI/10.0\r\nHost: ctldl.windowsupdate.com\r\n\r\n', + ], + bytes: [281], + }, + }, + }, + agent: { + type: ['endpoint'], + }, + user: { + name: ['NETWORK SERVICE'], + domain: ['NT AUTHORITY'], + }, + network: { + protocol: ['http'], + direction: ['outgoing'], + transport: ['tcp'], + }, + message: ['Endpoint network event'], + timestamp: '2021-02-08T19:19:38.241Z', + _id: '5Qwdg3cBX5UUcOOY03W7', +}; + +export const mockEndpointProcessExecEvent: Ecs = { + process: { + hash: { + md5: ['fbc61bd19421211e341e6d9b3f65e334'], + sha256: ['4bc018ac461706496302d1faab0a8bb39aad974eb432758665103165f3a2dd2b'], + sha1: ['1dc525922869533265fbeac8f7d3021489b60129'], + }, + name: ['mdworker_shared'], + parent: { + name: ['launchd'], + pid: [1], + }, + pid: [4454], + entity_id: [ + 'OTA1ZDkzMTctMjIxOS00ZjQ1LTg4NTMtYzNiYzk1NGU1ZGU4LTQ0NTQtMTMyNTY3NjYwMDEuNzIwMjkwMDA=', + ], + executable: [ + '/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared', + ], + args: [ + '/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared', + '-s', + 'mdworker', + '-c', + 'MDSImporterWorker', + '-m', + 'com.apple.mdworker.shared', + ], + }, + host: { + os: { + full: ['macOS 10.14.6'], + name: ['macOS'], + version: ['10.14.6'], + family: ['macos'], + kernel: [ + 'Darwin Kernel Version 18.7.0: Mon Aug 31 20:53:32 PDT 2020; root:xnu-4903.278.44~1/RELEASE_X86_64', + ], + platform: ['macos'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + name: ['test-mac.local'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['fce6b9f1-5c09-d8f0-3d99-9ecb30f995df'], + }, + event: { + category: ['process'], + kind: ['event'], + module: ['endpoint'], + action: ['exec'], + type: ['start'], + id: ['LuH/UjERrFf60dea+++++NW7'], + dataset: ['endpoint.events.process'], + }, + user: { + id: ['501'], + name: ['admin'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Endpoint process event'], + timestamp: '2021-02-02T19:00:01.972Z', + _id: '8lkaZHcBGrBB52F2aN8c', +}; + +export const mockEndpointProcessForkEvent: Ecs = { + process: { + hash: { + md5: ['24a77cf54ab89f3d0772c65204074710'], + sha256: ['cbf3d059cc9f9c0adff5ef15bf331b95ab381837fa0adecd965a41b5846f4bd4'], + sha1: ['6cc7c36da55c7af0969539fae73768fbef11aa1a'], + }, + name: ['zoom.us'], + parent: { + name: ['zoom.us'], + pid: [3961], + }, + pid: [4042], + entity_id: [ + 'OTA1ZDkzMTctMjIxOS00ZjQ1LTg4NTMtYzNiYzk1NGU1ZGU4LTQwNDItMTMyNTY2ODI5MjQuNzYxNDAwMA==', + ], + executable: ['/Applications/zoom.us.app/Contents/MacOS/zoom.us'], + args: ['/Applications/zoom.us.app/Contents/MacOS/zoom.us'], + }, + host: { + os: { + full: ['macOS 10.14.6'], + name: ['macOS'], + version: ['10.14.6'], + family: ['macos'], + kernel: [ + 'Darwin Kernel Version 18.7.0: Mon Aug 31 20:53:32 PDT 2020; root:xnu-4903.278.44~1/RELEASE_X86_64', + ], + platform: ['macos'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + name: ['test-mac.local'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['fce6b9f1-5c09-d8f0-3d99-9ecb30f995df'], + }, + event: { + category: ['process'], + kind: ['event'], + module: ['endpoint'], + action: ['fork'], + type: ['start'], + id: ['LuH/UjERrFf60dea+++++KYC'], + dataset: ['endpoint.events.process'], + }, + user: { + id: ['501'], + name: ['admin'], + }, + agent: { + type: ['endpoint'], + }, + message: ['Endpoint process event'], + timestamp: '2021-02-01T19:55:24.907Z', + _id: 'KXomX3cBGrBB52F2S9XY', +}; + export const mockEndgameIpv4ConnectionAcceptEvent: Ecs = { _id: 'LsjPcG0BOpWiDweSCNfu', user: { diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts index cc75518cf2899..f016b6cc34539 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts +++ b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_data.ts @@ -1302,3 +1302,186 @@ export const mockDnsEvent: Ecs = { ip: ['10.9.9.9'], }, }; + +export const mockEndpointProcessExecutionMalwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['177afc1eb0be88eb9983fb74111260c4'], + sha256: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb'], + sha1: ['f573b85e9beb32121f1949217947b2adc6749e3d'], + }, + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTY5MjAtMTMyNDg5OTk2OTAuNDgzMzA3NzAw', + ], + executable: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + name: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + pid: [6920], + args: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1518)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1518)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1518)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + name: ['win2019-endpoint-1'], + }, + file: { + mtime: ['2020-11-04T21:40:51.494Z'], + path: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + owner: ['sean'], + hash: { + md5: ['177afc1eb0be88eb9983fb74111260c4'], + sha256: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb'], + sha1: ['f573b85e9beb32121f1949217947b2adc6749e3d'], + }, + name: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe'], + extension: ['exe'], + size: [1604112], + }, + event: { + category: ['malware', 'intrusion_detection', 'process'], + outcome: ['success'], + severity: [73], + code: ['malicious_file'], + action: ['execution'], + id: ['LsuMZVr+sdhvehVM++++Gp2Y'], + kind: ['alert'], + created: ['2020-11-04T21:41:30.533Z'], + module: ['endpoint'], + type: ['info', 'start', 'denied'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2020-11-04T21:41:30.533Z', + message: ['Malware Prevention Alert'], + _id: '0dA2lXUBn9bLIbfPkY7d', +}; + +export const mockEndpointLibraryLoadEvent: Ecs = { + file: { + path: ['C:\\Windows\\System32\\bcrypt.dll'], + hash: { + md5: ['00439016776de367bad087d739a03797'], + sha1: ['2c4ba5c1482987d50a182bad915f52cd6611ee63'], + sha256: ['e70f5d8f87aab14e3160227d38387889befbe37fa4f8f5adc59eff52804b35fd'], + }, + name: ['bcrypt.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-1'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + }, + event: { + category: ['library'], + kind: ['event'], + created: ['2021-02-05T21:27:23.921Z'], + module: ['endpoint'], + action: ['load'], + type: ['start'], + id: ['LzzWB9jjGmCwGMvk++++Da5H'], + dataset: ['endpoint.events.library'], + }, + process: { + name: ['sshd.exe'], + pid: [9644], + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTk2NDQtMTMyNTcwMzQwNDEuNzgyMTczODAw', + ], + executable: ['C:\\Program Files\\OpenSSH-Win64\\sshd.exe'], + }, + agent: { + type: ['endpoint'], + }, + user: { + name: ['SYSTEM'], + domain: ['NT AUTHORITY'], + }, + message: ['Endpoint DLL load event'], + timestamp: '2021-02-05T21:27:23.921Z', + _id: 'IAUYdHcBGrBB52F2zo8Q', +}; + +export const mockEndpointRegistryModificationEvent: 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-1'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + }, + event: { + category: ['registry'], + kind: ['event'], + created: ['2021-02-04T13:44:31.559Z'], + module: ['endpoint'], + action: ['modification'], + type: ['change'], + id: ['LzzWB9jjGmCwGMvk++++CbOn'], + dataset: ['endpoint.events.registry'], + }, + process: { + name: ['GoogleUpdate.exe'], + pid: [7408], + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTc0MDgtMTMyNTY5MTk4NDguODY4NTI0ODAw', + ], + executable: ['C:\\Program Files (x86)\\Google\\Update\\GoogleUpdate.exe'], + }, + registry: { + hive: ['HKLM'], + key: [ + 'SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState', + ], + path: [ + 'HKLM\\SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState\\StateValue', + ], + value: ['StateValue'], + }, + agent: { + type: ['endpoint'], + }, + user: { + name: ['SYSTEM'], + domain: ['NT AUTHORITY'], + }, + message: ['Endpoint registry event'], + timestamp: '2021-02-04T13:44:31.559Z', + _id: '4cxLbXcBGrBB52F2uOfF', +}; diff --git a/x-pack/plugins/security_solution/public/graphql/introspection.json b/x-pack/plugins/security_solution/public/graphql/introspection.json index a2f1f222173dd..73b931bea5ff3 100644 --- a/x-pack/plugins/security_solution/public/graphql/introspection.json +++ b/x-pack/plugins/security_solution/public/graphql/introspection.json @@ -2618,6 +2618,7 @@ "inputFields": null, "interfaces": null, "enumValues": [ + { "name": "alerts", "description": "", "isDeprecated": false, "deprecationReason": null }, { "name": "auditd", "description": "", "isDeprecated": false, "deprecationReason": null }, { "name": "auditd_file", @@ -2625,6 +2626,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "library", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "netflow", "description": "", @@ -2632,6 +2639,12 @@ "deprecationReason": null }, { "name": "plain", "description": "", "isDeprecated": false, "deprecationReason": null }, + { + "name": "registry", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, { "name": "suricata", "description": "", diff --git a/x-pack/plugins/security_solution/public/graphql/types.ts b/x-pack/plugins/security_solution/public/graphql/types.ts index f70cd37b8da94..c8b7f8f02b9d2 100644 --- a/x-pack/plugins/security_solution/public/graphql/types.ts +++ b/x-pack/plugins/security_solution/public/graphql/types.ts @@ -287,10 +287,13 @@ export enum DataProviderType { } export enum RowRendererId { + alerts = 'alerts', auditd = 'auditd', auditd_file = 'auditd_file', + library = 'library', netflow = 'netflow', plain = 'plain', + registry = 'registry', suricata = 'suricata', system = 'system', system_dns = 'system_dns', diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/index.tsx index 00c7e86b0e4a7..65974a10c49c2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/index.tsx @@ -11,9 +11,12 @@ import { ExternalLinkIcon } from '../../../../common/components/external_link_ic import { RowRendererId } from '../../../../../common/types/timeline'; import { + AlertsExample, AuditdExample, AuditdFileExample, + LibraryExample, NetflowExample, + RegistryExample, SuricataExample, SystemExample, SystemDnsExample, @@ -47,6 +50,13 @@ export interface RowRendererOption { } export const renderers: RowRendererOption[] = [ + { + id: RowRendererId.alerts, + name: i18n.ALERTS_NAME, + description: i18n.ALERTS_DESCRIPTION, + example: AlertsExample, + searchableDescription: i18n.ALERTS_DESCRIPTION, + }, { id: RowRendererId.auditd, name: i18n.AUDITD_NAME, @@ -75,6 +85,13 @@ export const renderers: RowRendererOption[] = [ example: AuditdFileExample, searchableDescription: `${i18n.AUDITD_FILE_NAME} ${i18n.AUDITD_FILE_DESCRIPTION_PART1}`, }, + { + id: RowRendererId.library, + name: i18n.LIBRARY_NAME, + description: i18n.LIBRARY_DESCRIPTION, + example: LibraryExample, + searchableDescription: i18n.LIBRARY_DESCRIPTION, + }, { id: RowRendererId.system_security_event, name: i18n.AUTHENTICATION_NAME, @@ -140,6 +157,13 @@ export const renderers: RowRendererOption[] = [ example: SystemEndgameProcessExample, searchableDescription: `${i18n.PROCESS_DESCRIPTION_PART1} ${i18n.PROCESS_DESCRIPTION_PART2}`, }, + { + id: RowRendererId.registry, + name: i18n.REGISTRY_NAME, + description: i18n.REGISTRY_DESCRIPTION, + example: RegistryExample, + searchableDescription: i18n.REGISTRY_DESCRIPTION, + }, { id: RowRendererId.system_fim, name: i18n.FIM_NAME, diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts index ebfe178f14ac2..a0d6d4e121891 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/catalog/translations.ts @@ -7,6 +7,17 @@ import { i18n } from '@kbn/i18n'; +export const ALERTS_NAME = i18n.translate('xpack.securitySolution.eventRenderers.alertsName', { + defaultMessage: 'Alerts', +}); + +export const ALERTS_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.eventRenderers.alertsDescription', + { + defaultMessage: 'Alerts are displayed when malware or ransomware is prevented and detected', + } +); + export const AUDITD_NAME = i18n.translate('xpack.securitySolution.eventRenderers.auditdName', { defaultMessage: 'Auditd', }); @@ -112,6 +123,18 @@ export const FLOW_DESCRIPTION_PART2 = i18n.translate( } ); +export const LIBRARY_NAME = i18n.translate('xpack.securitySolution.eventRenderers.libraryName', { + defaultMessage: 'Library', +}); + +export const LIBRARY_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.eventRenderers.libraryDescription', + { + defaultMessage: + 'Library events display a Dynamically Linked Library (DLL) being loaded by a process', + } +); + export const PROCESS = i18n.translate('xpack.securitySolution.eventRenderers.processName', { defaultMessage: 'Process', }); @@ -132,6 +155,17 @@ export const PROCESS_DESCRIPTION_PART2 = i18n.translate( } ); +export const REGISTRY_NAME = i18n.translate('xpack.securitySolution.eventRenderers.registryName', { + defaultMessage: 'Registry', +}); + +export const REGISTRY_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.eventRenderers.registryDescription', + { + defaultMessage: 'Registry events show updates to the Windows Registry', + } +); + export const SOCKET_NAME = i18n.translate('xpack.securitySolution.eventRenderers.socketName', { defaultMessage: 'Socket (Network)', }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/alerts.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/alerts.tsx new file mode 100644 index 0000000000000..b0384155c5c10 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/alerts.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { mockEndpointProcessExecutionMalwarePreventionAlert } from '../../../../common/mock/mock_timeline_data'; +import { createEndpointAlertsRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { WAS_PREVENTED_FROM_EXECUTING_A_MALICIOUS_PROCESS } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const AlertsExampleComponent: React.FC = () => { + const alertsRowRenderer = createEndpointAlertsRowRenderer({ + eventAction: 'execution', + eventCategory: 'process', + eventType: 'denied', + skipRedundantFileDetails: true, + text: WAS_PREVENTED_FROM_EXECUTING_A_MALICIOUS_PROCESS, + }); + + return ( + <> + {alertsRowRenderer.renderRow({ + browserFields: {}, + data: mockEndpointProcessExecutionMalwarePreventionAlert, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + + ); +}; +export const AlertsExample = React.memo(AlertsExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx index 1b4e3b1723a2d..6932ca01835cc 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/index.tsx @@ -5,9 +5,12 @@ * 2.0. */ +export * from './alerts'; export * from './auditd'; export * from './auditd_file'; +export * from './library'; export * from './netflow'; +export * from './registry'; export * from './suricata'; export * from './system'; export * from './system_dns'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/library.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/library.tsx new file mode 100644 index 0000000000000..6198225fcb87d --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/library.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { mockEndpointLibraryLoadEvent } from '../../../../common/mock/mock_timeline_data'; +import { createEndpointLibraryRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { LOADED_LIBRARY } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const LibraryExampleComponent: React.FC = () => { + const libraryRowRenderer = createEndpointLibraryRowRenderer({ + actionName: 'load', + text: LOADED_LIBRARY, + }); + + return ( + <> + {libraryRowRenderer.renderRow({ + browserFields: {}, + data: mockEndpointLibraryLoadEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + + ); +}; +export const LibraryExample = React.memo(LibraryExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/registry.tsx b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/registry.tsx new file mode 100644 index 0000000000000..f00db0d94eed8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/row_renderers_browser/examples/registry.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { mockEndpointRegistryModificationEvent } from '../../../../common/mock/mock_timeline_data'; +import { createEndpointRegistryRowRenderer } from '../../timeline/body/renderers/system/generic_row_renderer'; +import { MODIFIED_REGISTRY_KEY } from '../../timeline/body/renderers/system/translations'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../constants'; + +const RegistryExampleComponent: React.FC = () => { + const registryRowRenderer = createEndpointRegistryRowRenderer({ + actionName: 'modification', + text: MODIFIED_REGISTRY_KEY, + }); + + return ( + <> + {registryRowRenderer.renderRow({ + browserFields: {}, + data: mockEndpointRegistryModificationEvent, + timelineId: ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, + })} + + ); +}; +export const RegistryExample = React.memo(RegistryExampleComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx index e6d79c4ba53bc..d7274f0774fc5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.test.tsx @@ -33,12 +33,15 @@ describe('FileDraggable', () => { endgameFileName="[endgameFileName]" endgameFilePath="[endgameFilePath]" eventId="1" + fileExtOriginalPath="[fileExtOriginalPath]" fileName="[fileName]" filePath="[filePath]" /> ); - expect(wrapper.text()).toEqual('[fileName]in[filePath]'); + expect(wrapper.text()).toEqual( + '[fileName]in[filePath]from its original path[fileExtOriginalPath]' + ); }); test('it returns an empty string when none of the files or paths are provided', () => { @@ -49,6 +52,7 @@ describe('FileDraggable', () => { endgameFileName={undefined} endgameFilePath={undefined} eventId="1" + fileExtOriginalPath={undefined} fileName={undefined} filePath={undefined} /> @@ -65,6 +69,7 @@ describe('FileDraggable', () => { endgameFileName="[endgameFileName]" endgameFilePath={undefined} eventId="1" + fileExtOriginalPath={undefined} fileName={undefined} filePath={undefined} /> @@ -81,6 +86,7 @@ describe('FileDraggable', () => { endgameFileName={undefined} endgameFilePath="[endgameFilePath]" eventId="1" + fileExtOriginalPath={undefined} fileName={undefined} filePath={undefined} /> @@ -97,6 +103,7 @@ describe('FileDraggable', () => { endgameFileName={undefined} endgameFilePath={undefined} eventId="1" + fileExtOriginalPath={undefined} fileName="[fileName]" filePath={undefined} /> @@ -113,6 +120,7 @@ describe('FileDraggable', () => { endgameFileName={undefined} endgameFilePath={undefined} eventId="1" + fileExtOriginalPath={undefined} fileName={undefined} filePath="[filePath]" /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.tsx index af118a1688ae3..703b38e627e55 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_draggable.tsx @@ -19,10 +19,19 @@ interface Props { eventId: string; fileName: string | null | undefined; filePath: string | null | undefined; + fileExtOriginalPath: string | null | undefined; } export const FileDraggable = React.memo( - ({ contextId, endgameFileName, endgameFilePath, eventId, fileName, filePath }) => { + ({ + contextId, + endgameFileName, + endgameFilePath, + eventId, + fileExtOriginalPath, + fileName, + filePath, + }) => { if ( isNillEmptyOrNotFinite(fileName) && isNillEmptyOrNotFinite(endgameFileName) && @@ -86,6 +95,23 @@ export const FileDraggable = React.memo( /> ) : null} + + {!isNillEmptyOrNotFinite(fileExtOriginalPath) && ( + <> + + {i18n.FROM_ITS_ORIGINAL_PATH} + + + + + + )} ); } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx new file mode 100644 index 0000000000000..e7e6274942bea --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.test.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { TestProviders } from '../../../../../common/mock'; +import '../../../../../common/mock/match_media'; +import { useMountAppended } from '../../../../../common/utils/use_mount_appended'; + +import { FileHash } from './file_hash'; + +jest.mock('@elastic/eui', () => { + const original = jest.requireActual('@elastic/eui'); + return { + ...original, + // eslint-disable-next-line react/display-name + EuiScreenReaderOnly: () => <>, + }; +}); + +describe('FileHash', () => { + const mount = useMountAppended(); + + const allProps = { + contextId: 'test', + eventId: '1', + fileHashSha256: undefined, + }; + + test('displays the fileHashSha256 when provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual('[fileHashSha256]'); + }); + + test('displays nothing when fileHashSha256 is null', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual(''); + }); + + test('displays nothing when fileHashSha256 is undefined', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual(''); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.tsx new file mode 100644 index 0000000000000..9e624ba17c921 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/file_hash.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; + +import { DraggableBadge } from '../../../../../common/components/draggables'; + +import { isNillEmptyOrNotFinite, TokensFlexItem } from './helpers'; + +const HashFlexGroup = styled(EuiFlexGroup)` + margin: ${({ theme }) => theme.eui.euiSizeXS}; +`; + +interface Props { + contextId: string; + eventId: string; + fileHashSha256: string | null | undefined; +} + +export const FileHash = React.memo(({ contextId, eventId, fileHashSha256 }) => { + if (isNillEmptyOrNotFinite(fileHashSha256)) { + return null; + } + + return ( + + + + + + ); +}); + +FileHash.displayName = 'FileHash'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.test.tsx index d32ec728d229b..6fe3726c328fa 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.test.tsx @@ -193,7 +193,19 @@ describe('helpers', () => { }); describe('valid values', () => { - const validValues = ['file_create_event', 'created', 'file_delete_event', 'deleted']; + const validValues = [ + 'created', + 'creation', + 'deleted', + 'deletion', + 'file_create_event', + 'file_delete_event', + 'files-encrypted', + 'load', + 'modification', + 'overwrite', + 'rename', + ]; validValues.forEach((eventAction) => { test(`${eventAction} returns true`, () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.tsx index ea84dc19908f0..e4644414fdc8e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/helpers.tsx @@ -60,6 +60,26 @@ export const isProcessStoppedOrTerminationEvent = ( ): boolean => ['process_stopped', 'termination_event'].includes(`${eventAction}`.toLowerCase()); export const showVia = (eventAction: string | null | undefined): boolean => - ['file_create_event', 'created', 'creation', 'file_delete_event', 'deleted', 'deletion'].includes( - `${eventAction}`.toLowerCase() - ); + [ + 'created', + 'creation', + 'deleted', + 'deletion', + 'file_create_event', + 'file_delete_event', + 'files-encrypted', + 'load', + 'modification', + 'overwrite', + 'rename', + ].includes(`${eventAction}`.toLowerCase()); + +export const excludeFileNameAndPath = ({ + eventAction, + eventCategory, + eventType, +}: { + eventAction: string | null | undefined; + eventCategory: string | null | undefined; + eventType: string | null | undefined; +}) => false; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx index 5dd30b84d2b74..9e90e061e94d5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.test.tsx @@ -22,81 +22,39 @@ jest.mock('@elastic/eui', () => { }; }); +const allProps = { + contextId: 'test', + eventId: '1', + processHashSha256: undefined, +}; + describe('ProcessHash', () => { const mount = useMountAppended(); - test('displays the processHashMd5, processHashSha1, and processHashSha256 when they are all provided', () => { + test('displays the processHashSha256 when provided', () => { const wrapper = mount( - + ); - expect(wrapper.text()).toEqual('[processHashSha256][processHashSha1][processHashMd5]'); + expect(wrapper.text()).toEqual('[processHashSha256]'); }); - test('displays nothing when processHashMd5, processHashSha1, and processHashSha256 are all undefined', () => { + test('displays nothing when processHashSha256 is null', () => { const wrapper = mount( - + ); expect(wrapper.text()).toEqual(''); }); - test('displays just processHashMd5 when the other hashes are undefined', () => { - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual('[processHashMd5]'); - }); - - test('displays just processHashSha1 when the other hashes are undefined', () => { + test('displays nothing when processHashSha256 is undefined', () => { const wrapper = mount( - + ); - expect(wrapper.text()).toEqual('[processHashSha1]'); - }); - - test('displays just processHashSha256 when the other hashes are undefined', () => { - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual('[processHashSha256]'); + expect(wrapper.text()).toEqual(''); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.tsx index 1af2daad7fc5a..32432afbf205c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/process_hash.tsx @@ -20,61 +20,27 @@ const HashFlexGroup = styled(EuiFlexGroup)` interface Props { contextId: string; eventId: string; - processHashMd5: string | null | undefined; - processHashSha1: string | null | undefined; processHashSha256: string | null | undefined; } -export const ProcessHash = React.memo( - ({ contextId, eventId, processHashMd5, processHashSha1, processHashSha256 }) => { - if ( - isNillEmptyOrNotFinite(processHashSha256) && - isNillEmptyOrNotFinite(processHashSha1) && - isNillEmptyOrNotFinite(processHashMd5) - ) { - return null; - } - - return ( - - {!isNillEmptyOrNotFinite(processHashSha256) && ( - - - - )} - - {!isNillEmptyOrNotFinite(processHashSha1) && ( - - - - )} - - {!isNillEmptyOrNotFinite(processHashMd5) && ( - - - - )} - - ); +export const ProcessHash = React.memo(({ contextId, eventId, processHashSha256 }) => { + if (isNillEmptyOrNotFinite(processHashSha256)) { + return null; } -); + + return ( + + + + + + ); +}); ProcessHash.displayName = 'ProcessHash'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx new file mode 100644 index 0000000000000..f37adef7e73cb --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.test.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { mockBrowserFields } from '../../../../../../common/containers/source/mock'; +import { + mockEndpointRegistryModificationEvent, + TestProviders, +} from '../../../../../../common/mock'; +import '../../../../../../common/mock/match_media'; +import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; +import { MODIFIED_REGISTRY_KEY } from '../system/translations'; + +import { RegistryEventDetails } from './registry_event_details'; + +jest.mock('@elastic/eui', () => { + const original = jest.requireActual('@elastic/eui'); + return { + ...original, + // eslint-disable-next-line react/display-name + EuiScreenReaderOnly: () => <>, + }; +}); + +describe('RegistryEventDetails', () => { + const mount = useMountAppended(); + + test('it renders the expected text given an Endpoint Registry modification event', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + 'SYSTEM\\NT AUTHORITY@win2019-endpoint-1modified registry keySOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentStatewith new valueHKLM\\SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState\\StateValueviaGoogleUpdate.exe(7408)' + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.tsx new file mode 100644 index 0000000000000..0bfb03168019a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { get } from 'lodash/fp'; +import React from 'react'; + +import { BrowserFields } from '../../../../../../common/containers/source'; +import { Details, isNillEmptyOrNotFinite } from '../helpers'; +import { Ecs } from '../../../../../../../common/ecs'; + +import { RegistryEventDetailsLine } from './registry_event_details_line'; + +interface Props { + browserFields: BrowserFields; + contextId: string; + data: Ecs; + text: string; +} + +const RegistryEventDetailsComponent: React.FC = ({ contextId, data, text }) => { + const hostName: string | null | undefined = get('host.name[0]', data); + const id = data._id; + const processName: string | null | undefined = get('process.name[0]', data); + const processPid: number | null | undefined = get('process.pid[0]', data); + const registryKey: string | null | undefined = get('registry.key[0]', data); + const registryPath: string | null | undefined = get('registry.path[0]', data); + const userDomain: string | null | undefined = get('user.domain[0]', data); + const userName: string | null | undefined = get('user.name[0]', data); + + if (isNillEmptyOrNotFinite(registryKey)) { + return null; + } + + return ( +
+ +
+ ); +}; + +RegistryEventDetailsComponent.displayName = 'RegistryEventDetailsComponent'; + +export const RegistryEventDetails = React.memo(RegistryEventDetailsComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx new file mode 100644 index 0000000000000..6be1529152523 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.test.tsx @@ -0,0 +1,135 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { TestProviders } from '../../../../../../common/mock'; +import '../../../../../../common/mock/match_media'; +import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; +import { RegistryEventDetailsLine } from './registry_event_details_line'; +import { MODIFIED_REGISTRY_KEY } from '../system/translations'; + +jest.mock('@elastic/eui', () => { + const original = jest.requireActual('@elastic/eui'); + return { + ...original, + // eslint-disable-next-line react/display-name + EuiScreenReaderOnly: () => <>, + }; +}); + +describe('DnsRequestEventDetailsLine', () => { + const mount = useMountAppended(); + + const allProps = { + contextId: 'test', + hostName: '[hostName]', + id: '1', + processName: '[processName]', + processPid: 123, + registryKey: '[registryKey]', + registryPath: '[registryPath]', + text: MODIFIED_REGISTRY_KEY, + userDomain: '[userDomain]', + userName: '[userName]', + }; + + test('it renders the expected text when all properties are provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]\\[userDomain]@[hostName]modified registry key[registryKey]with new value[registryPath]via[processName](123)' + ); + }); + + test('it returns an empty string when when registryKey is null', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual(''); + }); + + test('it returns an empty string when registryKey is undefined', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual(''); + }); + + test('it renders the expected text when hostName is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]\\[userDomain]modified registry key[registryKey]with new value[registryPath]via[processName](123)' + ); + }); + + test('it renders the expected text when processName is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]\\[userDomain]@[hostName]modified registry key[registryKey]with new value[registryPath]via(123)' + ); + }); + + test('it renders the expected text when processPid is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]\\[userDomain]@[hostName]modified registry key[registryKey]with new value[registryPath]via[processName]' + ); + }); + + test('it renders the expected text when registryPath is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]\\[userDomain]@[hostName]modified registry key[registryKey]via[processName](123)' + ); + }); + + test('it renders the expected text when userDomain is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '[userName]@[hostName]modified registry key[registryKey]with new value[registryPath]via[processName](123)' + ); + }); + + test('it renders the expected text when userName is NOT provided', () => { + const wrapper = mount( + + + + ); + expect(wrapper.text()).toEqual( + '\\[userDomain][hostName]modified registry key[registryKey]with new value[registryPath]via[processName](123)' + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.tsx new file mode 100644 index 0000000000000..b85ae25ed2509 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/registry_event_details_line.tsx @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup } from '@elastic/eui'; +import React, { useMemo } from 'react'; + +import { DraggableBadge } from '../../../../../../common/components/draggables'; +import { isNillEmptyOrNotFinite, TokensFlexItem } from '../helpers'; +import { ProcessDraggableWithNonExistentProcess } from '../process_draggable'; +import { UserHostWorkingDir } from '../user_host_working_dir'; + +import * as i18n from './translations'; + +interface Props { + contextId: string; + hostName: string | null | undefined; + id: string; + processName: string | null | undefined; + processPid: number | null | undefined; + registryKey: string | null | undefined; + registryPath: string | null | undefined; + text: string; + userDomain: string | null | undefined; + userName: string | null | undefined; +} + +const RegistryEventDetailsLineComponent: React.FC = ({ + contextId, + hostName, + id, + processName, + processPid, + registryKey, + registryPath, + text, + userDomain, + userName, +}) => { + const registryKeyTooltipContent = useMemo( + () => ( + <> +
{'registry.key'}
+
{registryKey}
+ + ), + [registryKey] + ); + + const registryPathTooltipContent = useMemo( + () => ( + <> +
{'registry.path'}
+
{registryPath}
+ + ), + [registryPath] + ); + + if (isNillEmptyOrNotFinite(registryKey)) { + return null; + } + + return ( + <> + + + + {!isNillEmptyOrNotFinite(registryKey) && ( + <> + + {text} + + + + + + )} + + {!isNillEmptyOrNotFinite(registryPath) && ( + <> + + {i18n.WITH_NEW_VALUE} + + + + + + )} + + + {i18n.VIA} + + + + + + + + ); +}; + +export const RegistryEventDetailsLine = React.memo(RegistryEventDetailsLineComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/translations.ts new file mode 100644 index 0000000000000..f1c1c9487dfd2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/registry/translations.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const VIA = i18n.translate( + 'xpack.securitySolution.timeline.body.renderers.registry.viaDescription', + { + defaultMessage: 'via', + } +); + +export const WITH_NEW_VALUE = i18n.translate( + 'xpack.securitySolution.timeline.body.renderers.registry.withNewValueDescription', + { + defaultMessage: 'with new value', + } +); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/__snapshots__/generic_file_details.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/__snapshots__/generic_file_details.test.tsx.snap index 8045ce95ca272..b33d77714adc9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/__snapshots__/generic_file_details.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/__snapshots__/generic_file_details.test.tsx.snap @@ -11,6 +11,8 @@ exports[`SystemGenericFileDetails rendering it renders the default SystemGeneric outcome="failure" processPid={6278} showMessage={true} + skipRedundantFileDetails={false} + skipRedundantProcessDetails={false} text="[generic-text-123]" userName="Evan" /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx index a3932fde44c1d..b660d823954ee 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.test.tsx @@ -106,6 +106,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={789} endgameProcessName="[endgameProcessName-123]" eventAction="[eventAction-123]" + fileExtOriginalPath="[fileExtOriginalPath]" + fileHashSha256="[fileHashSha256-123]" fileName="[fileName-123]" filePath="[filePath-123]" hostName="[hostname-123]" @@ -118,8 +120,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable=123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -138,7 +138,7 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][generic-text-123][fileName-123]in[filePath-123][processName-123](123)[arg-1][arg-2][arg-3][some-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][generic-text-123][fileName-123]in[filePath-123]from its original path[fileExtOriginalPath][processName-123](123)[arg-1][arg-2][arg-3][some-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][fileHashSha256-123][processHashSha256-123][message-123]' ); }); @@ -155,6 +155,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName={null} @@ -166,8 +168,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -203,6 +203,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -214,8 +216,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -251,6 +251,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -262,8 +264,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -299,6 +299,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -310,8 +312,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -349,6 +349,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -360,8 +362,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -399,6 +399,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -410,8 +412,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={null} processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -449,6 +449,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -460,8 +462,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable={null} processExitCode={null} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -499,6 +499,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -510,8 +512,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5={null} - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -536,7 +536,7 @@ describe('SystemGenericFileDetails', () => { ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode', () => { const wrapper = mount(
@@ -549,6 +549,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -560,8 +562,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1={null} processHashSha256={null} processParentName={null} processParentPid={null} @@ -582,61 +582,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123]with exit code-1with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashMd5-123][message-123]' - ); - }); - - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1', () => { - const wrapper = mount( - -
- -
-
- ); - expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123]with exit code-1with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processExecutable-123]with exit code-1with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]' ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256', () => { const wrapper = mount(
@@ -649,6 +599,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -660,8 +612,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName={null} processParentPid={null} @@ -682,11 +632,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123]with exit code-1with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processExecutable-123]with exit code-1with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName', () => { const wrapper = mount(
@@ -699,6 +649,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -710,8 +662,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={null} @@ -732,11 +682,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123]with exit code-1via parent process[processParentName-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processExecutable-123]with exit code-1via parent process[processParentName-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid', () => { const wrapper = mount(
@@ -749,6 +699,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -760,8 +712,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -782,11 +732,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123]with exit code-1via parent process[processParentName-123](789)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processExecutable-123]with exit code-1via parent process[processParentName-123](789)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid', () => { const wrapper = mount(
@@ -799,6 +749,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -810,8 +762,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -832,11 +782,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processExecutable-123](123)with exit code-1via parent process[processParentName-123](789)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processExecutable-123](123)with exit code-1via parent process[processParentName-123](789)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName', () => { + test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName', () => { const wrapper = mount(
@@ -849,6 +799,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction={null} + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -860,8 +812,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -882,11 +832,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processName-123](123)with exit code-1via parent process[processParentName-123](789)(456)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processName-123](123)with exit code-1via parent process[processParentName-123](789)(456)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod', () => { const wrapper = mount(
@@ -899,6 +849,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -910,8 +862,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -932,11 +882,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature', () => { const wrapper = mount(
@@ -949,6 +899,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -960,8 +912,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -982,11 +932,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text', () => { const wrapper = mount(
@@ -999,6 +949,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1010,8 +962,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1032,11 +982,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain', () => { const wrapper = mount(
@@ -1049,6 +999,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1060,8 +1012,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1082,11 +1032,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '\\[userDomain-123][hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '\\[userDomain-123][hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username', () => { const wrapper = mount(
@@ -1099,6 +1049,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1110,8 +1062,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1132,11 +1082,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[username-123]\\[userDomain-123]@[hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[username-123]\\[userDomain-123]@[hostname-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory', () => { const wrapper = mount(
@@ -1149,6 +1099,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1160,8 +1112,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1182,11 +1132,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title', () => { const wrapper = mount(
@@ -1199,6 +1149,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1210,8 +1162,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1232,11 +1182,11 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)[process-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)[process-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); - test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashMd5, processHashSha1, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title, args', () => { + test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, processExecutable, processExitCode, processHashSha256, processParentName, processParentPid, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title, args', () => { const wrapper = mount(
@@ -1249,6 +1199,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={null} endgameProcessName={null} eventAction="[eventAction-123]" + fileExtOriginalPath={null} + fileHashSha256={null} fileName={null} filePath={null} hostName="[hostname-123]" @@ -1260,8 +1212,6 @@ describe('SystemGenericFileDetails', () => { packageVersion="[packageVersion-123]" processExecutable="[processExecutable-123]" processExitCode={-1} - processHashMd5="[processHashMd5-123]" - processHashSha1="[processHashSha1-123]" processHashSha256="[processHashSha256-123]" processParentName="[processParentName-123]" processParentPid={789} @@ -1282,7 +1232,7 @@ describe('SystemGenericFileDetails', () => { ); expect(wrapper.text()).toEqual( - '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)[arg-1][arg-2][arg-3][process-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]' + '[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)[arg-1][arg-2][arg-3][process-title-123]with exit code-1[endgameExitCode-123]via parent process[processParentName-123][endgameParentProcessName-123](789)(456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][message-123]' ); }); @@ -1299,6 +1249,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1310,8 +1262,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1347,6 +1297,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName="[fileName]" filePath="[filePath]" hostName={undefined} @@ -1358,8 +1310,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1397,6 +1347,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={eventAction} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1408,8 +1360,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1449,6 +1399,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={eventAction} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1460,8 +1412,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1500,6 +1450,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={eventAction} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1511,8 +1463,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1553,6 +1503,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={eventAction} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1564,8 +1516,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1604,6 +1554,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={eventAction} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1615,8 +1567,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1653,6 +1603,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1664,8 +1616,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1702,6 +1652,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={undefined} endgameProcessName={undefined} eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1713,8 +1665,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1751,6 +1701,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={789} endgameProcessName="[endgameProcessName]" eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1762,8 +1714,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} @@ -1800,6 +1750,8 @@ describe('SystemGenericFileDetails', () => { endgamePid={789} endgameProcessName="[endgameProcessName]" eventAction={undefined} + fileExtOriginalPath={undefined} + fileHashSha256={undefined} fileName={undefined} filePath={undefined} hostName={undefined} @@ -1811,8 +1763,6 @@ describe('SystemGenericFileDetails', () => { packageVersion={undefined} processExecutable={undefined} processExitCode={undefined} - processHashMd5={undefined} - processHashSha1={undefined} processHashSha256={undefined} processParentName={undefined} processParentPid={undefined} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.tsx index 4026613ff7d0a..6df583656ff2d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_file_details.tsx @@ -23,6 +23,7 @@ import { Args } from '../args'; import { AuthSsh } from './auth_ssh'; import { ExitCodeDraggable } from '../exit_code_draggable'; import { FileDraggable } from '../file_draggable'; +import { FileHash } from '../file_hash'; import { Package } from './package'; import { Badge } from '../../../../../../common/components/page'; import { ParentProcessDraggable } from '../parent_process_draggable'; @@ -38,6 +39,8 @@ interface Props { endgamePid: number | null | undefined; endgameProcessName: string | null | undefined; eventAction: string | null | undefined; + fileExtOriginalPath: string | null | undefined; + fileHashSha256: string | null | undefined; fileName: string | null | undefined; filePath: string | null | undefined; hostName: string | null | undefined; @@ -54,11 +57,11 @@ interface Props { processPid: number | null | undefined; processPpid: number | null | undefined; processExecutable: string | null | undefined; - processHashMd5: string | null | undefined; - processHashSha1: string | null | undefined; processHashSha256: string | null | undefined; processTitle: string | null | undefined; showMessage: boolean; + skipRedundantFileDetails?: boolean; + skipRedundantProcessDetails?: boolean; sshSignature: string | null | undefined; sshMethod: string | null | undefined; text: string | null | undefined; @@ -78,6 +81,8 @@ export const SystemGenericFileLine = React.memo( endgamePid, endgameProcessName, eventAction, + fileExtOriginalPath, + fileHashSha256, fileName, filePath, hostName, @@ -91,14 +96,14 @@ export const SystemGenericFileLine = React.memo( packageSummary, packageVersion, processExecutable, - processHashMd5, - processHashSha1, processHashSha256, processName, processPid, processPpid, processTitle, showMessage, + skipRedundantFileDetails = false, + skipRedundantProcessDetails = false, sshSignature, sshMethod, text, @@ -119,14 +124,18 @@ export const SystemGenericFileLine = React.memo( {text} - + + {!skipRedundantFileDetails && ( + + )} {showVia(eventAction) && ( {i18n.VIA} @@ -190,13 +199,12 @@ export const SystemGenericFileLine = React.memo( packageVersion={packageVersion} /> - + {!skipRedundantFileDetails && ( + + )} + {!skipRedundantProcessDetails && ( + + )} {message != null && showMessage && ( <> @@ -221,12 +229,22 @@ interface GenericDetailsProps { data: Ecs; contextId: string; showMessage?: boolean; + skipRedundantFileDetails?: boolean; + skipRedundantProcessDetails?: boolean; text: string; timelineId: string; } export const SystemGenericFileDetails = React.memo( - ({ data, contextId, showMessage = true, text, timelineId }) => { + ({ + data, + contextId, + showMessage = true, + skipRedundantFileDetails = false, + skipRedundantProcessDetails = false, + text, + timelineId, + }) => { const id = data._id; const message: string | null = data.message != null ? data.message[0] : null; const hostName: string | null | undefined = get('host.name[0]', data); @@ -240,6 +258,8 @@ export const SystemGenericFileDetails = React.memo( const endgamePid: number | null | undefined = get('endgame.pid[0]', data); const endgameProcessName: string | null | undefined = get('endgame.process_name[0]', data); const eventAction: string | null | undefined = get('event.action[0]', data); + const fileExtOriginalPath: string | null | undefined = get('file.Ext.original.path[0]', data); + const fileHashSha256: string | null | undefined = get('file.hash.sha256[0]', data); const fileName: string | null | undefined = get('file.name[0]', data); const filePath: string | null | undefined = get('file.path[0]', data); const userDomain: string | null | undefined = get('user.domain[0]', data); @@ -251,8 +271,6 @@ export const SystemGenericFileDetails = React.memo( 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); const processPid: number | null | undefined = get('process.pid[0]', data); const processPpid: number | null | undefined = get('process.ppid[0]', data); @@ -278,6 +296,8 @@ export const SystemGenericFileDetails = React.memo( endgamePid={endgamePid} endgameProcessName={endgameProcessName} eventAction={eventAction} + fileExtOriginalPath={fileExtOriginalPath} + fileHashSha256={fileHashSha256} fileName={fileName} filePath={filePath} userDomain={userDomain} @@ -292,14 +312,14 @@ export const SystemGenericFileDetails = React.memo( packageName={packageName} packageSummary={packageSummary} packageVersion={packageVersion} - processHashMd5={processHashMd5} - processHashSha1={processHashSha1} processHashSha256={processHashSha256} processName={processName} processPid={processPid} processPpid={processPpid} processExecutable={processExecutable} showMessage={showMessage} + skipRedundantFileDetails={skipRedundantFileDetails} + skipRedundantProcessDetails={skipRedundantProcessDetails} sshSignature={sshSignature} sshMethod={sshMethod} outcome={outcome} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.test.tsx index 4de9bcbdd9c18..b7857e6bf4585 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.test.tsx @@ -15,6 +15,9 @@ import { mockBrowserFields } from '../../../../../../common/containers/source/mo import { Ecs } from '../../../../../../../common/ecs'; import { mockDnsEvent, + mockEndpointProcessExecutionMalwarePreventionAlert, + mockEndpointLibraryLoadEvent, + mockEndpointRegistryModificationEvent, mockFimFileCreatedEvent, mockFimFileDeletedEvent, mockSocketClosedEvent, @@ -38,10 +41,25 @@ import { mockEndgameUserLogon, mockEndpointDisconnectReceivedEvent, mockEndpointFileCreationEvent, + mockEndpointFileCreationMalwarePreventionAlert, + mockEndpointFileCreationMalwareDetectionAlert, + mockEndpointFilesEncryptedRansomwarePreventionAlert, + mockEndpointFilesEncryptedRansomwareDetectionAlert, + mockEndpointFileModificationMalwarePreventionAlert, + mockEndpointFileModificationMalwareDetectionAlert, + mockEndpointFileRenameMalwarePreventionAlert, + mockEndpointFileRenameMalwareDetectionAlert, mockEndpointFileDeletionEvent, + mockEndpointFileModificationEvent, + mockEndpointFileOverwriteEvent, + mockEndpointFileRenameEvent, mockEndpointNetworkConnectionAcceptedEvent, + mockEndpointNetworkHttpRequestEvent, mockEndpointNetworkLookupRequestedEvent, mockEndpointNetworkLookupResultEvent, + mockEndpointProcessExecEvent, + mockEndpointProcessExecutionMalwareDetectionAlert, + mockEndpointProcessForkEvent, mockEndpointProcessStartEvent, mockEndpointProcessEndEvent, mockEndpointSecurityLogOnSuccessEvent, @@ -53,11 +71,15 @@ import { RowRenderer } from '../row_renderer'; import { createDnsRowRenderer, createEndgameProcessRowRenderer, + createEndpointAlertsRowRenderer, + createEndpointLibraryRowRenderer, + createEndpointRegistryRowRenderer, createFimRowRenderer, createGenericSystemRowRenderer, createGenericFileRowRenderer, createSecurityEventRowRenderer, createSocketRowRenderer, + EndpointAlertCriteria, } from './generic_row_renderer'; import * as i18n from './translations'; @@ -197,7 +219,341 @@ describe('GenericRowRenderer', () => { }); }); + describe('#createEndpointAlertsRowRenderer', () => { + test('it renders a Malware File Creation Prevented alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'creation', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_CREATING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance(mockEndpointFileCreationMalwarePreventionAlert) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileCreationMalwarePreventionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'win2019-endpoint-1was prevented from creating a malicious file6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmpinC:\\Users\\sean\\Downloads\\6a5eabd6-1c79-4962-b411-a5e7d9e967d4.tmpviachrome.exe(8944)C:\\Program Files\\Google\\Chrome\\Application\\chrome.exevia parent processexplorer.exe(1008)with resultsuccess7cc42618e580f233fee47e82312cc5c3476cb5de9219ba3f9eb7f99ac0659c30' + ); + }); + + test('it renders a Malware File Creation Detected alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'creation', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_CREATING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance(mockEndpointFileCreationMalwareDetectionAlert) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileCreationMalwareDetectionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'DESKTOP-1was detected creating a malicious filemimikatz_write.exeinC:\\temp\\mimikatz_write.exeviapython.exe(4400)C:\\Python27\\python.exemain.py-a,execute-pc:\\tempvia parent processpythonservice.exe(2936)with resultsuccess263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0' + ); + }); + + test('it renders a Ransomware Files Encrypted Prevented alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'files-encrypted', + eventCategory: 'file', + eventType: 'denied', + skipRedundantFileDetails: true, + text: i18n.RANSOMWARE_WAS_PREVENTED_FROM_ENCRYPTING_FILES, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointFilesEncryptedRansomwarePreventionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFilesEncryptedRansomwarePreventionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'DESKTOP-1ransomware was prevented from encrypting filesviapowershell.exe(6056)powershell.exe-filemock_ransomware_v3.ps1via parent processcmd.exe(10680)with resultsuccesse9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7' + ); + }); + + test('it renders a Ransomware Files Encrypted Detected alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'files-encrypted', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantFileDetails: true, + text: i18n.RANSOMWARE_WAS_DETECTED_ENCRYPTING_FILES, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointFilesEncryptedRansomwareDetectionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFilesEncryptedRansomwareDetectionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'DESKTOP-1ransomware was detected encrypting filesviapowershell.exe(4684)powershell.exe-filemock_ransomware_v3.ps1via parent processcmd.exe(8616)e9fa973eb5ad446e0be31c7b8ae02d48281319e7f492e1ddaadddfbdd5b480c7' + ); + }); + + test('it renders a Malware File Modification Prevented alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'modification', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_MODIFYING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointFileModificationMalwarePreventionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileModificationMalwarePreventionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'win2019-endpoint-1was prevented from modifying a malicious filemimikatz - Copy.exeinC:\\Users\\sean\\Downloads\\mimikatz_trunk (1)\\x64\\mimikatz - Copy.exeviaexplorer.exe(1008)C:\\Windows\\Explorer.EXEvia parent processC:\\Windows\\System32\\userinit.exe(356)with resultsuccess31eb1de7e840a342fd468e558e5ab627bcb4c542a8fe01aec4d5ba01d539a0fc' + ); + }); + + test('it renders a Malware File Modification Detected alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'modification', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_MODIFYING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointFileModificationMalwareDetectionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileModificationMalwareDetectionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'mac-1.localwas detected modifying a malicious fileaircrackin/private/var/root/write_malware/modules/write_malware/aircrackviaPython(5995)/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Pythonmain.py-amodifyvia parent processPython(97)with resultsuccessf0954d9673878b2223b00b7ec770c7b438d876a9bb44ec78457e5c618f31f52b' + ); + }); + + test('it renders a Malware File Rename Prevented alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'rename', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_RENAMING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance(mockEndpointFileRenameMalwarePreventionAlert) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileRenameMalwarePreventionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'win2019-endpoint-1was prevented from renaming a malicious file23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exeinC:\\Users\\sean\\Downloads\\23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exeviaexplorer.exe(1008)C:\\Windows\\Explorer.EXEvia parent processC:\\Windows\\System32\\userinit.exe(356)with resultsuccess23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97' + ); + }); + + test('it renders a Malware File Rename Detected alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'rename', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_RENAMING_A_MALICIOUS_FILE, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance(mockEndpointFileRenameMalwareDetectionAlert) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileRenameMalwareDetectionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'win2019-endpoint-1was detected renaming a malicious file23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exeinC:\\Users\\sean\\Downloads\\23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97.exeviaexplorer.exe(1008)C:\\Windows\\Explorer.EXEvia parent processC:\\Windows\\System32\\userinit.exe(356)with resultsuccess23361f8f413dd9258545030e42056a352fe35f66bac376d49954551c9b4bcf97' + ); + }); + + test('it renders a Malware Process Execution Prevented alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'execution', + eventCategory: 'process', + eventType: 'denied', + skipRedundantFileDetails: true, + text: i18n.WAS_PREVENTED_FROM_EXECUTING_A_MALICIOUS_PROCESS, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointProcessExecutionMalwarePreventionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointProcessExecutionMalwarePreventionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'win2019-endpoint-1was prevented from executing a malicious processC:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe(6920)C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exewith resultsuccess3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb' + ); + }); + + test('it renders a Malware Process Execution Detected alert', () => { + const endpointAlertCriteria: EndpointAlertCriteria = { + eventAction: 'execution', + eventCategory: 'process', + eventType: 'allowed', + skipRedundantFileDetails: true, + text: i18n.WAS_DETECTED_EXECUTING_A_MALICIOUS_PROCESS, + }; + + const endpointAlertsRowRenderer = createEndpointAlertsRowRenderer(endpointAlertCriteria); + + const wrapper = mount( + + {endpointAlertsRowRenderer.isInstance( + mockEndpointProcessExecutionMalwareDetectionAlert + ) && + endpointAlertsRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointProcessExecutionMalwareDetectionAlert, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'DESKTOP-1was detected executing a malicious processmimikatz_write.exe(8668)c:\\temp\\mimikatz_write.exevia parent processpython.exewith resultsuccess263f09eeee80e03aa27a2d19530e2451978e18bf733c5f1c64ff2389c5dc17b0' + ); + }); + }); + describe('#createEndgameProcessRowRenderer', () => { + test('it renders an endpoint Process Exec event', () => { + const actionName = 'exec'; + const text = i18n.EXECUTED_PROCESS; + + const endpointProcessStartRowRenderer = createEndgameProcessRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointProcessStartRowRenderer.isInstance(mockEndpointProcessExecEvent) && + endpointProcessStartRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointProcessExecEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'admin@test-mac.localexecuted processmdworker_shared(4454)/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared-smdworker-cMDSImporterWorker-mcom.apple.mdworker.sharedvia parent processlaunchd(1)4bc018ac461706496302d1faab0a8bb39aad974eb432758665103165f3a2dd2b' + ); + }); + + test('it renders an endpoint Process Fork event', () => { + const actionName = 'fork'; + const text = i18n.FORKED_PROCESS; + + const endpointProcessStartRowRenderer = createEndgameProcessRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointProcessStartRowRenderer.isInstance(mockEndpointProcessForkEvent) && + endpointProcessStartRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointProcessForkEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'admin@test-mac.localforked processzoom.us(4042)/Applications/zoom.us.app/Contents/MacOS/zoom.usvia parent processzoom.us(3961)cbf3d059cc9f9c0adff5ef15bf331b95ab381837fa0adecd965a41b5846f4bd4' + ); + }); + test('it renders an endpoint process start event', () => { const actionName = 'start'; const text = i18n.PROCESS_STARTED; @@ -219,7 +575,7 @@ describe('GenericRowRenderer', () => { ); expect(wrapper.text()).toEqual( - 'SYSTEM\\NT AUTHORITY@win2019-endpoint-1started processconhost.exe(3636)C:\\Windows\\system32\\conhost.exe,0xffffffff,-ForceV1697334c236cce7d4c9e223146ee683a1219adced9729d4ae771fd6a1502a6b63e19da2c35ba1c38adf12d1a472c1fcf1f1a811a71b0e9b5fcb62de0787235ecca560b610' + 'SYSTEM\\NT AUTHORITY@win2019-endpoint-1started processconhost.exe(3636)C:\\Windows\\system32\\conhost.exe,0xffffffff,-ForceV1697334c236cce7d4c9e223146ee683a1219adced9729d4ae771fd6a1502a6b63' ); }); @@ -247,7 +603,7 @@ describe('GenericRowRenderer', () => { ); expect(wrapper.text()).toEqual( - 'Arun\\Anvi-Acer@HD-obe-8bf77f54started processMicrosoft.Photos.exe(441684)C:\\Program Files\\WindowsApps\\Microsoft.Windows.Photos_2018.18091.17210.0_x64__8wekyb3d8bbwe\\Microsoft.Photos.exe-ServerName:App.AppXzst44mncqdg84v7sv6p7yznqwssy6f7f.mcavia parent processsvchost.exe(8)d4c97ed46046893141652e2ec0056a698f6445109949d7fcabbce331146889ee12563599116157778a22600d2a163d8112aed84562d06d7235b37895b68de56687895743' + 'Arun\\Anvi-Acer@HD-obe-8bf77f54started processMicrosoft.Photos.exe(441684)C:\\Program Files\\WindowsApps\\Microsoft.Windows.Photos_2018.18091.17210.0_x64__8wekyb3d8bbwe\\Microsoft.Photos.exe-ServerName:App.AppXzst44mncqdg84v7sv6p7yznqwssy6f7f.mcavia parent processsvchost.exe(8)d4c97ed46046893141652e2ec0056a698f6445109949d7fcabbce331146889ee' ); }); @@ -272,7 +628,7 @@ describe('GenericRowRenderer', () => { ); 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' + 'SYSTEM\\NT AUTHORITY@win2019-endpointterminated processsvchost.exe(10392)C:\\Windows\\System32\\svchost.exe,-k,netsvcs,-p,-s,NetSetupSvcwith exit code-1via parent processservices.exe7fd065bac18c5278777ae44908101cdfed72d26fa741367f0ad4d02020787ab6' ); }); @@ -300,7 +656,7 @@ describe('GenericRowRenderer', () => { ); expect(wrapper.text()).toEqual( - 'Arun\\Anvi-Acer@HD-obe-8bf77f54terminated processRuntimeBroker.exe(442384)with exit code087976f3430cc99bc939e0694247c0759961a49832b87218f4313d6fc0bc3a776797255e72d5ed5c058d4785950eba7abaa057653bd4401441a21bf1abce6404f4231db4d' + 'Arun\\Anvi-Acer@HD-obe-8bf77f54terminated processRuntimeBroker.exe(442384)with exit code087976f3430cc99bc939e0694247c0759961a49832b87218f4313d6fc0bc3a776' ); }); @@ -470,6 +826,81 @@ describe('GenericRowRenderer', () => { ); }); + test('it renders an endpoint File (FIM) Modification event', () => { + const actionName = 'modification'; + const text = i18n.MODIFIED_FILE; + + const endpointFileModificationRowRenderer = createFimRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointFileModificationRowRenderer.isInstance(mockEndpointFileModificationEvent) && + endpointFileModificationRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileModificationEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'admin@test-Mac.localmodified a file.dat.nosync01a5.6hoWv1in/Users/admin/Library/Application Support/CrashReporter/.dat.nosync01a5.6hoWv1viadiagnostics_agent(421)' + ); + }); + + test('it renders an endpoint File (FIM) Overwrite event', () => { + const actionName = 'overwrite'; + const text = i18n.OVERWROTE_FILE; + + const endpointFileOverwriteRowRenderer = createFimRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointFileOverwriteRowRenderer.isInstance(mockEndpointFileOverwriteEvent) && + endpointFileOverwriteRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileOverwriteEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'LOCAL SERVICE\\NT AUTHORITY@windows-endpoint-1overwrote a filelastalive0.datinC:\\Windows\\ServiceState\\EventLog\\Data\\lastalive0.datviasvchost.exe(1228)' + ); + }); + + test('it renders an endpoint File (FIM) Rename event', () => { + const actionName = 'rename'; + const text = i18n.RENAMED_FILE; + + const endpointFileRenameRowRenderer = createFimRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointFileRenameRowRenderer.isInstance(mockEndpointFileRenameEvent) && + endpointFileRenameRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointFileRenameEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'LOCAL SERVICE\\NT AUTHORITY@windows-endpoint-1renamed a fileSRU.loginC:\\Windows\\System32\\sru\\SRU.logfrom its original pathC:\\Windows\\System32\\sru\\SRUtmp.logviasvchost.exe(1204)' + ); + }); + test('it renders an endgame file_delete_event', () => { const actionName = 'file_delete_event'; const text = i18n.DELETED_FILE; @@ -667,6 +1098,87 @@ describe('GenericRowRenderer', () => { ); }); + describe('#createEndpointRegistryRowRenderer', () => { + test('it renders an endpoint Registry Modification event', () => { + const actionName = 'modification'; + const text = i18n.MODIFIED_REGISTRY_KEY; + + const endpointRegistryModificationRowRenderer = createEndpointRegistryRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointRegistryModificationRowRenderer.isInstance( + mockEndpointRegistryModificationEvent + ) && + endpointRegistryModificationRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointRegistryModificationEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'SYSTEM\\NT AUTHORITY@win2019-endpoint-1modified registry keySOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentStatewith new valueHKLM\\SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState\\StateValueviaGoogleUpdate.exe(7408)' + ); + }); + }); + + describe('#createEndpointLibraryRowRenderer', () => { + test('it renders an endpoint Library Load event', () => { + const actionName = 'load'; + const text = i18n.LOADED_LIBRARY; + + const endpointLibraryLoadRowRenderer = createEndpointLibraryRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointLibraryLoadRowRenderer.isInstance(mockEndpointLibraryLoadEvent) && + endpointLibraryLoadRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointLibraryLoadEvent, + timelineId: 'test', + })} + + ); + + expect(wrapper.text()).toEqual( + 'SYSTEM\\NT AUTHORITY@win2019-endpoint-1loaded librarybcrypt.dllinC:\\Windows\\System32\\bcrypt.dllviasshd.exe(9644)e70f5d8f87aab14e3160227d38387889befbe37fa4f8f5adc59eff52804b35fd' + ); + }); + }); + + test('it renders an Endpoint network HTTP Request event', () => { + const actionName = 'http_request'; + const text = i18n.MADE_A_HTTP_REQUEST_VIA; + + const endpointHttpRequestEventRowRenderer = createSocketRowRenderer({ + actionName, + text, + }); + + const wrapper = mount( + + {endpointHttpRequestEventRowRenderer.isInstance(mockEndpointNetworkHttpRequestEvent) && + endpointHttpRequestEventRowRenderer.renderRow({ + browserFields: mockBrowserFields, + data: mockEndpointNetworkHttpRequestEvent, + timelineId: 'test', + })} + + ); + + expect(removeExternalLinkText(wrapper.text())).toEqual( + 'NETWORK SERVICE\\NT AUTHORITY@win2019-endpoint-1made a http request viasvchost.exe(2232)Endpoint network eventoutgoinghttptcpSource10.1.2.3:51570Destination10.11.12.13:80North AmericaUnited States🇺🇸USArizonaPhoenix' + ); + }); + test('it renders an Endgame ipv4_connection_accept_event', () => { const actionName = 'ipv4_connection_accept_event'; const text = i18n.ACCEPTED_A_CONNECTION_VIA; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.tsx index 69a6317ebcd11..211fa9152dc8d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/generic_row_renderer.tsx @@ -15,6 +15,7 @@ import { RowRendererId } from '../../../../../../../common/types/timeline'; import { DnsRequestEventDetails } from '../dns/dns_request_event_details'; import { EndgameSecurityEventDetails } from '../endgame/endgame_security_event_details'; import { isFileEvent, isNillEmptyOrNotFinite } from '../helpers'; +import { RegistryEventDetails } from '../registry/registry_event_details'; import { RowRenderer, RowRendererContainer } from '../row_renderer'; import { SystemGenericDetails } from './generic_details'; @@ -115,6 +116,86 @@ export const createFimRowRenderer = ({ ), }); +export interface EndpointAlertCriteria { + eventAction: string; + eventCategory: string; + eventType: string; + skipRedundantFileDetails?: boolean; + skipRedundantProcessDetails?: boolean; + text: string; +} + +export const createEndpointAlertsRowRenderer = ({ + eventAction, + eventCategory, + eventType, + skipRedundantFileDetails = false, + skipRedundantProcessDetails = false, + text, +}: EndpointAlertCriteria): RowRenderer => ({ + id: RowRendererId.alerts, + isInstance: (ecs) => { + const action: string[] | null | undefined = get('event.action', ecs); + const category: string[] | null | undefined = get('event.category', ecs); + const dataset: string | null | undefined = get('event.dataset[0]', ecs); + const type: string[] | null | undefined = get('event.type', ecs); + + const eventActionMatches = action?.includes(eventAction) ?? false; + const eventCategoryMatches = category?.includes(eventCategory) ?? false; + const eventTypeMatches = type?.includes(eventType) ?? false; + + return ( + dataset?.toLowerCase() === 'endpoint.alerts' && + eventTypeMatches && + eventCategoryMatches && + eventActionMatches + ); + }, + renderRow: ({ browserFields, data, timelineId }) => ( + + + + ), +}); + +export const createEndpointLibraryRowRenderer = ({ + actionName, + text, +}: { + actionName: string; + text: string; +}): RowRenderer => ({ + id: RowRendererId.library, + isInstance: (ecs) => { + const action: string | null | undefined = get('event.action[0]', ecs); + const dataset: string | null | undefined = get('event.dataset[0]', ecs); + return ( + dataset?.toLowerCase() === 'endpoint.events.library' && action?.toLowerCase() === actionName + ); + }, + renderRow: ({ browserFields, data, timelineId }) => ( + + + + ), +}); + export const createGenericFileRowRenderer = ({ actionName, text, @@ -218,6 +299,34 @@ export const createDnsRowRenderer = (): RowRenderer => ({ ), }); +export const createEndpointRegistryRowRenderer = ({ + actionName, + text, +}: { + actionName: string; + text: string; +}): RowRenderer => ({ + id: RowRendererId.registry, + isInstance: (ecs) => { + const action: string | null | undefined = get('event.action[0]', ecs); + const dataset: string | null | undefined = get('event.dataset[0]', ecs); + + return ( + dataset?.toLowerCase() === 'endpoint.events.registry' && action?.toLowerCase() === actionName + ); + }, + renderRow: ({ browserFields, data, timelineId }) => ( + + + + ), +}); + const systemLoginRowRenderer = createGenericSystemRowRenderer({ actionName: 'user_login', text: i18n.ATTEMPTED_LOGIN, @@ -238,6 +347,11 @@ const endpointProcessStartRowRenderer = createEndgameProcessRowRenderer({ text: i18n.PROCESS_STARTED, }); +const endpointRegistryModificationRowRenderer = createEndpointRegistryRowRenderer({ + actionName: 'modification', + text: i18n.MODIFIED_REGISTRY_KEY, +}); + const systemProcessStoppedRowRenderer = createGenericFileRowRenderer({ actionName: 'process_stopped', text: i18n.PROCESS_STOPPED, @@ -278,6 +392,21 @@ const endpointFileDeletionEventRowRenderer = createFimRowRenderer({ text: i18n.DELETED_FILE, }); +const endpointModificationEventRowRenderer = createFimRowRenderer({ + actionName: 'modification', + text: i18n.MODIFIED_FILE, +}); + +const endpointFileOverwriteEventRowRenderer = createFimRowRenderer({ + actionName: 'overwrite', + text: i18n.OVERWROTE_FILE, +}); + +const endpointFileRenamedEventRowRenderer = createFimRowRenderer({ + actionName: 'rename', + text: i18n.RENAMED_FILE, +}); + const fimFileDeletedEventRowRenderer = createFimRowRenderer({ actionName: 'deleted', text: i18n.DELETED_FILE, @@ -288,6 +417,88 @@ const systemExistingRowRenderer = createGenericFileRowRenderer({ text: i18n.EXISTING_PROCESS, }); +const endpointAlertCriteria: EndpointAlertCriteria[] = [ + { + eventAction: 'creation', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_CREATING_A_MALICIOUS_FILE, + }, + { + eventAction: 'creation', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_CREATING_A_MALICIOUS_FILE, + }, + { + eventAction: 'files-encrypted', + eventCategory: 'file', + eventType: 'denied', + skipRedundantFileDetails: true, + text: i18n.RANSOMWARE_WAS_PREVENTED_FROM_ENCRYPTING_FILES, + }, + { + eventAction: 'files-encrypted', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantFileDetails: true, + text: i18n.RANSOMWARE_WAS_DETECTED_ENCRYPTING_FILES, + }, + { + eventAction: 'modification', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_MODIFYING_A_MALICIOUS_FILE, + }, + { + eventAction: 'modification', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_MODIFYING_A_MALICIOUS_FILE, + }, + { + eventAction: 'rename', + eventCategory: 'file', + eventType: 'denied', + skipRedundantProcessDetails: true, + text: i18n.WAS_PREVENTED_FROM_RENAMING_A_MALICIOUS_FILE, + }, + { + eventAction: 'rename', + eventCategory: 'file', + eventType: 'allowed', + skipRedundantProcessDetails: true, + text: i18n.WAS_DETECTED_RENAMING_A_MALICIOUS_FILE, + }, + { + eventAction: 'execution', + eventCategory: 'process', + eventType: 'denied', + skipRedundantFileDetails: true, + text: i18n.WAS_PREVENTED_FROM_EXECUTING_A_MALICIOUS_PROCESS, + }, + { + eventAction: 'execution', + eventCategory: 'process', + eventType: 'allowed', + skipRedundantFileDetails: true, + text: i18n.WAS_DETECTED_EXECUTING_A_MALICIOUS_PROCESS, + }, +]; + +const endpointAlertsRowRenderers: RowRenderer[] = endpointAlertCriteria.map((criteria) => + createEndpointAlertsRowRenderer(criteria) +); + +const endpointLibraryLoadRowRenderer = createEndpointLibraryRowRenderer({ + actionName: 'load', + text: i18n.LOADED_LIBRARY, +}); + const systemSocketOpenedRowRenderer = createSocketRowRenderer({ actionName: 'socket_opened', text: i18n.SOCKET_OPENED, @@ -308,6 +519,21 @@ const endpointConnectionAcceptedEventRowRenderer = createSocketRowRenderer({ text: i18n.ACCEPTED_A_CONNECTION_VIA, }); +const endpointHttpRequestEventRowRenderer = createSocketRowRenderer({ + actionName: 'http_request', + text: i18n.MADE_A_HTTP_REQUEST_VIA, +}); + +const endpointProcessExecRowRenderer = createEndgameProcessRowRenderer({ + actionName: 'exec', + text: i18n.EXECUTED_PROCESS, +}); + +const endpointProcessForkRowRenderer = createEndgameProcessRowRenderer({ + actionName: 'fork', + text: i18n.FORKED_PROCESS, +}); + const endgameIpv6ConnectionAcceptEventRowRenderer = createSocketRowRenderer({ actionName: 'ipv6_connection_accept_event', text: i18n.ACCEPTED_A_CONNECTION_VIA, @@ -448,8 +674,17 @@ export const systemRowRenderers: RowRenderer[] = [ endpointFileCreationEventRowRenderer, endgameFileDeleteEventRowRenderer, endpointFileDeletionEventRowRenderer, + endpointFileOverwriteEventRowRenderer, + endpointFileRenamedEventRowRenderer, + ...endpointAlertsRowRenderers, + endpointLibraryLoadRowRenderer, + endpointModificationEventRowRenderer, + endpointRegistryModificationRowRenderer, endgameIpv4ConnectionAcceptEventRowRenderer, endpointConnectionAcceptedEventRowRenderer, + endpointHttpRequestEventRowRenderer, + endpointProcessExecRowRenderer, + endpointProcessForkRowRenderer, endgameIpv6ConnectionAcceptEventRowRenderer, endgameIpv4DisconnectReceivedEventRowRenderer, endpointDisconnectReceivedEventRowRenderer, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/translations.ts index e007746ea5cc3..266579fbc228e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/system/translations.ts @@ -91,6 +91,62 @@ export const DELETED_FILE = i18n.translate('xpack.securitySolution.system.delete defaultMessage: 'deleted a file', }); +export const EXECUTED_PROCESS = i18n.translate( + 'xpack.securitySolution.rowRenderer.executedProcessDescription', + { + defaultMessage: 'executed process', + } +); + +export const FORKED_PROCESS = i18n.translate( + 'xpack.securitySolution.rowRenderer.forkedProcessDescription', + { + defaultMessage: 'forked process', + } +); + +export const LOADED_LIBRARY = i18n.translate( + 'xpack.securitySolution.rowRenderer.loadedLibraryDescription', + { + defaultMessage: 'loaded library', + } +); + +export const MADE_A_HTTP_REQUEST_VIA = i18n.translate( + 'xpack.securitySolution.rowRenderer.madeAHttpRequestViaDescription', + { + defaultMessage: 'made a http request via', + } +); + +export const MODIFIED_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.modifiedFileDescription', + { + defaultMessage: 'modified a file', + } +); + +export const MODIFIED_REGISTRY_KEY = i18n.translate( + 'xpack.securitySolution.rowRenderer.modifiedRegistryKeyDescription', + { + defaultMessage: 'modified registry key', + } +); + +export const OVERWROTE_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.overwroteFileDescription', + { + defaultMessage: 'overwrote a file', + } +); + +export const RENAMED_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.renamedFileDescription', + { + defaultMessage: 'renamed a file', + } +); + export const EXISTING_PROCESS = i18n.translate( 'xpack.securitySolution.system.existingProcessDescription', { @@ -207,6 +263,76 @@ export const VIA_PARENT_PROCESS = i18n.translate( } ); +export const RANSOMWARE_WAS_PREVENTED_FROM_ENCRYPTING_FILES = i18n.translate( + 'xpack.securitySolution.rowRenderer.ransomwareWasPreventedFromeEcryptingFilesDescription', + { + defaultMessage: 'ransomware was prevented from encrypting files', + } +); + +export const RANSOMWARE_WAS_DETECTED_ENCRYPTING_FILES = i18n.translate( + 'xpack.securitySolution.rowRenderer.ransomwareWasDetectedEcryptingFilesDescription', + { + defaultMessage: 'ransomware was detected encrypting files', + } +); + +export const WAS_DETECTED_CREATING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasDetectedCreatingAMaliciousFileDescription', + { + defaultMessage: 'was detected creating a malicious file', + } +); + +export const WAS_PREVENTED_FROM_CREATING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasPreventedFromCreatingAMaliciousFileDescription', + { + defaultMessage: 'was prevented from creating a malicious file', + } +); + +export const WAS_DETECTED_MODIFYING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasDetectedModifyingAMaliciousFileDescription', + { + defaultMessage: 'was detected modifying a malicious file', + } +); + +export const WAS_PREVENTED_FROM_MODIFYING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasPreventedFromModifyingAMaliciousFileDescription', + { + defaultMessage: 'was prevented from modifying a malicious file', + } +); + +export const WAS_DETECTED_RENAMING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasDetectedRenamingAMaliciousFileDescription', + { + defaultMessage: 'was detected renaming a malicious file', + } +); + +export const WAS_PREVENTED_FROM_RENAMING_A_MALICIOUS_FILE = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasPreventedFromRenamingAMaliciousFileDescription', + { + defaultMessage: 'was prevented from renaming a malicious file', + } +); + +export const WAS_DETECTED_EXECUTING_A_MALICIOUS_PROCESS = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasDetectedExecutingAMaliciousProcessDescription', + { + defaultMessage: 'was detected executing a malicious process', + } +); + +export const WAS_PREVENTED_FROM_EXECUTING_A_MALICIOUS_PROCESS = i18n.translate( + 'xpack.securitySolution.rowRenderer.wasPreventedFromExecutingAMaliciousProcessDescription', + { + defaultMessage: 'was prevented from executing a malicious process', + } +); + export const WITH_EXIT_CODE = i18n.translate( 'xpack.securitySolution.system.withExitCodeDescription', { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts index 132501a33d724..476fd77ce0647 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/translations.ts @@ -15,6 +15,13 @@ export const DESTINATION = i18n.translate('xpack.securitySolution.timeline.desti defaultMessage: 'Destination', }); +export const FROM_ITS_ORIGINAL_PATH = i18n.translate( + 'xpack.securitySolution.timeline.file.fromOriginalPathDescription', + { + defaultMessage: 'from its original path', + } +); + export const PROTOCOL = i18n.translate('xpack.securitySolution.timeline.protocol', { defaultMessage: 'Protocol', }); diff --git a/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts index 41523c7869db0..79da343cb2733 100644 --- a/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts @@ -144,10 +144,13 @@ export const timelineSchema = gql` } enum RowRendererId { + alerts auditd auditd_file + library netflow plain + registry suricata system system_dns diff --git a/x-pack/plugins/security_solution/server/graphql/types.ts b/x-pack/plugins/security_solution/server/graphql/types.ts index 0d6a0e63455b0..c8f8b0f634458 100644 --- a/x-pack/plugins/security_solution/server/graphql/types.ts +++ b/x-pack/plugins/security_solution/server/graphql/types.ts @@ -289,10 +289,13 @@ export enum DataProviderType { } export enum RowRendererId { + alerts = 'alerts', auditd = 'auditd', auditd_file = 'auditd_file', + library = 'library', netflow = 'netflow', plain = 'plain', + registry = 'registry', suricata = 'suricata', system = 'system', system_dns = 'system_dns', diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts b/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts index 5e9391df5b8a4..5ed324496e609 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts @@ -70,6 +70,7 @@ export const TIMELINE_EVENTS_FIELDS = [ 'auditd.summary.how', 'auditd.summary.message_type', 'auditd.summary.sequence', + 'file.Ext.original.path', 'file.name', 'file.target_path', 'file.extension', @@ -95,6 +96,8 @@ export const TIMELINE_EVENTS_FIELDS = [ 'host.os.family', 'host.id', 'host.ip', + 'registry.key', + 'registry.path', 'rule.reference', 'source.bytes', 'source.packets',