Tor Exit Addresses Feed

Tor is free software and an open network that helps you defend against traffic analysis, a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security.

Data Enrichment & Threat Intelligence · Tor Exit Addresses Feed · Feed

Details

IDTor Exit Addresses Feed
ProviderOpen Source
CategoryData Enrichment & Threat Intelligence
From Version5.5.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Tor is free software and an open network that helps you defend against traffic analysis, a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security.

Configure Tor Exit Addresses Feed in Cortex

Parameter Description Required
Fetch indicators   False
Indicator Reputation Indicators from this integration instance will be marked with this reputation False
Source Reliability Reliability of the source providing the intelligence data True
Traffic Light Protocol Color The Traffic Light Protocol (TLP) designation to apply to indicators fetched from the feed False
Feed Fetch Interval   False
Bypass exclusion list When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. False
Tags Supports CSV values. False
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.

tor-get-indicators


Gets the feed indicators.

Base Command

tor-get-indicators

Input

Argument Name Description Required
limit The maximum number of results to return. The default value is 50. Default is 50. Optional

Context Output

There is no context output for this command.

Configuration parameters

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

Commands (1)

  • tor-get-indicators

    Gets the feed indicators.

import demistomock as demisto
import requests
import urllib3
from CommonServerPython import *

from CommonServerUserPython import *

# Disable insecure warnings
urllib3.disable_warnings()

SOURCE_NAME = "Tor Exit Addresses"
DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"


class Client(BaseClient):
    def __init__(self, insecure: bool = False, proxy: bool = False, tlp_color: str | None = None):
        super().__init__(base_url="https://check.torproject.org/exit-addresses", verify=not insecure, proxy=proxy)
        self.url = "https://check.torproject.org/exit-addresses"
        self.tlp_color = tlp_color

    def http_request_indicators(self):
        res = requests.get(url=self.url, verify=self._verify)

        try:
            res.raise_for_status()

        except Exception:
            LOG(f"Tor Exit Addresses - exception in request: {res.status_code!r} {res.content!r}")
            raise

        return res.text

    def datestring_to_server_format(self, date_string):
        """
        formats a datestring to the ISO-8601 format which the server expects to recieve
        :param date_string: Date represented as a tring
        :return: ISO-8601 date string
        """
        parsed_date = dateparser.parse(date_string, settings={"TIMEZONE": "UTC"})
        assert parsed_date is not None, f"could not parse {date_string}"
        return parsed_date.strftime(DATE_FORMAT)

    def build_iterator(self, feedTags, limit):
        raw_res = self.http_request_indicators()
        raw_indicator_list = raw_res.split("\n")
        indicator_list = []  # type: List
        indicator = {}  # type: Dict
        current_indicator_index = 0
        for line in raw_indicator_list:
            if line.startswith("ExitNode"):
                indicator = {"type": FeedIndicatorType.IP, "name": line.split()[1]}

            elif line.startswith("Published"):
                date = line.split(" ", 1)[1]
                indicator["firstseenbysource"] = self.datestring_to_server_format(date)

            elif line.startswith("LastStatus"):
                date = line.split(" ", 1)[1]
                indicator["lastseenbysource"] = self.datestring_to_server_format(date)

            elif line.startswith("ExitAddress"):
                indicator["value"] = line.split()[1]
                raw_json = indicator.copy()
                indicator["rawJSON"] = raw_json
                indicator["fields"] = {
                    "firstseenbysource": indicator.get("firstseenbysource"),
                    "lastseenbysource": indicator.get("lastseenbysource"),
                    "tags": feedTags,
                }

                if self.tlp_color:
                    indicator["fields"]["trafficlightprotocol"] = self.tlp_color

                indicator_list.append(indicator)

                current_indicator_index = current_indicator_index + 1
                if limit is not None and current_indicator_index >= limit:
                    break

        return indicator_list


def fetch_indicators_command(client, feedTags=None, limit=None):
    indicator_list = client.build_iterator(feedTags, limit)
    return indicator_list


def get_indicators_command(client: Client, args: dict):
    limit = args.get("limit")
    if limit:
        limit = int(limit)
    indicator_list = fetch_indicators_command(client, None, limit)
    human_readable = tableToMarkdown(
        "Indicators from Tor Exit Addresses:",
        indicator_list,
        headers=["value", "type", "firstseenbysource", "lastseenbysource", "name"],
        removeNull=True,
    )
    return human_readable, {}, indicator_list


def module_test_command(client: Client, args: dict):
    client.http_request_indicators()
    return "ok", {}, {}


def main():
    params = demisto.params()
    feedTags = argToList(params.get("feedTags"))
    tlp_color = params.get("tlp_color")
    client = Client(params.get("insecure"), params.get("proxy"), tlp_color)

    command = demisto.command()
    demisto.info(f"Command being called is {command}")
    # Switch case
    commands = {"test-module": module_test_command, "tor-get-indicators": get_indicators_command}
    try:
        if demisto.command() == "fetch-indicators":
            indicators = fetch_indicators_command(client, feedTags)
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](client, demisto.args())
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        raise Exception(f"Error in {SOURCE_NAME} Integration [{e}]")


if __name__ == "__builtin__" or __name__ == "builtins":
    main()