Skip to content

Detections

Introduction

The DetectionMgr class in the detection module enables you to search for and retrieve detection rules. Currently this includes:

  • Yara
  • Sigma
  • Snort

See the API Reference for internal details of the module.

Notes

  • In this module, the fetch and search methods are functionally identical. Internally, fetch simply calls search with the given doc_id. The fetch method is provided for convenience, making it easier to retrieve a detection rule by its ID.

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: Fetch a detection rule and save it to a file

This example assumes that you have a detection rule ID either from a previously collected analyst note written by the Recorded Future Insikt Group or from an integration/security tool. We will use only two alert IDs for demonstration. Here we have a detection rule with ID doc:aqofps, which is a Recorded Future specific ID. After fetching it, you can save it with the save_rule helper function, which takes the whole DetectionRule object created by the fetch method and saves the content of the rule as a file.

from pathlib import Path

from psengine.detection import DetectionMgr
from psengine.detection.helpers import save_rule

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

mgr = DetectionMgr()
rule = mgr.fetch('doc:aqofps')
save_rule(rule, OUTPUT_DIR)

2: Find the 10 detection rules published yesterday

In this example, we use the search method to find detection rules based on specific criteria. We set the created_after to a relative date, like -1d to fetch the rules that have been released yesterday.

from pathlib import Path

from psengine.detection import DetectionMgr

OUTPUT_DIR = Path.cwd() / 'rules'
OUTPUT_DIR.mkdir(exist_ok=True)
mgr = DetectionMgr()
rules = mgr.search(created_after='-1d')
for rule in rules:
    print(rule)

In this example, we use the search method to find detection rules based on specific criteria. By setting detection_rule to yara, we filter for Yara rules only. To further narrow the results to those related to Command and Control activities, we use the MITRE code entity mitre:T1071. Each matching rule is then saved to a file.

from pathlib import Path

from psengine.detection import DetectionMgr
from psengine.detection.helpers import save_rule

OUTPUT_DIR = Path.cwd() / 'rules'
OUTPUT_DIR.mkdir(exist_ok=True)
mgr = DetectionMgr()
rules = mgr.search(
    detection_rule='yara', entities=['mitre:T1071']
)
for rule in rules:
    save_rule(rule, OUTPUT_DIR)

This example involves using a different module in combination with the detection module. It is very similar to the example above, but in this case we cannot pass the entity CVE-2021-44228 directly into the list of entities, since this parameter requires the Recorded Future ID of the entity. To find it, we need to use the entity_match module. Please look at that module’s documentation for more information.

We first search for the CVE ID using the entity_mgr.match method. This always returns a list of entities of length less than or equal to limit, even if entities are not found. You can safely extract the first element and check its is_found attribute to see if the lookup was successful. If yes, you can use the .content.id_ to filter the detection search.

from pathlib import Path

from psengine.detection import DetectionMgr
from psengine.detection.helpers import save_rule
from psengine.entity_match import EntityMatchMgr

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

mgr = DetectionMgr()
entity_mgr = EntityMatchMgr()

match_entities = entity_mgr.match(
    'CVE-2021-44228',
    entity_type='CyberVulnerability',
    limit=1,
)
cve = match_entities[0]

if cve.is_found:
    rules = mgr.search(entities=[cve.content.id_])
    for rule in rules:
        save_rule(rule, OUTPUT_DIR)