Darktrace Event Collector

Use this integration to fetch model breaches from Darktrace as events in XSIAM.

Analytics & SIEM · Darktrace

Details

IDDarktrace Event Collector
ProviderThoma Bravo
CategoryAnalytics & SIEM
From Version6.9.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Use this integration to fetch a list of model breaches, filtered by the specified parameters. This is important for organizations that wish to integrate Darktrace programmatically into their SOC environment.
The integration was integrated and tested with version v5.2 API of Darktrace.

This is the default integration for this content pack when configured by the Data Onboarder in Cortex XSIAM.

Configure Darktrace Event Collector in Cortex

Parameter Description Required
Server URL (e.g. https://example.cloud.darktrace.com) REST API Endpoint of Darktrace server. True
Trust any certificate (not secure)   False
Use system proxy settings   False
Public API Token Public token obtained by creating an API token pair on the /config configuration page. True
Private API Token Private token obtained by creating an API token pair on the /config configuration page. True
Max events per fetch Maximum number of Darktrace model breaches to fetch at a time. False
First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) Time to start fetching the first incidents. Limited to 1 Year. False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

darktrace-get-events


Gets events from Darktrace Event Collector.

Base Command

darktrace-get-events

Input

Argument Name Description Required
limit The number of events to return. Default is 10. Optional
start_time The start time by which to filter events. Date format will be the same as in the first_fetch parameter. Optional
end_time The end time by which to filter events. Optional
should_push_events Set this argument to True in order to create events, otherwise the command will only display them. Possible values are: true, false. Default is false. Required

Context Output

There is no context output for this command.

Configuration parameters

  • base_url — Server URL (e.g., https://example.cloud.darktrace.com) (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • public_creds — (required)
  • private_creds — (required)
  • max_fetch — Max events per fetch
  • first_fetch — First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)

Commands (1)

  • darktrace-get-events

    Gets events from Darktrace.

from freezegun import freeze_time
import demistomock as demisto
import json
import pytest


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


def mock_params(mocker, params=None):
    if params is None:
        params = {
            "first_fetch": "3 days",
            "max_fetch": "2",
            "insecure": True,
            "proxy": False,
            "base_url": '"https://mock.darktrace.com"',
            "public_creds": {"password": "example_pub"},
            "private_creds": {"password": "example_pri"},
        }
    mocker.patch.object(demisto, "params", return_value=params)


@pytest.fixture(autouse=True)
def client(mocker):
    from DarktraceEventCollector import Client

    mocker.patch.object(Client, "_http_request", return_value=None)
    mocker.patch.object(Client, "parse_respone", return_value=util_load_json("test_data/mocked_get_events.json"))
    return Client(base_url="https://mock.darktrace.com", verify=False, proxy=False, auth=("example_pub", "example_pri"))


"""*****COMMAND FUNCTIONS****"""


def test_fetch_events_max_fetch(client):
    """
    Given: A mock Darktrace client.
    When: Running fetch-events with a max_fetch of 2, while there are three events.
    Then: Ensure only two events is returned.
    """
    from DarktraceEventCollector import fetch_events

    mock_start_time = 1
    mock_end_time = 2
    max_fetch = 2
    events, _ = fetch_events(client=client, max_fetch=max_fetch, last_run={}, start_time=mock_start_time, end_time=mock_end_time)
    assert len(events) == 2


def test_fetch_events_with_last_run(client):
    """
    Given: A mock Darktrace client.
    When: Running fetch-events with a max_fetch of 2 and last run, while there are three events.
    Then: Ensure only last two events is returned.
    """
    from DarktraceEventCollector import fetch_events

    mock_start_time = 1
    mock_end_time = 2
    max_fetch = 2
    events, _ = fetch_events(
        client=client, max_fetch=max_fetch, last_run={"last_fetch_pid": 11111}, start_time=mock_start_time, end_time=mock_end_time
    )
    assert len(events) == 2
    assert events == client.parse_respone.return_value[1:]


def test_get_events_command_limit(client):
    """
    Given: A mock Darktrace client.
    When: Running get_events_command with a limit of 2, while there are three events.
    Then: Ensure only two events is returned.
    """
    from DarktraceEventCollector import get_events_command

    mock_args = {"limit": "2"}
    mock_first_fetch_time = 1687009200
    events, _ = get_events_command(client=client, args=mock_args, first_fetch_time_timestamp=mock_first_fetch_time)
    assert len(events) == 2


@freeze_time("2023-06-20 13:40:00 UTC")
@pytest.mark.parametrize(
    "mock_date,expected_res",
    [("3 days", 1687009200), ("2021-01-01T00:00:00Z", 1609459200), ("1609459200", 1609459200)],
    ids=["XSOAR_FORMAT", "ISO_FORMAT", "TIME_STAMP_FORMAT"],
)
def test_convert_to_timestamp(mock_date, expected_res):
    """
    Given: A mock Darktrace client.
    When: Running get_events_command with a limit of 2, while there are three events.
    Then: Ensure only two events is returned.
    """
    from DarktraceEventCollector import convert_to_timestamp
    from CommonServerPython import arg_to_datetime

    parsed_date = convert_to_timestamp(date=arg_to_datetime(mock_date))
    assert parsed_date == expected_res


@freeze_time("2023-06-20 13:40:00 UTC")
def test_test_module_ok(client, mocker):
    from DarktraceEventCollector import test_module, convert_to_timestamp
    from CommonServerPython import arg_to_datetime

    params = {"max_fetch": "1", "first_fetch": "3 days"}

    mock_params(mocker, params)
    assert test_module(client, convert_to_timestamp(arg_to_datetime(params.get("first_fetch"))), last_run={}) == "ok"


@pytest.mark.parametrize(
    "params,error_msg",
    [
        ({"max_fetch": "1", "first_fetch": ""}, 'Failed to execute test-module command.\nError:\n"" is not a valid date'),
        (
            {"max_fetch": "not a number", "first_fetch": "3 days"},
            'Failed to execute test-module command.\nError:\n"not a number" is not a valid number',
        ),
        (
            {"max_fetch": "1", "first_fetch": "not a date"},
            'Failed to execute test-module command.\nError:\n"not a date" is not a valid date',
        ),
    ],
    ids=["empty_str_first_fetch", "invalid_max_fetch", "invalid_first_fetch"],
)
def test_test_module_failure(mocker, params, error_msg):
    """
    Given: different assignments for integration parameters.
    When: Running test-module command.
    Then: Make sure the correct message is returned.
    """
    from DarktraceEventCollector import main

    mock_params(mocker, params)
    mocker.patch.object(demisto, "command", return_value="test-module")
    return_error = mocker.patch("DarktraceEventCollector.return_error")
    main()
    assert return_error.call_args[0][0] == error_msg