DarktraceMBs

Rapid detection of malicious behaviour can make all the difference in the response to a security event. This pack includes configurations to combine the world-class threat detection of Darktrace with the synchrony and automation abilities of XSOAR, allowing security teams to investigate model breaches and all model breach related actions (such as commenting, acknowledging and model logic info).

Network Security · Darktrace

Details

IDDarktraceMBs
ProviderDarktrace
CategoryNetwork Security
From Version6.6.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Darktrace is a Cyber AI platform for threat detection and response across cloud, email, industrial, and the network.
This integration was integrated and tested with version 6.0.0 of Darktrace

Configure Darktrace in Cortex

Parameter Description Required
url Server URL (e.g. https://example.net) True
isFetch Fetch incidents False
insecure Trust any certificate (not secure) False
proxy Use system proxy settings False
public_api_token Public API Token True
private_api_token Private API Token True
min_score Minimum Score True
max_alerts Maximum Model Breaches per Fetch False
first_fetch First fetch time 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-model-breach


darktrace-get-model-breach returns a model breach based on its model breach id (pbid)

Base Command

darktrace-get-model-breach

Input

Argument Name Description Required
pbid Model breach ID Required

Context Output

Path Type Description
Darktrace.ModelBreach.pbid Number Model breach ID
Darktrace.ModelBreach.time Date Model breach generated time.
Darktrace.ModelBreach.commentCount Number Number of comments on the model breach
Darktrace.ModelBreach.score Number Score of Darktrace model breach (0 to 1)
Darktrace.ModelBreach.device.did Number Darktrace device ID of Device that breached the model
Darktrace.ModelBreach.device.macaddress String MAC address of the device involved in the model breach (if applicable)
Darktrace.ModelBreach.device.vendor String Vendor of the device involved in the model breach (if applicable)
Darktrace.ModelBreach.device.ip String IP of the device involved in the model breach (if applicable)
Darktrace.ModelBreach.device.hostname String Hostname of the device involved in the model breach (if applicable)
Darktrace.ModelBreach.device.devicelabel String Device label of the device involved in the model breach (if applicable)
Darktrace.ModelBreach.model.name String Darktrace model that was breached
Darktrace.ModelBreach.model.pid Number Model ID of the model that was breached
Darktrace.ModelBreach.model.uuid String Model UUID of the model that was breached
Darktrace.ModelBreach.model.tags Unknown List of model tags for the model that was breached
Darktrace.ModelBreach.model.priority Number Priority of the model that was breached (0 to 5)
Darktrace.ModelBreach.model.description String Darktrace model description

Command Example

!darktrace-get-model-breach pbid=95

Context Example

{
    "Darktrace": {
        "ModelBreach": {
            "commentCount": 0,
            "device": {
                "devicelabel": "Kelly's Laptop",
                "did": 823,
                "hostname": "sf-l-kjohnson",
                "ip": "172.31.32.146",
                "macaddress": "06:42:04:c2:b0:48",
                "vendor": "HP"
            },
            "model": {
                "description": "A device is connecting to watched domains or IP addresses. The watch list can be edited from the main GUI menu, Intel sub-menu, under the icon Watched Domains.\\n\\nAction: Review the domain and IP being connected to.",
                "name": "Compromise::Watched Domain",
                "pid": 762,
                "priority": 5,
                "tags": ["AP: C2 Comms"],
                "uuid": "3338210a-8979-4a1b-8039-63ca8addf166"
            },
            "pbid": 95,
            "score": 1,
            "time": "2020-10-08T21:11:21.000Z"
        }
    }
}

Human Readable Output

Darktrace Model Breach 95

commentCount device model pbid score time
0 did: 823
macaddress: 0a:df:4b:52:64:7a
vendor: HP
ip: 172.31.32.146
hostname: ip-172-31-32-146
devicelabel: Kelly’s Laptop
name: Compromise::Watched Domain
pid: 762
uuid: 3338210a-8979-4a1b-8039-63ca8addf166
tags: [AP: C2 Comms]
priority: 5
description: A device is connecting to watched domains or IP addresses. The watch list can be edited from the main GUI menu, Intel sub-menu, under the icon Watched Domains.
95 1 2020-10-08T21:11:21.000Z

darktrace-get-model-breach-comments


Returns the comments on a model breach based on its model breach id (pbid)

Base Command

darktrace-get-model-breach-comments

Input

Argument Name Description Required
pbid Model Breach ID Required

Context Output

Path Type Description
Darktrace.ModelBreach.Comment.message Unknown comments on Model Breach
Darktrace.ModelBreach.pbid Unknown Model breach identifier
Darktrace.ModelBreach.Comment.username Unknown Commented by user
Darktrace.ModelBreach.Comment.time Unknown Comment timestamp

Command Example

!darktrace-get-model-breach-comments pbid=46

Context Example

{
    "Darktrace": {
        "ModelBreach": {
            "comments": [
                {
                    "message": "Flag for follow-up",
                    "pbid": 46,
                    "pid": 210,
                    "time": "2020-10-08T21:11:21.000Z",
                    "username": "user.one"
                },
                {
                    "message": "Activity has been remediated",
                    "pbid": 46,
                    "pid": 210,
                    "time": "2020-10-08T23:11:21.000Z",
                    "username": "user.two"
                }
            ]
        }
    }
}

Human Readable Output

Darktrace Model Breach 46 Comments

message pbid pid time username
Flag for follow-up 46 210 2020-10-08T21:11:21.000Z user.one
Activity has been remediated 46 210 2020-10-08T23:11:21.000Z user.two

darktrace-acknowledge-model-breach


Acknowledge a model breach as specified by Model Breach ID

Base Command

darktrace-acknowledge-model-breach

Input

Argument Name Description Required
pbid Model Breach ID Required

Context Output

Path Type Description
Darktrace.ModelBreach.acknowledged String Whether the model breach is acknowledged in Darktrace
Darktrace.ModelBreach.pbid Number Model breach ID
Darktrace.ModelBreach.acknowledged.response Number Message response from acknowledge action

Command Example

!darktrace-acknowledge-model-breach pbid=111

Context Example

{
    "Darktrace": {
        "ModelBreach": {
            "acknowledged": true,
            "pbid": 111
        }
    }
}

Human Readable Output

Model Breach 111 Acknowledged

response
Successfully acknowledged.

darktrace-unacknowledge-model-breach


Unacknowledges a model breach as specified by Model Breach ID

Base Command

darktrace-unacknowledge-model-breach

Input

Argument Name Description Required
pbid Darktrace model breach ID Required

Context Output

Path Type Description
Darktrace.ModelBreach.acknowledged String Whether the model breach is acknowledged
Darktrace.ModelBreach.pbid Number Model breach ID
Darktrace.ModelBreach.acknowledged.response String Message response from acknowledge action

Command Example

!darktrace-unacknowledge-model-breach pbid=111

Context Example

{
    "Darktrace": {
        "ModelBreach": {
            "acknowledged": false,
            "pbid": 111
        }
    }
}

Human Readable Output

Model Breach 111 Unacknowledged

response
Successfully unacknowledged.

darktrace-get-model-breach-connections


Returns connections encountered by the device during a model breach.

Base Command

darktrace-get-model-breach-connections

Input

Argument Name Description Required
pbid Darktrace model breach ID Required
endtime Endtime of data retrieved Not Required
count The amount of lines returned Not Required
offset The offset of data pulled Not Required

Context Output

Path Type Description
Darktrace.ModelBreach Dictionary Details of the model breach

darktrace-get-model


Returns a model given a UUID

Base Command

darktrace-get-model

Input

Argument Name Description Required
uuid Darktrace model ID Required

Context Output

Path Type Description
Darktrace.Model Dictionary Details of the model

darktrace-get-model-component


Returns the details of a component given a CID

Base Command

darktrace-get-model-component

Input

Argument Name Description Required
cid Darktrace components ID Required

Context Output

Path Type Description
Darktrace.Model.Component Dictionary Details of the component

darktrace-post-comment-to-model-breach


Posts a specified comment to a model breach.

Base Command

darktrace-post-comment-to-model-breach

Input

Argument Name Description Required
pbid Darktrace model breach unique identifier Required
message Comment message Required

Context Output

Path Type Description
Darktrace.ModelBreach.commented String Whether the model breach is commented in Darktrace
Darktrace.ModelBreach.pbid Number Model breach ID
Darktrace.ModelBreach.message String Comment content
Darktrace.ModelBreach.response String Message response from comment action

Configuration parameters

  • url — Server URL (e.g. https://example.net) (required)
  • isFetch — Fetch incidents
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval
  • publicApiKey — Public API Token (required)
  • privateApiKey — Private API Token (required)
  • min_score — Minimum Score (required)
  • max_fetch — Maximum Model Breaches per Fetch
  • first_fetch — First fetch time

Commands (8)

  • darktrace-acknowledge-model-breach

    Acknowledge a model breach as specified by Model Breach ID.

  • darktrace-get-model

    Fetch the configuration details behind a specified model.

  • darktrace-get-model-breach

    Fetch details about a specific Model Breach.

  • darktrace-get-model-breach-comments

    Fetch all comments for a given model brach.

  • darktrace-get-model-breach-connections

    Retrieve connections relevant to a specified model breach.

  • darktrace-get-model-component

    Get details of a component.

  • darktrace-post-comment-to-model-breach

    Post a comment to a model breach.

  • darktrace-unacknowledge-model-breach

    Unacknowledge a given model breach.

import json


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


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


def test_get_model_breach(requests_mock):
    """Tests darktrace-get--model-breach command function.

    Configures requests_mock instance to generate the appropriate
    get_alerts API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, get_model_breach_command

    # GIVEN an integration is configured to Darktrace
    mock_api_response = util_load_json("test_data/get_breach.json")
    requests_mock.get("https://mock.darktrace.com/modelbreaches?pbid=95", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 95
    args = {
        "pbid": "95",
    }

    integration_response = get_model_breach_command(client, args)
    expected_response = util_load_json("test_data/formatted_get_breach.json")

    # THEN the response should be returned and formatted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"


def test_fetch_incidents(requests_mock):
    """Tests the fetch-incidents command function.

    Configures requests_mock instance to generate the appropriate
    get_alert API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, fetch_incidents

    # GIVEN an integration is configured and fetch incidents
    mock_response = util_load_json("test_data/fetch_breach.json")
    requests_mock.get(
        "https://usw1-51965-01.cloud.darktrace.com/modelbreaches?minscore=0.0&starttime=1598932817000", json=mock_response
    )

    client = Client(base_url="https://usw1-51965-01.cloud.darktrace.com/", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the most recent call was made on Mon, Aug 31, 2020 9 PM Pacific
    last_run = {
        "last_fetch": 1598932817000  # Mon, Aug 31, 2020 9 PM Pacific
    }

    _, integration_response = fetch_incidents(
        client=client, max_alerts=20, last_run=last_run, first_fetch_time="1 day ago", min_score=0
    )

    # THEN the relevant information will be fetched and pulled
    expected_response = util_load_json("test_data/formatted_fetch_breach.json")

    assert integration_response == expected_response
    assert len(integration_response) == 2


def test_get_model_breach_connections(mocker):
    """Tests the get-modelbreach-connections command function.
    Configures requests_mock instance to generate the appropriate
    get_alert API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, get_model_breach_connections_command

    # GIVEN an integration is configured and you would like to find similar devices
    mock_api_response = util_load_json("test_data/breach_details.json")
    mocker.patch.object(Client, "get_model_breach_connections", return_value=mock_api_response)
    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the specified device id is 1 and there are 2 results max desired
    args = {"pbid": "123", "count": "2", "endtime": 1629803362, "offset": 0}

    # THEN the context will be updated and information about similar devices will be fetched and pulled
    integration_response = get_model_breach_connections_command(client, args)
    expected_response = util_load_json("test_data/formatted_breach_details.json")

    assert integration_response.outputs == expected_response
    assert len(mock_api_response) == len(expected_response) + 1
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"


def test_get_model(requests_mock):
    """Tests the get-model command function.
    Configures requests_mock instance to generate the appropriate
    get_alert API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, get_model_command

    # GIVEN an integration is configured and you would like to find similar devices
    mock_api_response = util_load_json("test_data/model.json")
    requests_mock.get("https://mock.darktrace.com/models?uuid=80010119-6d7f-0000-0305-5e0000000325", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the specified device id is 1 and there are 2 results max desired
    args = {"uuid": "80010119-6d7f-0000-0305-5e0000000325"}

    # THEN the context will be updated and information about similar devices will be fetched and pulled
    integration_response = get_model_command(client, args)
    expected_response = util_load_json("test_data/formatted_model.json")

    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.Model"


def test_get_model_component(requests_mock):
    """Tests the get-component command function.
    Configures requests_mock instance to generate the appropriate
    get_alert API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, get_model_component_command

    # GIVEN an integration is configured and you would like to find similar devices
    mock_api_response = util_load_json("test_data/component.json")
    requests_mock.get("https://mock.darktrace.com/components?cid=254503", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the specified device id is 1 and there are 2 results max desired
    args = {"cid": "254503"}

    # THEN the context will be updated and information about similar devices will be fetched and pulled
    integration_response = get_model_component_command(client, args)
    expected_response = util_load_json("test_data/formatted_component.json")

    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.Model.Component"


def test_get_model_breach_comments(requests_mock):
    """Tests darktrace-get-model-breach-comments command function.

    Configures requests_mock instance to generate the appropriate
    get_alerts API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, get_model_breach_comments_command

    # GIVEN an integration is configured and comments are desired
    mock_api_response = util_load_json("test_data/get_comments.json")
    requests_mock.get("https://mock.darktrace.com/mbcomments?pbid=2507", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 46
    args = {
        "pbid": "2507",
    }

    integration_response = get_model_breach_comments_command(client, args)
    expected_response = util_load_json("test_data/formatted_get_comments.json")

    # THEN the comments should be returned and formatted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach.Comment"


def test_acknowledge_model_breach(requests_mock):
    """Tests darktrace-acknowledge-model-breach command function.

    Configures requests_mock instance to generate the appropriate
    get_alerts API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, acknowledge_model_breach_command

    # GIVEN an integration is configured and you would like to acknowledge a breach
    mock_api_response = util_load_json("test_data/ack_success.json")
    requests_mock.post("https://mock.darktrace.com/modelbreaches/2509/acknowledge", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 111
    args = {
        "pbid": "2509",
    }

    integration_response = acknowledge_model_breach_command(client, args)
    expected_response = util_load_json("test_data/formatted_ack_success.json")

    # THEN the breach should be acknowledged, context updated, and message posted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"
    assert integration_response.outputs_key_field == "pbid"


def test_unacknowledge(requests_mock):
    """Tests darktrace-unacknowledge command function.

    Configures requests_mock instance to generate the appropriate
    get_alerts API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, unacknowledge_model_breach_command

    # GIVEN an integration is configured and you would like to unacknowledge a breach
    mock_api_response = util_load_json("test_data/ack_success.json")
    requests_mock.post("https://mock.darktrace.com/modelbreaches/2509/unacknowledge", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 111
    args = {
        "pbid": "2509",
    }

    integration_response = unacknowledge_model_breach_command(client, args)
    expected_response = util_load_json("test_data/formatted_unack_success.json")

    # THEN the breach should be acknowledged, context updated, and message posted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"
    assert integration_response.outputs_key_field == "pbid"


def test_post_comment_to_model_breach(requests_mock):
    from DarktraceMBs import Client, post_comment_to_model_breach_command

    # GIVEN an integration is configured and you would like to unacknowledge a breach
    mock_api_response = util_load_json("test_data/comment_post.json")
    requests_mock.post("https://mock.darktrace.com/modelbreaches/2509/comments", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 111
    args = {"pbid": "2509", "message": "Test comment post"}

    integration_response = post_comment_to_model_breach_command(client, args)
    expected_response = util_load_json("test_data/formatted_comment_post.json")

    # THEN the breach should be acknowledged, context updated, and message posted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"
    assert integration_response.outputs_key_field == "pbid"


def test_acknowledge_model_breach_UV(requests_mock):
    """Tests darktrace-acknowledge-model-breach command function.

    Configures requests_mock instance to generate the appropriate
    get_alerts API response, loaded from a local JSON file. Checks
    the output of the command function with the expected output.
    """
    from DarktraceMBs import Client, acknowledge_model_breach_command

    # GIVEN an integration is configured and you would like to acknowledge a breach
    mock_api_response = util_load_json("test_data/ack_success_UV.json")
    requests_mock.post("https://mock.darktrace.com/modelbreaches/1000000000001/acknowledge", json=mock_api_response)

    client = Client(base_url="https://mock.darktrace.com", verify=False, auth=("examplepub", "examplepri"))

    # WHEN the desired model breach has id 111
    args = {
        "pbid": "1000000000001",
    }

    integration_response = acknowledge_model_breach_command(client, args)
    expected_response = util_load_json("test_data/formatted_ack_success_UV.json")

    # THEN the breach should be acknowledged, context updated, and message posted
    assert integration_response.outputs == expected_response
    assert integration_response.outputs_prefix == "Darktrace.ModelBreach"
    assert integration_response.outputs_key_field == "pbid"


def test_test_module(requests_mock):
    """
    Tests the test module function
    """
    from DarktraceMBs import Client, test_module

    # GIVEN an integration is configured and you would like to test the configuration
    mock_api_response = util_load_json("test_data/fetch_breach.json")
    requests_mock.get(
        "https://mock.darktrace.com/modelbreaches?minscore=0&starttime=1598932817000&minimal=false&deviceattop=true",
        json=mock_api_response,
    )

    client = Client(base_url="https://mock.darktrace.com/", verify=False, auth=("examplepub", "examplepri"))

    first_fetch_time = 1598932817000

    integration_response = test_module(client, first_fetch_time)
    expected_response = "ok"

    # THEN if there is no error, test_module should return 'ok'
    assert len(integration_response) == 2
    assert isinstance(expected_response, str)


def test_helper_stringify_data():
    """
    Tests the stringify_data helper function.
    """
    from DarktraceMBs import stringify_data

    # GIVEN you have a params data structure in dictionary format and would like to test the stringify_data helper function
    data_1 = {"first": 1}
    data_2 = {"first": 1, "second": 2}
    data_3 = {}
    data_4 = {"test_1": "string_1", "test_2": 2}

    # WHEN calling the helper function
    integration_response_1 = stringify_data(data_1)
    integration_response_2 = stringify_data(data_2)
    integration_response_3 = stringify_data(data_3)
    integration_response_4 = stringify_data(data_4)

    # THEN the following outputs are expected
    assert integration_response_1 == "first=1"
    assert integration_response_2 == "first=1&second=2"
    assert integration_response_3 == ""
    assert integration_response_4 == "test_1=string_1&test_2=2"