Skip to content

Classic Alerts

Introduction

The ClassicAlertMgr class of the classic_alerts module allows you to fetch, search, and update alerts coming from your Recorded Future enterprise.

Classic Alerts mean:

  • Alerts from the Recorded Future Intelligence Goals Library
  • Custom alerts created by a user using the Advanced Query Builder

See the API Reference for internal details of the module.

Notes

  • The search, fetch, and fetch_bulk methods all return a ClassicAlert object, or a list of them. If you want to look for new alerts you can use the search endpoint, while if you have alert IDs and you need to look up the alerts related to them, you will need to use fetch (for a very small number of IDs to look up) or fetch_bulk (for bigger lookups).
  • All the methods mentioned in point 1 accept a fields parameter to increase or reduce the information retrieved for each alert. The following fields are always requested: id, log, title, rule, no matter which fields you specify.
    • search uses only the required fields by default if the fields parameter is not specified.
    • fetch and fetch_bulk use all the fields if the fields parameter is not specified.
  • The more fields that are requested, the slower the action will be: make sure to balance the number of fields and the amount of alerts to search or fetch. A full list of fields can be found in ALL_CA_FIELDS in the constants file for this module.

Examples

Warning

The following examples demonstrate how to use this module. Be sure to add appropriate error handling as needed; all possible errors for each method or function are listed in the API Reference page.

Additionally, you must configure the RF_TOKEN environment variable before getting started. For instructions, see Learn.

1: Search the latest new alerts and save them as markdown

To search for new alerts you can use the search method, with a -1d trigger time lookback. To get only new alerts from the platform, use the value New for the status parameter.

To build markdown for alerts you only need the url field in addition to the fields that are always requested. In the example below, only the minimum information will be retrieved and saved as markdown.

from pathlib import Path

from psengine.classic_alerts import ClassicAlertMgr

OUTPUT_DIR = Path.cwd() / 'alerts'
OUTPUT_DIR.mkdir(exist_ok=True)

mgr = ClassicAlertMgr()
alerts = mgr.search(
    triggered='-1d', status='New', fields=['url']
)

for alert in alerts:
    markdown = alert.markdown(
        ai_insights=False,
        triggered_by=False,
        defang_iocs=True,
    )
    (OUTPUT_DIR / f'{alert.id_}.md').write_text(markdown)

Tip

To run this example, update the ALERT_IDS list with one or more alert IDs from your enterprise. You can either hardcode these IDs or use the search method described above to find them. For each alert found, use the id_ attribute to obtain its ID.

This example starts with the assumption that you have a list of alert IDs retrieved by a search, or a colleague, or another integration/security tool. We will use only two alert IDs for demonstration.

In this example we use the fetch_bulk method to download the alerts. We use max_workers=2 to split the task into two threads for better performance.

The alerts might have an image ID in their payload, which will be collected by the fetch_all_images method. This method does not return the images but saves them in an images property of the alert object. If you need to access these images programmatically you can do that with alert.images.

save_images will save in OUTPUT_DIR a .png file for each image called img:<image_id>.png.

from pathlib import Path

from psengine.classic_alerts import ClassicAlertMgr
from psengine.classic_alerts.helpers import save_images

OUTPUT_DIR = Path.cwd() / 'alerts'
OUTPUT_DIR.mkdir(exist_ok=True)

ALERT_IDS = ['9Z0ts8', '9Z0ttT']

mgr = ClassicAlertMgr()
alerts = mgr.fetch_bulk(ALERT_IDS, max_workers=2)

for alert in alerts:
    mgr.fetch_all_images(alert)
    save_images(alert, OUTPUT_DIR)

3: Fetch all the hits of an alert, and save the result as a JSON file

Tip

To run this example, update the ALERT_IDS list with one or more alert IDs from your enterprise. You can either hardcode these IDs or use the search method described above to find them. For each alert found, use the id_ attribute to obtain its ID.

This example starts with the assumption that you have an alert ID retrieved by a search, or a colleague, or another integration/security tool. We will use only two alert IDs for demonstration.

The fetch_hits method allows you to download all the "Hits" of an alert, meaning the entities that triggered the alert. The list of ClassicAlertHit objects returned by fetch_hits is based on how many hits have triggered the alert. If there are more than one, you will see more than one object that has the same alert_id field.

For this reason we first create a dictionary data where we group all the hits by alert_id. The use of defaultdict is mainly to avoid if/else statements in the for loop.

Note that for each hit object we use the json method. This method is available on any PSEngine-created object and allows you to dump it as a JSON-compatible dictionary.

Once the new data dictionary is populated we can save the content to a file after transforming it to a string with json.dumps.

import json
from collections import defaultdict
from pathlib import Path

from psengine.classic_alerts import ClassicAlertMgr

OUTPUT_DIR = Path.cwd() / 'alerts'
OUTPUT_DIR.mkdir(exist_ok=True)

ALERT_IDS = ['9Z0ts8', '9Z0ttT']

data = defaultdict(list)
mgr = ClassicAlertMgr()
hits = mgr.fetch_hits(ALERT_IDS)

for hit in hits:
    data[hit.alert_id].append(hit.json())

for alert_id, hits in data.items():
    Path(OUTPUT_DIR / f'{alert_id}.json').write_text(
        json.dumps(hits, indent=4)
    )