Skip to content

Commit

Permalink
[EDR Workflows][Process descendants filter] Transform event filter en…
Browse files Browse the repository at this point in the history
…try for filtering process descendant (#187141)

## Summary

This PR adds logic to server side artifact logic, in order to transform
Event Filter entries to the expected format, if process descendant
filtering is enabled.

Conditions:
- feature flag is enabled:
`xpack.securitySolution.enableExperimental.filterProcessDescendantsForEventFiltersEnabled`
- amongst the `tags`, there is the `filter_process_descendants` tag

Output: the output contains a new operator called `descendent_of`, with
all the original entries listed as the operator's values, and one
additional `event.category is process` entry.

Example input entry (only relevant fields):
```json
            "entries": [
              {
                "field": "process.args",
                "operator": "included",
                "type": "match",
                "value": "IGNOREMYCHILDREN"
              }
            ],
            "tags": [
              "filter_process_descendants"
            ],
```

Example output entry:
```json
{
  "entries": [
    {
      "type": "simple",
      "entries": [
        {
          "operator": "included",
          "type": "descendent_of", // note: writing descendEnt here to harmonise with endpoint implementation
          "value": {
            "entries": [
              {
                "type": "simple",
                "entries": [
                  {
                    "field": "process.args",
                    "operator": "included",
                    "type": "exact_cased",
                    "value": "IGNOREMYCHILDREN"
                  },
                  {
                    "field": "event.category",
                    "operator": "included",
                    "type": "exact_cased",
                    "value": "process"
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  ]
}
```

### e2e testing
- spin up Kibana with the FF enabled
- spin up a v15-snapshot Agent with Endpoint integration on VM, enroll
it
- create an Event Filter with the following setup, where '_Process
descendants_' is selected and `process.args` is `IGNOREMYCHILDREN`:
<img width="1454" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/075d300a-a353-4c8f-ab7d-08c978df0c4b">

- create a `test.sh` on your VM with the following content:

```sh
echo "Creating file test_file_$1.tmp"
touch test_file_$1.tmp

# recursively call the original script
if [ $1 -ge 1 ]
then
	sh test.sh $(( $1 - 1 )) $2
fi
```

(alternatively you can use the python script from the endpoint tests,
https://github.com/elastic/endpoint-dev/blob/790c611325998c6ef8578144844d9260b8f73044/Python/endpoint/test/test_event_filtering.py#L439-L450)
- run the script `sh test.sh 6 DO_NOT_IGNOREMYCHILDREN`
<img width="476" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/283b9e9c-dd64-40f0-a107-8bb0c483058c">

- go to Security -> Explore -> Hosts to see the reported events
- I added some filters to easily see the events
<img width="632" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/aca83e75-fe14-424f-a514-7ef7de785f8b">

- you should see that all events are there
<img width="1236" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/5f4d7a74-de91-4e10-969d-2bb856c01b0a">

- now try with `sh test.sh 9 IGNOREMYCHILDREN`
<img width="429" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/9e476507-719e-4f52-a4f4-305259cbe674">

- now only the events of the top process are visible, the events from
descendants are not
<img width="1173" alt="image"
src="https://github.com/elastic/kibana/assets/39014407/e17443ea-d1a4-4e1a-b555-11cc83313e04">


### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
gergoabraham and kibanamachine authored Jul 1, 2024
1 parent d864fed commit c209f34
Show file tree
Hide file tree
Showing 8 changed files with 409 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,31 @@
* 2.0.
*/

import type { EntryMatch } from '@kbn/securitysolution-io-ts-list-types';
import { ENDPOINT_ARTIFACT_LIST_IDS } from '@kbn/securitysolution-list-constants';
import { EVENT_FILTERS_OPERATORS } from '@kbn/securitysolution-list-utils';

export const BY_POLICY_ARTIFACT_TAG_PREFIX = 'policy:';

export const GLOBAL_ARTIFACT_TAG = `${BY_POLICY_ARTIFACT_TAG_PREFIX}all`;

export const FILTER_PROCESS_DESCENDANTS_TAG = 'filter_process_descendants';

export const PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY: EntryMatch = Object.freeze({
field: 'event.category',
operator: 'included',
type: 'match',
value: 'process',
});

export const PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY_TEXT: string = `${
PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY.field
} ${
EVENT_FILTERS_OPERATORS.find(
({ type }) => type === PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY.type
)?.message
} ${PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY.value}`;

// TODO: refact all uses of `ALL_ENDPOINT_ARTIFACTS_LIST_IDS to sue new const from shared package
export const ALL_ENDPOINT_ARTIFACT_LIST_IDS = ENDPOINT_ARTIFACT_LIST_IDS;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type TagFilter = (tag: string) => boolean;
const POLICY_ID_START_POSITION = BY_POLICY_ARTIFACT_TAG_PREFIX.length;

export const isArtifactGlobal = (item: Partial<Pick<ExceptionListItemSchema, 'tags'>>): boolean => {
return (item.tags ?? []).find((tag) => tag === GLOBAL_ARTIFACT_TAG) !== undefined;
return (item.tags ?? []).includes(GLOBAL_ARTIFACT_TAG);
};

export const isArtifactByPolicy = (item: Pick<ExceptionListItemSchema, 'tags'>): boolean => {
Expand Down Expand Up @@ -96,7 +96,7 @@ export const getEffectedPolicySelectionByTags = (

export const isFilterProcessDescendantsEnabled = (
item: Partial<Pick<ExceptionListItemSchema, 'tags'>>
): boolean => (item.tags ?? []).find((tag) => tag === FILTER_PROCESS_DESCENDANTS_TAG) !== undefined;
): boolean => (item.tags ?? []).includes(FILTER_PROCESS_DESCENDANTS_TAG);

export const isFilterProcessDescendantsTag: TagFilter = (tag) =>
tag === FILTER_PROCESS_DESCENDANTS_TAG;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ import type { OnChangeProps } from '@kbn/lists-plugin/public';
import type { ValueSuggestionsGetFn } from '@kbn/unified-search-plugin/public/autocomplete/providers/value_suggestion_provider';
import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features';
import { useGetUpdatedTags } from '../../../../hooks/artifacts';
import { FILTER_PROCESS_DESCENDANTS_TAG } from '../../../../../../common/endpoint/service/artifacts/constants';
import {
FILTER_PROCESS_DESCENDANTS_TAG,
PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY_TEXT,
} from '../../../../../../common/endpoint/service/artifacts/constants';
import {
isFilterProcessDescendantsEnabled,
isFilterProcessDescendantsTag,
Expand Down Expand Up @@ -547,12 +550,7 @@ export const EventFiltersForm: React.FC<ArtifactFormComponentProps & { allowSele
defaultMessage="Additional condition added:"
/>
</EuiText>
<code>
<FormattedMessage
id="xpack.securitySolution.eventFilters.filterProcessDescendants.additionalCondition"
defaultMessage="event.category is process"
/>
</code>
<code>{PROCESS_DESCENDANT_EVENT_FILTER_EXTRA_ENTRY_TEXT}</code>
<EuiSpacer size="m" />
</>
)}
Expand Down
Loading

0 comments on commit c209f34

Please sign in to comment.