Contents

Alerting using SIEM Detections and ElastAlert2

ElasticSearch SIEM Detections and Alerts and Actions are quite useful features, except for the fact that actual alerting is behind a license paywall. So while both of these features can run rules, check for conditions, and record the results in an index, neither of them actually provide alerting support.

Alerting requires a Gold License, which if alerting is the only thing you want, is an excessive cost.

If you can’t move off ElasticSearch to OpenSearch, which has Alerting available for free, you can use tools such as ElastAlert21 to handle the Alerting requirements.

SIEM Detections

The following example is for SIEM Detections, and alerting with ElastAlert2.

SIEM Detections record their results in an index called .siem-signals-default. The -default part is based on the Kibana space, so if you’re using a Kibana space called exampleA, the index name would be .siem-signals-examplea.

Make sure to create a Kibana Index Pattern for this index, so you can explore it fully.

The key field to be aware of is the signal.rule.name, which is of course the SIEM Detection Rule name. This is what we’ll use to create an ElastAlert rule.

You’ll want to check what kind of ElastAlert rule you want to create, which you can find here ( https://elastalert2.readthedocs.io/en/latest/ruletypes.html#rule-types ).

For many of our SIEM Detection rules we use the ElastAlert any rule type. According to the ElastAlert documentation:

The any rule will match everything. Every hit that the query returns will generate an alert.

In many cases this will not be what you want as it could generate a lot of noise, but in the case of SIEM Detections, if they’re tuned well, hopefully they won’t be generating hundreds of records that this ElastAlert rule would be alerting on.

Below is an example ElastAlert rule that alerts us when there are Azure Subscription level IAM changes (as detected by a SIEM Detection rule).

name: Azure Subscription IAM Change

index: .siem-signals-default-*

filter:
- query:
    query_string:
      query: 'signal.rule.name: "Azure Subscription IAM Change" AND event.outcome: *'

type: any

realert:
  minutes: 0

alert:
- "slack"

alert_subject: "Azure Subscription IAM Change"

alert_text: "
{0}\n
Grantor:\n
User Name: {1}\n
Application Name: {2}\n
Application ID: {3}\n
\n
Grantee:\n
Principal Name: {4}\n
Principal ID: {5}\n
Principal Type: {6}\n
Role Name: {7}\n
Role ID: {8}\n
Subscription Name: {9}\n
Subscription ID: {10}\n
\n"

alert_missing_value: "N/A"

alert_text_args:
- "signal.rule.name"
- "user.name"
- "aad.application.name"
- "aad.application.id"
- "azure.iam.principal.name"
- "azure.iam.principal.id"
- "azure.iam.principal.type"
- "azure.iam.role.name"
- "azure.iam.role.id"
- "azure.subscription.name"
- "azure.subscription.id"

alert_text_type: alert_text_only

Note: ElastAlert uses the older Lucene query syntax, whereas modern Kibana uses Kibana Query Language (KQL) by default. Make sure to switch to using Lucene in Kibana when exploring or writing searches for use with ElastAlert.

ElastAlert has an extensive set of possible alert targets, in the example I’m using Slack, but a few of the other common ones I use are:

  • HTTP POST
  • Command
  • Alerta (quite useful alert dashboard)
  • Email
  • Jira

The full list can be found here: ElastAlert Alerters

Notes

  1. ElastAlert2 is the community fork of the original Yelp created ElastAlert which they abandoned a year or two ago, without any real effort to hand over to anyone to maintain.