Binalyze AIR

Collect your forensics data under 10 minutes.

Forensics & Malware Analysis · Binalyze AIR

Details

IDBinalyze AIR
ProviderBinalyze
CategoryForensics & Malware Analysis
From Version6.2.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Binalyze AIR Integration

This integration allows you to use the Binalyze AIR’s isolation and evidence collecting features easily

Collect your forensics data under 10 minutes.
This integration was integrated and tested with version 2.6.2 of Binalyze AIR

Configure Binalyze AIR in Cortex

Parameter Description Required
Binalyze AIR Server URL Binalyze AIR Server URL True
API Key e.g.: api_1234567890abcdef1234567890abcdef True
Trust any certificate (not secure)   False
Use system proxy settings   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.

binalyze-air-isolate


Isolate an endpoint

Base Command

binalyze-air-isolate

Input

Argument Name Description Required
hostname Hostname of endpoint. Required
organization_id Organization ID of the endpoint. For the use of a custom organization ID, you can specify a custom value outside the predefined set. Required
isolation To isolate use enable. Possible values are: enable, disable. Required

Context Output

Path Type Description
BinalyzeAIR.Isolate.result._id string Isolation unique task ID
BinalyzeAIR.Isolate.result.name string Isolation task name
BinalyzeAIR.Isolate.result.organizationId number Organization Id of endpoint

binalyze-air-acquire


Acquire evidence from an endpoint

Base Command

binalyze-air-acquire

Input

Argument Name Description Required
hostname Hostname of endpoint. Required
profile Acquisition profile. To use a custom acquisition profile, you can specify a custom value outside the predefined set. Possible values are: compromise-assessment, browsing-history, event-logs, memory-ram-pagefile, quick, full. Required
case_id ID for the case,e.g. C-2022-0001. Required
organization_id Organization ID of the endpoint. For the use of a custom organization ID, you can specify a custom value outside the predefined set. Required

Context Output

Path Type Description
BinalyzeAIR.Acquire.result._id string Acquisition unique task ID
BinalyzeAIR.Acquire.result.name string Acquisiton task name
BinalyzeAIR.Acquire.result.organizationId number Organization Id of endpoint

Configuration parameters

  • server — Binalyze AIR Server URL (required)
  • api_key — API Key (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (2)

  • binalyze-air-acquire

    Acquire evidence from an endpoint.

  • binalyze-air-isolate

    Isolate an endpoint.

import json

from CommonServerPython import *
from typing import Any


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


def test_api_success(requests_mock: Any) -> None:
    """Successful test for the test-api command"""
    from BinalyzeAIR import Client, test_connection

    mock_response: dict[str, bool] = {"statusCode": 200}

    expected_mocked_command_result: str = "ok"

    requests_mock.get("https://nonexistent-domain.com/api/public/endpoints?filter[organizationIds]=0", json=mock_response)

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False)

    mocked_command_result: str = test_connection(client)
    if mocked_command_result is expected_mocked_command_result:
        assert mocked_command_result == expected_mocked_command_result


def test_api_fail(requests_mock: Any) -> None:
    """Authorization fail test for the test-api command."""

    from BinalyzeAIR import Client, test_connection

    mock_response: str = "Authorization Error"

    expected_mocked_command_result: str = "Authorization Error: Make sure API Key is correctly set."

    requests_mock.get("https://nonexistent-domain.com/api/public/endpoints?filter[organizationIds]=0", json=mock_response)

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False)

    mocked_command_result: str = test_connection(client)
    if mocked_command_result is expected_mocked_command_result:
        assert mocked_command_result == expected_mocked_command_result


def test_api_connection_fail(requests_mock: Any) -> None:
    """Connectivity fail test for the test-api command."""

    from BinalyzeAIR import Client, test_connection

    mock_response: str = "Connection Error"

    expected_mocked_command_result: str = "Connection Error: Test connection failed."

    requests_mock.get("https://nonexistent-domain.com/api/public/endpoints?filter[organizationIds]=0", json=mock_response)

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False)

    mocked_command_result: str = test_connection(client)
    if mocked_command_result is expected_mocked_command_result:
        assert mocked_command_result == expected_mocked_command_result


def test_get_profile_id_preset() -> None:
    from BinalyzeAIR import Client

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False)
    mocked_profile = "full"
    result = client.get_profile_id(mocked_profile, 1)
    assert result == mocked_profile


def test_get_profile_id_custom(requests_mock: Any) -> None:
    from BinalyzeAIR import Client

    mock_response = util_load_json("test_data/profile_id.json")
    requests_mock.get(
        "https://nonexistent-domain.com/api/public/acquisitions/profiles?filter[name]=profile&filter[organizationIds]=0",
        json=mock_response,
    )
    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False)
    result = client.get_profile_id("profile", 0)
    expected_mocked_profile_id = mock_response.get("result", {}).get("entities", {})[0].get("_id", None)
    assert expected_mocked_profile_id == result


def test_air_acquire_command(requests_mock: Any) -> None:
    from BinalyzeAIR import Client, air_acquire_command

    args: dict[str, Any] = {
        "hostname": "endpointhostname",
        "profile": "quick",
        "case_id": "case_id will be here",
        "organization_id": 0,
    }
    headers: dict[str, Any] = {
        "Authorization": "Bearer api_key",
        "User-Agent": "Binalyze AIR",
        "Content-type": "application/json",
        "Accept-Charset": "UTF-8",
    }
    mock_response = util_load_json("test_data/test_acquire_success.json")

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False, headers=headers)
    mock_get_response = util_load_json("test_data/profile_id.json")
    requests_mock.get(
        "https://nonexistent-domain.com/api/public/acquisitions/profiles?filter[name]=profile_name&filter[organizationIds]=0",
        json=mock_get_response,
    )
    requests_mock.post("https://nonexistent-domain.com/api/public/acquisitions/acquire", json=mock_response)

    mocked_command_result: CommandResults = air_acquire_command(client, args)
    mocked_readable_output = util_load_json("test_data/test_acquire_success.json").get("results")
    mocked_command_output = ({"Result": mock_response.get("result"), "Success": mock_response.get("success")},)
    if mocked_command_result == 404:
        assert mocked_readable_output == "No contex for queried hostname."

    assert mocked_command_result.outputs_prefix == "BinalyzeAIR.Acquisition"
    assert mocked_command_result.outputs_key_field == "hostname"
    assert mocked_command_output


def test_air_isolate_command(requests_mock: Any) -> None:
    from BinalyzeAIR import Client, air_isolate_command

    args: dict[str, Any] = {"hostname": "endpointhostname", "organization_id": 0, "isolation": True}
    headers: dict[str, Any] = {
        "Authorization": "Bearer api_key",
        "User-Agent": "Binalyze AIR",
        "Content-type": "application/json",
        "Accept-Charset": "UTF-8",
    }
    mock_response = util_load_json("test_data/test_isolate_success.json")

    client: Client = Client(base_url="https://nonexistent-domain.com", verify=False, headers=headers)
    requests_mock.post("https://nonexistent-domain.com/api/public/endpoints/tasks/isolation", json=mock_response)

    mocked_command_result: CommandResults = air_isolate_command(client, args)
    mocked_readable_output = util_load_json("test_data/test_isolate_success.json").get("results")
    mocked_command_output = ({"Result": mock_response.get("result"), "Success": mock_response.get("success")},)
    if mocked_command_result == 404:
        assert mocked_readable_output == "No contex for queried hostname."

    assert mocked_command_result.outputs_prefix == "BinalyzeAIR.Isolate"
    assert mocked_command_result.outputs_key_field == "hostname"
    assert mocked_command_output