Webhooks

Important

Webhooks are only available with Stamus NDR

What are Webhooks?

Webhooks are a mechanism used to push data to other systems, such as a ticketing system, a SOAR, a messaging app like Slack or Mattermost, and so on, using HTTP requests.

When a Declaration of Compromise is created, it can trigger a Webhook.

Webhooks are built using Jinja2 templating system which is a powerful templating system allowing logical construction and access to Python-like variables.

In order to set up webhooks: in the Administration menu go to the upper left corner click on Stamus Networks logo drop down icon -> Integrations.

Objects & Variables

When resolving a template, the following objects and variables are available to the user.

Variable

Type

Description

family.pk

integer

family primary key (id)

family.family_id

integer

family unique id

family.name

string

family name

family.family_type

choice/string

Threat actors / Threat family / Generic threat

family.description

string

family description

family.version

integer

family version

threat.pk

integer

threat primary key (id)

threat.threat_id

integer

threat unique id

threat.name

string

family name

threat.description

string

threat description

threat.additional_info

string

more information on family

threat.criticity

integer

level of criticity

threat.version

integer

threat version

threat.active

boolean

Indicates if the threat is active or not

threat.creation_date

date/string

family description

threat.user_defined

boolean

threat created by user or predifined threat

method.pk

integer

method primary key (id)

method.method_id

integer

threat unique id

method.target_key

string

src_ip or dest_ip as target

method.source_key

string

src_ip or dest_ip as target

method.description

string

method.method description

method.version

integer

method version

method.active

boolean

the method is active or not

method.target_type

choice/string

ip /username / mail

method.method_type

choice/string

Signature / Code

method.kill_chain

choice/integer

most advanced killchain on this method 1

method.original_sid

integer

method generated from rule with this SID

method.owner

string

assigned user

method.user_defined

boolean

method created by user or predifined threat

method.action

foreign key

action created in Hunt => user_defined is true

asset.pk

integer

asset primary key (id)

asset.first_seen

date/string

asset seen for the first time

asset.last_seen

date/string

asset seen for the last time

asset.close_status_date

date/string

asset has been closed at this date

asset.value

string

ip: ‘192.168.0.12’ / username: ‘Neo’ / mail: neo@myprovider.com

asset.asset_type

choice/string

ip /username / mail

asset.network_def

string

associated network

asset.status

choice/string

global status of the Asset new / fixed

asset.tenant

integer

from which tenant the asset is from

asset.kill_chain

choice/integer

most advanced killchain on this asset 1

threat_status.pk

integer

threatstatus primary key (id)

threat_status.status

choice/string

status for the pair threat and asset (new / fixed )

threat_status.tenant

integer

from which tenant the asset is from

threat_status.first_seen

date/string

pair asset and threat seen for the first time

threat_status.last_seen

date/string

pair asset and threat seen for the first time

threat_status.close_status_date

date/string

pair asset and threat has been closed at this date

threat_status.kill_chain

choice/integer

killchain on pair threat and asset 1

event

string

Metadata information about the event (suricata event)

family_url

string

link the URL of the Threat Family in Stamus Central Server

threat_url

string

link the URL of the Threat in Stamus Central Server

killchain_name

string

the textual name of the kill chain phase 1

threat_list

list

list of names of threats seen on the current asset

family_list

list

list of names of families seen on the current asset

threat_kill_chain

string

asset kill chain phase in the threat

family_kill_chain

string

asset kill chain phase in the family

asset_kill_chain

string

asset absolute kill chain phase

Footnotes

1(1,2,3,4)

The Killchain phases are identified as follow:

  1. Reconnaissance

  2. Weaponization

  3. Delivery

  4. Exploitation

  5. Installation

  6. Command & Control

  7. Actions On Objectives

Conditional webhooks

The webhook template jinja syntax allows the use of conditions directly when setting the webhook. Based on the condition the webhook will be send or not.

{% if condition == True %}
  {"text": "New Declaration of Compromise:
  * Asset under attack: **{{ asset.value | tojson }}**
  * Threat: **{{ threat.name | tojson }}**
  * Threat Family: **{{ family.name | tojson }}**
  * Killchain phase: **{{ killchain_name | tojson }}**

  Investigate using Stamus Central Server: {{ family_url | tojson }}"}
{% endif %}

In the example above, if the condition variable is equal to False the webhook will not be send.

Examples

Splunk

Stamus Central Server can trigger a Webhook to Splunk using Splunk HTTP Event Collector. The minimum required parameters are:

  • The URL such as https://SPLUNK_IP:8088/services/collector/event

  • The only header to send is Authorization: Splunk YOUR_HEC_TOKEN

An example event for a Threat on new Asset could be:

{
  "event":
  {
     "event_type": "stamus_threat",
     "threat_status": "new",
     "threat": "{{ threat.name | tojson }}",
     "asset": "{{ asset.value | tojson }}",
     "killchain": "{{ killchain_name }}",
     "timestamp": "{{event.timestamp | tojson }}",
     "data": {{ event | tojson }}
  }
}

Service Now

You can do a POST on your instance of ServiceNow at the following address: https://myinstannce.service-now.com/api/global/em/jsonv2

With regard to the headers, you need:

Content-Type: application/json
Authorization: Basic BASE64(user:password)

An example event for a Threat on new Asset could be:

{ "records":
  [
   {
   "source":"Stamus",
   "event_class":"{{ threat.name | tojson }} on {{ asset.value | tojson }}",
   "node":"{{ asset.value | tojson }}",
   "severity":"4",
   "description":"Threat {{ threat.name | tojson }} has been discovered on {{ asset.value | tojson }} at kill chain phase {{ killchain_name }}.",
   "time_of_event": "{{ event.timestamp | tojson }}",
   "message_key": "{{asset.value | tojson }}-{{ threat.name | tojson }}",
   "additional_info":{
          {% if event.stamus.source %}
          "offender": "{{ event.stamus.source | tojson }}",
          {% endif %}
          "asset": "{{ asset.value | tojson }}",
          "killchain": "{{ killchain_name }}"
      }
    }
  ]
}

Slack / Mattermost

This example post a new message on your chat application such as Slack or Mattermost when a new threat is detected.

In the headers, just keep the default.

Content-Type: application/json

The following text is an example of notification for Mattermost for a new threat seen on an asset.

{
"text": "Stamus Networks - **Asset under attack:** `{{ asset.value }}`, **Killchain:** `{{ killchain_name }}`. **Threat Family:** `{{ family.name }}`. **Threat:** `{{ threat.name }}` have been detected.\nIncident Response ticket:\nhttps://192.168.1.26/HIVE/ir/\n\nFollow up with investigation using Stamus Central Server:\n{{ family_url }}"
}

TheHive

In the headers, you will need something like:

Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

The URL that you need to use to send alerts is http://THEHIVE_IP:PORT/api/alert.

The following text is an example of alert for TheHive for a New Threat. It will add basic data and extract observables coming from the application layer analysis. You can customize the message by setting the variables at the beginning.

{% set hook = 'new threat' %}
{% set case_template = 'external-alert' %}
{% set stamus_tag = 'Stamus' %}
{% set stamus_prefix = 'Stamus' %}
{% set asset_tag = 'Stamus:asset' %}
{% set offender_tag = 'Stamus:offender' %}
{% if event.stamus.asset == event.src_ip %}
  {% set server_tag = offender_tag %}
  {% set client_tag = asset_tag %}
{% else %}
  {% set server_tag = asset_tag %}
  {% set client_tag = offender_tag %}
{% endif %}
{
  {% if hook == 'new threat' %}
    "title": "Threat {{ threat.name | tojson }} seen on asset {{ asset.value | tojson }}",
  {% else %}
    "title": "Progression in kill chain to {{ killchain_name }} for {{ threat.name | tojson }} on asset {{ asset.value | tojson }}",
  {% endif %}
    "description": "{{ threat.description | tojson }}",
    "type": "stamus",
  {% if event.host %}
    "source": "{{ event.host.name }}",
  {% else %}
    "source": "Stamus",
  {% endif %}
    "sourceRef": "{{ threat_status.pk  }}-{{ method.kill_chain  }}",
    "severity": 3,
    "tlp": 2,
    "tags": ["network", "{{ threat.name | tojson }}", "{{ stamus_tag }}"],
    "artifacts": [
        {% if event.tls %}
           {% if event.tls.sni %}
        { "dataType": "fqdn", "data": "{{ event.tls.sni | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:tls.sni"] },
           {% endif %}
           {% if event.tls.fingerprint %}
        { "dataType": "other", "data": "{{ event.tls.fingerprint | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:tls.fingerprint"] },
           {% endif %}
           {% if event.tls.ja3 %}
        { "dataType": "other", "data": "{{ event.tls.ja3.hash | tojson }}", "tags": ["{{ client_tag }}", "{{ stamus_prefix }}:tls.ja3"] },
           {% endif %}
           {% if event.tls.ja3s %}
        { "dataType": "other", "data": "{{ event.tls.ja3s.hash | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:tls.ja3s"] },
           {% endif %}
        {% endif %}
        {% if event.http %}
           {% if event.http.hostname %}
        { "dataType": "fqdn", "data": "{{ event.http.hostname | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:http.hostname"] },
           {% endif %}
           {% if event.http.url %}
        { "dataType": "uri_path", "data": "{{ event.http.url | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:http.url"] },
           {% endif %}
           {% if event.http.http_user_agent %}
        { "dataType": "user-agent", "data": "{{ event.http.http_user_agent | tojson }}", "tags": ["{{ client_tag }}", "{{ stamus_prefix }}:http.http_user_agent"] },
           {% endif %}
        {% endif %}
        {% if event.dns %}
           {% if event.dns.query[0].rrname %}
        { "dataType": "fqdn", "data": "{{ event.dns.query[0].rrname | tojson }}", "tags": ["{{ server_tag }}", "{{ stamus_prefix }}:dns.query.rrname"] },
           {% endif %}
        {% endif %}
        {% if event.fileinfo %}
           {% if event.fileinfo.sha256 %}
        { "dataType": "hash", "data": "{{ event.fileinfo.sha256 | tojson }}", "tags": ["{{ stamus_tag }}", "{{ stamus_prefix }}:fileinfo.sha256"] },
           {% endif %}
           {% if event.fileinfo.filename %}
        { "dataType": "filename", "data": "{{ event.fileinfo.filename | tojson }}", "tags": ["{{ stamus_tag }}", "{{ stamus_prefix }}:fileinfo.filename"] },
           {% endif %}
        {% endif %}
        {% if event.stamus.source %}
        { "dataType": "ip", "data": "{{ event.stamus.source | tojson }}", "tags": ["{{ offender_tag }}", "{{ stamus_prefix }}:stamus.source"] },
        {% endif %}
        { "dataType": "ip", "data": "{{ asset.value | tojson }}", "tags": ["{{ asset_tag }}", "{{ stamus_prefix }}:stamus.asset"] }
    ],
    "caseTemplate": "{{ case_template }}"
}

Discord

You can do a POST on your instance of Discord at the following address: https://link-to-your-discord.com/api/webhooks/

In the headers, just keep the default.

Content-Type: application/json

Template format should be kept to the default one - json.

Next, you need to add a Template content. The following text is a working example of notification for Discord for a new threat seen on an asset:

{"content": "Stamus Networks - **Asset under attack:** `{{ asset.value | tojson  }}`, **Killchain:** `{{ killchain_name | tojson  }}`. **Threat Family:** `{{ family.name | tojson  }}`. **Threat:** `{{ threat.name | tojson  }}` has been detected.\n\nFollow up with investigation using Scirius security Platform:\n\n{{ family_url | tojson  }}"}

Special Cases

In some specific cases, if you are using the AIO, Logstash over VLAN, etc. - you would need to adjust the webhooks template content, in order to make it work.

Webhook takes the scirius visible address to construct the links to NDR. Since in such cases, the visible address might differ, you can use the following Template content:

{"text": "New Declaration of Compromise:
* Asset under attack: **{{ asset.value | tojson  }}**
* Threat: **{{ threat.name | tojson  }}**
* Threat Family: **{{ family.name | tojson  }}**
* Killchain phase: **{{ killchain_name | tojson  }}**

Investigate using Stamus Central Server: https://new.ip.ip.ip/appliances/str/family/{{ family.id }}