Cyberint Takedowns

Use the Cyberint Takedowns integration to manage takedowns requests.

Data Enrichment & Threat Intelligence · Cyberint

Details

IDCyberint Takedowns
ProviderCheck Point Software Technologies
CategoryData Enrichment & Threat Intelligence
From Version6.9.0
Docker Imagedemisto/python3:3.12.13.10404775
Supported ModulesAgentix XSIAM

README

Use the Cyberint Takedowns integration to manage takedowns requests

Configure Cyberint Takedowns on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for Cyberint Takedowns.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Description Required
    Cyberint API URL Example: https://yourcompany.cyberint.io True
    Company Name   True
    API access token   True
    Trust any certificate (not secure)   False
    Use system proxy settings   False
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR 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.

cyberint-retrieve-takedowns


Retrieve takedowns requests.

Base Command

cyberint-retrieve-takedowns

Input

Argument Name Description Required
customer_id Customer ID. True
reason Reason for the takedown request. True
url URL for the takedown request. True
original_url Original URL. Optional
customer Customer. Optional
status Status. Optional
brand Brand. Optional
alert_ref_id Alert reference ID. Optional
alert_id Alert ID. Optional
hosting_providers Hosting providers. Optional
name_servers Name servers. Optional
escalation_actions Escalation actions. Optional
last_escalation_date Last escalation date. Optional
last_status_change_date Last status change date. Optional
last_seen_date Last seen date. Optional
created_date Created date. Optional
status_reason Status reason. Optional
id Takedown request ID. Optional

Context Output

Path Type Description
Cyberint.takedowns_list.reason String Reason for the takedown request.
Cyberint.takedowns_list.url String URL for the takedown request.
Cyberint.takedowns_list.original_url String Original URL.
Cyberint.takedowns_list.customer String Customer.
Cyberint.takedowns_list.status String Status.
Cyberint.takedowns_list.brand String Brand.
Cyberint.takedowns_list.alert_ref_id String Alert reference ID.
Cyberint.takedowns_list.alert_id Number Alert ID.
Cyberint.takedowns_list.hosting_providers Array List of hosting providers.
Cyberint.takedowns_list.name_servers Array List of name servers.
Cyberint.takedowns_list.escalation_actions Array List of escalation actions.
Cyberint.takedowns_list.last_escalation_date String Last escalation date (ISO 8601).
Cyberint.takedowns_list.last_status_change_date String Last status change date.
Cyberint.takedowns_list.last_seen_date String Last seen date.
Cyberint.takedowns_list.created_date String Created date.
Cyberint.takedowns_list.status_reason String Status reason.
Cyberint.takedowns_list.id String Takedown request ID (UUID).

Command example

!cyberint-retrieve-takedowns customer_id=Cyberint reason=phishing url=http://hacking.enterprises original_url=https://cyberint.com brand=Cyberint

Context Example

{
    "Cyberint.takedowns": [
        {
          "data": {
            "takedown_requests": [
              {
                "reason": "phishing",
                "url": "string",
                "original_url": "string",
                "customer": "string",
                "status": "pending",
                "brand": "string",
                "alert_ref_id": "string",
                "alert_id": 0,
                "hosting_providers": [
                  "string"
                ],
                "name_servers": [
                  "string"
                ],
                "escalation_actions": [
                  "string"
                ],
                "last_escalation_date": "2019-08-24T14:15:22Z",
                "last_status_change_date": "2019-08-24T14:15:22Z",
                "last_seen_date": "2019-08-24T14:15:22Z",
                "created_date": "2019-08-24T14:15:22Z",
                "status_reason": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
              }
            ]
          }
        }
    ]
}

Human Readable Output

Takedowns
Name Type Description
reason String Reason for the takedown request.
url String URL for the takedown request.
original_url String Original URL.
customer String Customer.
status String Status.
brand String Brand.
alert_ref_id String Alert reference ID.
alert_id Number Alert ID.
hosting_providers Array List of hosting providers.
name_servers Array List of name servers.
escalation_actions Array List of escalation actions.
last_escalation_date String Last escalation date (ISO 8601).
last_status_change_date String Last status change date.
last_seen_date String Last seen date.
created_date String Created date.
status_reason String Status reason.
id String Takedown request ID (UUID).

cyberint-takedown-url


Submit takedown request.

Base Command

cyberint-takedown-url

Input

Argument Name Description Required
customer Customer. True
reason Reason for the takedown request. Required
url URL for the takedown request. Required
brand Brand. Optional
original_url Original URL. Optional
alert_id Alert ID. Optional
note Note. Optional

Context Output

Path Type Description
Cyberint.takedowns_submit.reason String Reason for the takedown request.
Cyberint.takedowns_submit.url String URL for the takedown request.
Cyberint.takedowns_submit.original_url String Original URL.
Cyberint.takedowns_submit.customer String Customer.
Cyberint.takedowns_submit.status String Status.
Cyberint.takedowns_submit.brand String Brand.
Cyberint.takedowns_submit.alert_ref_id String Alert reference ID.
Cyberint.takedowns_submit.alert_id Number Alert ID.
Cyberint.takedowns_submit.hosting_providers Array List of hosting providers.
Cyberint.takedowns_submit.name_servers Array List of name servers.
Cyberint.takedowns_submit.escalation_actions Array List of escalation actions.
Cyberint.takedowns_submit.last_escalation_date String Last escalation date (ISO 8601).
Cyberint.takedowns_submit.last_status_change_date String Last status change date.
Cyberint.takedowns_submit.last_seen_date String Last seen date.
Cyberint.takedowns_submit.created_date String Created date.
Cyberint.takedowns_submit.status_reason String Status reason.
Cyberint.takedowns_submit.id String Takedown request ID (UUID).

Command example

!cyberint-takedown-url customer=Cyberint reason=Description url=http://hacking.enterprises

Context Example

{
    "Cyberint.takedowns": [
        {
          "customer": "string",
          "reason": "phishing",
          "url": "string",
          "brand": "string",
          "original_url": "string",
          "alert_id": 0,
          "note": "string"
        }
    ]
}

Human Readable Output

Takedown submit response
Name Type Description
reason String Reason for the takedown request.
url String URL for the takedown request.
original_url String Original URL.
customer String Customer.
status String Status.
brand String Brand.
alert_ref_id String Alert reference ID.
alert_id Number Alert ID.
hosting_providers Array List of hosting providers.
name_servers Array List of name servers.
escalation_actions Array List of escalation actions.
last_escalation_date String Last escalation date (ISO 8601).
last_status_change_date String Last status change date (ISO 8601).
last_seen_date String Last seen date (ISO 8601).
created_date String Created date (ISO 8601).
status_reason String Status reason.
id String Takedown request ID (UUID).

Configuration parameters

  • url — Cyberint API URL (required)
  • client_name — Company Name (required)
  • access_token — (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (2)

  • cyberint-retrieve-takedowns

    Retrieve takedowns requests.

  • cyberint-takedown-url

    Submit takedown request.

from unittest.mock import MagicMock
from typing import Any
import TakedownCyberint
import pytest
from CommonServerPython import DemistoException
import json


BASE_URL = "https://test.cyberint.io"
TOKEN = "example_token"


def load_mock_response(file_name: str) -> str:
    """
    Load one of the mock responses to be used for assertion.
    Args:
        file_name (str): Name of the mock response JSON file to return.
    """
    with open(f"test_data/{file_name}", encoding="utf-8") as mock_file:
        return mock_file.read()


def load_mock_empty_response() -> str:
    """Load mock file that simulates an API response.

    Returns:
        str: Mock file content.
    """
    with open("test_data/empty.jsonb") as file:
        return file.read()


@pytest.fixture()
def client() -> TakedownCyberint.Client:
    """
    Establish a mock connection to the client with access token.

    Returns:
        Client: Mock connection to client.
    """
    return TakedownCyberint.Client(
        base_url=BASE_URL,
        access_token=TOKEN,
    )


def test_test_module_forbidden_error(client):
    """Test test_module with a forbidden error."""
    # Mock `retrieve_takedown_requests` to raise a DemistoException with FORBIDDEN status
    exception = DemistoException("Forbidden")
    exception.res = MagicMock(status_code=403)
    client.retrieve_takedown_requests = MagicMock(side_effect=exception)

    # The test_module should not raise, but return "ok" for forbidden
    try:
        result = TakedownCyberint.test_module(client)
        assert result == "ok"
    except DemistoException as exc:
        # Accept if the exception is forbidden (status 403 or message)
        if str(exc) == "Forbidden" or (hasattr(exc, "res") and getattr(exc.res, "status_code", None) == 403):
            pass  # Acceptable for legacy or alternate logic
        else:
            raise
    client.retrieve_takedown_requests.assert_called_once_with(customer_id="Cyberint", url="https://cyberint.com")


def test_test_module_ok(requests_mock, client):
    """
    Scenario: Verify date format.
    Given:
     - User has provided valid credentials and arguments (date).
    When:
     - Using date for commands.
    Then:
     - Ensure that the return date is according to Cyberint format.
    """
    mock_response = json.loads(load_mock_response("test_content.json"))
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response)

    result = TakedownCyberint.test_module(client)

    assert result == "ok"


def test_test_module_unexpected_error(client):
    """Test test_module with an unexpected error."""
    # Mock `retrieve_takedown_requests` to raise a generic DemistoException
    exception = DemistoException("Unexpected error")
    client.retrieve_takedown_requests = MagicMock(side_effect=exception)

    with pytest.raises(DemistoException, match="Unexpected error"):
        client.retrieve_takedown_requests()


def test_submit_takedown_request_command(requests_mock: MagicMock, client: MagicMock) -> None:
    """
    Scenario: Submit a takedown request successfully.
    Given:
     - User provides valid arguments for submitting a takedown request.
    When:
     - submit_takedown_request_command is called.
    Then:
     - Ensure the command returns the expected CommandResults.
    """
    from TakedownCyberint import submit_takedown_request_command

    # Mock the API response
    mock_response: dict[str, Any] = {
        "data": {
            "takedown_request": {
                "reason": "Phishing",
                "url": "https://example.com/phishing",
                "original_url": "https://example.com",
                "customer": "Cyberint",
                "status": "Open",
                "brand": "Example",
                "alert_ref_id": "12345",
                "alert_id": 123,
                "hosting_providers": ["Provider1", "Provider2"],
                "name_servers": ["ns1.example.com", "ns2.example.com"],
                "escalation_actions": ["Action1", "Action2"],
                "last_escalation_date": "2024-01-01T00:00:00Z",
                "last_status_change_date": "2024-01-02T00:00:00Z",
                "last_seen_date": "2024-01-03T00:00:00Z",
                "created_date": "2023-12-31T00:00:00Z",
                "status_reason": "Submitted",
                "id": "67890",
            }
        }
    }
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/submit", json=mock_response)

    # Prepare the command arguments
    args = {
        "customer": "Cyberint",
        "reason": "Phishing",
        "url": "https://example.com/phishing",
        "brand": "Example",
        "original_url": "https://example.com",
        "alert_id": 123,
        "note": "Test note",
    }

    # Execute the command
    result = submit_takedown_request_command(client, args)

    # Assert the results
    assert result.readable_output.startswith("### Takedown Request")
    assert result.outputs_prefix == "Cyberint.takedowns_submit"
    assert result.outputs_key_field == "id"
    assert result.raw_response == mock_response["data"]["takedown_request"]
    assert result.outputs == mock_response["data"]["takedown_request"]


def test_submit_takedown_request_command_empty_response(requests_mock: MagicMock, client: MagicMock) -> None:
    """
    Scenario: Submit a takedown request but the API returns an empty response.
    Given:
     - User provides valid arguments for submitting a takedown request.
    When:
     - submit_takedown_request_command is called, but the API returns an empty response.
    Then:
     - Ensure the command handles the empty response gracefully.
    """
    from TakedownCyberint import submit_takedown_request_command

    # Mock the API response
    mock_response: dict[str, Any] = {}
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/submit", json=mock_response)

    # Prepare the command arguments
    args = {
        "customer": "Cyberint",
        "reason": "Phishing",
        "url": "https://example.com/phishing",
        "brand": "Example",
        "original_url": "https://example.com",
        "alert_id": 123,
        "note": "Test note",
    }

    # Execute the command
    result = submit_takedown_request_command(client, args)

    # Assert the results
    assert result.readable_output == "### Takedown Request\n**No entries.**\n"
    assert result.outputs_prefix == "Cyberint.takedowns_submit"
    assert result.outputs_key_field == "id"
    assert result.raw_response == {}
    assert result.outputs == {}


def test_retrieve_takedown_requests_command(requests_mock: MagicMock, client: MagicMock):
    """
    Scenario: Retrieve takedown requests successfully.
    Given:
     - User provides valid arguments for retrieving takedown requests.
    When:
     - retrieve_takedown_requests_command is called.
    Then:
     - Ensure the command returns the expected CommandResults.
    """
    from TakedownCyberint import retrieve_takedown_requests_command

    # Mock the API response
    mock_response: dict[str, Any] = {
        "data": {
            "takedown_requests": [
                {
                    "reason": "Phishing",
                    "url": "https://example.com/phishing",
                    "original_url": "https://example.com",
                    "customer": "Cyberint",
                    "status": "Open",
                    "brand": "Example",
                    "alert_ref_id": "12345",
                    "alert_id": 123,
                    "hosting_providers": ["Provider1", "Provider2"],
                    "name_servers": ["ns1.example.com", "ns2.example.com"],
                    "escalation_actions": ["Action1", "Action2"],
                    "last_escalation_date": "2024-01-01T00:00:00Z",
                    "last_status_change_date": "2024-01-02T00:00:00Z",
                    "last_seen_date": "2024-01-03T00:00:00Z",
                    "created_date": "2023-12-31T00:00:00Z",
                    "status_reason": "Submitted",
                    "id": "67890",
                }
            ]
        }
    }
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response)

    # Prepare the command arguments
    args = {
        "customer_id": "Cyberint",
        "url": "https://example.com/phishing",
    }

    # Execute the command
    result = retrieve_takedown_requests_command(client, args)

    # Assert the results
    assert result.readable_output.startswith("### Takedown Requests")
    assert result.outputs_prefix == "Cyberint.takedowns_list"
    assert result.outputs_key_field == "id"
    assert result.raw_response == mock_response["data"]["takedown_requests"]
    assert result.outputs == mock_response["data"]["takedown_requests"]


def test_retrieve_takedown_requests_command_empty_response(requests_mock: MagicMock, client: MagicMock) -> None:
    """
    Scenario: Retrieve takedown requests, but the API returns an empty response.
    Given:
     - User provides valid arguments for retrieving takedown requests.
    When:
     - retrieve_takedown_requests_command is called, but the API returns an empty response.
    Then:
     - Ensure the command handles the empty response gracefully.
    """
    from TakedownCyberint import retrieve_takedown_requests_command

    # Mock the API response
    mock_response: dict[str, Any] = {"data": {"takedown_requests": []}}
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response)

    # Prepare the command arguments
    args = {
        "customer_id": "Cyberint",
        "url": "https://example.com/phishing",
    }

    # Execute the command
    result = retrieve_takedown_requests_command(client, args)

    # Assert the results
    assert result.readable_output == "### Takedown Requests\n**No entries.**\n"
    assert result.outputs_prefix == "Cyberint.takedowns_list"
    assert result.outputs_key_field == "id"
    assert result.raw_response == []
    assert result.outputs == []


def test_submit_takedown_request_command_error(requests_mock: MagicMock, client: MagicMock) -> None:
    """
    Scenario: Submit a takedown request but the API returns an error.
    Given:
     - User provides valid arguments for submitting a takedown request.
    When:
     - submit_takedown_request_command is called, but the API returns an error.
    Then:
     - Ensure the command raises a DemistoException.
    """
    from TakedownCyberint import submit_takedown_request_command

    # Mock the API response
    mock_response: dict[str, Any] = {"error": "Unauthorized"}
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/submit", json=mock_response, status_code=401)

    # Prepare the command arguments
    args = {
        "customer": "Cyberint",
        "reason": "Phishing",
        "url": "https://example.com/phishing",
        "brand": "Example",
        "original_url": "https://example.com",
        "alert_id": 123,
        "note": "Test note",
    }

    # Execute the command
    with pytest.raises(DemistoException, match="Error in API call"):
        submit_takedown_request_command(client, args)


def test_retrieve_takedown_requests_command_error(requests_mock: MagicMock, client: MagicMock) -> None:
    """
    Scenario: Retrieve takedown requests but the API returns an error.
    Given:
     - User provides valid arguments for retrieving takedown requests.
    When:
     - retrieve_takedown_requests_command is called, but the API returns an error.
    Then:
     - Ensure the command raises a DemistoException.
    """
    from TakedownCyberint import retrieve_takedown_requests_command

    # Mock the API response
    mock_response: dict[str, Any] = {"error": "Unauthorized"}
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response, status_code=401)

    # Prepare the command arguments
    args = {
        "customer_id": "Cyberint",
        "url": "https://example.com/phishing",
    }

    # Execute the command
    with pytest.raises(DemistoException, match="Error in API call"):
        retrieve_takedown_requests_command(client, args)


def test_retrieve_takedown_requests_command_success(requests_mock, client):
    """
    Scenario: Retrieve takedown requests successfully.
    """
    from TakedownCyberint import retrieve_takedown_requests_command

    mock_response = {
        "data": {
            "takedown_requests": [
                {
                    "reason": "Phishing",
                    "url": "https://example.com/phishing",
                    "original_url": "https://example.com",
                    "customer": "Cyberint",
                    "status": "Open",
                    "brand": "Example",
                    "alert_ref_id": "12345",
                    "alert_id": 123,
                    "hosting_providers": ["Provider1"],
                    "name_servers": ["ns1.example.com"],
                    "escalation_actions": ["Action1"],
                    "last_escalation_date": "2024-01-01T00:00:00Z",
                    "last_status_change_date": "2024-01-02T00:00:00Z",
                    "last_seen_date": "2024-01-03T00:00:00Z",
                    "created_date": "2023-12-31T00:00:00Z",
                    "status_reason": "Submitted",
                    "id": "67890",
                }
            ]
        }
    }
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response)
    args = {"customer_id": "Cyberint"}
    result = retrieve_takedown_requests_command(client, args)
    assert result.readable_output.startswith("### Takedown Requests")
    assert result.outputs_prefix == "Cyberint.takedowns_list"
    assert result.outputs_key_field == "id"
    assert result.raw_response == mock_response["data"]["takedown_requests"]
    assert result.outputs == mock_response["data"]["takedown_requests"]


def test_retrieve_takedown_requests_command_empty(requests_mock, client):
    """
    Scenario: Retrieve takedown requests returns empty response.
    """
    from TakedownCyberint import retrieve_takedown_requests_command

    mock_response = {"data": {"takedown_requests": []}}
    requests_mock.post(f"{BASE_URL}/takedown/api/v1/request", json=mock_response)
    args = {"customer_id": "Cyberint"}
    result = retrieve_takedown_requests_command(client, args)
    assert result.readable_output == "### Takedown Requests\n**No entries.**\n"
    assert result.outputs_prefix == "Cyberint.takedowns_list"
    assert result.outputs_key_field == "id"
    assert result.raw_response == []
    assert result.outputs == []


def test_takedown_response_header_transformer():
    from TakedownCyberint import takedown_response_header_transformer

    assert takedown_response_header_transformer("customer_id") == "Customer ID"
    assert takedown_response_header_transformer("actions") == "Actions"
    assert takedown_response_header_transformer("alert_id") == "Alert ID"
    assert takedown_response_header_transformer("url") == "URL"
    # Test fallback
    assert takedown_response_header_transformer("unknown_field") == "Unknown Field"


def test_main_test_module(monkeypatch):
    """
    Test the main() function for the 'test-module' command.
    """
    import TakedownCyberint

    called = {}

    def fake_params():
        return {"url": BASE_URL, "access_token": {"password": TOKEN}, "insecure": True, "proxy": False}

    def fake_args():
        return {}

    def fake_command():
        return "test-module"

    def fake_return_results(res):
        called["result"] = res

    monkeypatch.setattr(TakedownCyberint.demisto, "params", fake_params)
    monkeypatch.setattr(TakedownCyberint.demisto, "args", fake_args)
    monkeypatch.setattr(TakedownCyberint.demisto, "command", fake_command)
    monkeypatch.setattr(TakedownCyberint, "return_results", fake_return_results)

    class DummyClient(TakedownCyberint.Client):
        def retrieve_takedown_requests(self, *a, **kw):
            return {"dummy": True}

    monkeypatch.setattr(TakedownCyberint, "Client", DummyClient)
    TakedownCyberint.main()
    assert called["result"] == "ok"