ANY.RUN TI Feed

Threat Intelligence Feeds provide data on the known indicators of compromise such as malicious IPs, URLs, Domains.

Data Enrichment & Threat Intelligence · ANY.RUN · Feed

Details

IDANY.RUN TI Feed
ProviderAnyRun
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/anyrun-sdk:1.0.0.10440656
Supported ModulesAgentix XSIAM EDR Cortex Cloud Cloud Runtime Security

README

Threat Intelligence Feed provide data on the known indicators of compromise: malicious IPs, URLs, Domains

Generate your API key

Please contact your ANY.RUN account manager to get your API key.

Warning

Prefixed API keys and Basic Authentication for TI Feeds will not be supported in future releases.

Configure ANY.RUN Feed in Cortex

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for ANY.RUN.
  3. Click Add instance to create and configure a new integration instance.
  4. Insert ANY.RUN TI Feeds API key into the Password parameter.
  5. Please use “ANY.RUN” as username.
  6. Click Test to validate the URLs, token, and connection.
Parameter Description Required
Password Example: WmNfqnpo…2Sjon7mtvm8e True

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.

anyrun-get-indicators


Receive ANY.RUN Indicators

Base Command

anyrun-get-indicators

Input

Argument Name Description Required
collection ANY.RUN indicator collection type. Supports: full, ip, url, domain. Possible values are: full, ip, url, domain. Optional
match_type Filter results based on the STIX object types. Optional
match_id IOC identifier. Optional
match_revoked Enable or disable receiving revoked feeds in report. Default is False. Optional
match_version Filter STIX objects by their object version. Default is last. Optional
added_after Receive IOCs after specified date. Format: YYYY-MM-DD. Optional
modified_after Receive IOCs after specified date. Format: YYYY-MM-DD. Required
limit Number of tasks on a page. Default, all IOCs are included. Default is 100. Optional

Context Output

There is no context output for this command.

Configuration parameters

  • credentials — Username. (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • modified_after — Modified after.
  • feed — Fetch indicators
  • feedReputation — Indicator Reputation
  • feedReliability — Source Reliability
  • feedExpirationPolicy
  • feedExpirationInterval
  • feedFetchInterval — Feed Fetch Interval
  • feedBypassExclusionList — Bypass exclusion list
  • feedTags — Tags
  • feedIncremental — Incremental Feed
  • tlp_color — Traffic Light Protocol Color

Commands (0)

This integration defines no commands.

from datetime import datetime

import demistomock as demisto
from CommonServerPython import *

from anyrun.connectors import FeedsConnector
from anyrun.iterators import FeedsIterator
from anyrun import RunTimeException

DATE_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
VERSION = "PA-XSOAR:2.4.0"


def test_module(params: dict) -> str:  # pragma: no cover
    """Performs ANY.RUN API call to verify integration is operational"""
    try:
        with FeedsConnector(
            params.get("credentials", {}).get("password"), integration=VERSION, verify_ssl=not params.get("insecure")
        ) as connector:
            connector.check_authorization()
            return "ok"
    except RunTimeException as exception:
        return str(exception)


def extract_indicator_data(indicator: dict) -> tuple[str, str]:
    """
    Extracts indicator type, value using raw indicator

    :param indicator: Raw ANY.RUN indicator
    :return: ANY.RUN indicator type, ANY.RUN indicator value
    """
    pattern = indicator.get("pattern", "")
    indicator_type = pattern.split(":")[0][1:]
    indicator_value = pattern.split(" = '")[1][:-2]

    return indicator_type, indicator_value


def get_timestamp(params: dict) -> str:  # pragma: no cover
    """
    Extracts actual fetch timestamp

    :param params: Demisto params
    :return: Fetch timestamp
    """
    if demisto.getLastRun():
        return demisto.getLastRun().get("next_fetch")
    return params.get("modified_after", "")


def update_timestamp(new_timestamp: datetime | None) -> None:  # pragma: no cover
    """
    Updates fetch timestamp if exists

    :param new_timestamp: New generated fetch timestamp
    """
    if new_timestamp:
        if demisto.getLastRun():
            actual_timestamp = datetime.strptime(demisto.getLastRun().get("next_fetch"), DATE_TIME_FORMAT)

            if new_timestamp > actual_timestamp:
                demisto.setLastRun({"next_fetch": new_timestamp.strftime(DATE_TIME_FORMAT)})
        else:
            demisto.setLastRun({"next_fetch": new_timestamp.strftime(DATE_TIME_FORMAT)})


def convert_indicators(indicators: list[dict]) -> list[dict]:
    """
    Converts ANY.RUN indicator to XSOAR indicator format

    :param indicators: ANY.RUN indicator
    :return: XSOAR indicator
    """
    converted_indicators: list[dict] = []

    for indicator in indicators:
        indicator_type, indicator_value = extract_indicator_data(indicator)

        fields: dict[str, Any] = {
            "firstseenbysource": indicator.get("created"),
            "first_seen": indicator.get("created"),
            "modified": indicator.get("modified"),
            "last_seen": indicator.get("modified"),
            "vendor": "ANY.RUN",
            "source": "ANY.RUN TI Feed",
            "tags": indicator.get("labels") or [],
            "publications": [
                {
                    "title": ref.get("source_name") or "",
                    "link": ref.get("url") or "",
                    "source": "ANY.RUN TI Feed",
                    "timestamp": indicator.get("created"),
                }
                for ref in indicator.get("external_references") or []
                if ref.get("url")
            ],
        }
        if indicator_type == "domain-name":
            fields["communitynotes"] = [
                {
                    "notes": ref["url"],
                    "timestamp": indicator.get("created"),
                }
                for ref in indicator.get("external_references") or []
                if ref.get("url")
            ]

        indicator_payload = {
            "value": indicator_value,
            "type": {"ipv4-addr": "IP", "url": "URL", "domain-name": "Domain"}.get(indicator_type),
            "fields": fields,
        }

        converted_indicators.append(indicator_payload)

    return converted_indicators


def fetch_indicators_command(params: dict) -> None:  # pragma: no cover
    """
    Initializes the update of indicators

    :param params: Demisto params
    """
    modified_after = get_timestamp(params)

    with FeedsConnector(
        params.get("credentials", {}).get("password"), integration=VERSION, verify_ssl=not params.get("insecure")
    ) as connector:
        connector._taxii_delta_timestamp = None
        for chunk in FeedsIterator.taxii_stix(
            connector, match_type="indicator", match_version="all", modified_after=modified_after, limit=10000, chunk_size=10000
        ):
            demisto.createIndicators(convert_indicators(chunk))

        update_timestamp(connector._taxii_delta_timestamp)


def main():  # pragma: no cover
    """Main Execution block"""
    params = demisto.params()

    if params.get("proxy"):
        handle_proxy()

    try:
        if demisto.command() == "fetch-indicators":
            fetch_indicators_command(params)
        elif demisto.command() == "test-module":
            result = test_module(params)
            return_results(result)
        else:
            raise NotImplementedError(f"Command {demisto.command()} is not implemented")
    except RunTimeException as exception:
        return_error(exception.description, error=str(exception.json))


if __name__ in ["__main__", "builtin", "builtins"]:
    main()