[SIEM] Endgame Row Renderers: DNS, File (FIM), Network, Security (Authentication), Process (#48277)

## [SIEM] Endgame Row Renderers: DNS, File (FIM), Network, Security (Authentication), Process

This PR renders Endgame events via _row renderers_ in the Timeline, per the following screenshot:

![endgame-row-renderers](https://user-images.githubusercontent.com/4459398/66854649-fa6d7900-ef3e-11e9-97cc-5b229041f186.png)

The following Endgame event types / subtypes will be rendered via row renderers in the Timeline:

* DNS (`dns_event`)
  - [X] `request_event`
* File (FIM) (`file_event`)
  - [X] `file_create_event`
  - [X] `file_delete_event`
* Network (`network_event`)
  - [X] `ipv4_connection_accept_event`
  - [X] `ipv6_connection_accept_event`
  - [X] `ipv4_disconnect_received_event`
  - [X] `ipv6_disconnect_received_event`
* Security (Authentication) (`security_event`)
  - [X] `user_logon`
  - [X] `admin_logon`
  - [X] `explicit_user_logon`
  - [X] `user_logoff`
* Process (`process_event`)
  - [X] `creation_event`
  - [X] `termination_event`

This PR also adds row rendering support for some non-Endgame events that conform to the [Elastic Common Schema](https://www.elastic.co/guide/en/ecs/current/index.html) (ECS):
* DNS requests
* FIM file creation events
* FIM file deletion events

RELEASE NOTE: To view Endgame events in existing SIEM deployments, you must manually add `endgame-*` to the SIEM index pattern in `Kibana Management > Advanced Settings > SIEM > Elasticsearch indices`.

## DNS Request events

Endgame DNS events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: dns_event and endgame.event_subtype_full: request_event
```

_To view these Endgame DNS events in a timeline, add `endgame-*` to the `SIEM` > `Elasticsearch indices` setting in Kibana `Advanced Settings`, then paste the query above into a timeline to view events._

### Runtime matching criteria

All DNS events, including Endgame and non-Endgame DNS events matching the following criteria will be rendered:

```
dns.question.type: * and dns.question.name: *
```

_The query above can be executed in a timeline to view all data that will be rendered via the (new) DNS event row renderer._

### Sample rendered DNS event

![endgame-dns-event](https://user-images.githubusercontent.com/4459398/66856414-643b5200-ef42-11e9-8d50-894b7f7abf3d.png)

Each field with `this formatting` will be draggable (to pivot a search) in the row-rendered event:

`Arun` \ `Anvi-Acer` @ `HD-obe-8bf77f54` asked for `clients4.google.com` with question type `A`, which resolved to `10.58.197.78` (response code: `NOERROR`) via `chrome.exe` `(11620)` [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `3008`]

### Fields in a DNS event

The following fields will be used to render a DNS event:

`user.name` \ `user.domain`  @ `host.name` asked for `dns.question.name` with question type `dns.question.type`, which resolved to `dns.resolved_ip` (resp code: `dns.response_code`) via `process.name` `(process.pid)` [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `event.code | winlog.event_id`]

Note: At the time of this writing, Endgame DNS events do not populate `dns.response_code`. Row renderers are designed to still render partial results when fields are missing. In this case the following text:

> (resp code: `dns.response_code`)

will NOT be rendered, but the other (populated) fields in the DNS event will be rendered.

### Additional Rendering of DNS events by the Netflow row renderer

In addition to being rendered by the new DNS renderer described above, DNS events will also be rendered by the Netflow row renderer.

The Neflow row renderer shows the directionality, protocol, and flow of data between a source and destination

### Non-Endgame DNS events

The following screenshot shows a DNS event from `packetbeat` rendered by the new DNS row renderer:

![non-endgame-dns-event](https://user-images.githubusercontent.com/4459398/66857061-b7fa6b00-ef43-11e9-894a-d717539db96c.png)

_A non-Endgame DNS event that conforms to ECS_

## File (FIM) Creation events

Endgame File (FIM) Creation events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: file_event and endgame.event_subtype_full: file_create_event
```

### Runtime matching criteria

All file creation events, including Endgame and non-Endgame events matching the following criteria will be rendered:

```
(event.category: file and event.action: file_create_event) or (event.dataset: file and event.action: created)
```

### Sample rendered File (FIM) Creation event

![file-create-event](https://user-images.githubusercontent.com/4459398/66857794-3f94a980-ef45-11e9-9030-fff35403e8f4.png)

`Arun` \ `Anvi-Acer` @ `HD-obe-8bf77f54` created file `the-real-index~RFa99cd75.TMP` in `C:\Users\Arun\AppData\Local\Google\Chrome\User Data\Default\Service Worker\CacheStorage\579544fd7d0441717f082c9eb123588966aa57ac\d81a98b1-59b9-43b2-a228-b3daf7da56df\index-dir\the-real-index~RFa99cd75.TMP` via `chrome.exe` `(11620)`

### Fields in a File (FIM) Creation event

`user.name` \ `user.domain` @ `host.name` created file `file.name | endgame.file_name` in `file.path | endgame.file_path` via `process.name | endgame.process_name` `(process.pid | endgame.pid)`

## File (FIM) Deletion events

Endgame File (FIM) Deletion events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: file_event and endgame.event_subtype_full: file_delete_event
```

### Runtime matching criteria

All file deletion events, including Endgame and non-Endgame events matching the following criteria will be rendered:

```
(event.category: file and event.action: file_delete_event) or (event.dataset: file and event.action: deleted)
```

### Sample rendered File (FIM) Deletion event

![file-delete-event](https://user-images.githubusercontent.com/4459398/66857970-9a2e0580-ef45-11e9-97bb-219c8673a2f2.png)

`SYSTEM` \ `NT AUTHORITY` @ `HD-v1s-d2118419` deleted file `tmp0000031a` in `C:\Windows\TEMP\tmp00000404\tmp0000031a` via `AmSvc.exe` `(1084)`

### Fields in a File (FIM) Deletion event

`user.name` \ `user.domain` @ `host.name` deleted file `file.name | endgame.file_name` in `file.path | endgame.file_path` via `process.name | endgame.process_name` `(process.pid | endgame.pid)`

## Network Connection Accepted events

Endgame Network Connection Accepted events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
(endgame.event_type_full: network_event and endgame.event_subtype_full: ipv4_connection_accept_event) or (endgame.event_type_full: network_event and endgame.event_subtype_full: ipv6_connection_accept_event)
````

### Runtime matching criteria

All Endgame Connection Accepted events, and existing "socket opened" events matching the following criteria will be rendered:

```
event.action: ipv4_connection_accept_event or event.action: ipv6_connection_accept_event or event.action: socket_opened
```

### Sample rendered Network Connection Accepted event

![ipv4-connection-accept-event](https://user-images.githubusercontent.com/4459398/66858241-16c0e400-ef46-11e9-9fa8-f8b852490bd8.png)

`SYSTEM` \ `NT AUTHORITY` @ `HD-gqf-0af7b4fe` accepted a connection via `AmSvc.exe` `(1084)`

Network Connection Accepted events are also be rendered with the Netflow row renderer, like the `event.action: socket_opened` events are rendered today. The Network Connection Accepted row renderer displays information about the principal actors in the event (i.e. `user.name`, `host.name`, `process.name`), and the Netflow row renderer displays information about the directionality, source / destination, protocol, etc.

### Fields in a Network Connection Accepted event

`user.name` \ `user.domain` @ `host.name` accepted a connection via `process.name` `(process.pid)`

## Network Disconnect Received events

Endgame Network Disconnect Received events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
(endgame.event_type_full: network_event and endgame.event_subtype_full: ipv4_disconnect_received_event) or (endgame.event_type_full: network_event and endgame.event_subtype_full: ipv6_disconnect_received_event)
````
### Runtime matching criteria

All Endgame Network Disconnect Received events, and existing "socket closed" events matching the following criteria will be rendered:

```
event.action: ipv4_disconnect_received_event or event.action: ipv6_disconnect_received_event or event.action: socket_closed
```

### Sample rendered Network Disconnect Received event

![ipv4-disconnect-received-event](https://user-images.githubusercontent.com/4459398/66859155-fa25ab80-ef47-11e9-995c-7628fc0885bf.png)

`SYSTEM` \ `NT AUTHORITY` @ `HD-gqf-0af7b4fe` disconnected via `AmSvc.exe` `(1084)`

The existing row renderer for `event.action: socket_closed` will be enhanced to display additional fields:
- `user.domain`
- `process.pid`

Network Disconnect Received events will also be rendered with the Netflow row renderer, like the `event.action: socket_closed` events are rendered today. The Network Connection Accepted row renderer displays information about the principal actors in the event (i.e. `user.name`, `host.name`, `process.name`), and the Netflow row renderer displays information about the directionality, source / destination, protocol, etc.

### Fields in a Network Disconnect Received event

`user.name` \ `user.domain` @ `host.name` disconnected via `process.name` `(process.pid)`

## Security (Authentication) User Logon events

Endgame Security (Authentication) User Logon events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: security_event and endgame.event_subtype_full: user_logon
```

### Runtime matching criteria

Security (Authentication) User Logon events matching the following criteria will be rendered:

```
event.category: authentication and event.action: user_logon
```

### Sample rendered Security (Authentication) User Logon event

![user-logon](https://user-images.githubusercontent.com/4459398/66859339-525cad80-ef48-11e9-851c-c08c302df0fc.png)

`SYSTEM` \ `NT AUTHORITY` @ `HD-v1s-d2118419` successfully logged in using logon type `5 - Service` (target logon ID `0x3e7`) via `C:\Windows\System32\services.exe` (`432`) as requested by subject `WIN-Q3DOP1UKA81$` \ `WORKGROUP` (source logon ID `0x3e7`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `4624`]

### Fields in an Security (Authentication) User Logon event

`user.name` \ `user.domain` @ `host.name` successfully logged in using logon type `endgame.logon_type` (target logon ID `endgame.target_logon_id`) via `process.name | process.executable` (`process.pid`) as requested by subject `endgame.subject_user_name` \ `endgame.subject_domain_name` (subject logon ID `endgame.subject_logon_id`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `event.code | winlog.event_id`]

### Reference: LogonType Enumerations

The following enumerated values will humanize the numeric `endgame.logon_type` field:

```
2 - Interactive
3 - Network
4 - Batch
5 - Service
7 - Unlock
8 - Network Cleartext
9 - New Credentials
10 - Remote Interactive
11 - Cached Interactive
```

## Security (Authentication) Admin Logon events

Endgame Security (Authentication) Admin Logon events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: security_event and endgame.event_subtype_full: admin_logon
```

### Runtime matching criteria

Security (Authentication) Admin Logon events matching the following criteria will be rendered:

```
event.category: authentication and event.action: admin_logon
```

### Sample rendered Security (Authentication) Admin Logon event

![admin-logon](https://user-images.githubusercontent.com/4459398/66860598-bc765200-ef4a-11e9-9e58-a96c2b97f4e1.png)

With special privileges, `SYSTEM` \ `NT AUTHORITY` @ `HD-v1s-d2118419` successfully logged in via `C:\Windows\System32\services.exe` (`964`) as requested by subject `SYSTEM` \ `NT AUTHORITY` (subject logon ID `0x3e7`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `4672`]

### Fields in a Security (Authentication) Admin Logon event

With special privileges, `user.name` \ `user.domain` @ `host.name` successfully logged in via `process.name | process.executable` (`process.pid`) as requested by subject `endgame.subject_user_name` \ `endgame.subject_domain_name` (subject logon ID `endgame.subject_logon_id`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `event.code | winlog.event_id`]

## Security (Authentication) Explicit User Logon events

Endgame Security (Authentication) Explicit User Logon events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: security_event and endgame.event_subtype_full: explicit_user_logon
```

### Runtime matching criteria

Security (Authentication) Explicit User Logon events matching the following criteria will be rendered:

```
event.category: authentication and event.action: explicit_user_logon
```

### Sample rendered Security (Authentication) Explicit User Logon event

![explicit-user-logon](https://user-images.githubusercontent.com/4459398/66860797-170fae00-ef4b-11e9-88c5-befd3dcab070.png)

A login was attempted using explicit credentials `Arun` \ `Anvi-Acer` to `HD-v1s-d2118419` via `C:\Windows\System32\services.exe` (`1736`) as requested by subject `ANVI-ACER$` \ `WORKGROUP` (subject logon ID `0x3e7`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `4648`]

### Fields in an Security (Authentication) Explicit User Logon event

A login was attempted using explicit credentials `endgame.target_user_name` \ `endgame.target_domain_name` to `host.name` via `process.name | process.executable` (`process.pid`) as requested by subject `endgame.subject_user_name` \ `endgame.subject_domain_name` (subject logon ID `endgame.subject_logon_id`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `event.code | winlog.event_id`]

## Security (Authentication) User Logoff events

Endgame Security (Authentication) User Logoff events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: security_event and endgame.event_subtype_full: user_logoff
```

### Runtime matching criteria

Security (Authentication) User Logoff events matching the following criteria will be rendered:

```
event.category: authentication and event.action: user_logoff
```

### Sample rendered Security (Authentication) User Logoff event

![user-logoff](https://user-images.githubusercontent.com/4459398/66861089-9a310400-ef4b-11e9-9f71-b148409c75a7.png)

`Arun` \ `Anvi-Acer` @ `HD-55b-3ec87f66` logged off using logon type `2 - Interactive` (target logon ID `0x16db41e`) via `C:\Windows\System32\services.exe` (`964`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `4634` ]

### Fields in Security (Authentication) User Logoff event

`endgame.target_user_name` \ `endgame.target_domain_name` @ `host.name` logged off using logon type `endgame.logon_type` (target logon ID `endgame.target_logon_id`) via `process.name | process.executable` (`process.pid`) [![windows-logo](https://user-images.githubusercontent.com/4459398/66249835-e3d15180-e6f6-11e9-89c3-5517c5ed1596.png) `event.code | winlog.event_id`]

## Process Creation events

Endgame Process Creation events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: process_event and endgame.event_subtype_full: creation_event
```

### Runtime matching criteria

Process Creation events matching the following criteria will be rendered:

```
event.category: process and event.action: creation_event
```

### Sample rendered Process Creation event

![creation-event](https://user-images.githubusercontent.com/4459398/66861295-fbf16e00-ef4b-11e9-9455-8a1f13463974.png)

`Arun` \ `Anvi-Acer` @ `HD-obe-8bf77f54` started process `Microsoft.Photos.exe` (`441684`) `-ServerName:App.AppXzst44mncqdg84v7sv6p7yznqwssy6f7f.mca` via parent process `svchost.exe` (`8`)

`sha256 d4c97ed46046893141652e2ec0056a698f6445109949d7fcabbce331146889ee`

`sha1 12563599116157778a22600d2a163d8112aed845`

`md5 62d06d7235b37895b68de56687895743`

### Fields in a Process Creation event

The following fields will be used to render a Process Creation event:

`user.name` \ `user.domain` @ `host.name` started process `process.name` (`process.pid`) `process.args` via parent process `endgame.parent_process_name` (`process.ppid`)

`process.hash.sha256`

`process.hash.sha1`

`process.hash.md5`

## Process Termination events

Endgame Process Termination events with the following event type and subtype will be rendered in the Timeline via row renderers:

```
endgame.event_type_full: process_event and endgame.event_subtype_full: termination_event
```

### Runtime matching criteria

Process Termination events matching the following criteria will be rendered:

```
event.category: process and event.action: termination_event
```

### Sample rendered Process Termination event

![termination-event](https://user-images.githubusercontent.com/4459398/66861495-57bbf700-ef4c-11e9-8e6e-923e9c6bab3e.png)

`Arun` \ `Anvi-Acer` @ `HD-obe-8bf77f54` terminated process `RuntimeBroker.exe` (`442384`) with exit code `0`

`sha256 87976f3430cc99bc939e0694247c0759961a49832b87218f4313d6fc0bc3a776`

`sha1 797255e72d5ed5c058d4785950eba7abaa057653`

`md5 bd4401441a21bf1abce6404f4231db4d`

### Fields in a Process Termination event

The following fields will be used to render a Process Termination event:

`user.name` \ `user.domain` @ `host.name` terminated process `process.name` (`process.pid`) with exit code `endgame.exit_code`

`process.hash.sha256`

`process.hash.sha1`

`process.hash.md5`

## Testing

Desk tested in:
* Dark / light mode
* Chrome `77.0.3865.90`
* Firefox `69.0.3`
* Safari `13.0.1`
* NOT tested in IE11 (due to current blocker)

https://github.com/elastic/ecs-dev/issues/178
This commit is contained in:
Andrew Goldstein 2019-10-16 02:30:06 -06:00 committed by GitHub
parent 314ba8269c
commit 730ba21ed4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 4482 additions and 252 deletions

View file

@ -1,10 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Args rendering it renders against shallow snapshot 1`] = `
<Component
args="arg1 arg2 arg3"
contextId="context-123"
eventId="event-123"
processTitle="process-title-1"
/>
<Fragment>
<TokensFlexItem
component="span"
grow={false}
key="context-123-args-0-arg1"
>
<DraggableBadge
contextId="context-123-args-0-arg1"
eventId="event-123"
field="process.args"
value="arg1"
/>
</TokensFlexItem>
<TokensFlexItem
component="span"
grow={false}
key="context-123-args-1-arg2"
>
<DraggableBadge
contextId="context-123-args-1-arg2"
eventId="event-123"
field="process.args"
value="arg2"
/>
</TokensFlexItem>
<TokensFlexItem
component="span"
grow={false}
key="context-123-args-2-arg3"
>
<DraggableBadge
contextId="context-123-args-2-arg3"
eventId="event-123"
field="process.args"
value="arg3"
/>
</TokensFlexItem>
<TokensFlexItem
component="span"
grow={false}
>
<DraggableBadge
contextId="context-123"
eventId="event-123"
field="process.title"
value="process-title-1"
/>
</TokensFlexItem>
</Fragment>
`;

View file

@ -3,6 +3,8 @@
exports[`ProcessDraggable rendering it renders against shallow snapshot 1`] = `
<Component
contextId="context-123"
endgamePid={456}
endgameProcessName="endgame-process-name-123"
eventId="event-123"
processExecutable="process-executable-1"
processName="process-name-1"

View file

@ -5,6 +5,7 @@ exports[`UserHostWorkingDir rendering it renders against shallow snapshot 1`] =
contextId="context-123"
eventId="event-123"
hostName="[hostName-123]"
userDomain="[userDomain-123]"
userName="[userName-123]"
workingDirectory="[working-directory-123]"
/>

View file

@ -10,7 +10,6 @@ import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../mock';
import { getEmptyString } from '../../../empty_value';
import { Args } from './args';
describe('Args', () => {
@ -20,28 +19,60 @@ describe('Args', () => {
<Args
contextId="context-123"
eventId="event-123"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
processTitle="process-title-1"
/>
);
expect(toJson(wrapper)).toMatchSnapshot();
});
test('it returns null if args is undefined', () => {
test('it returns an empty string when both args and process title are undefined', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args
contextId="context-123"
eventId="event-123"
args={undefined}
processTitle="process-title-1"
processTitle={undefined}
/>
</TestProviders>
);
expect(wrapper.isEmptyRender()).toBeTruthy();
expect(wrapper.text()).toEqual('');
});
test('it returns null if args is null', () => {
test('it returns an empty string when both args and process title are null', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args contextId="context-123" eventId="event-123" args={null} processTitle={null} />
</TestProviders>
);
expect(wrapper.text()).toEqual('');
});
test('it returns an empty string when args is an empty array, and title is an empty string', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args contextId="context-123" eventId="event-123" args={[]} processTitle="" />
</TestProviders>
);
expect(wrapper.text()).toEqual('');
});
test('it returns args when args are provided, and process title is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args
contextId="context-123"
eventId="event-123"
args={['arg1', 'arg2', 'arg3']}
processTitle={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('arg1arg2arg3');
});
test('it returns process title when process title is provided, and args is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args
@ -52,21 +83,21 @@ describe('Args', () => {
/>
</TestProviders>
);
expect(wrapper.isEmptyRender()).toBeTruthy();
expect(wrapper.text()).toEqual('process-title-1');
});
test('it returns empty string if args happens to be an empty string', () => {
test('it returns both args and process title, when both are provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<Args
contextId="context-123"
eventId="event-123"
args=""
args={['arg1', 'arg2', 'arg3']}
processTitle="process-title-1"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(getEmptyString());
expect(wrapper.text()).toEqual('arg1arg2arg3process-title-1');
});
});
});

View file

@ -5,30 +5,48 @@
*/
import * as React from 'react';
import { pure } from 'recompose';
import { DraggableBadge } from '../../../draggables';
import { TokensFlexItem } from './helpers';
import { isNillEmptyOrNotFinite, TokensFlexItem } from './helpers';
interface Props {
eventId: string;
args: string[] | null | undefined;
contextId: string;
args: string | null | undefined;
eventId: string;
processTitle: string | null | undefined;
}
export const Args = pure<Props>(({ eventId, contextId, args, processTitle }) =>
args != null ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.title"
queryValue={processTitle != null ? processTitle : ''}
value={args}
/>
</TokensFlexItem>
) : null
);
export const Args = React.memo<Props>(({ args, contextId, eventId, processTitle }) => {
if (isNillEmptyOrNotFinite(args) && isNillEmptyOrNotFinite(processTitle)) {
return null;
}
return (
<>
{args != null &&
args.map((arg, i) => (
<TokensFlexItem key={`${contextId}-args-${i}-${arg}`} grow={false} component="span">
<DraggableBadge
contextId={`${contextId}-args-${i}-${arg}`}
eventId={eventId}
field="process.args"
value={arg}
/>
</TokensFlexItem>
))}
{!isNillEmptyOrNotFinite(processTitle) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.title"
value={processTitle}
/>
</TokensFlexItem>
)}
</>
);
});
Args.displayName = 'Args';

View file

@ -44,7 +44,7 @@ describe('GenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionalice@zeek-sanfranin/generic-text-123gpgconf--list-dirs agent-socket'
'Sessionalice@zeek-sanfranin/generic-text-123gpgconf(5402)gpgconf--list-dirsagent-socketgpgconf --list-dirs agent-socket'
);
});
@ -82,13 +82,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -109,13 +109,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -136,13 +136,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -163,13 +163,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -190,13 +190,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -217,13 +217,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-2]as[username-3]@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-2]as[username-3]@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -244,13 +244,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-1]as[username-2]@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-1]as[username-2]@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -271,13 +271,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -298,13 +298,13 @@ describe('GenericDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
result="success"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123process-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123process-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -408,7 +408,7 @@ describe('GenericDetails', () => {
expect(wrapper.text()).toEqual('Sessiongeneric-text-123some-process-name');
});
test('it returns only session and user name if process title with id is given', () => {
test('it returns session, user name, and process title if process title with id is given', () => {
const wrapper = mountWithIntl(
<TestProviders>
<AuditdGenericLine
@ -430,7 +430,7 @@ describe('GenericDetails', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('Sessionsome-user-name');
expect(wrapper.text()).toEqual('Sessionsome-user-namesome-process-title');
});
test('it returns only a working directory if that is all that is given with a id', () => {
@ -465,7 +465,7 @@ describe('GenericDetails', () => {
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
args="arg1 arg2 arg 3"
args={['arg1', 'arg2', 'arg 3']}
userName={undefined}
secondary={undefined}
session={undefined}
@ -480,7 +480,7 @@ describe('GenericDetails', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('Sessionarg1 arg2 arg 3');
expect(wrapper.text()).toEqual('Sessionarg1arg2arg 3');
});
});
});

View file

@ -34,7 +34,7 @@ interface Props {
processExecutable: string | null | undefined;
processTitle: string | null | undefined;
workingDirectory: string | null | undefined;
args: string | null | undefined;
args: string[] | null | undefined;
session: string | null | undefined;
}
@ -56,7 +56,7 @@ export const AuditdGenericLine = pure<Props>(
session,
text,
}) => (
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<SessionUserHostWorkingDir
eventId={id}
contextId={contextId}
@ -75,6 +75,8 @@ export const AuditdGenericLine = pure<Props>(
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
eventId={id}
processPid={processPid}
processName={processName}
@ -124,8 +126,7 @@ export const AuditdGenericDetails = pure<GenericDetailsProps>(
const workingDirectory: string | null | undefined = get('process.working_directory[0]', data);
const primary: string | null | undefined = get('auditd.summary.actor.primary[0]', data);
const secondary: string | null | undefined = get('auditd.summary.actor.secondary[0]', data);
const rawArgs: string[] | null | undefined = get('process.args', data);
const args: string | null = rawArgs != null ? rawArgs.slice(1).join(' ') : null;
const args: string[] | null | undefined = get('process.args', data);
if (data.process != null) {
return (
<Details>

View file

@ -48,7 +48,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionalice@zeek-sanfranin/generic-text-123usinggpgconf--list-dirs agent-socket'
'Sessionalice@zeek-sanfranin/generic-text-123usinggpgconf(5402)gpgconf--list-dirsagent-socketgpgconf --list-dirs agent-socket'
);
});
@ -87,7 +87,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -95,7 +95,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -116,7 +116,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -124,7 +124,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -145,7 +145,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -153,7 +153,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -174,7 +174,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -182,7 +182,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -203,7 +203,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -211,7 +211,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1username-1@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -232,7 +232,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -240,7 +240,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-2]as[username-3]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-2]as[username-3]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -261,7 +261,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -269,7 +269,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-1]as[username-2]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-1]as[username-2]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -290,7 +290,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -298,7 +298,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -319,7 +319,7 @@ describe('GenericFileDetails', () => {
processExecutable="process-1"
processTitle="process-title-1"
workingDirectory="working-directory-1"
args="arg1 arg2 arg3"
args={['arg1', 'arg2', 'arg3']}
filePath="/somepath"
fileIcon="document"
result="success"
@ -327,7 +327,7 @@ describe('GenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1arg1 arg2 arg3with resultsuccess'
'Sessionsession-1[username-primary]@host-1inworking-directory-1generic-text-123/somepathusingprocess-name-1(123)arg1arg2arg3process-title-1with resultsuccess'
);
});
@ -439,7 +439,7 @@ describe('GenericFileDetails', () => {
expect(wrapper.text()).toEqual('Sessiongeneric-text-123usingsome-process-name');
});
test('it returns only session and user name if process title with id is given', () => {
test('it returns session user name and title if process title with id is given', () => {
const wrapper = mountWithIntl(
<TestProviders>
<AuditdGenericFileLine
@ -463,7 +463,7 @@ describe('GenericFileDetails', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('Sessionsome-user-name');
expect(wrapper.text()).toEqual('Sessionsome-user-namesome-process-title');
});
test('it returns only a working directory if that is all that is given with a id', () => {
@ -500,7 +500,7 @@ describe('GenericFileDetails', () => {
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
args="arg1 arg2 arg 3"
args={['arg1', 'arg2', 'arg 3']}
fileIcon="document"
userName={undefined}
secondary={undefined}
@ -517,7 +517,7 @@ describe('GenericFileDetails', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('Sessionarg1 arg2 arg 3');
expect(wrapper.text()).toEqual('Sessionarg1arg2arg 3');
});
});
});

View file

@ -36,7 +36,7 @@ interface Props {
processExecutable: string | null | undefined;
processTitle: string | null | undefined;
workingDirectory: string | null | undefined;
args: string | null | undefined;
args: string[] | null | undefined;
session: string | null | undefined;
}
@ -60,7 +60,7 @@ export const AuditdGenericFileLine = pure<Props>(
text,
fileIcon,
}) => (
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<SessionUserHostWorkingDir
eventId={id}
contextId={contextId}
@ -93,6 +93,8 @@ export const AuditdGenericFileLine = pure<Props>(
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
eventId={id}
processPid={processPid}
processName={processName}
@ -144,8 +146,7 @@ export const AuditdGenericFileDetails = pure<GenericDetailsProps>(
const filePath: string | null | undefined = get('file.path[0]', data);
const primary: string | null | undefined = get('auditd.summary.actor.primary[0]', data);
const secondary: string | null | undefined = get('auditd.summary.actor.secondary[0]', data);
const rawArgs: string[] | null | undefined = get('process.args', data);
const args: string | null = rawArgs != null ? rawArgs.slice(1).join(' ') : null;
const args: string[] | null | undefined = get('process.args', data);
if (data.process != null) {
return (

View file

@ -92,7 +92,7 @@ describe('GenericRowRenderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some children Session246alice@zeek-londonsome textwgetwith resultsuccessDestination93.184.216.34:80'
'some children Session246alice@zeek-londonsome textwget(1490)wget www.example.comwith resultsuccessDestination93.184.216.34:80'
);
});
});
@ -171,7 +171,7 @@ describe('GenericRowRenderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some children Sessionunsetroot@zeek-londonin/some text/proc/15990/attr/currentusingsystemd-journalwith resultsuccess'
'some children Sessionunsetroot@zeek-londonin/some text/proc/15990/attr/currentusingsystemd-journal(27244)/lib/systemd/systemd-journaldwith resultsuccess'
);
});
});

View file

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../../mock';
import { mockBrowserFields } from '../../../../../../public/containers/source/mock';
import { mockEndgameDnsRequest } from '../../../../../../public/mock/mock_endgame_ecs_data';
import { DnsRequestEventDetails } from './dns_request_event_details';
describe('DnsRequestEventDetails', () => {
test('it renders the expected text given an Endgame DNS request_event', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetails
browserFields={mockBrowserFields}
contextId="test-context"
data={mockEndgameDnsRequest}
timelineId="timeline-id-test"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'SYSTEM\\NT AUTHORITY@HD-obe-8bf77f54asked forupdate.googleapis.comwith question typeA, which resolved to10.100.197.67viaGoogleUpdate.exe(443192)3008dns'
);
});
});

View file

@ -0,0 +1,64 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiSpacer } from '@elastic/eui';
import { get } from 'lodash/fp';
import * as React from 'react';
import { BrowserFields } from '../../../../../containers/source';
import { Details } from '../helpers';
import { Ecs } from '../../../../../graphql/types';
import { NetflowRenderer } from '../netflow';
import { DnsRequestEventDetailsLine } from './dns_request_event_details_line';
interface Props {
browserFields: BrowserFields;
contextId: string;
data: Ecs;
timelineId: string;
}
export const DnsRequestEventDetails = React.memo<Props>(({ data, contextId, timelineId }) => {
const dnsQuestionName: string | null | undefined = get('dns.question.name[0]', data);
const dnsQuestionType: string | null | undefined = get('dns.question.type[0]', data);
const dnsResolvedIp: string | null | undefined = get('dns.resolved_ip[0]', data);
const dnsResponseCode: string | null | undefined = get('dns.response_code[0]', data);
const eventCode: string | null | undefined = get('event.code[0]', data);
const hostName: string | null | undefined = get('host.name[0]', data);
const id = data._id;
const processExecutable: string | null | undefined = get('process.executable[0]', data);
const processName: string | null | undefined = get('process.name[0]', data);
const processPid: number | null | undefined = get('process.pid[0]', data);
const userDomain: string | null | undefined = get('user.domain[0]', data);
const userName: string | null | undefined = get('user.name[0]', data);
const winlogEventId: string | null | undefined = get('winlog.event_id[0]', data);
return (
<Details>
<DnsRequestEventDetailsLine
contextId={contextId}
dnsQuestionName={dnsQuestionName}
dnsQuestionType={dnsQuestionType}
dnsResolvedIp={dnsResolvedIp}
dnsResponseCode={dnsResponseCode}
eventCode={eventCode}
hostName={hostName}
id={id}
processExecutable={processExecutable}
processName={processName}
processPid={processPid}
userDomain={userDomain}
userName={userName}
winlogEventId={winlogEventId}
/>
<EuiSpacer size="s" />
<NetflowRenderer data={data} timelineId={timelineId} />
</Details>
);
});
DnsRequestEventDetails.displayName = 'DnsRequestEventDetails';

View file

@ -0,0 +1,383 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../../mock';
import { DnsRequestEventDetailsLine } from './dns_request_event_details_line';
describe('DnsRequestEventDetailsLine', () => {
test('it renders the expected text when all properties are provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when dnsQuestionName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName={undefined}
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when dnsQuestionType is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType={undefined}
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when dnsResolvedIp is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp={undefined}
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when dnsResponseCode is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode={undefined}
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp]via[processName](123)[eventCode]'
);
});
test('it renders the expected text when eventCode is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode={undefined}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[winlogEventId]'
);
});
test('it renders the expected text when hostName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName={undefined}
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when processExecutable is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable={undefined}
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when processName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName={undefined}
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processExecutable](123)[eventCode]'
);
});
test('it renders the expected text when processPid is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={undefined}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName][eventCode]'
);
});
test('it renders the expected text when userDomain is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain={undefined}
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when userName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName={undefined}
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'\\[userDomain][hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when winlogEventId is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)[eventCode]'
);
});
test('it renders the expected text when both eventCode and winlogEventId are NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<DnsRequestEventDetailsLine
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode={null}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)'
);
});
});

View file

@ -0,0 +1,179 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiFlexGroup } from '@elastic/eui';
import * as React from 'react';
import { DraggableBadge } from '../../../../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;
dnsQuestionName: string | null | undefined;
dnsQuestionType: string | null | undefined;
dnsResolvedIp: string | null | undefined;
dnsResponseCode: string | null | undefined;
eventCode: string | null | undefined;
hostName: string | null | undefined;
id: string;
processExecutable: string | null | undefined;
processName: string | null | undefined;
processPid: number | null | undefined;
userDomain: string | null | undefined;
userName: string | null | undefined;
winlogEventId: string | null | undefined;
}
export const DnsRequestEventDetailsLine = React.memo<Props>(
({
contextId,
dnsQuestionName,
dnsQuestionType,
dnsResolvedIp,
dnsResponseCode,
eventCode,
hostName,
id,
processExecutable,
processName,
processPid,
userDomain,
userName,
winlogEventId,
}) => {
return (
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
contextId={contextId}
eventId={id}
hostName={hostName}
userDomain={userDomain}
userName={userName}
workingDirectory={undefined}
/>
{!isNillEmptyOrNotFinite(dnsQuestionName) && (
<>
<TokensFlexItem component="span" data-test-subj="asked-for" grow={false}>
{i18n.ASKED_FOR}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="dns.question.name"
value={dnsQuestionName}
/>
</TokensFlexItem>
</>
)}
{!isNillEmptyOrNotFinite(dnsQuestionType) && (
<>
<TokensFlexItem component="span" data-test-subj="with-question-type" grow={false}>
{i18n.WITH_QUESTION_TYPE}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="dns.question.type"
value={dnsQuestionType}
/>
</TokensFlexItem>
</>
)}
{!isNillEmptyOrNotFinite(dnsResolvedIp) && (
<>
<TokensFlexItem component="span" data-test-subj="which-resolved-to" grow={false}>
{i18n.WHICH_RESOLVED_TO}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="dns.resolved_ip"
value={dnsResolvedIp}
/>
</TokensFlexItem>
</>
)}
{!isNillEmptyOrNotFinite(dnsResponseCode) && (
<>
<TokensFlexItem component="span" grow={false}>
{'('}
</TokensFlexItem>
<TokensFlexItem component="span" data-test-subj="response-code" grow={false}>
{i18n.RESPONSE_CODE}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="dns.response_code"
value={dnsResponseCode}
/>
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
{')'}
</TokensFlexItem>
</>
)}
<TokensFlexItem component="span" grow={false}>
{i18n.VIA}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<ProcessDraggableWithNonExistentProcess
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
eventId={id}
processPid={processPid}
processName={processName}
processExecutable={processExecutable}
/>
</TokensFlexItem>
{(!isNillEmptyOrNotFinite(eventCode) || !isNillEmptyOrNotFinite(winlogEventId)) && (
<>
{!isNillEmptyOrNotFinite(eventCode) ? (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="event.code"
value={eventCode}
/>
</TokensFlexItem>
) : (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
iconType="logoWindows"
field="winlog.event_id"
value={winlogEventId}
/>
</TokensFlexItem>
)}
</>
)}
</EuiFlexGroup>
</>
);
}
);
DnsRequestEventDetailsLine.displayName = 'DnsRequestEventDetailsLine';

View file

@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
export const ASKED_FOR = i18n.translate(
'xpack.siem.timeline.body.renderers.dns.askedForDescription',
{
defaultMessage: 'asked for',
}
);
export const RESPONSE_CODE = i18n.translate(
'xpack.siem.timeline.body.renderers.dns.responseCodeDescription',
{
defaultMessage: 'response code:',
}
);
export const VIA = i18n.translate('xpack.siem.timeline.body.renderers.dns.viaDescription', {
defaultMessage: 'via',
});
export const WHICH_RESOLVED_TO = i18n.translate(
'xpack.siem.timeline.body.renderers.dns.whichResolvedToDescription',
{
defaultMessage: ', which resolved to',
}
);
export const WITH_QUESTION_TYPE = i18n.translate(
'xpack.siem.timeline.body.renderers.dns.withQuestionTypeDescription',
{
defaultMessage: 'with question type',
}
);

View file

@ -0,0 +1,90 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../../mock';
import { mockBrowserFields } from '../../../../../../public/containers/source/mock';
import {
mockEndgameAdminLogon,
mockEndgameExplicitUserLogon,
mockEndgameUserLogon,
mockEndgameUserLogoff,
} from '../../../../../../public/mock/mock_endgame_ecs_data';
import { EndgameSecurityEventDetails } from './endgame_security_event_details';
describe('EndgameSecurityEventDetails', () => {
test('it renders the expected text given an Endgame Security user_logon event', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetails
browserFields={mockBrowserFields}
contextId="test-context"
data={mockEndgameUserLogon}
timelineId="timeline-id-test"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'SYSTEM\\NT AUTHORITY@HD-v1s-d2118419successfully logged inusing logon type5 - Service(target logon ID0x3e7)viaC:\\Windows\\System32\\services.exe(432)as requested by subjectWIN-Q3DOP1UKA81$(subject logon ID0x3e7)4624'
);
});
test('it renders the expected text given an Endgame Security admin_logon event', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetails
browserFields={mockBrowserFields}
contextId="test-context"
data={mockEndgameAdminLogon}
timelineId="timeline-id-test"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,SYSTEM\\NT AUTHORITY@HD-obe-8bf77f54successfully logged inviaC:\\Windows\\System32\\lsass.exe(964)as requested by subjectSYSTEM\\NT AUTHORITY4672'
);
});
test('it renders the expected text given an Endgame Security explicit_user_logon event', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetails
browserFields={mockBrowserFields}
contextId="test-context"
data={mockEndgameExplicitUserLogon}
timelineId="timeline-id-test"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentialsArun\\Anvi-AcertoHD-55b-3ec87f66viaC:\\Windows\\System32\\svchost.exe(1736)as requested by subjectANVI-ACER$\\WORKGROUP(subject logon ID0x3e7)4648'
);
});
test('it renders the expected text given an Endgame Security user_logoff event', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetails
browserFields={mockBrowserFields}
contextId="test-context"
data={mockEndgameUserLogoff}
timelineId="timeline-id-test"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Arun\\Anvi-Acer@HD-55b-3ec87f66logged offusing logon type2 - Interactive(target logon ID0x16db41e)viaC:\\Windows\\System32\\lsass.exe(964)4634'
);
});
});

View file

@ -0,0 +1,81 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiSpacer } from '@elastic/eui';
import { get } from 'lodash/fp';
import * as React from 'react';
import { BrowserFields } from '../../../../../containers/source';
import { Ecs } from '../../../../../graphql/types';
import { NetflowRenderer } from '../netflow';
import { EndgameSecurityEventDetailsLine } from './endgame_security_event_details_line';
import { Details } from '../helpers';
interface Props {
browserFields: BrowserFields;
contextId: string;
data: Ecs;
timelineId: string;
}
export const EndgameSecurityEventDetails = React.memo<Props>(({ data, contextId, timelineId }) => {
const endgameLogonType: number | null | undefined = get('endgame.logon_type[0]', data);
const endgameSubjectDomainName: string | null | undefined = get(
'endgame.subject_domain_name[0]',
data
);
const endgameSubjectLogonId: string | null | undefined = get('endgame.subject_logon_id[0]', data);
const endgameSubjectUserName: string | null | undefined = get(
'endgame.subject_user_name[0]',
data
);
const endgameTargetLogonId: string | null | undefined = get('endgame.target_logon_id[0]', data);
const endgameTargetDomainName: string | null | undefined = get(
'endgame.target_domain_name[0]',
data
);
const endgameTargetUserName: string | null | undefined = get('endgame.target_user_name[0]', data);
const eventAction: string | null | undefined = get('event.action[0]', data);
const eventCode: string | null | undefined = get('event.code[0]', data);
const hostName: string | null | undefined = get('host.name[0]', data);
const id = data._id;
const processExecutable: string | null | undefined = get('process.executable[0]', data);
const processName: string | null | undefined = get('process.name[0]', data);
const processPid: number | null | undefined = get('process.pid[0]', data);
const userDomain: string | null | undefined = get('user.domain[0]', data);
const userName: string | null | undefined = get('user.name[0]', data);
const winlogEventId: string | null | undefined = get('winlog.event_id[0]', data);
return (
<Details>
<EndgameSecurityEventDetailsLine
contextId={contextId}
endgameLogonType={endgameLogonType}
endgameSubjectDomainName={endgameSubjectDomainName}
endgameSubjectLogonId={endgameSubjectLogonId}
endgameSubjectUserName={endgameSubjectUserName}
endgameTargetDomainName={endgameTargetDomainName}
endgameTargetLogonId={endgameTargetLogonId}
endgameTargetUserName={endgameTargetUserName}
eventAction={eventAction}
eventCode={eventCode}
hostName={hostName}
id={id}
processExecutable={processExecutable}
processName={processName}
processPid={processPid}
userDomain={userDomain}
userName={userName}
winlogEventId={winlogEventId}
/>
<EuiSpacer size="s" />
<NetflowRenderer data={data} timelineId={timelineId} />
</Details>
);
});
EndgameSecurityEventDetails.displayName = 'EndgameSecurityEventDetails';

View file

@ -0,0 +1,589 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../../mock';
import { EndgameSecurityEventDetailsLine } from './endgame_security_event_details_line';
describe('EndgameSecurityEventDetailsLine', () => {
test('it renders the expected text when all properties are provided and event action is admin_logon', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,[userName]\\[userDomain]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when all properties are provided and event action is explicit_user_logon', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameLogonType is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={undefined}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName](target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameSubjectDomainName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName={undefined}
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameSubjectLogonId is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId={undefined}
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName][eventCode]'
);
});
test('it renders the expected text when when endgameSubjectUserName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName={undefined}
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameTargetDomainName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName={undefined}
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameTargetLogonId is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId={undefined}
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactivevia[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when endgameTargetUserName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName={undefined}
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials\\[endgameTargetDomainName][hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when eventAction is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction={undefined}
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[userName]\\[userDomain]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when eventCode is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode={undefined}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[winlogEventId]'
);
});
test('it renders the expected text when hostName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName={undefined}
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when processExecutable is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable={undefined}
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when processName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName={undefined}
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processExecutable](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when processPid is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="explicit_user_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={undefined}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'A login was attempted using explicit credentials[endgameTargetUserName]\\[endgameTargetDomainName]to[hostName]using logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName]as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when userDomain is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain={undefined}
userName="[userName]"
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,[userName]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when userName is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName={undefined}
winlogEventId="[winlogEventId]"
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,\\[userDomain][hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when winlogEventId is NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode="[eventCode]"
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,[userName]\\[userDomain]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])[eventCode]'
);
});
test('it renders the expected text when BOTH eventCode and winlogEventId are NOT provided', () => {
const wrapper = mountWithIntl(
<TestProviders>
<EndgameSecurityEventDetailsLine
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode={undefined}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'With special privileges,[userName]\\[userDomain]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])'
);
});
});

View file

@ -0,0 +1,255 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiFlexGroup } from '@elastic/eui';
import * as React from 'react';
import { DraggableBadge } from '../../../../draggables';
import { isNillEmptyOrNotFinite, TokensFlexItem } from '../helpers';
import { ProcessDraggableWithNonExistentProcess } from '../process_draggable';
import { UserHostWorkingDir } from '../user_host_working_dir';
import {
getEventDetails,
getHostNameSeparator,
getHumanReadableLogonType,
getUserDomainField,
getUserNameField,
useTargetUserAndTargetDomain,
} from './helpers';
import * as i18n from './translations';
interface Props {
contextId: string;
endgameLogonType: number | null | undefined;
endgameSubjectDomainName: string | null | undefined;
endgameSubjectLogonId: string | null | undefined;
endgameSubjectUserName: string | null | undefined;
endgameTargetDomainName: string | null | undefined;
endgameTargetLogonId: string | null | undefined;
endgameTargetUserName: string | null | undefined;
eventAction: string | null | undefined;
eventCode: string | null | undefined;
hostName: string | null | undefined;
id: string;
processExecutable: string | null | undefined;
processName: string | null | undefined;
processPid: number | null | undefined;
userDomain: string | null | undefined;
userName: string | null | undefined;
winlogEventId: string | null | undefined;
}
export const EndgameSecurityEventDetailsLine = React.memo<Props>(
({
contextId,
endgameLogonType,
endgameSubjectDomainName,
endgameSubjectLogonId,
endgameSubjectUserName,
endgameTargetDomainName,
endgameTargetLogonId,
endgameTargetUserName,
eventAction,
eventCode,
hostName,
id,
processExecutable,
processName,
processPid,
userDomain,
userName,
winlogEventId,
}) => {
const domain = useTargetUserAndTargetDomain(eventAction) ? endgameTargetDomainName : userDomain;
const eventDetails = getEventDetails(eventAction);
const hostNameSeparator = getHostNameSeparator(eventAction);
const user = useTargetUserAndTargetDomain(eventAction) ? endgameTargetUserName : userName;
const userDomainField = getUserDomainField(eventAction);
const userNameField = getUserNameField(eventAction);
return (
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
{eventAction === 'admin_logon' && (
<TokensFlexItem component="span" data-test-subj="with-special-privileges" grow={false}>
{i18n.WITH_SPECIAL_PRIVILEGES}
</TokensFlexItem>
)}
{eventAction === 'explicit_user_logon' && (
<TokensFlexItem component="span" data-test-subj="a-login-was-attempted" grow={false}>
{i18n.A_LOGIN_WAS_ATTEMPTED_USING_EXPLICIT_CREDENTIALS}
</TokensFlexItem>
)}
<UserHostWorkingDir
contextId={contextId}
eventId={id}
hostName={hostName}
hostNameSeparator={hostNameSeparator}
userDomain={domain}
userDomainField={userDomainField}
userName={user}
userNameField={userNameField}
workingDirectory={undefined}
/>
<TokensFlexItem component="span" data-test-subj="event-details" grow={false}>
{eventDetails}
</TokensFlexItem>
{!isNillEmptyOrNotFinite(endgameLogonType) && (
<>
<TokensFlexItem component="span" data-test-subj="using-logon-type" grow={false}>
{i18n.USING_LOGON_TYPE}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="endgame.logon_type"
queryValue={String(endgameLogonType)}
value={`${endgameLogonType} - ${getHumanReadableLogonType(endgameLogonType)}`}
/>
</TokensFlexItem>
</>
)}
{!isNillEmptyOrNotFinite(endgameTargetLogonId) && (
<>
<TokensFlexItem component="span" grow={false}>
{'('}
</TokensFlexItem>
<TokensFlexItem component="span" data-test-subj="using-logon-type" grow={false}>
{i18n.TARGET_LOGON_ID}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="endgame.target_logon_id"
value={endgameTargetLogonId}
/>
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
{')'}
</TokensFlexItem>
</>
)}
<TokensFlexItem component="span" grow={false}>
{i18n.VIA}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<ProcessDraggableWithNonExistentProcess
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
eventId={id}
processPid={processPid}
processName={processName}
processExecutable={processExecutable}
/>
</TokensFlexItem>
{!isNillEmptyOrNotFinite(endgameSubjectUserName) && (
<>
<TokensFlexItem
component="span"
data-test-subj="as-requested-by-subject"
grow={false}
>
{i18n.AS_REQUESTED_BY_SUBJECT}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="endgame.subject_user_name"
iconType="user"
value={endgameSubjectUserName}
/>
</TokensFlexItem>
</>
)}
{endgameSubjectDomainName != null && (
<>
<TokensFlexItem
component="span"
data-test-subj="subject-domain-name-domain-separator-text"
grow={false}
>
{'\\'}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="endgame.subject_domain_name"
value={endgameSubjectDomainName}
/>
</TokensFlexItem>
</>
)}
{!isNillEmptyOrNotFinite(endgameSubjectLogonId) && (
<>
<TokensFlexItem component="span" grow={false}>
{'('}
</TokensFlexItem>
<TokensFlexItem component="span" data-test-subj="subject-login-id" grow={false}>
{i18n.SUBJECT_LOGON_ID}
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="endgame.subject_logon_id"
value={endgameSubjectLogonId}
/>
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
{')'}
</TokensFlexItem>
</>
)}
{(!isNillEmptyOrNotFinite(eventCode) || !isNillEmptyOrNotFinite(winlogEventId)) && (
<>
{!isNillEmptyOrNotFinite(eventCode) ? (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
field="event.code"
value={eventCode}
/>
</TokensFlexItem>
) : (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
contextId={contextId}
eventId={id}
iconType="logoWindows"
field="winlog.event_id"
value={winlogEventId}
/>
</TokensFlexItem>
)}
</>
)}
</EuiFlexGroup>
</>
);
}
);
EndgameSecurityEventDetailsLine.displayName = 'EndgameSecurityEventDetailsLine';

View file

@ -0,0 +1,208 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
getHostNameSeparator,
getHumanReadableLogonType,
useTargetUserAndTargetDomain,
getUserDomainField,
getUserNameField,
getEventDetails,
} from './helpers';
describe('helpers', () => {
describe('#getHumanReadableLogonType', () => {
test('it returns an empty string when endgameLogonType is undefined', () => {
expect(getHumanReadableLogonType(undefined)).toEqual('');
});
test('it returns an empty string when endgameLogonType is null', () => {
expect(getHumanReadableLogonType(null)).toEqual('');
});
test('it returns an empty string when endgameLogonType is NaN', () => {
expect(getHumanReadableLogonType(NaN)).toEqual('');
});
test('it returns an empty string when endgameLogonType is Infinity', () => {
expect(getHumanReadableLogonType(Infinity)).toEqual('');
});
test('it returns a string "0" given 0, an unknown logon type', () => {
expect(getHumanReadableLogonType(0)).toEqual('0');
});
test('it returns a string "-1" given -1, an unknown logon type', () => {
expect(getHumanReadableLogonType(-1)).toEqual('-1');
});
test('it returns "Interactive" given 2', () => {
expect(getHumanReadableLogonType(2)).toEqual('Interactive');
});
test('it returns "Network" given 3', () => {
expect(getHumanReadableLogonType(3)).toEqual('Network');
});
test('it returns "Batch" given 4', () => {
expect(getHumanReadableLogonType(4)).toEqual('Batch');
});
test('it returns "Service" given 5', () => {
expect(getHumanReadableLogonType(5)).toEqual('Service');
});
test('it returns "Unlock" given 7', () => {
expect(getHumanReadableLogonType(7)).toEqual('Unlock');
});
test('it returns "Network Cleartext" given 8', () => {
expect(getHumanReadableLogonType(8)).toEqual('Network Cleartext');
});
test('it returns "New Credentials" given 9', () => {
expect(getHumanReadableLogonType(9)).toEqual('New Credentials');
});
test('it returns "Remote Interactive" given 10', () => {
expect(getHumanReadableLogonType(10)).toEqual('Remote Interactive');
});
test('it returns "Cached Interactive" given 11', () => {
expect(getHumanReadableLogonType(11)).toEqual('Cached Interactive');
});
});
describe('#getHostNameSeparator', () => {
test('it returns "@" when eventAction is undefined', () => {
expect(getHostNameSeparator(undefined)).toEqual('@');
});
test('it returns "@" when eventAction is null', () => {
expect(getHostNameSeparator(null)).toEqual('@');
});
test('it returns "@" when eventAction is an empty string', () => {
expect(getHostNameSeparator('')).toEqual('@');
});
test('it returns "@" when eventAction is a random value', () => {
expect(getHostNameSeparator('a random value')).toEqual('@');
});
test('it returns "@" when eventAction is "user_logoff"', () => {
expect(getHostNameSeparator('user_logoff')).toEqual('@');
});
test('it returns "to" when eventAction is "explicit_user_logon"', () => {
expect(getHostNameSeparator('explicit_user_logon')).toEqual('to');
});
});
describe('#useTargetUserAndTargetDomain', () => {
test('it returns false when eventAction is undefined', () => {
expect(useTargetUserAndTargetDomain(undefined)).toEqual(false);
});
test('it returns false when eventAction is null', () => {
expect(useTargetUserAndTargetDomain(null)).toEqual(false);
});
test('it returns false when eventAction is an empty string', () => {
expect(useTargetUserAndTargetDomain('')).toEqual(false);
});
test('it returns false when eventAction is a random value', () => {
expect(useTargetUserAndTargetDomain('a random value')).toEqual(false);
});
test('it returns true when eventAction is "explicit_user_logon"', () => {
expect(useTargetUserAndTargetDomain('explicit_user_logon')).toEqual(true);
});
test('it returns true when eventAction is "user_logoff"', () => {
expect(useTargetUserAndTargetDomain('user_logoff')).toEqual(true);
});
});
describe('#getUserDomainField', () => {
test('it returns user.domain when eventAction is undefined', () => {
expect(getUserDomainField(undefined)).toEqual('user.domain');
});
test('it returns user.domain when eventAction is null', () => {
expect(getUserDomainField(null)).toEqual('user.domain');
});
test('it returns user.domain when eventAction is an empty string', () => {
expect(getUserDomainField('')).toEqual('user.domain');
});
test('it returns user.domain when eventAction is a random value', () => {
expect(getUserDomainField('a random value')).toEqual('user.domain');
});
test('it returns endgame.target_domain_name when eventAction is "explicit_user_logon"', () => {
expect(getUserDomainField('explicit_user_logon')).toEqual('endgame.target_domain_name');
});
test('it returns endgame.target_domain_name when eventAction is "user_logoff"', () => {
expect(getUserDomainField('user_logoff')).toEqual('endgame.target_domain_name');
});
});
describe('#getUserNameField', () => {
test('it returns user.name when eventAction is undefined', () => {
expect(getUserNameField(undefined)).toEqual('user.name');
});
test('it returns user.name when eventAction is null', () => {
expect(getUserNameField(null)).toEqual('user.name');
});
test('it returns user.name when eventAction is an empty string', () => {
expect(getUserNameField('')).toEqual('user.name');
});
test('it returns user.name when eventAction is a random value', () => {
expect(getUserNameField('a random value')).toEqual('user.name');
});
test('it returns endgame.target_user_name when eventAction is "explicit_user_logon"', () => {
expect(getUserNameField('explicit_user_logon')).toEqual('endgame.target_user_name');
});
test('it returns endgame.target_user_name when eventAction is "user_logoff"', () => {
expect(getUserNameField('user_logoff')).toEqual('endgame.target_user_name');
});
});
describe('#getEventDetails', () => {
test('it returns successfully logged in when eventAction is undefined', () => {
expect(getEventDetails(undefined)).toEqual('successfully logged in');
});
test('it returns successfully logged in when eventAction is null', () => {
expect(getEventDetails(null)).toEqual('successfully logged in');
});
test('it returns successfully logged in when eventAction is an empty string', () => {
expect(getEventDetails('')).toEqual('successfully logged in');
});
test('it returns successfully logged in when eventAction is a random value', () => {
expect(getEventDetails('a random value')).toEqual('successfully logged in');
});
test('it returns an empty string when eventAction is "explicit_user_logon"', () => {
expect(getEventDetails('explicit_user_logon')).toEqual('');
});
test('it returns logged off when eventAction is "user_logoff"', () => {
expect(getEventDetails('user_logoff')).toEqual('logged off');
});
});
});

View file

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { isNillEmptyOrNotFinite } from '../helpers';
import * as i18n from './translations';
export const getHumanReadableLogonType = (endgameLogonType: number | null | undefined): string => {
if (isNillEmptyOrNotFinite(endgameLogonType)) {
return '';
}
switch (endgameLogonType) {
case 2:
return i18n.LOGON_TYPE_INTERACTIVE;
case 3:
return i18n.LOGON_TYPE_NETWORK;
case 4:
return i18n.LOGON_TYPE_BATCH;
case 5:
return i18n.LOGON_TYPE_SERVICE;
case 7:
return i18n.LOGON_TYPE_UNLOCK;
case 8:
return i18n.LOGON_TYPE_NETWORK_CLEARTEXT;
case 9:
return i18n.LOGON_TYPE_NEW_CREDENTIALS;
case 10:
return i18n.LOGON_TYPE_REMOTE_INTERACTIVE;
case 11:
return i18n.LOGON_TYPE_CACHED_INTERACTIVE;
default:
return `${endgameLogonType}`;
}
};
export const getHostNameSeparator = (eventAction: string | null | undefined): string =>
eventAction === 'explicit_user_logon' ? i18n.TO : '@';
export const useTargetUserAndTargetDomain = (eventAction: string | null | undefined): boolean =>
eventAction === 'explicit_user_logon' || eventAction === 'user_logoff';
export const getUserDomainField = (eventAction: string | null | undefined): string =>
useTargetUserAndTargetDomain(eventAction) ? 'endgame.target_domain_name' : 'user.domain';
export const getUserNameField = (eventAction: string | null | undefined): string =>
useTargetUserAndTargetDomain(eventAction) ? 'endgame.target_user_name' : 'user.name';
export const getEventDetails = (eventAction: string | null | undefined): string => {
switch (eventAction) {
case 'explicit_user_logon':
return ''; // no details
case 'user_logoff':
return i18n.LOGGED_OFF;
default:
return i18n.SUCCESSFULLY_LOGGED_IN;
}
};

View file

@ -0,0 +1,134 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
export const A_LOGIN_WAS_ATTEMPTED_USING_EXPLICIT_CREDENTIALS = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.aLoginWasAttemptedUsingExplicitCredentialsDescription',
{
defaultMessage: 'A login was attempted using explicit credentials',
}
);
export const AS_REQUESTED_BY_SUBJECT = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.asRequestedBySubjectDescription',
{
defaultMessage: 'as requested by subject',
}
);
export const LOGGED_OFF = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.loggedOffDescription',
{
defaultMessage: 'logged off',
}
);
export const LOGON_TYPE_BATCH = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeBatchDescription',
{
defaultMessage: 'Batch',
}
);
export const LOGON_TYPE_CACHED_INTERACTIVE = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeCachedInteractiveDescription',
{
defaultMessage: 'Cached Interactive',
}
);
export const LOGON_TYPE_INTERACTIVE = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeInteractiveDescription',
{
defaultMessage: 'Interactive',
}
);
export const LOGON_TYPE_NETWORK = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeNetworkDescription',
{
defaultMessage: 'Network',
}
);
export const LOGON_TYPE_NETWORK_CLEARTEXT = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeNetworkCleartextDescription',
{
defaultMessage: 'Network Cleartext',
}
);
export const LOGON_TYPE_NEW_CREDENTIALS = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeNewCredentialsDescription',
{
defaultMessage: 'New Credentials',
}
);
export const LOGON_TYPE_REMOTE_INTERACTIVE = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeRemoteInteractiveDescription',
{
defaultMessage: 'Remote Interactive',
}
);
export const LOGON_TYPE_SERVICE = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeServiceDescription',
{
defaultMessage: 'Service',
}
);
export const LOGON_TYPE_UNLOCK = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.logonTypeUnlockDescription',
{
defaultMessage: 'Unlock',
}
);
export const SUBJECT_LOGON_ID = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.subjectLogonIdDescription',
{
defaultMessage: 'subject logon ID',
}
);
export const SUCCESSFULLY_LOGGED_IN = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.successfullyLoggedInDescription',
{
defaultMessage: 'successfully logged in',
}
);
export const TARGET_LOGON_ID = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.targetLogonIdDescription',
{
defaultMessage: 'target logon ID',
}
);
export const TO = i18n.translate('xpack.siem.timeline.body.renderers.endgame.toDescription', {
defaultMessage: 'to',
});
export const USING_LOGON_TYPE = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.usingLogonTypeDescription',
{
defaultMessage: 'using logon type',
}
);
export const VIA = i18n.translate('xpack.siem.timeline.body.renderers.endgame.viaDescription', {
defaultMessage: 'via',
});
export const WITH_SPECIAL_PRIVILEGES = i18n.translate(
'xpack.siem.timeline.body.renderers.endgame.withSpecialPrivilegesDescription',
{
defaultMessage: 'With special privileges,',
}
);

View file

@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { DraggableBadge } from '../../../draggables';
import { isNillEmptyOrNotFinite, TokensFlexItem } from './helpers';
interface Props {
contextId: string;
endgameExitCode: string | null | undefined;
eventId: string;
text: string | null | undefined;
}
export const ExitCodeDraggable = React.memo<Props>(
({ contextId, endgameExitCode, eventId, text }) => {
if (isNillEmptyOrNotFinite(endgameExitCode)) {
return null;
}
return (
<>
{!isNillEmptyOrNotFinite(text) && (
<TokensFlexItem data-test-subj="exit-code-draggable-text" grow={false} component="span">
{text}
</TokensFlexItem>
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.exit_code"
value={endgameExitCode}
/>
</TokensFlexItem>
</>
);
}
);
ExitCodeDraggable.displayName = 'ExitCodeDraggable';

View file

@ -0,0 +1,93 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { DraggableBadge } from '../../../draggables';
import { isNillEmptyOrNotFinite, TokensFlexItem } from './helpers';
import * as i18n from './translations';
interface Props {
contextId: string;
endgameFileName: string | null | undefined;
endgameFilePath: string | null | undefined;
eventId: string;
fileName: string | null | undefined;
filePath: string | null | undefined;
}
export const FileDraggable = React.memo<Props>(
({ contextId, endgameFileName, endgameFilePath, eventId, fileName, filePath }) => {
if (
isNillEmptyOrNotFinite(fileName) &&
isNillEmptyOrNotFinite(endgameFileName) &&
isNillEmptyOrNotFinite(filePath) &&
isNillEmptyOrNotFinite(endgameFilePath)
) {
return null;
}
const fileNameIsKnown =
!isNillEmptyOrNotFinite(fileName) || !isNillEmptyOrNotFinite(endgameFileName);
return (
<>
{!isNillEmptyOrNotFinite(fileName) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="file.name"
value={fileName}
iconType="document"
/>
</TokensFlexItem>
) : !isNillEmptyOrNotFinite(endgameFileName) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.file_name"
value={endgameFileName}
iconType="document"
/>
</TokensFlexItem>
) : null}
{fileNameIsKnown && (
<TokensFlexItem data-test-subj="in" grow={false} component="span">
{i18n.IN}
</TokensFlexItem>
)}
{!isNillEmptyOrNotFinite(filePath) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="file.path"
value={filePath}
iconType="document"
/>
</TokensFlexItem>
) : !isNillEmptyOrNotFinite(endgameFilePath) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.file_path"
value={endgameFilePath}
iconType="document"
/>
</TokensFlexItem>
) : null}
</>
);
}
);
FileDraggable.displayName = 'FileDraggable';

View file

@ -131,7 +131,7 @@ describe('get_column_renderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some child Braden@zeek-londonattempted a login via6278with resultfailureSource128.199.212.120'
'some child Braden@zeek-londonattempted a login via(6278)with resultfailureSource128.199.212.120'
);
});
@ -150,7 +150,7 @@ describe('get_column_renderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some child Sessionalice@zeek-sanfranin/executedgpgconf--list-dirs agent-socket'
'some child Sessionalice@zeek-sanfranin/executedgpgconf(5402)gpgconf--list-dirsagent-socketgpgconf --list-dirs agent-socket'
);
});
});

View file

@ -8,7 +8,7 @@ import { cloneDeep } from 'lodash/fp';
import { TimelineNonEcsData } from '../../../../graphql/types';
import { mockTimelineData } from '../../../../mock';
import { deleteItemIdx, findItem, getValues } from './helpers';
import { deleteItemIdx, findItem, getValues, isNillEmptyOrNotFinite, showVia } from './helpers';
describe('helpers', () => {
describe('#deleteItemIdx', () => {
@ -123,4 +123,70 @@ describe('helpers', () => {
expect(getValues('user.name', nullValue)).toBeUndefined();
});
});
describe('#isNillEmptyOrNotFinite', () => {
test('undefined returns true', () => {
expect(isNillEmptyOrNotFinite(undefined)).toEqual(true);
});
test('null returns true', () => {
expect(isNillEmptyOrNotFinite(null)).toEqual(true);
});
test('empty string returns true', () => {
expect(isNillEmptyOrNotFinite('')).toEqual(true);
});
test('empty array returns true', () => {
expect(isNillEmptyOrNotFinite([])).toEqual(true);
});
test('NaN returns true', () => {
expect(isNillEmptyOrNotFinite(NaN)).toEqual(true);
});
test('Infinity returns true', () => {
expect(isNillEmptyOrNotFinite(Infinity)).toEqual(true);
});
test('a single space string returns false', () => {
expect(isNillEmptyOrNotFinite(' ')).toEqual(false);
});
test('a simple string returns false', () => {
expect(isNillEmptyOrNotFinite('a simple string')).toEqual(false);
});
test('the number 0 returns false', () => {
expect(isNillEmptyOrNotFinite(0)).toEqual(false);
});
test('a non-empty array return false', () => {
expect(isNillEmptyOrNotFinite(['non empty array'])).toEqual(false);
});
});
describe('#showVia', () => {
test('undefined returns false', () => {
expect(showVia(undefined)).toEqual(false);
});
test('null returns false', () => {
expect(showVia(undefined)).toEqual(false);
});
test('empty string false', () => {
expect(showVia('')).toEqual(false);
});
test('a random string returns false', () => {
expect(showVia('a random string')).toEqual(false);
});
['file_create_event', 'created', 'file_delete_event', 'deleted'].forEach(eventAction => {
test(`${eventAction} returns true`, () => {
expect(showVia(eventAction)).toEqual(true);
});
});
});
});

View file

@ -5,6 +5,7 @@
*/
import { EuiFlexItem } from '@elastic/eui';
import { isNumber, isEmpty } from 'lodash/fp';
import styled from 'styled-components';
import { TimelineNonEcsData } from '../../../../graphql/types';
@ -27,6 +28,9 @@ export const getValues = (field: string, data: TimelineNonEcsData[]): string[] |
export const Details = styled.div`
margin: 5px 0 5px 10px;
& .euiBadge {
margin: 2px 0 2px 0;
}
`;
Details.displayName = 'Details';
@ -34,3 +38,23 @@ export const TokensFlexItem = styled(EuiFlexItem)`
margin-left: 3px;
`;
TokensFlexItem.displayName = 'TokensFlexItem';
export function isNillEmptyOrNotFinite<T>(value: string | number | T[] | null | undefined) {
return isNumber(value) ? !isFinite(value) : isEmpty(value);
}
export const isFimEvent = ({
eventCategory,
eventDataset,
}: {
eventCategory: string | null | undefined;
eventDataset: string | null | undefined;
}) =>
(eventCategory != null && eventCategory.toLowerCase() === 'file') ||
(eventDataset != null && eventDataset.toLowerCase() === 'file');
export const isProcessStoppedOrTerminationEvent = (eventAction: string | null | undefined) =>
eventAction === 'process_stopped' || eventAction === 'termination_event';
export const showVia = (eventAction: string | null | undefined) =>
['file_create_event', 'created', 'file_delete_event', 'deleted'].includes(`${eventAction}`);

View file

@ -0,0 +1,74 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as React from 'react';
import { DraggableBadge } from '../../../draggables';
import {
isNillEmptyOrNotFinite,
isProcessStoppedOrTerminationEvent,
TokensFlexItem,
} from './helpers';
interface Props {
contextId: string;
endgameParentProcessName: string | null | undefined;
eventAction: string | null | undefined;
eventId: string;
processPpid: number | undefined | null;
text: string | null | undefined;
}
export const ParentProcessDraggable = React.memo<Props>(
({ contextId, endgameParentProcessName, eventAction, eventId, processPpid, text }) => {
if (
(isNillEmptyOrNotFinite(endgameParentProcessName) && isNillEmptyOrNotFinite(processPpid)) ||
isProcessStoppedOrTerminationEvent(eventAction)
) {
return null;
}
return (
<>
{!isNillEmptyOrNotFinite(text) && (
<TokensFlexItem
data-test-subj="parent-process-draggable-text"
grow={false}
component="span"
>
{text}
</TokensFlexItem>
)}
{!isNillEmptyOrNotFinite(endgameParentProcessName) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.parent_process_name"
value={endgameParentProcessName}
/>
</TokensFlexItem>
)}
{!isNillEmptyOrNotFinite(processPpid) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.ppid"
queryValue={String(processPpid)}
value={`(${String(processPpid)})`}
/>
</TokensFlexItem>
)}
</>
);
}
);
ParentProcessDraggable.displayName = 'ParentProcessDraggable';

View file

@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiFlexGroup } from '@elastic/eui';
import * as React from 'react';
import styled from 'styled-components';
import { DraggableBadge } from '../../../draggables';
import { isNillEmptyOrNotFinite, TokensFlexItem } from './helpers';
const HashFlexGroup = styled(EuiFlexGroup)`
margin: ${({ theme }) => theme.eui.euiSizeXS};
`;
interface Props {
contextId: string;
eventId: string;
processHashMd5: string | null | undefined;
processHashSha1: string | null | undefined;
processHashSha256: string | null | undefined;
}
export const ProcessHash = React.memo<Props>(
({ contextId, eventId, processHashMd5, processHashSha1, processHashSha256 }) => {
if (
isNillEmptyOrNotFinite(processHashSha256) &&
isNillEmptyOrNotFinite(processHashSha1) &&
isNillEmptyOrNotFinite(processHashMd5)
) {
return null;
}
return (
<HashFlexGroup alignItems="center" direction="column" gutterSize="none">
{!isNillEmptyOrNotFinite(processHashSha256) && (
<TokensFlexItem grow={false} component="div">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.hash.sha256"
iconType="number"
value={processHashSha256}
/>
</TokensFlexItem>
)}
{!isNillEmptyOrNotFinite(processHashSha1) && (
<TokensFlexItem grow={false} component="div">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.hash.sha1"
iconType="number"
value={processHashSha1}
/>
</TokensFlexItem>
)}
{!isNillEmptyOrNotFinite(processHashMd5) && (
<TokensFlexItem grow={false} component="div">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.hash.md5"
iconType="number"
value={processHashMd5}
/>
</TokensFlexItem>
)}
</HashFlexGroup>
);
}
);
ProcessHash.displayName = 'ProcessHash';

View file

@ -10,7 +10,7 @@ import * as React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { TestProviders } from '../../../../mock';
import { ProcessDraggable, isNillOrEmptyString } from './process_draggable';
import { ProcessDraggable } from './process_draggable';
describe('ProcessDraggable', () => {
describe('rendering', () => {
@ -18,6 +18,8 @@ describe('ProcessDraggable', () => {
const wrapper = shallow(
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName="endgame-process-name-123"
eventId="event-123"
processExecutable="process-executable-1"
processName="process-name-1"
@ -32,6 +34,8 @@ describe('ProcessDraggable', () => {
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
eventId="event-123"
processExecutable={null}
processName={null}
@ -47,6 +51,8 @@ describe('ProcessDraggable', () => {
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
eventId="event-123"
processExecutable={undefined}
processName={undefined}
@ -62,6 +68,8 @@ describe('ProcessDraggable', () => {
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
eventId="event-123"
processExecutable={undefined}
processName="[process-name]"
@ -77,6 +85,8 @@ describe('ProcessDraggable', () => {
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
eventId="event-123"
processExecutable="[process-executable]"
processName={null}
@ -92,6 +102,8 @@ describe('ProcessDraggable', () => {
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
eventId="event-123"
processExecutable={null}
processName={null}
@ -99,14 +111,16 @@ describe('ProcessDraggable', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('123');
expect(wrapper.text()).toEqual('(123)');
});
test('it returns process name if everything else is an empty string', () => {
test('it returns just process name if process.pid and endgame.pid are NaN', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={NaN}
endgameProcessName={undefined}
eventId="event-123"
processExecutable=""
processName="[process-name]"
@ -117,11 +131,13 @@ describe('ProcessDraggable', () => {
expect(wrapper.text()).toEqual('[process-name]');
});
test('it returns process executable if everything else is an empty string', () => {
test('it returns just process executable if process.pid and endgame.pid are NaN', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={NaN}
endgameProcessName={null}
eventId="event-123"
processExecutable="[process-executable]"
processName=""
@ -132,11 +148,64 @@ describe('ProcessDraggable', () => {
expect(wrapper.text()).toEqual('[process-executable]');
});
test('it returns process executable if everything else is an empty string or NaN', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={NaN}
endgameProcessName=""
eventId="event-123"
processExecutable="[process-executable]"
processName=""
processPid={NaN}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-executable]');
});
test('it returns endgame.process_name if everything else is an empty string or NaN', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={NaN}
endgameProcessName="[endgame-process_name]"
eventId="event-123"
processExecutable=""
processName=""
processPid={NaN}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[endgame-process_name]');
});
test('it returns endgame.process_name and endgame.pid if everything else is an empty string or undefined', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName="[endgame-process_name]"
eventId="event-123"
processExecutable=""
processName=""
processPid={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[endgame-process_name](456)');
});
test('it returns process pid if everything else is an empty string', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName=""
eventId="event-123"
processExecutable=""
processName=""
@ -144,14 +213,33 @@ describe('ProcessDraggable', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('123');
expect(wrapper.text()).toEqual('(123)');
});
test('it returns process name if everything is filled', () => {
test('it returns endgame.pid if everything else is an empty string', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName=""
eventId="event-123"
processExecutable=""
processName=""
processPid={undefined}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('(456)');
});
test('it returns pid and process name if everything is filled', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName="[endgame-process_name]"
eventId="event-123"
processExecutable="[process-executable]"
processName="[process-name]"
@ -159,14 +247,50 @@ describe('ProcessDraggable', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-name]');
expect(wrapper.text()).toEqual('[process-name](123)');
});
test('it returns process executable if process name is undefined', () => {
test('it returns process pid and executable and if process name and endgame process name are null', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
eventId="event-123"
processExecutable="[process-executable]"
processName={null}
processPid={123}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-executable](123)');
});
test('it returns endgame pid and executable and if process name and endgame process name are null', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={456}
endgameProcessName={null}
eventId="event-123"
processExecutable="[process-executable]"
processName={null}
processPid={null}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-executable](456)');
});
test('it returns process pid and executable and if process name is undefined', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
eventId="event-123"
processExecutable="[process-executable]"
processName={undefined}
@ -174,14 +298,16 @@ describe('ProcessDraggable', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-executable]');
expect(wrapper.text()).toEqual('[process-executable](123)');
});
test('it returns process executable if process name is an empty string', () => {
test('it returns process pid and executable if process name is an empty string', () => {
const wrapper = mountWithIntl(
<TestProviders>
<ProcessDraggable
contextId="context-123"
endgamePid={null}
endgameProcessName=""
eventId="event-123"
processExecutable="[process-executable]"
processName=""
@ -189,29 +315,7 @@ describe('ProcessDraggable', () => {
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('[process-executable]');
});
});
describe('isNillOrEmptyString', () => {
test('undefined returns true', () => {
expect(isNillOrEmptyString(undefined)).toEqual(true);
});
test('null returns true', () => {
expect(isNillOrEmptyString(null)).toEqual(true);
});
test('empty string returns true', () => {
expect(isNillOrEmptyString('')).toEqual(true);
});
test('single space string returns false', () => {
expect(isNillOrEmptyString(' ')).toEqual(false);
});
test('regular value returns false', () => {
expect(isNillOrEmptyString('[process-name-1]')).toEqual(false);
expect(wrapper.text()).toEqual('[process-executable](123)');
});
});
});

View file

@ -4,88 +4,120 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { isNumber, isString } from 'lodash/fp';
import * as React from 'react';
import { pure } from 'recompose';
import { DraggableBadge } from '../../../draggables';
import { isNillEmptyOrNotFinite } from './helpers';
import * as i18n from './translations';
export const isNillOrEmptyString = (value: string | number | null | undefined) => {
if (value == null) {
return true;
} else if (isString(value)) {
return value === '';
} else if (isNumber(value)) {
return !isFinite(value);
}
};
interface Props {
contextId: string;
endgamePid: number | null | undefined;
endgameProcessName: string | null | undefined;
eventId: string;
processExecutable: string | undefined | null;
processPid?: number | undefined | null;
processName?: string | undefined | null;
processPid: number | undefined | null;
processName: string | undefined | null;
}
export const ProcessDraggable = pure<Props>(
({ contextId, eventId, processExecutable, processName, processPid }) => {
({
contextId,
endgamePid,
endgameProcessName,
eventId,
processExecutable,
processName,
processPid,
}) => {
if (
!isNillOrEmptyString(processName) ||
(processName === '' &&
isNillOrEmptyString(processExecutable) &&
isNillOrEmptyString(processPid))
isNillEmptyOrNotFinite(processName) &&
isNillEmptyOrNotFinite(processExecutable) &&
isNillEmptyOrNotFinite(endgameProcessName) &&
isNillEmptyOrNotFinite(processPid) &&
isNillEmptyOrNotFinite(endgamePid)
) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.name"
value={processName}
iconType="console"
/>
);
} else if (
!isNillOrEmptyString(processExecutable) ||
(processExecutable === '' && isNillOrEmptyString(processPid))
) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.executable"
value={processExecutable}
iconType="console"
/>
);
} else if (processPid != null) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.pid"
value={String(processPid)}
iconType="number"
/>
);
} else {
return null;
}
return (
<div>
{!isNillEmptyOrNotFinite(processName) ? (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.name"
value={processName}
iconType="console"
/>
) : !isNillEmptyOrNotFinite(processExecutable) ? (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.executable"
value={processExecutable}
iconType="console"
/>
) : !isNillEmptyOrNotFinite(endgameProcessName) ? (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.process_name"
value={endgameProcessName}
iconType="console"
/>
) : null}
{!isNillEmptyOrNotFinite(processPid) ? (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.pid"
queryValue={String(processPid)}
value={`(${String(processPid)})`}
/>
) : !isNillEmptyOrNotFinite(endgamePid) ? (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="endgame.pid"
queryValue={String(endgamePid)}
value={`(${String(endgamePid)})`}
/>
) : null}
</div>
);
}
);
ProcessDraggable.displayName = 'ProcessDraggable';
export const ProcessDraggableWithNonExistentProcess = pure<Props>(
({ contextId, eventId, processExecutable, processName, processPid }) => {
if (processExecutable == null && processName == null && processPid == null) {
({
contextId,
endgamePid,
endgameProcessName,
eventId,
processExecutable,
processName,
processPid,
}) => {
if (
endgamePid == null &&
endgameProcessName == null &&
processExecutable == null &&
processName == null &&
processPid == null
) {
return <>{i18n.NON_EXISTENT}</>;
} else {
return (
<ProcessDraggable
contextId={contextId}
endgamePid={endgamePid}
endgameProcessName={endgameProcessName}
eventId={eventId}
processExecutable={processExecutable}
processName={processName}

View file

@ -44,7 +44,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Braden@zeek-london[generic-text-123]6278with resultfailureSource128.199.212.120'
'Braden@zeek-london[generic-text-123](6278)with resultfailureSource128.199.212.120'
);
});
});
@ -69,6 +69,7 @@ describe('SystemGenericDetails', () => {
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[generic-text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
/>
@ -76,7 +77,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][generic-text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][generic-text-123][processName-123](123)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -99,6 +100,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -127,6 +129,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -155,6 +158,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -183,6 +187,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -211,6 +216,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -241,6 +247,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -271,6 +278,7 @@ describe('SystemGenericDetails', () => {
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -295,12 +303,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={null}
processName={null}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -308,7 +317,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processExecutable-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -325,12 +334,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName={null}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -338,7 +348,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processExecutable-123](123)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -355,12 +365,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -368,7 +379,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processName-123](123)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -385,12 +396,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod="[sshMethod-123]"
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -398,7 +410,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processName-123](123)with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -415,12 +427,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -428,7 +441,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processName-123](123)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -445,12 +458,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain={null}
userName={null}
workingDirectory={null}
/>
@ -458,11 +472,11 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][text-123][processName-123](123)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username', () => {
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, userDomain, username', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
@ -475,12 +489,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory={null}
/>
@ -488,11 +503,11 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123][text-123][processName-123](123)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username, working-directory', () => {
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
@ -505,12 +520,13 @@ describe('SystemGenericDetails', () => {
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processPid={123}
processName="[processName-123]"
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
/>
@ -518,7 +534,7 @@ describe('SystemGenericDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
});

View file

@ -38,6 +38,7 @@ interface Props {
sshMethod: string | null | undefined;
sshSignature: string | null | undefined;
text: string | null | undefined;
userDomain: string | null | undefined;
userName: string | null | undefined;
workingDirectory: string | null | undefined;
}
@ -58,14 +59,16 @@ export const SystemGenericLine = pure<Props>(
sshSignature,
sshMethod,
text,
userDomain,
userName,
workingDirectory,
}) => (
<>
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
contextId={contextId}
eventId={id}
userDomain={userDomain}
userName={userName}
hostName={hostName}
workingDirectory={workingDirectory}
@ -76,6 +79,8 @@ export const SystemGenericLine = pure<Props>(
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
eventId={id}
processPid={processPid}
processName={processName}
@ -141,6 +146,7 @@ export const SystemGenericDetails = pure<GenericDetailsProps>(
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);
const userDomain: string | null | undefined = get('user.domain[0]', data);
const userName: string | null | undefined = get('user.name[0]', data);
const outcome: string | null | undefined = get('event.outcome[0]', data);
const packageName: string | null | undefined = get('system.audit.package.name[0]', data);
@ -170,6 +176,7 @@ export const SystemGenericDetails = pure<GenericDetailsProps>(
sshMethod={sshMethod}
sshSignature={sshSignature}
text={text}
userDomain={userDomain}
userName={userName}
workingDirectory={workingDirectory}
/>

View file

@ -46,7 +46,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'Evan@zeek-london[generic-text-123]6278with resultfailureSource128.199.212.120'
'Evan@zeek-london[generic-text-123](6278)with resultfailureSource128.199.212.120'
);
});
});
@ -59,20 +59,35 @@ describe('SystemGenericFileDetails', () => {
<SystemGenericFileLine
id="[id-123]"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName="[endgameFileName-123]"
endgameFilePath="[endgameFilePath-123]"
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={789}
endgameProcessName="[endgameProcessName-123]"
eventAction="[eventAction-123]"
fileName="[fileName-123]"
filePath="[filePath-123]"
hostName="[hostname-123]"
message="[message-123]"
outcome="[outcome-123]"
processTitle="[some-title-123]"
args="[arg-1] [arg-2] [arg-3]"
args={['[arg-1]', '[arg-2]', '[arg-3]']}
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageExecutable=123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[generic-text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
/>
@ -80,7 +95,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][generic-text-123][processName-123][arg-1] [arg-2] [arg-3]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[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[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
@ -90,6 +105,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName={null}
id="[id-123]"
message={null}
@ -98,20 +122,26 @@ describe('SystemGenericFileDetails', () => {
packageSummary={null}
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
processTitle={null}
args={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual('to an unknown process');
expect(wrapper.text()).toEqual('an unknown process');
});
test('it can return only the host name', () => {
@ -120,6 +150,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message={null}
@ -128,11 +167,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary={null}
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -141,7 +186,7 @@ describe('SystemGenericFileDetails', () => {
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual('[hostname-123]to an unknown process');
expect(wrapper.text()).toEqual('[hostname-123]an unknown process');
});
test('it can return the host, message', () => {
@ -150,6 +195,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -158,11 +212,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary={null}
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -171,7 +231,7 @@ describe('SystemGenericFileDetails', () => {
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual('[hostname-123]to an unknown process[message-123]');
expect(wrapper.text()).toEqual('[hostname-123]an unknown process[message-123]');
});
test('it can return the host, message, outcome', () => {
@ -180,6 +240,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -188,11 +257,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary={null}
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -202,7 +277,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123]to an unknown processwith result[outcome-123][message-123]'
'[hostname-123]an unknown processwith result[outcome-123][message-123]'
);
});
@ -212,6 +287,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -220,11 +304,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary={null}
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -234,7 +324,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123]to an unknown processwith result[outcome-123][packageName-123][message-123]'
'[hostname-123]an unknown processwith result[outcome-123][packageName-123][message-123]'
);
});
@ -244,6 +334,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -252,11 +351,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion={null}
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -266,7 +371,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123]to an unknown processwith result[outcome-123][packageName-123][packageSummary-123][message-123]'
'[hostname-123]an unknown processwith result[outcome-123][packageName-123][packageSummary-123][message-123]'
);
});
@ -276,6 +381,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -284,11 +398,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable={null}
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -298,7 +418,7 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123]to an unknown processwith result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123]an unknown processwith result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
);
});
@ -308,6 +428,15 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -316,11 +445,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5={null}
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -334,12 +469,21 @@ describe('SystemGenericFileDetails', () => {
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid', () => {
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -348,11 +492,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processPid={123}
processHashMd5="[processHashMd5-123]"
processHashSha1={null}
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -362,16 +512,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName', () => {
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -380,11 +539,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processPid={123}
processName="[processName-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256={null}
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -394,16 +559,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod', () => {
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -412,11 +586,158 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={null}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
args={null}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][packageVersion-123]with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
outcome="[outcome-123]"
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[processExecutable-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={null}
processName={null}
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
args={null}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processExecutable-123](123)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName={null}
endgamePid={null}
endgameProcessName={null}
eventAction={null}
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
outcome="[outcome-123]"
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod={null}
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
args={null}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123](123)via parent process(456)with result[outcome-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
outcome="[outcome-123]"
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature={null}
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -426,16 +747,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -444,11 +774,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text={null}
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -458,16 +794,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -476,11 +821,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain={null}
userName={null}
workingDirectory={null}
processTitle={null}
@ -490,16 +841,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[hostname-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[hostname-123][text-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -508,11 +868,64 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName={null}
workingDirectory={null}
processTitle={null}
args={null}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'\\[userDomain-123][hostname-123][text-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
outcome="[outcome-123]"
packageName="[packageName-123]"
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory={null}
processTitle={null}
@ -522,16 +935,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123][text-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username, working-directory', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -540,11 +962,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
processTitle={null}
@ -554,16 +982,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username, working-directory, process-title', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -572,11 +1009,17 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
processTitle="[process-title-123]"
@ -586,16 +1029,25 @@ describe('SystemGenericFileDetails', () => {
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][text-123][processName-123]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][message-123]'
'[username-123]\\[userDomain-123]@[hostname-123]in[working-directory-123][text-123][processName-123](123)[process-title-123]with exit code[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
test('it can return the host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processPid, processName, sshMethod, sshSignature, text, username, working-directory, process-title, args', () => {
test('it can return the endgameExitCode, endgameParentProcessName, eventAction, host, message, outcome, packageName, pacakgeSummary, packageVersion, packageExecutable, processHashMd5, processHashSha1, processHashSha256, processPid, processPpid, processName, sshMethod, sshSignature, text, userDomain, username, working-directory, process-title, args', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<SystemGenericFileLine
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
endgameFilePath={null}
endgameParentProcessName="[endgameParentProcessName-123]"
endgamePid={null}
endgameProcessName={null}
eventAction="[eventAction-123]"
fileName={null}
filePath={null}
hostName="[hostname-123]"
id="[id-123]"
message="[message-123]"
@ -604,21 +1056,27 @@ describe('SystemGenericFileDetails', () => {
packageSummary="[packageSummary-123]"
packageVersion="[packageVersion-123]"
processExecutable="[packageVersion-123]"
processHashMd5="[processHashMd5-123]"
processHashSha1="[processHashSha1-123]"
processHashSha256="[processHashSha256-123]"
processPid={123}
processPpid={456}
processName="[processName-123]"
showMessage={true}
sshMethod="[sshMethod-123]"
sshSignature="[sshSignature-123]"
text="[text-123]"
userDomain="[userDomain-123]"
userName="[username-123]"
workingDirectory="[working-directory-123]"
processTitle="[process-title-123]"
args="[args-1] [args-2] [args-3]"
args={['[arg-1]', '[arg-2]', '[arg-3]']}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual(
'[username-123]@[hostname-123]in[working-directory-123][text-123][processName-123][args-1] [args-2] [args-3]with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-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[endgameExitCode-123]via parent process[endgameParentProcessName-123](456)with result[outcome-123][sshSignature-123][sshMethod-123][packageName-123][packageVersion-123][packageSummary-123][processHashSha256-123][processHashSha1-123][processHashMd5-123][message-123]'
);
});
});

View file

@ -17,16 +17,29 @@ import { OverflowField } from '../../../../tables/helpers';
import * as i18n from './translations';
import { NetflowRenderer } from '../netflow';
import { UserHostWorkingDir } from '../user_host_working_dir';
import { Details, TokensFlexItem } from '../helpers';
import { Details, showVia, TokensFlexItem } from '../helpers';
import { ProcessDraggableWithNonExistentProcess } from '../process_draggable';
import { Args } from '../args';
import { AuthSsh } from './auth_ssh';
import { ExitCodeDraggable } from '../exit_code_draggable';
import { FileDraggable } from '../file_draggable';
import { Package } from './package';
import { Badge } from '../../../../page';
import { ParentProcessDraggable } from '../parent_process_draggable';
import { ProcessHash } from '../process.hash';
interface Props {
args: string | null | undefined;
args: string[] | null | undefined;
contextId: string;
endgameExitCode: string | null | undefined;
endgameFileName: string | null | undefined;
endgameFilePath: string | null | undefined;
endgameParentProcessName: string | null | undefined;
endgamePid: number | null | undefined;
endgameProcessName: string | null | undefined;
eventAction: string | null | undefined;
fileName: string | null | undefined;
filePath: string | null | undefined;
hostName: string | null | undefined;
id: string;
message: string | null | undefined;
@ -36,11 +49,17 @@ interface Props {
packageVersion: string | null | undefined;
processName: string | null | undefined;
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;
sshSignature: string | null | undefined;
sshMethod: string | null | undefined;
text: string | null | undefined;
userDomain: string | null | undefined;
userName: string | null | undefined;
workingDirectory: string | null | undefined;
}
@ -49,6 +68,15 @@ export const SystemGenericFileLine = pure<Props>(
({
args,
contextId,
endgameExitCode,
endgameFileName,
endgameFilePath,
endgameParentProcessName,
endgamePid,
endgameProcessName,
eventAction,
fileName,
filePath,
hostName,
id,
message,
@ -57,20 +85,27 @@ export const SystemGenericFileLine = pure<Props>(
packageSummary,
packageVersion,
processExecutable,
processHashMd5,
processHashSha1,
processHashSha256,
processName,
processPid,
processPpid,
processTitle,
showMessage,
sshSignature,
sshMethod,
text,
userDomain,
userName,
workingDirectory,
}) => (
<>
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
eventId={id}
contextId={contextId}
userDomain={userDomain}
userName={userName}
workingDirectory={workingDirectory}
hostName={hostName}
@ -78,16 +113,45 @@ export const SystemGenericFileLine = pure<Props>(
<TokensFlexItem grow={false} component="span">
{text}
</TokensFlexItem>
<FileDraggable
contextId={contextId}
endgameFileName={endgameFileName}
endgameFilePath={endgameFilePath}
eventId={id}
fileName={fileName}
filePath={filePath}
/>
{showVia(eventAction) && (
<TokensFlexItem data-test-subj="via" grow={false} component="span">
{i18n.VIA}
</TokensFlexItem>
)}
<TokensFlexItem grow={false} component="span">
<ProcessDraggableWithNonExistentProcess
contextId={contextId}
endgamePid={endgamePid}
endgameProcessName={endgameProcessName}
eventId={id}
processPid={processPid}
processName={processName}
processExecutable={processExecutable}
/>
</TokensFlexItem>
<Args eventId={id} args={args} contextId={contextId} processTitle={processTitle} />
<Args args={args} contextId={contextId} eventId={id} processTitle={processTitle} />
<ExitCodeDraggable
contextId={contextId}
endgameExitCode={endgameExitCode}
eventId={id}
text={i18n.WITH_EXIT_CODE}
/>
<ParentProcessDraggable
contextId={contextId}
endgameParentProcessName={endgameParentProcessName}
eventAction={eventAction}
eventId={id}
processPpid={processPpid}
text={i18n.VIA_PARENT_PROCESS}
/>
{outcome != null && (
<TokensFlexItem grow={false} component="span">
{i18n.WITH_RESULT}
@ -116,7 +180,15 @@ export const SystemGenericFileLine = pure<Props>(
packageVersion={packageVersion}
/>
</EuiFlexGroup>
{message != null && (
<ProcessHash
contextId={contextId}
eventId={id}
processHashMd5={processHashMd5}
processHashSha1={processHashSha1}
processHashSha256={processHashSha256}
/>
{message != null && showMessage && (
<>
<EuiSpacer size="xs" />
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
@ -138,29 +210,46 @@ interface GenericDetailsProps {
browserFields: BrowserFields;
data: Ecs;
contextId: string;
showMessage?: boolean;
text: string;
timelineId: string;
}
export const SystemGenericFileDetails = pure<GenericDetailsProps>(
({ data, contextId, text, timelineId }) => {
({ data, contextId, showMessage = true, 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);
const endgameExitCode: string | null | undefined = get('endgame.exit_code[0]', data);
const endgameFileName: string | null | undefined = get('endgame.file_name[0]', data);
const endgameFilePath: string | null | undefined = get('endgame.file_path[0]', data);
const endgameParentProcessName: string | null | undefined = get(
'endgame.parent_process_name[0]',
data
);
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 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);
const userName: string | null | undefined = get('user.name[0]', data);
const outcome: string | null | undefined = get('event.outcome[0]', data);
const packageName: string | null | undefined = get('system.audit.package.name[0]', data);
const packageSummary: string | null | undefined = get('system.audit.package.summary[0]', data);
const packageVersion: string | null | undefined = get('system.audit.package.version[0]', data);
const 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', data);
const processPid: number | null | undefined = get('process.pid[0]', data);
const processPpid: number | null | undefined = get('process.ppid[0]', data);
const processName: string | null | undefined = get('process.name[0]', data);
const sshSignature: string | null | undefined = get('system.auth.ssh.signature[0]', data);
const sshMethod: string | null | undefined = get('system.auth.ssh.method[0]', data);
const processExecutable: string | null | undefined = get('process.executable[0]', data);
const processTitle: string | null | undefined = get('process.title[0]', data);
const workingDirectory: string | null | undefined = get('process.working_directory[0]', data);
const rawArgs: string[] | null | undefined = get('process.args', data);
const args: string | null = rawArgs != null ? rawArgs.slice(1).join(' ') : null;
const args: string[] | null | undefined = get('process.args', data);
return (
<Details>
@ -169,6 +258,16 @@ export const SystemGenericFileDetails = pure<GenericDetailsProps>(
contextId={contextId}
text={text}
hostName={hostName}
endgameExitCode={endgameExitCode}
endgameFileName={endgameFileName}
endgameFilePath={endgameFilePath}
endgameParentProcessName={endgameParentProcessName}
endgamePid={endgamePid}
endgameProcessName={endgameProcessName}
eventAction={eventAction}
fileName={fileName}
filePath={filePath}
userDomain={userDomain}
userName={userName}
message={message}
processTitle={processTitle}
@ -177,9 +276,14 @@ export const SystemGenericFileDetails = pure<GenericDetailsProps>(
packageName={packageName}
packageSummary={packageSummary}
packageVersion={packageVersion}
processHashMd5={processHashMd5}
processHashSha1={processHashSha1}
processHashSha256={processHashSha256}
processName={processName}
processPid={processPid}
processPpid={processPpid}
processExecutable={processExecutable}
showMessage={showMessage}
sshSignature={sshSignature}
sshMethod={sshMethod}
outcome={outcome}

View file

@ -77,7 +77,7 @@ describe('GenericRowRenderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some children Evan@zeek-londonsome text6278with resultfailureSource128.199.212.120'
'some children Evan@zeek-londonsome text(6278)with resultfailureSource128.199.212.120'
);
});
});
@ -140,7 +140,7 @@ describe('GenericRowRenderer', () => {
</TestProviders>
);
expect(wrapper.text()).toContain(
'some children Braden@zeek-londonsome text6278with resultfailureSource128.199.212.120'
'some children Braden@zeek-londonsome text(6278)with resultfailureSource128.199.212.120'
);
});
});

View file

@ -7,7 +7,11 @@
import { get } from 'lodash/fp';
import React from 'react';
import { DnsRequestEventDetails } from '../dns/dns_request_event_details';
import { EndgameSecurityEventDetails } from '../endgame/endgame_security_event_details';
import { isFimEvent, isNillEmptyOrNotFinite } from '../helpers';
import { RowRenderer, RowRendererContainer } from '../row_renderer';
import { SystemGenericDetails } from './generic_details';
import { SystemGenericFileDetails } from './generic_file_details';
import * as i18n from './translations';
@ -45,6 +49,74 @@ export const createGenericSystemRowRenderer = ({
),
});
export const createEndgameProcessRowRenderer = ({
actionName,
text,
}: {
actionName: string;
text: string;
}): RowRenderer => ({
isInstance: ecs => {
const action: string | null | undefined = get('event.action[0]', ecs);
const category: string | null | undefined = get('event.category[0]', ecs);
return (
category != null &&
category.toLowerCase() === 'process' &&
action != null &&
action.toLowerCase() === actionName
);
},
renderRow: ({ browserFields, data, children, timelineId }) => (
<>
{children}
<RowRendererContainer>
<SystemGenericFileDetails
browserFields={browserFields}
data={data}
contextId={`endgame-process-${actionName}-${timelineId}`}
showMessage={false}
text={text}
timelineId={timelineId}
/>
</RowRendererContainer>
</>
),
});
export const createFimRowRenderer = ({
actionName,
text,
}: {
actionName: string;
text: string;
}): RowRenderer => ({
isInstance: ecs => {
const action: string | null | undefined = get('event.action[0]', ecs);
const category: string | null | undefined = get('event.category[0]', ecs);
const dataset: string | null | undefined = get('event.dataset[0]', ecs);
return (
isFimEvent({ eventCategory: category, eventDataset: dataset }) &&
action != null &&
action.toLowerCase() === actionName
);
},
renderRow: ({ browserFields, data, children, timelineId }) => (
<>
{children}
<RowRendererContainer>
<SystemGenericFileDetails
browserFields={browserFields}
data={data}
contextId={`fim-${actionName}-${timelineId}`}
showMessage={false}
text={text}
timelineId={timelineId}
/>
</RowRendererContainer>
</>
),
});
export const createGenericFileRowRenderer = ({
actionName,
text,
@ -78,6 +150,84 @@ export const createGenericFileRowRenderer = ({
),
});
export const createSocketRowRenderer = ({
actionName,
text,
}: {
actionName: string;
text: string;
}): RowRenderer => ({
isInstance: ecs => {
const action: string | null | undefined = get('event.action[0]', ecs);
return action != null && action.toLowerCase() === actionName;
},
renderRow: ({ browserFields, data, children, timelineId }) => (
<>
{children}
<RowRendererContainer>
<SystemGenericFileDetails
browserFields={browserFields}
data={data}
contextId={`socket-${actionName}-${timelineId}`}
text={text}
timelineId={timelineId}
/>
</RowRendererContainer>
</>
),
});
export const createSecurityEventRowRenderer = ({
actionName,
}: {
actionName: string;
}): RowRenderer => ({
isInstance: ecs => {
const category: string | null | undefined = get('event.category[0]', ecs);
const action: string | null | undefined = get('event.action[0]', ecs);
return (
category != null &&
category.toLowerCase() === 'authentication' &&
action != null &&
action.toLowerCase() === actionName
);
},
renderRow: ({ browserFields, data, children, timelineId }) => (
<>
{children}
<RowRendererContainer>
<EndgameSecurityEventDetails
browserFields={browserFields}
data={data}
contextId={`authentication-${actionName}-${timelineId}`}
timelineId={timelineId}
/>
</RowRendererContainer>
</>
),
});
export const createDnsRowRenderer = (): RowRenderer => ({
isInstance: ecs => {
const dnsQuestionType: string | null | undefined = get('dns.question.type[0]', ecs);
const dnsQuestionName: string | null | undefined = get('dns.question.name[0]', ecs);
return !isNillEmptyOrNotFinite(dnsQuestionType) && !isNillEmptyOrNotFinite(dnsQuestionName);
},
renderRow: ({ browserFields, data, children, timelineId }) => (
<>
{children}
<RowRendererContainer>
<DnsRequestEventDetails
browserFields={browserFields}
data={data}
contextId={`dns-request-${timelineId}`}
timelineId={timelineId}
/>
</RowRendererContainer>
</>
),
});
const systemLoginRowRenderer = createGenericSystemRowRenderer({
actionName: 'user_login',
text: i18n.ATTEMPTED_LOGIN,
@ -88,26 +238,94 @@ const systemProcessStartedRowRenderer = createGenericFileRowRenderer({
text: i18n.PROCESS_STARTED,
});
const endgameProcessStartedRowRenderer = createEndgameProcessRowRenderer({
actionName: 'creation_event',
text: i18n.PROCESS_STARTED,
});
const systemProcessStoppedRowRenderer = createGenericFileRowRenderer({
actionName: 'process_stopped',
text: i18n.PROCESS_STOPPED,
});
const endgameProcessTerminationRowRenderer = createEndgameProcessRowRenderer({
actionName: 'termination_event',
text: i18n.TERMINATED_PROCESS,
});
const endgameFileCreateEventRowRenderer = createFimRowRenderer({
actionName: 'file_create_event',
text: i18n.CREATED_FILE,
});
const fimFileCreateEventRowRenderer = createFimRowRenderer({
actionName: 'created',
text: i18n.CREATED_FILE,
});
const endgameFileDeleteEventRowRenderer = createFimRowRenderer({
actionName: 'file_delete_event',
text: i18n.DELETED_FILE,
});
const fimFileDeletedEventRowRenderer = createFimRowRenderer({
actionName: 'deleted',
text: i18n.DELETED_FILE,
});
const systemExistingRowRenderer = createGenericFileRowRenderer({
actionName: 'existing_process',
text: i18n.EXISTING_PROCESS,
});
const systemSocketOpenedRowRenderer = createGenericFileRowRenderer({
const systemSocketOpenedRowRenderer = createSocketRowRenderer({
actionName: 'socket_opened',
text: i18n.SOCKET_OPENED,
});
const systemSocketClosedRowRenderer = createGenericFileRowRenderer({
const systemSocketClosedRowRenderer = createSocketRowRenderer({
actionName: 'socket_closed',
text: i18n.SOCKET_CLOSED,
});
const endgameIpv4ConnectionAcceptEventRowRenderer = createSocketRowRenderer({
actionName: 'ipv4_connection_accept_event',
text: i18n.ACCEPTED_A_CONNECTION_VIA,
});
const endgameIpv6ConnectionAcceptEventRowRenderer = createSocketRowRenderer({
actionName: 'ipv6_connection_accept_event',
text: i18n.ACCEPTED_A_CONNECTION_VIA,
});
const endgameIpv4DisconnectReceivedEventRowRenderer = createSocketRowRenderer({
actionName: 'ipv4_disconnect_received_event',
text: i18n.DISCONNECTED_VIA,
});
const endgameIpv6DisconnectReceivedEventRowRenderer = createSocketRowRenderer({
actionName: 'ipv6_disconnect_received_event',
text: i18n.DISCONNECTED_VIA,
});
const endgameAdminLogonRowRenderer = createSecurityEventRowRenderer({
actionName: 'admin_logon',
});
const endgameExplicitUserLogonRowRenderer = createSecurityEventRowRenderer({
actionName: 'explicit_user_logon',
});
const endgameUserLogoffRowRenderer = createSecurityEventRowRenderer({
actionName: 'user_logoff',
});
const endgameUserLogonRowRenderer = createSecurityEventRowRenderer({
actionName: 'user_logon',
});
const dnsRowRenderer = createDnsRowRenderer();
const systemExistingUserRowRenderer = createGenericSystemRowRenderer({
actionName: 'existing_user',
text: i18n.EXISTING_USER,
@ -195,6 +413,21 @@ const systemUserRemovedRowRenderer = createGenericSystemRowRenderer({
});
export const systemRowRenderers: RowRenderer[] = [
dnsRowRenderer,
endgameAdminLogonRowRenderer,
endgameExplicitUserLogonRowRenderer,
endgameFileCreateEventRowRenderer,
endgameFileDeleteEventRowRenderer,
endgameIpv4ConnectionAcceptEventRowRenderer,
endgameIpv6ConnectionAcceptEventRowRenderer,
endgameIpv4DisconnectReceivedEventRowRenderer,
endgameIpv6DisconnectReceivedEventRowRenderer,
endgameProcessStartedRowRenderer,
endgameProcessTerminationRowRenderer,
endgameUserLogoffRowRenderer,
endgameUserLogonRowRenderer,
fimFileCreateEventRowRenderer,
fimFileDeletedEventRowRenderer,
systemAcceptedRowRenderer,
systemBootRowRenderer,
systemErrorRowRenderer,

View file

@ -32,10 +32,21 @@ export const WAS_AUTHORIZED_TO_USE = i18n.translate(
}
);
export const ACCEPTED_A_CONNECTION_VIA = i18n.translate(
'xpack.siem.system.acceptedAConnectionViaDescription',
{
defaultMessage: 'accepted a connection via',
}
);
export const ATTEMPTED_LOGIN = i18n.translate('xpack.siem.system.attemptedLoginDescription', {
defaultMessage: 'attempted a login via',
});
export const DISCONNECTED_VIA = i18n.translate('xpack.siem.system.disconnectedViaDescription', {
defaultMessage: 'disconnected via',
});
export const LOGGED_OUT = i18n.translate('xpack.siem.system.loggedOutDescription', {
defaultMessage: 'logged out via',
});
@ -52,6 +63,18 @@ export const PROCESS_STOPPED = i18n.translate('xpack.siem.system.processStoppedD
defaultMessage: 'stopped process',
});
export const TERMINATED_PROCESS = i18n.translate('xpack.siem.system.terminatedProcessDescription', {
defaultMessage: 'terminated process',
});
export const CREATED_FILE = i18n.translate('xpack.siem.system.createdFileDescription', {
defaultMessage: 'created a file',
});
export const DELETED_FILE = i18n.translate('xpack.siem.system.deletedFileDescription', {
defaultMessage: 'deleted a file',
});
export const EXISTING_PROCESS = i18n.translate('xpack.siem.system.existingProcessDescription', {
defaultMessage: 'is running process',
});
@ -123,3 +146,15 @@ export const PACKAGE_REMOVED = i18n.translate('xpack.siem.system.packageRemovedD
export const USER_REMOVED = i18n.translate('xpack.siem.system.userRemovedDescription', {
defaultMessage: 'was removed',
});
export const VIA = i18n.translate('xpack.siem.system.viaDescription', {
defaultMessage: 'via',
});
export const VIA_PARENT_PROCESS = i18n.translate('xpack.siem.system.viaParentProcessDescription', {
defaultMessage: 'via parent process',
});
export const WITH_EXIT_CODE = i18n.translate('xpack.siem.system.withExitCodeDescription', {
defaultMessage: 'with exit code',
});

View file

@ -27,5 +27,5 @@ export const IN = i18n.translate('xpack.siem.auditd.inDescription', {
});
export const NON_EXISTENT = i18n.translate('xpack.siem.auditd.nonExistentDescription', {
defaultMessage: 'to an unknown process',
defaultMessage: 'an unknown process',
});

View file

@ -19,6 +19,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain="[userDomain-123]"
userName="[userName-123]"
hostName="[hostName-123]"
workingDirectory="[working-directory-123]"
@ -27,12 +28,13 @@ describe('UserHostWorkingDir', () => {
expect(toJson(wrapper)).toMatchSnapshot();
});
test('it returns null if userName, hostName, and workingDirectory are all null', () => {
test('it returns null if userDomain, userName, hostName, and workingDirectory are all null', () => {
const wrapper = mountWithIntl(
<TestProviders>
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={null}
userName={null}
hostName={null}
workingDirectory={null}
@ -42,12 +44,13 @@ describe('UserHostWorkingDir', () => {
expect(wrapper.isEmptyRender()).toBeTruthy();
});
test('it returns null if userName, hostName, and workingDirectory are all undefined', () => {
test('it returns null if userDomain, userName, hostName, and workingDirectory are all undefined', () => {
const wrapper = mountWithIntl(
<TestProviders>
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={undefined}
userName={undefined}
hostName={undefined}
workingDirectory={undefined}
@ -57,6 +60,24 @@ describe('UserHostWorkingDir', () => {
expect(wrapper.isEmptyRender()).toBeTruthy();
});
test('it returns userDomain if that is the only attribute defined', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
userName={undefined}
hostName={undefined}
workingDirectory={undefined}
/>
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual('\\[user-domain-123]');
});
test('it returns userName if that is the only attribute defined', () => {
const wrapper = mountWithIntl(
<TestProviders>
@ -64,6 +85,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={undefined}
userName="[user-name-123]"
hostName={undefined}
workingDirectory={undefined}
@ -81,6 +103,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={undefined}
userName={null}
hostName="[host-name-123]"
workingDirectory={undefined}
@ -98,6 +121,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={null}
userName={null}
hostName={null}
workingDirectory="[working-directory-123]"
@ -115,6 +139,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={null}
userName="[user-name-123]"
hostName={null}
workingDirectory="[working-directory-123]"
@ -132,6 +157,7 @@ describe('UserHostWorkingDir', () => {
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain={null}
userName={null}
hostName="[host-name-123]"
workingDirectory="[working-directory-123]"
@ -142,13 +168,14 @@ describe('UserHostWorkingDir', () => {
expect(wrapper.text()).toEqual('[host-name-123]in[working-directory-123]');
});
test('it returns userName, hostName', () => {
test('it returns userName, userDomain, hostName', () => {
const wrapper = mountWithIntl(
<TestProviders>
<div>
<UserHostWorkingDir
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
userName="[user-name-123]"
hostName="[host-name-123]"
workingDirectory={null}
@ -156,7 +183,7 @@ describe('UserHostWorkingDir', () => {
</div>
</TestProviders>
);
expect(wrapper.text()).toEqual('[user-name-123]@[host-name-123]');
expect(wrapper.text()).toEqual('[user-name-123]\\[user-domain-123]@[host-name-123]');
});
});
});

View file

@ -14,27 +14,62 @@ import { HostWorkingDir } from './host_working_dir';
interface Props {
contextId: string;
eventId: string;
userDomain: string | null | undefined;
userDomainField?: string;
userName: string | null | undefined;
userNameField?: string;
hostName: string | null | undefined;
hostNameSeparator?: string;
workingDirectory: string | null | undefined;
}
export const UserHostWorkingDir = pure<Props>(
({ contextId, eventId, userName, hostName, workingDirectory }) =>
userName != null || hostName != null || workingDirectory != null ? (
({
contextId,
eventId,
hostName,
hostNameSeparator = '@',
userDomain,
userDomainField = 'user.domain',
userName,
userNameField = 'user.name',
workingDirectory,
}) =>
userName != null || userDomain != null || hostName != null || workingDirectory != null ? (
<>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="user.name"
field={userNameField}
value={userName}
iconType="user"
/>
</TokensFlexItem>
{userDomain != null && (
<>
<TokensFlexItem
data-test-subj="user-host-working-dir-domain-separator-text"
grow={false}
component="span"
>
{'\\'}
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={userDomainField}
value={userDomain}
/>
</TokensFlexItem>
</>
)}
{hostName != null && userName != null && (
<TokensFlexItem grow={false} component="span">
{'@'}
{hostNameSeparator}
</TokensFlexItem>
)}
<HostWorkingDir

View file

@ -0,0 +1,579 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { Ecs } from '../graphql/types';
export const mockEndgameDnsRequest: Ecs = {
_id: 'S8jPcG0BOpWiDweSou3g',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['request_event'],
category: ['network'],
kind: ['event'],
},
message: [
'DNS query is completed for the name %1, type %2, query options %3 with status %4 Results %5 ',
],
timestamp: '1569555712000',
dns: {
question: {
name: ['update.googleapis.com'],
type: ['A'],
},
resolved_ip: ['10.100.197.67'],
},
network: {
protocol: ['dns'],
},
process: {
pid: [443192],
name: ['GoogleUpdate.exe'],
executable: ['C:\\Program Files (x86)\\Google\\Update\\GoogleUpdate.exe'],
},
winlog: {
event_id: [3008],
},
endgame: {
process_name: ['GoogleUpdate.exe'],
pid: [443192],
},
};
export const mockEndgameFileCreateEvent: Ecs = {
_id: '98jPcG0BOpWiDweSouzg',
user: {
id: ['S-1-5-21-3573271228-3407584681-1597858646-1002'],
domain: ['Anvi-Acer'],
name: ['Arun'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['file_create_event'],
category: ['file'],
kind: ['event'],
},
timestamp: '1569555712000',
endgame: {
process_name: ['chrome.exe'],
pid: [11620],
file_path: [
'C:\\Users\\Arun\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\63d78c21-e593-4484-b7a9-db33cd522ddc.tmp',
],
},
};
export const mockEndgameFileDeleteEvent: Ecs = {
_id: 'OMjPcG0BOpWiDweSeuW9',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['10.0'],
},
ip: ['10.134.159.150'],
name: ['HD-v1s-d2118419'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['file_delete_event'],
category: ['file'],
kind: ['event'],
},
timestamp: '1569555704000',
endgame: {
pid: [1084],
file_name: ['tmp000002f6'],
file_path: ['C:\\Windows\\TEMP\\tmp00000404\\tmp000002f6'],
process_name: ['AmSvc.exe'],
},
};
export const mockEndgameIpv4ConnectionAcceptEvent: Ecs = {
_id: 'LsjPcG0BOpWiDweSCNfu',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['10.0'],
},
ip: ['10.43.255.177'],
name: ['HD-gqf-0af7b4fe'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['ipv4_connection_accept_event'],
category: ['network'],
kind: ['event'],
},
timestamp: '1569555676000',
network: {
community_id: ['1:PFLzPy11bhJJZCUQhIVPEBoDLG4='],
transport: ['tcp'],
},
process: {
pid: [1084],
name: ['AmSvc.exe'],
executable: ['C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe'],
},
source: {
ip: ['127.0.0.1'],
port: [49306],
},
destination: {
port: [49305],
ip: ['127.0.0.1'],
},
endgame: {
pid: [1084],
},
};
export const mockEndgameIpv6ConnectionAcceptEvent: Ecs = {
_id: '-8SucG0BOpWiDweS0wrq',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.240.11.26'],
name: ['HD-55b-3ec87f66'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['ipv6_connection_accept_event'],
category: ['network'],
kind: ['event'],
},
timestamp: '1569553566000',
network: {
community_id: ['1:bUcbuDIApRZPr7rMsEG5Ngk/ids='],
transport: ['tcp'],
},
process: {
pid: [4],
},
source: {
ip: ['::1'],
port: [51324],
},
destination: {
port: [5357],
ip: ['::1'],
},
endgame: {
pid: [4],
},
};
export const mockEndgameIpv4DisconnectReceivedEvent: Ecs = {
_id: 'hMjPcG0BOpWiDweSoOin',
user: {
id: ['S-1-5-21-3573271228-3407584681-1597858646-1002'],
domain: ['Anvi-Acer'],
name: ['Arun'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['ipv4_disconnect_received_event'],
category: ['network'],
kind: ['event'],
},
timestamp: '1569555712000',
network: {
community_id: ['1:LxYHJJv98b2O0fNccXu6HheXmwk='],
transport: ['tcp'],
bytes: [8344],
},
process: {
pid: [11620],
name: ['chrome.exe'],
executable: ['C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'],
},
source: {
ip: ['192.168.0.6'],
port: [59356],
bytes: [2151],
},
destination: {
port: [443],
ip: ['54.156.162.53'],
bytes: [6193],
},
endgame: {
process_name: ['chrome.exe'],
},
};
export const mockEndgameIpv6DisconnectReceivedEvent: Ecs = {
_id: 'EcSucG0BOpWiDweS1Ayg',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.240.11.26'],
name: ['HD-55b-3ec87f66'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['ipv6_disconnect_received_event'],
category: ['network'],
kind: ['event'],
},
timestamp: '1569553566000',
network: {
community_id: ['1:ZylzQhsB1dcptA2t4DY8S6l9o8E='],
transport: ['tcp'],
bytes: [8086],
},
process: {
pid: [4],
},
source: {
ip: ['::1'],
port: [51338],
bytes: [7837],
},
destination: {
port: [2869],
ip: ['::1'],
bytes: [249],
},
endgame: {
pid: [4],
},
};
export const mockEndgameUserLogon: Ecs = {
_id: 'QsjPcG0BOpWiDweSeuRE',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['10.0'],
},
ip: ['10.134.159.150'],
name: ['HD-v1s-d2118419'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['user_logon'],
category: ['authentication'],
type: ['authentication_success'],
kind: ['event'],
},
message: [
'An account was successfully logged on.\r\n\r\nSubject:\r\n\tSecurity ID:\t\tS-1-5-18\r\n\tAccount Name:\t\tWIN-Q3DOP1UKA81$\r\n\tAccount Domain:\t\tWORKGROUP\r\n\tLogon ID:\t\t0x3e7\r\n\r\nLogon Type:\t\t\t5\r\n\r\nNew Logon:\r\n\tSecurity ID:\t\tS-1-5-18\r\n\tAccount Name:\t\tSYSTEM\r\n\tAccount Domain:\t\tNT AUTHORITY\r\n\tLogon ID:\t\t0x3e7\r\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\r\n\r\nProcess Information:\r\n\tProcess ID:\t\t0x1b0\r\n\tProcess Name:\t\tC:\\Windows\\System32\\services.exe\r\n\r\nNetwork Information:\r\n\tWorkstation Name:\t\r\n\tSource Network Address:\t-\r\n\tSource Port:\t\t-\r\n\r\nDetailed Authentication Information:\r\n\tLogon Process:\t\tAdvapi \r\n\tAuthentication Package:\tNegotiate\r\n\tTransited Services:\t-\r\n\tPackage Name (NTLM only):\t-\r\n\tKey Length:\t\t0\r\n\r\nThis event is generated when a logon session is created. It is generated on the computer that was accessed.\r\n\r\nThe subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.\r\n\r\nThe logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).\r\n\r\nThe New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.\r\n\r\nThe network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.\r\n\r\nThe authentication information fields provide detailed information about this specific logon request.\r\n\t- Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.\r\n\t- Transited services indicate which intermediate services have participated in this logon request.\r\n\t- Package name indicates which sub-protocol was used among the NTLM protocols.\r\n\t- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.',
],
timestamp: '1569555704000',
process: {
pid: [432],
name: ['C:\\Windows\\System32\\services.exe'],
executable: ['C:\\Windows\\System32\\services.exe'],
},
winlog: {
event_id: [4624],
},
endgame: {
target_logon_id: ['0x3e7'],
pid: [432],
process_name: ['C:\\Windows\\System32\\services.exe'],
logon_type: [5],
subject_user_name: ['WIN-Q3DOP1UKA81$'],
subject_logon_id: ['0x3e7'],
target_user_name: ['SYSTEM'],
target_domain_name: ['NT AUTHORITY'],
},
};
export const mockEndgameAdminLogon: Ecs = {
_id: 'psjPcG0BOpWiDweSoelR',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['admin_logon'],
category: ['authentication'],
type: ['authentication_success'],
kind: ['event'],
},
message: [
'Special privileges assigned to new logon.\r\n\r\nSubject:\r\n\tSecurity ID:\t\tS-1-5-18\r\n\tAccount Name:\t\tSYSTEM\r\n\tAccount Domain:\t\tNT AUTHORITY\r\n\tLogon ID:\t\t0x3E7\r\n\r\nPrivileges:\t\tSeAssignPrimaryTokenPrivilege\r\n\t\t\tSeTcbPrivilege\r\n\t\t\tSeSecurityPrivilege\r\n\t\t\tSeTakeOwnershipPrivilege\r\n\t\t\tSeLoadDriverPrivilege\r\n\t\t\tSeBackupPrivilege\r\n\t\t\tSeRestorePrivilege\r\n\t\t\tSeDebugPrivilege\r\n\t\t\tSeAuditPrivilege\r\n\t\t\tSeSystemEnvironmentPrivilege\r\n\t\t\tSeImpersonatePrivilege\r\n\t\t\tSeDelegateSessionUserImpersonatePrivilege',
],
timestamp: '1569555712000',
process: {
pid: [964],
executable: ['C:\\Windows\\System32\\lsass.exe'],
},
winlog: {
event_id: [4672],
},
endgame: {
subject_domain_name: ['NT AUTHORITY'],
subject_user_name: ['SYSTEM'],
pid: [964],
},
};
export const mockEndgameExplicitUserLogon: Ecs = {
_id: '-cSvcG0BOpWiDweSvi_s',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.240.11.26'],
name: ['HD-55b-3ec87f66'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['explicit_user_logon'],
category: ['authentication'],
type: ['authentication_success'],
kind: ['event'],
},
message: [
'A logon was attempted using explicit credentials.\r\n\r\nSubject:\r\n\tSecurity ID:\t\tS-1-5-18\r\n\tAccount Name:\t\tANVI-ACER$\r\n\tAccount Domain:\t\tWORKGROUP\r\n\tLogon ID:\t\t0x3E7\r\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\r\n\r\nAccount Whose Credentials Were Used:\r\n\tAccount Name:\t\tArun\r\n\tAccount Domain:\t\tAnvi-Acer\r\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\r\n\r\nTarget Server:\r\n\tTarget Server Name:\tlocalhost\r\n\tAdditional Information:\tlocalhost\r\n\r\nProcess Information:\r\n\tProcess ID:\t\t0x6c8\r\n\tProcess Name:\t\tC:\\Windows\\System32\\svchost.exe\r\n\r\nNetwork Information:\r\n\tNetwork Address:\t127.0.0.1\r\n\tPort:\t\t\t0\r\n\r\nThis event is generated when a process attempts to log on an account by explicitly specifying that accounts credentials. This most commonly occurs in batch-type configurations such as scheduled tasks, or when using the RUNAS command.',
],
timestamp: '1569553626000',
process: {
pid: [1736],
name: ['C:\\Windows\\System32\\svchost.exe'],
executable: ['C:\\Windows\\System32\\svchost.exe'],
},
winlog: {
event_id: [4648],
},
endgame: {
subject_domain_name: ['WORKGROUP'],
target_user_name: ['Arun'],
pid: [1736],
subject_user_name: ['ANVI-ACER$'],
target_domain_name: ['Anvi-Acer'],
process_name: ['C:\\Windows\\System32\\svchost.exe'],
subject_logon_id: ['0x3e7'],
},
};
export const mockEndgameUserLogoff: Ecs = {
_id: 'rcSvcG0BOpWiDweSvi5K',
user: {
id: ['S-1-5-18'],
domain: ['NT AUTHORITY'],
name: ['SYSTEM'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.240.11.26'],
name: ['HD-55b-3ec87f66'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['user_logoff'],
category: ['authentication'],
kind: ['event'],
},
message: [
'An account was logged off.\r\n\r\nSubject:\r\n\tSecurity ID:\t\tS-1-5-21-3573271228-3407584681-1597858646-1002\r\n\tAccount Name:\t\tArun\r\n\tAccount Domain:\t\tAnvi-Acer\r\n\tLogon ID:\t\t0x16DB41E\r\n\r\nLogon Type:\t\t\t2\r\n\r\nThis event is generated when a logon session is destroyed. It may be positively correlated with a logon event using the Logon ID value. Logon IDs are only unique between reboots on the same computer.',
],
timestamp: '1569553626000',
process: {
pid: [964],
executable: ['C:\\Windows\\System32\\lsass.exe'],
},
winlog: {
event_id: [4634],
},
endgame: {
logon_type: [2],
target_user_name: ['Arun'],
target_logon_id: ['0x16db41e'],
target_domain_name: ['Anvi-Acer'],
},
};
export const mockEndgameCreationEvent: Ecs = {
_id: 'BcjPcG0BOpWiDweSou3g',
user: {
id: ['S-1-5-21-3573271228-3407584681-1597858646-1002'],
domain: ['Anvi-Acer'],
name: ['Arun'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['creation_event'],
category: ['process'],
type: ['process_start'],
kind: ['event'],
},
timestamp: '1569555712000',
process: {
hash: {
md5: ['62d06d7235b37895b68de56687895743'],
sha1: ['12563599116157778a22600d2a163d8112aed845'],
sha256: ['d4c97ed46046893141652e2ec0056a698f6445109949d7fcabbce331146889ee'],
},
pid: [441684],
ppid: [8],
name: ['Microsoft.Photos.exe'],
executable: [
'C:\\Program Files\\WindowsApps\\Microsoft.Windows.Photos_2018.18091.17210.0_x64__8wekyb3d8bbwe\\Microsoft.Photos.exe',
],
args: [
'C:\\Program Files\\WindowsApps\\Microsoft.Windows.Photos_2018.18091.17210.0_x64__8wekyb3d8bbwe\\Microsoft.Photos.exe',
'-ServerName:App.AppXzst44mncqdg84v7sv6p7yznqwssy6f7f.mca',
],
},
endgame: {
process_name: ['Microsoft.Photos.exe'],
pid: [441684],
parent_process_name: ['svchost.exe'],
},
};
export const mockEndgameTerminationEvent: Ecs = {
_id: '2MjPcG0BOpWiDweSoutC',
user: {
id: ['S-1-5-21-3573271228-3407584681-1597858646-1002'],
domain: ['Anvi-Acer'],
name: ['Arun'],
},
host: {
os: {
platform: ['windows'],
name: ['Windows'],
version: ['6.1'],
},
ip: ['10.178.85.222'],
name: ['HD-obe-8bf77f54'],
},
event: {
module: ['endgame'],
dataset: ['esensor'],
action: ['termination_event'],
category: ['process'],
kind: ['event'],
},
timestamp: '1569555712000',
process: {
hash: {
md5: ['bd4401441a21bf1abce6404f4231db4d'],
sha1: ['797255e72d5ed5c058d4785950eba7abaa057653]'],
sha256: ['87976f3430cc99bc939e0694247c0759961a49832b87218f4313d6fc0bc3a776]'],
},
pid: [442384],
ppid: [8],
name: ['RuntimeBroker.exe'],
executable: ['C:\\Windows\\System32\\RuntimeBroker.exe'],
},
endgame: {
pid: [442384],
process_name: ['RuntimeBroker.exe'],
exit_code: [0],
},
};