Create and delete training alerts in TheHive

TheHive Case Management

TheHive is a scalable, open source and free Security Incident Response Platform, which tightly integrates with MISP. It supports a feature that allows you to convert one or more alerts, for example alerts sent by security devices, to a security case (an investigation). The creation, and handling, of these alerts can be done via an API.

Creating, and then afterwards deleting, these alerts to showcase the features of TheHive during a training session can be a time-consuming process. So why not automate this process?

Create and Delete Alerts

With the Python script training-alert.py you can easily create a large number of alerts, and delete them if you want to start over. The created alerts are unique and contain a set of random elements, such as title and observables.

You can get the script from TheHive-Resources/contrib/ManageTrainingAlerts/, or below this post.

Create alerts

Creating alerts can be done by calling the script with the, create option and then supplying the number of alerts to be created. The alert details such as title, alert type and source are randomly generated. The alert is extended with two random tags and with one observable.

training-alert.py create 5

The random values are stored in the variables sources, alert_type, title and tags.



Delete alerts

The deletion of these alerts can be done by calling the script with the delete option and then either supplying an alert id or a tag. With the alert id, one single alert gets deleted. With the tag option, all the alerts which have the supplied tag, will be deleted.

A warning, this deletion does not take into account if the alerts were previously created by this script or not.

training-alert.py delete _id 1fd272233688b6cd685b138092970ce8

training-alert.py delete tag Perimeter

The deletion of the alerts are done by calling the API with the force parameter. Calling the script with the tag parameter causes it to first list the alerts with the given tag, and then recursively call the delete function with the found id.

Training sessions for TheHive

The alert feature in TheHive, and the option to convert these alerts into cases and link the observables to previous cases is a great feature. But having to create these alerts manually with curl (or similar) can be tedious. This script can save you a lot of time if you give a training session of TheHive. Good luck!

training-alert.py

#!/usr/bin/env python3

'''
TheHive - Create and Delete alerts. Useful during a training session.
Koen Van Impe - 2020

 Create 5 alerts:
    training-alert.py create 5
 Delete specific alert:
    training-alert.py delete _id 1fd272233688b6cd685b138092970ce8
 Delete alerts with a tag:
    training-alert.py delete tag Perimeter
'''

import requests
import json
import random
import sys

auth = "<AUTHKEY>"
host = "http://127.0.0.1:9000"


def create_alert():
    maxrand = 10000
    sources = ['IDS', 'AV', 'Firewall', 'Honeypot']
    alert_type = ['Internal', 'External', 'Human']
    title = ['Rare process', 'Rare scheduled task', 'Unusual activity', 'Outbound tunnel', 'Cleartext traffic', 'Malware alert', 'New SUID']
    title_ip = '{}.{}.{}.{}'.format(random.randrange(1, 223), random.randrange(1, 223), random.randrange(1, 223), random.randrange(1, 223))
    tags = ['MISP', 'Sigma', 'Perimeter', 'BIA:1', 'High-confidence']

    headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(auth), 'Accept': 'text/plain'}
    url = "{}/api/alert".format(host)

    data = {'title': '{} - {}'.format(random.choice(title), title_ip), 'description': 'Alert Description', 'type': random.choice(alert_type), 'source': random.choice(sources), 'sourceRef': '{} - {} - {}'.format(random.randrange(maxrand), random.randrange(maxrand), random.randrange(maxrand)), 'tags': [random.choice(tags), random.choice(tags)], 'artifacts': [{'dataType': 'ip', 'data': title_ip, 'message': 'Victim'}]}

    result = requests.post(url, headers=headers, data=json.dumps(data))
    if result.json()['status'] == 'New':
        print('Alert {} added'.format(result.json()['_id']))
    else:
        print('Failed to add alert')
        print(data)


def delete_alert(_id=False, tag=False):
    if _id:
        url = "{}/api/alert/{}?force=1".format(host, _id)
        headers = {'Authorization': 'Bearer {}'.format(auth)}
        result = requests.delete(url, headers=headers)
        if result.status_code == 204:
            print('Alert {} deleted'.format(_id))
        else:
            print('Failed to delete {}'.format(_id))

    if tag:
        url = "{}/api/alert/_search?range=all".format(host)
        headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer {}'.format(auth), 'Accept': 'text/plain'}
        data = {'query': {'tags': tag}}
        result = requests.post(url, headers=headers, data=json.dumps(data))
        if result.status_code == 200:
            if result.json():
                for alert in result.json():
                    delete_alert(_id=alert['_id'])
            else:
                print("Nothing to delete")
        else:
            print("Failed to delete", result)


if len(sys.argv) > 1:
    action = sys.argv[1]
    if action == "create":
        i = 0
        count = int(sys.argv[2])
        while i <= count:
            create_alert()
            i = i + 1
    if action == "delete":
        subaction = sys.argv[2]
        if subaction == "_id":
            _id = sys.argv[3]
            delete_alert(_id=_id)
        elif subaction == "tag":
            tag = sys.argv[3]
            delete_alert(tag=tag)
else:
    print("Invalid arguments")

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.