Automating security alerting with ElastAlert and Cortex XSOAR

As I’ve mentioned previously, here at Code42 our Security Operations team uses Elasticsearch as one of our tools for log aggregation, searching, and alerting. When it comes to alerting, we use the open source tool developed by Yelp called ElastAlert. It’s a very powerful tool that allows us to create alerts based on a wide variety of criteria, from simple “are there any documents that match this pattern” queries to more complex rate-based or time-value aggregations, alerting only if certain thresholds are met. While it doesn’t support complex, multi event timeline correlation alerts like a SIEM tool can support, I think that simple alerting is almost always good enough when it comes to handling security events.

ElastAlert supports many notification mechanisms, such as email, Slack, JIRA, and so on, but out of the box it doesn’t support the automation tool that we have implemented, Palo Alto Cortex XSOAR. Despite this, we have been able to very easily implement a method to send data from ElastAlert to Cortex XSOAR in order to automate investigation and response of alerts.

ElastAlert supports a generic script action that can run when alert criteria is met. This is a very flexible option that allows for both passing any number of arbitrary command line arguments, plus sending the JSON of the documents that triggered the alert. To leverage this, we created a very simple Python script that takes a number of arguments that helps with processing, along with the alert matches. Below is an example of a script action block for an alert from Microsoft Advanced Threat Analytics (ATA):

command: ["/usr/bin/python3", "/home/elastalert/demisto_commands/createincident.py", "--name", "Microsoft ATA Alert", "--type", "Microsoft ATA Alert", "--details", "Microsoft ATA has generated an alert: %(rule.description)s", "--labels", "host.name,rule.description,rule.id,rule.name,source.domain", "--severity", "1"]
pipe_match_json: true

Most of the arguments are pretty self-explanatory: the incident name, type, severity, and description are all set, with the ability to include fields from the document data itself. In addition, data can be passed either via XSOAR incident custom fields (not shown here), or via incident labels. Both of those options allow for processing of the data by XSOAR playbooks.

Internally, the createincident.py script uses the Demisto Client for Python (the former name of Cortex XSOAR), which provides a very simple interface to the API for creating incidents. Since the script only needs to glue together the ElastAlert output to the XSOAR API input, it ends up at about 100 lines of code.

In Cortex XSOAR, the incident looks like this:

Cortex XSOAR Incident Context
Cortex XSOAR Incident Context

The data is ready to be parsed and acted upon by Cortex XSOAR, and since we have the Elasticsearch integration enabled, that can include querying Elasticsearch itself for more data.

With a couple of open-source tools and a bit of Python glue, we are able to increase efficiency and automate our response to security alerts, and drive centralized management of alerts no matter where they come from. It’s a pretty good win all around!