ProofpointFeed
Detailed feed of domains and IP addresses classified in different categories. You need a valid authorization code from Proofpoint ET to access this feed.
Data Enrichment & Threat Intelligence · Proofpoint Feed · Feed
Details
| ID | ProofpointFeed |
|---|---|
| Provider | Thoma Bravo |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
README
Detailed feed of domains and ips classified in different categories. You need a valid authorization code from Proofpoint ET to access this feed
Configure Proofpoint Feed in Cortex
| Parameter | Description | Required |
|---|---|---|
| Fetch indicators | False | |
| Authorization Code | True | |
| 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 |
| False | ||
| 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 |
| Indicator Type | The indicator type in the feed to fetch. Domain is referring to “https://rules.emergingthreats.net/auth_code/reputation/detailed-iprepdata.txt”, IP is referring to “https://rules.emergingthreats.net/auth_code/reputation/detailed-domainrepdata.txt”. | True |
| 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.
proofpoint-get-indicators
Gets indicators from the feed.
Base Command
proofpoint-get-indicators
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of results to return to the output. The default value is “50”. Default is 50. | Optional |
| indicator_type | The indicator type to fetch. Possible values are: all, domain, ip. Default is all. | Optional |
Context Output
There is no context output for this command.
Configuration parameters
feed— Fetch indicatorsauth_code— Authorization Codecredentials_auth_code—feedReputation— Indicator ReputationfeedReliability— Source Reliability (required)tlp_color— Traffic Light Protocol ColorfeedExpirationPolicy—feedExpirationInterval—feedFetchInterval— Feed Fetch IntervalfeedBypassExclusionList— Bypass exclusion listindicator_type— Indicator Type (required)feedTags— Tagsinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (1)
-
proofpoint-get-indicatorsGets indicators from the feed.
import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * """ IMPORTS """ import csv from collections.abc import Generator import urllib3 # disable insecure warnings urllib3.disable_warnings() SOURCE_NAME = "Proofpoint Feed" class Client(BaseClient): def __init__(self, base_url, auth_code, tags: list = None, tlp_color: str | None = None, **kwargs): if tags is None: tags = [] self._tags: list = tags self.tlp_color = tlp_color base_url = url_concat(base_url, auth_code, "reputation") super().__init__(base_url, **kwargs) DOMAIN_TYPE = "domain" IP_TYPE = "ip" IP_URL = "detailed-iprepdata.txt" DOMAIN_URL = "detailed-domainrepdata.txt" ALL_TYPE = "all" TYPES = (DOMAIN_TYPE, IP_TYPE, ALL_TYPE) indicator_types_to_endpoint = { IP_TYPE: [IP_URL], DOMAIN_TYPE: [DOMAIN_URL], ALL_TYPE: [DOMAIN_URL, IP_URL], } _CATEGORY_NAME = [ "CnC", "Bot", "Spam", "Drop", "SpywareCnC", "OnlineGaming", "DriveBySrc", "ChatServer", "TorNode", "Compromised", "P2P", "Proxy", "IPCheck", "Utility", "DDoSTarget", "Scanner", "Brute_Forcer", "FakeAV", "DynDNS", "Undesirable", "AbusedTLD", "SelfSignedSSL", "Blackhole", "RemoteAccessService", "P2PCnC", "Parking", "VPN", "EXE_Source", "Mobile_CnC", "Mobile_Spyware_CnC", "Skype_SuperNode", "Bitcoin_Related", "DDoSAttacker", ] def _build_iterator(self, indicator_type: str = ALL_TYPE) -> Generator[dict, None, None]: endpoints = self.indicator_types_to_endpoint[indicator_type] for endpoint in endpoints: resp = self._http_request("GET", endpoint, resp_type="text", timeout=(30, 60)) resp = resp.splitlines() csv_repr = csv.reader(resp) headers: list = next(csv_repr) headers = [header.replace(" ", "").replace("(|)", "") for header in headers] for line in csv_repr: item: dict = {headers[i]: line[i] for i in range(len(headers))} demisto.debug(f"Parsed item: {item}") category = item.get("category", "") # Check if category exists and is a numeric value try: if category and category.strip().isdigit(): category_index = int(category.strip()) - 1 # Check if the index is within the bounds of the category name array if 0 <= category_index < len(self._CATEGORY_NAME): item["category_name"] = self._CATEGORY_NAME[category_index] else: demisto.debug(f"Category index {category_index} out of bounds for _CATEGORY_NAME array") item["category_name"] = "Unknown" else: demisto.debug(f"Non-numeric category value: {category}") item["category_name"] = "Unknown" except (ValueError, TypeError) as e: demisto.debug(f"Error processing category '{category}': {str(e)}") item["category_name"] = "Unknown" # add type/value to item. if "domain" in item: item["type"] = FeedIndicatorType.Domain indicator_value = item.get("domain", "") # As part of the domain feed, also DomainGlob indicators will be returned, so we are checking if the # domain has '*' in their value if indicator_value and "*" in indicator_value: item["type"] = FeedIndicatorType.DomainGlob elif "ip" in item: item["type"] = FeedIndicatorType.IP indicator_value = item.get("ip", "") # domain key was present but value was None if not indicator_value: demisto.debug(f"Indicator value is None: {item} will be skipped") continue item["value"] = indicator_value yield item @staticmethod def _process_item(item: dict, tags: list, tlp_color: str | None = None) -> dict: indicator_obj = { "value": item["value"], "type": item["type"], "rawJSON": item, "fields": { "tags": tags, "port": item.get("ports", "").split() if isinstance(item.get("ports"), str) else item.get("ports"), "firstseenbysource": item.get("first_seen", ""), "lastseenbysource": item.get("last_seen", ""), "threattypes": { "threatcategory": item.get("category_name", ""), "threatcategoryconfidence": item.get("score", ""), }, }, } if tlp_color: indicator_obj["fields"]["trafficlightprotocol"] = tlp_color return indicator_obj def _build_iterator_domain(self) -> Generator[dict, None, None]: """Gets back a dict of domain attributes. Returns: Generator of dicts. """ return self._build_iterator(self.DOMAIN_TYPE) def _build_iterator_ip(self) -> Generator[dict, None, None]: """Gets back a dict of ip attributes. Returns: Generator of dicts. """ return self._build_iterator(self.IP_TYPE) def get_indicators_domain(self) -> list[dict]: """Gets indicator's dict of domains Returns: list of indicators """ return [self._process_item(item, self._tags, self.tlp_color) for item in self._build_iterator_domain()] def get_indicators_ip(self) -> list[dict]: """Gets indicator's dict of ips Returns: list of indicators """ return [self._process_item(item, self._tags, self.tlp_color) for item in self._build_iterator_ip()] def get_indicators(self) -> list[dict]: """Gets indicator's dict of domains and ips Returns: list of indicators """ return self.get_indicators_domain() + self.get_indicators_ip() def url_concat(*args: str) -> str: """Joining arguments into a url Examples: >>> url_concat("https://example.com", "apitoken/", "/path_to_thing/", "file.exe") 'https://example.com/apitoken/path_to_thing/file.exe' Args: *args: str representing url paths Returns: url """ if args: url = "/".join(element.strip("/") for element in args if element) return url + "/" if args[-1].endswith("/") else url return "" def module_test_command(client: Client, indicator_type: str) -> str: """Simple command that checks if the api is working Args: client: Client object indicator_type: one of ['ip', 'domain', 'all'] Returns: 'ok' if working, else raises an error """ fetch_indicators_command(client, indicator_type) return "ok" def fetch_indicators_command(client: Client, indicator_type: str | None): """Retrieving indicators from the API Args: client: Client object indicator_type: one of ['ip', 'domain', 'all'] Returns: """ if indicator_type == client.IP_TYPE: return client.get_indicators_ip() elif indicator_type == client.DOMAIN_TYPE: return client.get_indicators_domain() else: return client.get_indicators() def get_indicators_command(client: Client, args: dict) -> tuple[str, dict, list]: """Gets indicator to context Args: client: Client object args: demisto.args() Returns: readable_output, context, raw_response """ indicator_type = args.get("indicator_type") if indicator_type not in client.TYPES: return_error(f"{SOURCE_NAME}: Got indicator_type {indicator_type} but expected one of {client.TYPES}") limit = int(args.get("limit", 50)) if limit < 1: limit = 1 indicators_list = fetch_indicators_command(client, indicator_type)[:limit] hr = tableToMarkdown( f"Indicators from {SOURCE_NAME}", indicators_list[:limit], headers=["type", "value"], ) return hr, {}, indicators_list def main(): params = demisto.params() args = demisto.args() base_url = "https://rules.emergingthreats.net/" auth_code = params.get("credentials_auth_code", {}).get("password") or params.get("auth_code") if not auth_code: raise DemistoException("Authorization code must be provided.") client = Client( base_url, auth_code=auth_code, verify=not params.get("insecure", False), proxy=params.get("proxy"), tags=argToList(params.get("feedTags")), tlp_color=params.get("tlp_color"), ) command = demisto.command() demisto.info(f"Command being called is {command}") # Switch case try: if command == "fetch-indicators": indicators = fetch_indicators_command(client, params.get("indicator_type")) # we submit the indicators in batches for b in batch(indicators, batch_size=2000): demisto.createIndicators(b) elif command == "test-module": return_outputs(module_test_command(client, params.get("indicator_type"))) elif command == "proofpoint-get-indicators": readable_output, outputs, raw_response = get_indicators_command(client, args) return_outputs(readable_output, outputs, raw_response) except Exception as e: return_error( f"Error in {SOURCE_NAME} Integration - Encountered an issue with createIndicators" if "failed to create" in str(e) else f"Error in {SOURCE_NAME} Integration [{e}]" ) if __name__ == "builtins": main()