update TheHiveAlerter module

This commit is contained in:
Wes Lambert
2019-12-30 21:10:56 +00:00
parent bbd95c977c
commit bc533bef24

View File

@@ -1,51 +1,45 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals # HiveAlerter modified from original at: https://raw.githubusercontent.com/Nclose-ZA/elastalert_hive_alerter/master/elastalert_hive_alerter/hive_alerter.py
import uuid import uuid
import re
from elastalert.alerts import Alerter from elastalert.alerts import Alerter
from thehive4py.api import TheHiveApi from thehive4py.api import TheHiveApi
from thehive4py.models import Alert, AlertArtifact, CustomFieldHelper from thehive4py.models import Alert, AlertArtifact, CustomFieldHelper
class TheHiveAlerter(Alerter): class TheHiveAlerter(Alerter):
""" """
Use matched data to create alerts containing observables in an instance of TheHive Use matched data to create alerts containing observables in an instance of TheHive
This is a modified version for use with Security Onion
""" """
required_options = set(['hive_connection', 'hive_alert_config']) required_options = set(['hive_connection', 'hive_alert_config'])
def alert(self, matches): def get_aggregation_summary_text(self, matches):
text = super(TheHiveAlerter, self).get_aggregation_summary_text(matches)
connection_details = self.rule['hive_connection'] if text:
text = '```\n{0}```\n'.format(text)
api = TheHiveApi( return text
connection_details.get('hive_host'),
connection_details.get('hive_apikey', ''),
proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}),
cert=connection_details.get('hive_verify', False))
for match in matches:
context = {'rule': self.rule, 'match': match}
def create_artifacts(self, match):
artifacts = [] artifacts = []
context = {'rule': self.rule, 'match': match}
for mapping in self.rule.get('hive_observable_data_mapping', []): for mapping in self.rule.get('hive_observable_data_mapping', []):
for observable_type, match_data_key in mapping.items(): for observable_type, match_data_key in mapping.items():
try: try:
match_data_keys = re.findall(r'\{match\[([^\]]*)\]', match_data_key)
rule_data_keys = re.findall(r'\{rule\[([^\]]*)\]', match_data_key)
data_keys = match_data_keys + rule_data_keys
context_keys = list(context['match'].keys()) + list(context['rule'].keys())
if all([True if k in context_keys else False for k in data_keys]):
artifacts.append(AlertArtifact(dataType=observable_type, data=match_data_key.format(**context))) artifacts.append(AlertArtifact(dataType=observable_type, data=match_data_key.format(**context)))
except KeyError: except KeyError as e:
raise KeyError('\nformat string\n{}\nmatch data\n{}'.format(match_data_key, context)) print(('format string {} fail cause no key {} in {}'.format(e, match_data_key, context)))
return artifacts
def create_alert_config(self, match):
context = {'rule': self.rule, 'match': match}
alert_config = { alert_config = {
'artifacts': artifacts, 'artifacts': self.create_artifacts(match),
'sourceRef': str(uuid.uuid4())[0:6], 'sourceRef': str(uuid.uuid4())[0:6],
'title': '{rule[index]}_{rule[name]}'.format(**context) 'title': '{rule[name]}'.format(**context)
} }
alert_config.update(self.rule.get('hive_alert_config', {})) alert_config.update(self.rule.get('hive_alert_config', {}))
for alert_config_field, alert_config_value in alert_config.items(): for alert_config_field, alert_config_value in alert_config.items():
@@ -70,12 +64,41 @@ class TheHiveAlerter(Alerter):
formatted_list.append(element) formatted_list.append(element)
alert_config[alert_config_field] = formatted_list alert_config[alert_config_field] = formatted_list
return alert_config
def send_to_thehive(self, alert_config):
connection_details = self.rule['hive_connection']
api = TheHiveApi(
connection_details.get('hive_host', ''),
connection_details.get('hive_apikey', ''),
proxies=connection_details.get('hive_proxies', {'http': '', 'https': ''}),
cert=connection_details.get('hive_verify', False))
alert = Alert(**alert_config) alert = Alert(**alert_config)
response = api.create_alert(alert) response = api.create_alert(alert)
if response.status_code != 201: if response.status_code != 201:
raise Exception('alert not successfully created in TheHive\n{}'.format(response.text)) raise Exception('alert not successfully created in TheHive\n{}'.format(response.text))
def alert(self, matches):
if self.rule.get('hive_alert_config_type', 'custom') != 'classic':
for match in matches:
alert_config = self.create_alert_config(match)
self.send_to_thehive(alert_config)
else:
alert_config = self.create_alert_config(matches[0])
artifacts = []
for match in matches:
artifacts += self.create_artifacts(match)
if 'related_events' in match:
for related_event in match['related_events']:
artifacts += self.create_artifacts(related_event)
alert_config['artifacts'] = artifacts
alert_config['title'] = self.create_title(matches)
alert_config['description'] = self.create_alert_body(matches)
self.send_to_thehive(alert_config)
def get_info(self): def get_info(self):
return { return {