Intel471 Malware Indicator Feed
Intel471's Malware Intelligence is focused on the provisioning of a high fidelity and timely indicators feed with rich context, TTP information, and malware intelligence reports. This feed allows customers to block and gain an understanding of the latest crimeware campaigns and is for those that value timeliness, confidence (little to no false positives), and seek rich context and insight around the attacks they are seeing.
Data Enrichment & Threat Intelligence · Intel471 Feed · Feed
Details
| ID | Intel471 Malware Indicator Feed |
|---|---|
| Provider | Intel 471 |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/py3-tools:1.0.0.8544956 |
| Supported Modules | Agentix XSIAM |
README
Intel471’s Malware Intelligence is focused on the provisioning of a high fidelity and timely indicators feed with rich context, TTP information, and malware intelligence reports.
This feed allows customers to block and gain an understanding of the latest crimeware campaigns and is for those that value timeliness, confidence (little to no false positives), and seek rich context and insight around the attacks they are seeing.”
Configure Intel471 Indicator Feed in Cortex
| Parameter | Description | Required |
|---|---|---|
| Fetch indicators | False | |
| Username | 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 |
| Indicator Expiration Method | False | |
| Feed Expiration Interval | False | |
| Feed Fetch Interval | False | |
| Indicator Type | Type of the indicator in the feed. | True |
| Search by Threat Type | “Search indicators by threat type (e.g. malware, bulletproof_hosting, proxy_service). If empty, all threat types will be considered.” |
False |
| Malware Family | “Search indicators by malware family (e.g. gozi_isfb, smokeloader, trickbot). If empty, all malware families will be considered.” |
False |
| Search by confidence | Search indicators by confidence. See detailed description of the confidence levels below. | False |
| Free text indicator search (all fields included) | False | |
| First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) | How far back in time to go when performing the first fetch. | False |
| Tags | Supports CSV values. | 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 |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False | |
| Create relationships | Create relationships between indicators as part of Enrichment. | 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.
intel471-indicators-get-indicators
Gets the feed indicators.
Base Command
intel471-indicators-get-indicators
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of results to return. Default is 50. Will limit the result for each indicator type. | Optional |
Context Output
There is no context output for this command.
Command Example
!intel471-indicators-get-indicators limit=5
Human Readable Output
Indicators
value type rawJSON https://example.com URL uid: 3cbf2c65f7d7b86c3276094b795e289a
threat: {“type”: “malware”, “uid”: “2103dcd99080ee86a7808912f3ff4382”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.68”}}
expiration: 1622633644000
confidence: high
context: {“description”: “qbot controller URL”}
mitre_tactics: command_and_control
indicator_type: url
indicator_data: {“url”: “https://example.com”}
intel_requirements: 1.3.4,
1.1.4https://example.com URL uid: 46c4335a6e4f07cbc073754ce830b23b
threat: {“type”: “malware”, “uid”: “355b864087900df6130bc1605ace1035”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.12”}}
expiration: 1622634181000
confidence: high
context: {“description”: “qbot controller URL”}
mitre_tactics: command_and_control
indicator_type: url
indicator_data: {“url”: “https://example.com”}
intel_requirements: 1.3.4,
1.1.4https://example.com URL uid: 3ac312ba14bb661ac165ff9b06a4de51
threat: {“type”: “malware”, “uid”: “22e7a5f41d4f3cc5c704758ffa505556”, “data”: {“malware_family_profile_uid”: “20eb1f82621001883ea0c2085aff5729”, “family”: “lokibot”, “version”: “1.8”}}
expiration: 1622636921000
confidence: high
context: {“description”: “lokibot controller URL”}
mitre_tactics: command_and_control
indicator_type: url
indicator_data: {“url”: “https://example.com”}
intel_requirements: 1.1.5,
1.1.6https://example.com URL uid: 3c2b4db3d8016f7ad1e97821d6f58cff
threat: {“type”: “malware”, “uid”: “2103dcd99080ee86a7808912f3ff4382”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.68”}}
expiration: 1622637063000
confidence: high
context: {“description”: “qbot controller URL”}
mitre_tactics: command_and_control
indicator_type: url
indicator_data: {“url”: “https://example.com”}
intel_requirements: 1.3.4,
1.1.4http://example.com URL uid: f2509c1f7c725e2ffa6ae8e93f3dd4da
threat: {“type”: “malware”, “uid”: “2beba14b4653bf651e1dee439b1caf48”, “data”: {“malware_family_profile_uid”: “dbdf04e70d844c5d9373f9069998bbcb”, “family”: “formbook”, “version”: “4.1”}}
expiration: 1622637530000
confidence: high
context: {“description”: “formbook controller URL”}
mitre_tactics: command_and_control
indicator_type: url
indicator_data: {“url”: “http://example.com”}
intel_requirements: 1.1.5,
1.1.6d55d6ffe62778604b95c4af57bbd25010a26869668516e1139865d907b4177a7 File uid: ed7e66db788ccdef60c0a30f37da66e2
threat: {“type”: “malware”, “uid”: “456c1d6b360423fffff2bff49d0662eb”, “data”: {“malware_family_profile_uid”: “456c1d6b360423fffff2bff49d0662eb”, “family”: “cobaltstrike”}}
expiration: 1651577888000
confidence: medium
context: {“description”: “core component downloaded by cobaltstrike malware family”}
mitre_tactics: stage_capabilities
indicator_type: file
indicator_data: {“file”: {“md5”: “c274ce1427910a47d7acbfcb36f8e5c9”, “sha1”: “2479bdbd4f4a5b04e995eccc477ed44d7bbabf43”, “sha256”: “d55d6ffe62778604b95c4af57bbd25010a26869668516e1139865d907b4177a7”, “type”: “DATA”, “size”: 180854, “download_url”: “https://api.intel471.com/v1/download/malwareIntel/d55d6ffe62778604b95c4af57bbd25010a26869668516e1139865d907b4177a7.zip”}}
intel_requirements: 1.1ba1a42a7875ba307126d3f470617107973b8557756d08b386c1d9e2fbdfe3f0f File uid: 2a930e90451169755fe2b65620a28364
threat: {“type”: “malware”, “uid”: “183ee6a5aec804f5df69eea69edddce0”, “data”: {“malware_family_profile_uid”: “886b44916f8e62d9a9da5f7a8b143fb8”, “family”: “smokeloader”, “version”: “2020”}}
expiration: 1651578048000
confidence: medium
context: {“description”: “executable downloaded by smokeloader malware family”}
mitre_tactics: command_and_control
indicator_type: file
indicator_data: {“file”: {“md5”: “0d0fec0f2a6af96ad0a7d0d3c96cb98d”, “sha1”: “223f50da553a39823c8b731fbc68f72471cb5152”, “sha256”: “ba1a42a7875ba307126d3f470617107973b8557756d08b386c1d9e2fbdfe3f0f”, “type”: “PEEXE_x64”, “size”: 5613568, “download_url”: “https://api.intel471.com/v1/download/malwareIntel/ba1a42a7875ba307126d3f470617107973b8557756d08b386c1d9e2fbdfe3f0f.zip”}}
intel_requirements: 1.1.5,
1.1.61d96205e9fd00d5dd4a57e101eee21f47d850c505d592998c5ea12ff867e1865 File uid: df7c2e16d384f1fbfe09e3fafab93fa6
threat: {“type”: “malware”, “uid”: “183ee6a5aec804f5df69eea69edddce0”, “data”: {“malware_family_profile_uid”: “886b44916f8e62d9a9da5f7a8b143fb8”, “family”: “smokeloader”, “version”: “2020”}}
expiration: 1651578052000
confidence: medium
context: {“description”: “executable downloaded by smokeloader malware family”}
mitre_tactics: command_and_control
indicator_type: file
indicator_data: {“file”: {“md5”: “9bcb6653def44687d0d8f971ca5d0cf5”, “sha1”: “b900e03a9770a4345f1276c198843a5b2bc02223”, “sha256”: “1d96205e9fd00d5dd4a57e101eee21f47d850c505d592998c5ea12ff867e1865”, “type”: “PEEXE_x86”, “size”: 771072, “download_url”: “https://api.intel471.com/v1/download/malwareIntel/1d96205e9fd00d5dd4a57e101eee21f47d850c505d592998c5ea12ff867e1865.zip”}}
intel_requirements: 1.1.5,
1.1.626e9bac9d285ba198b272999ae48e7049eb7847c2d37c142b79931779130df8b File uid: 35faa35978b8ee7f3a32c0f83291163d
threat: {“type”: “malware”, “uid”: “4bff756d3eacb5066dbdeebdaf3f9aeb”, “data”: {“malware_family_profile_uid”: “b38ef686caf0103866339452d3d1c4fb”, “family”: “dridex”, “version”: “2.165”}}
expiration: 1651578060000
confidence: medium
context: {“description”: “web_inject plugin downloaded by dridex malware family”}
mitre_tactics: stage_capabilities
indicator_type: file
indicator_data: {“file”: {“md5”: “8a72d4c069d724bcf70ccde3148df130”, “sha1”: “398484e2c3bd11f2e8bff37614db4cc5943b966d”, “sha256”: “26e9bac9d285ba198b272999ae48e7049eb7847c2d37c142b79931779130df8b”, “type”: “PEDLL_x64”, “size”: 614400, “download_url”: “https://api.intel471.com/v1/download/malwareIntel/26e9bac9d285ba198b272999ae48e7049eb7847c2d37c142b79931779130df8b.zip”}}
intel_requirements: 1.3.4,
1.1.4055c7a3ecbc64032aa4e08d3e9954183a216ae085e1a25cd85108414534aa92d File uid: fec667f3d059f9635a231e4b57bd18f8
threat: {“type”: “malware”, “uid”: “355b864087900df6130bc1605ace1035”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.12”}}
expiration: 1651578135000
confidence: high
context: {“description”: “sample of qbot malware family”}
mitre_tactics: command_and_control
indicator_type: file
indicator_data: {“file”: {“md5”: “5a8d0dd7df9a2f5996dbbb3d62303a4c”, “sha1”: “62b32aa8e61ff1e66d55fee4649b9aef52d50e60”, “sha256”: “055c7a3ecbc64032aa4e08d3e9954183a216ae085e1a25cd85108414534aa92d”, “type”: “PEDLL_x86”, “size”: 1004032, “download_url”: “https://api.intel471.com/v1/download/malwareIntel/055c7a3ecbc64032aa4e08d3e9954183a216ae085e1a25cd85108414534aa92d.zip”}}
intel_requirements: 1.3.4,
1.1.4x.x.x.x IP uid: e71f7b0300d6bc37fd4cb27fd03c98ed
threat: {“type”: “malware”, “uid”: “2103dcd99080ee86a7808912f3ff4382”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.68”}}
expiration: 1622633644000
confidence: medium
context: {“description”: “qbot controller IPv4”}
mitre_tactics: command_and_control
indicator_type: ipv4
indicator_data: {“address”: “x.x.x.x”}
intel_requirements: 1.3.4,
1.1.4x.x.x.x IP uid: 09ae761c2a9cbaaa6210129a3c89474a
threat: {“type”: “malware”, “uid”: “355b864087900df6130bc1605ace1035”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.12”}}
expiration: 1622634181000
confidence: medium
context: {“description”: “qbot controller IPv4”}
mitre_tactics: command_and_control
indicator_type: ipv4
indicator_data: {“address”: “x.x.x.x”}
intel_requirements: 1.3.4,
1.1.4x.x.x.x IP uid: fdc225adafa78bae33ca9651bbfcc36e
threat: {“type”: “malware”, “uid”: “22e7a5f41d4f3cc5c704758ffa505556”, “data”: {“malware_family_profile_uid”: “20eb1f82621001883ea0c2085aff5729”, “family”: “lokibot”, “version”: “1.8”}}
expiration: 1622636921000
confidence: medium
context: {“description”: “lokibot controller IPv4”}
mitre_tactics: command_and_control
indicator_type: ipv4
indicator_data: {“address”: “x.x.x.x”}
intel_requirements: 1.1.5,
1.1.6x.x.x.x IP uid: a9a3a50497dc52eee69be35cffd22b5c
threat: {“type”: “malware”, “uid”: “2103dcd99080ee86a7808912f3ff4382”, “data”: {“malware_family_profile_uid”: “d9b8af17f349af0718badc314ce6b4bd”, “family”: “qbot”, “version”: “0402.68”}}
expiration: 1622637063000
confidence: medium
context: {“description”: “qbot controller IPv4”}
mitre_tactics: command_and_control
indicator_type: ipv4
indicator_data: {“address”: “x.x.x.x”}
intel_requirements: 1.3.4,
1.1.4x.x.x.x IP uid: c4e482756324c8020ea96beda15db0cc
threat: {“type”: “malware”, “uid”: “12699e2e6873f0e319e2db36e28f6262”, “data”: {“malware_family_profile_uid”: “886b44916f8e62d9a9da5f7a8b143fb8”, “family”: “smokeloader”, “version”: “2019”}}
expiration: 1622639358000
confidence: medium
context: {“description”: “smokeloader controller IPv4”}
mitre_tactics: command_and_control
indicator_type: ipv4
indicator_data: {“address”: “x.x.x.x”}
intel_requirements: 1.1.5,
1.1.6
Configuration parameters
intel471_backend— Intel 471 backend (required)feed— Fetch indicatorscredentials— UsernamefeedReputation— Indicator ReputationfeedReliability— Source Reliability (required)tlp_color— Traffic Light Protocol ColorfeedExpirationPolicy—feedExpirationInterval—feedFetchInterval— Feed Fetch Intervalindicator_type— Indicator Type (required)malware_family— Malware Familyconfidence— Search by confidenceindicator— Free text indicator search (all fields included)fetch_time— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)feedTags— TagsfeedBypassExclusionList— Bypass exclusion listproxy— Use system proxy settingsinsecure— Trust any certificate (not secure)create_relationships— Create relationships
Commands (1)
-
intel471-indicators-get-indicatorsGets the feed indicators.
from typing import Any import urllib3 from CommonServerPython import * # disable insecure warnings urllib3.disable_warnings() INTEGRATION_NAME = "Intel 471 Malware Feed" FEED_URL_INDICATORS_TITAN = "https://api.intel471.com/v1/indicators/stream" FEED_URL_INDICATORS_VERITY471 = "https://api.intel471.cloud/integrations/indicators/v1/indicators/stream" FEED_URL_GIRS_TITAN = "https://api.intel471.com/v1/girs" FEED_URL_MALWARE_FILE_VERITY471 = "https://api.intel471.cloud/integrations/malware-intel/v1/malware/files" DEMISTO_VERSION = demisto.demistoVersion() CONTENT_PACK = f"Intel471 Feed/{get_pack_version()!s}" INTEGRATION = "Intel471 Malware Indicator Feed" USER_AGENT = f'XSOAR/{DEMISTO_VERSION["version"]}.{DEMISTO_VERSION["buildNumber"]} - {CONTENT_PACK} - {INTEGRATION}' MAX_COUNT = 100 MAX_BATCH = 10000 INDICATOR_TYPES = { "domain": FeedIndicatorType.Domain, "email": FeedIndicatorType.Email, "file": FeedIndicatorType.File, "ipv4": FeedIndicatorType.IP, "url": FeedIndicatorType.URL, } THREAT_TYPE = "malware" class Client: """ Client to use in the Intel 471 Feed integration. Overrides BaseClient. """ headers = {"user-agent": USER_AGENT} def __init__( self, auth: tuple[str, str], insecure: bool = False, tags: list | None = None, tlp_color: str | None = None, intel471_backend: str | None = None, indicator: str | None = "*", indicator_type: str | None = None, threat_type: str | None = None, malware_family: str | None = None, confidence: str | None = None, fetch_time: str | None = None, ): """ Implements class for Intel 471 feed. :param auth: credentials for accessing the feed. :param insecure: boolean, if *false* feed HTTPS server certificate is verified. Default: *false*. :param tags: list of tags. :param tlp_color: Traffic Light Protocol color. :param intel471_backend: str, intel 471 backend selector. :param indicator: str, free text indicator filter. :param indicator_type: str, indicator type filter. :param threat_type: str, threat type filter. :param malware_family: str, malware family filter. :param confidence: str, confidence filter. :param fetch_time: str, fetch time filter. """ self.auth = auth self._verify: bool = insecure self.tags = [] if tags is None else tags self.tlp_color = tlp_color self.intel471_backend = intel471_backend self.indicator = indicator self.indicator_type = indicator_type self.threat_type = threat_type self.malware_family = malware_family self.confidence = confidence self.fetch_time = fetch_time self._proxies = handle_proxy(proxy_param_name="proxy", checkbox_default_value=False) def get_girs(self) -> list: """Retrieves a list of General Intelligence Requirements (GIRs). Returns: GIRs. """ result: list = [] feed_url = FEED_URL_GIRS_TITAN params = {} params["count"] = MAX_COUNT params["offset"] = 0 should_continue: bool = True while should_continue: try: response = requests.get( url=feed_url, params=params, verify=self._verify, proxies=self._proxies, headers=self.headers, auth=self.auth, ) response.raise_for_status() data = response.json() girs: list = data.get("girs", []) if girs: result.extend(girs) else: should_continue = False if len(girs) < MAX_COUNT: should_continue = False params["offset"] = params["offset"] + MAX_COUNT except requests.exceptions.SSLError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your not secure parameter.\n\n{err}" ) except requests.ConnectionError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your Server URL parameter.\n\n{err}" ) except requests.exceptions.HTTPError as err: demisto.debug(f"Got an error from {feed_url} while fetching GIRs {err!s} ") except ValueError as err: demisto.debug(str(err)) raise ValueError(f"Could not parse returned data to JSON. \n\nError massage: {err}") return result def build_iterator_titan(self, save_state: bool, limit: int = -1) -> list: """Retrieves all entries from the Titan feed. Args: save_state: save state (cursor). limit: limit the results. Returns: A list of objects, containing the indicators. """ result = [] feed_url = FEED_URL_INDICATORS_TITAN integration_context = get_integration_context() params = {} if self.indicator: params["indicator"] = self.indicator if self.indicator_type and "All" not in self.indicator_type: params["indicatorType"] = " || ".join(self.indicator_type).lower() if self.threat_type: params["threatType"] = self.threat_type if self.malware_family: params["malwareFamily"] = self.malware_family if self.confidence: params["confidence"] = self.confidence params["count"] = str(MAX_COUNT) last_updated_from = integration_context.get("last_updated_from", "") if not last_updated_from: start_date, end_date = parse_date_range(self.fetch_time, utc=True, to_timestamp=True) last_updated_from = str(start_date) params["lastUpdatedFrom"] = last_updated_from cursor = integration_context.get("cursor", "") if cursor: params["cursor"] = cursor should_continue: bool = True while should_continue: encoded_params = urllib.parse.urlencode(params, quote_via=urllib.parse.quote) try: response = requests.get( url=feed_url, params=encoded_params, verify=self._verify, proxies=self._proxies, headers=self.headers, auth=self.auth, ) response.raise_for_status() data = response.json() indicators: list = data.get("indicators", []) if indicators: result.extend(indicators) else: should_continue = False if len(indicators) < MAX_COUNT: should_continue = False if limit > 0: if len(result) >= limit: should_continue = False result = result[:limit] else: if len(result) >= MAX_BATCH: should_continue = False cursor_next = data.get("cursorNext", "") if cursor_next: params["cursor"] = cursor_next except requests.exceptions.SSLError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your not secure parameter.\n\n{err}" ) except requests.ConnectionError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your Server URL parameter.\n\n{err}" ) except requests.exceptions.HTTPError as err: demisto.debug(f"Got an error from {feed_url} while fetching indicators {err!s} ") raise Exception(f"HTTP error in the API call to {INTEGRATION_NAME}.\nCheck your configuration.\n\n{err}") except ValueError as err: demisto.debug(str(err)) raise ValueError(f"Could not parse returned data to JSON. \n\nError massage: {err}") if save_state: set_integration_context({"last_updated_from": last_updated_from}) set_integration_context({"cursor": cursor}) return result def build_iterator_verity471(self, save_state: bool, limit: int = -1) -> list: """Retrieves all entries from the Verity471 feed. Args: save_state: save state (cursor). limit: limit the results. Returns: A list of objects, containing the indicators. """ result = [] feed_url = FEED_URL_INDICATORS_VERITY471 integration_context = get_integration_context() params = {} if self.indicator: params["text_filter"] = self.indicator if self.indicator_type and "All" not in self.indicator_type: params["type"] = self.indicator_type if self.threat_type: params["threat_type"] = self.threat_type if self.malware_family: params["malware_family_name"] = self.malware_family if self.confidence: params["confidence"] = self.confidence params["size"] = str(MAX_COUNT) cursor = integration_context.get("cursor") if cursor: params["cursor"] = cursor from_ts = integration_context.get("from_ts", "") if not from_ts: start_date, end_date = parse_date_range(self.fetch_time, utc=True, to_timestamp=True) from_ts = str(start_date) params["from"] = from_ts should_continue: bool = True while should_continue: encoded_params = urllib.parse.urlencode(params, quote_via=urllib.parse.quote) try: response = requests.get( url=feed_url, params=encoded_params, verify=self._verify, proxies=self._proxies, headers=self.headers, auth=self.auth, ) response.raise_for_status() data = response.json() indicators: list = data.get("indicators", []) if indicators: result.extend(indicators) else: should_continue = False if len(indicators) < MAX_COUNT: should_continue = False if limit > 0: if len(result) >= limit: should_continue = False result = result[:limit] else: if len(result) >= MAX_BATCH: should_continue = False cursor = data.get("cursor_next") if cursor: params["cursor"] = cursor except requests.exceptions.SSLError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your not secure parameter.\n\n{err}" ) except requests.ConnectionError as err: demisto.debug(str(err)) raise Exception( f"Connection error in the API call to {INTEGRATION_NAME}.\nCheck your Server URL parameter.\n\n{err}" ) except requests.exceptions.HTTPError as err: demisto.debug(f"Got an error from {feed_url} while fetching indicators {err!s} ") raise Exception(f"HTTP error in the API call to {INTEGRATION_NAME}.\nCheck your configuration.\n\n{err}") except ValueError as err: demisto.debug(str(err)) raise ValueError(f"Could not parse returned data to JSON. \n\nError massage: {err}") if save_state: set_integration_context({"from_ts": from_ts}) set_integration_context({"cursor": cursor}) return result def test_module(client: Client, *_) -> str: """Builds the iterator to check that the feed is accessible. Args: client: Client object. Returns: Outputs. """ if client.intel471_backend == "Verity471": client.build_iterator_verity471(False, MAX_COUNT) else: client.build_iterator_titan(False, MAX_COUNT) return "ok" def build_relationships(type_: str, value_: str, malware_family: str) -> list: """Creates a list of relationships for the indicator. Args: type_ (str): relationship type. value_ (str): indicator value. malware_family (str): malware family. Returns: List: A list of relationships. """ relationships: list = [] relationships.append( EntityRelationship( name=EntityRelationship.Relationships.INDICATOR_OF, entity_a=value_, entity_a_type=type_, entity_b=malware_family, entity_b_type="Malware", ).to_indicator() ) return relationships def build_indicator_titan(client: Client, raw_data: dict[str, Any], titan_girs: list) -> dict[str, Any]: """Creates a Titan sourced indicator object. Args: raw_data: raw data of the indicator. titan_girs: a list of GIRs. Returns: Dictionary representing the indicator object. """ malware_family: str = raw_data.get("data", {}).get("threat", {}).get("data", {}).get("family", "") type_: str = INDICATOR_TYPES.get(raw_data.get("data", {}).get("indicator_type", ""), "") indicator_data = raw_data.get("data", {}).get("indicator_data", {}) intel_requirements: list = [] intel_requirement_paths: list = raw_data.get("data", {}).get("intel_requirements", []) for irp in intel_requirement_paths: gir: dict = next(filter(lambda g: g.get("data", {}).get("gir", {}).get("path", {}) == irp, titan_girs), {}) if gir: name = gir.get("data", {}).get("gir", {}).get("name", "") intel_requirements.append(f"GIR: {irp} - {name}") value_: str = "" fields: dict = {} if type_ == FeedIndicatorType.File: value_ = indicator_data.get("file", {}).get("sha256", "") fields["md5"] = indicator_data.get("file", {}).get("md5", "") fields["sha1"] = indicator_data.get("file", {}).get("sha1", "") fields["sha256"] = indicator_data.get("file", {}).get("sha256", "") fields["ssdeep"] = indicator_data.get("file", {}).get("ssdeep", "") fields["filetype"] = indicator_data.get("file", {}).get("type", "") fields["downloadurl"] = indicator_data.get("file", {}).get("download_url", "") fields["size"] = indicator_data.get("file", {}).get("size", 0) elif type_ == FeedIndicatorType.IP: value_ = indicator_data.get("address", "") elif type_ == FeedIndicatorType.URL: value_ = indicator_data.get("url", "") fields["firstseenbysource"] = datetime.fromtimestamp(raw_data.get("activity", {}).get("first") / 1000).isoformat("T") fields["lastseenbysource"] = datetime.fromtimestamp(raw_data.get("activity", {}).get("last") / 1000).isoformat("T") fields["trafficlightprotocol"] = client.tlp_color fields["tags"] = [raw_data.get("data", {}).get("context", {}).get("description", "")] fields["tags"].append(raw_data.get("data", {}).get("mitre_tactics", "")) fields["tags"].extend(intel_requirements) fields["tags"].extend(client.tags) indicator_obj = { "value": value_, "type": type_, "rawJSON": raw_data, "fields": fields, "relationships": build_relationships(type_, value_, malware_family), } return indicator_obj def build_indicator_verity471(client: Client, raw_data: dict[str, Any]) -> dict[str, Any]: """Creates a Verity471 sourced indicator object. Args: raw_data: raw data of the indicator. titan_girs: a list of GIRs. Returns: Dictionary representing the indicator object. """ malware_family: str = raw_data.get("threat", {}).get("data", {}).get("malware_family", {}).get("name", "") type_: str = INDICATOR_TYPES.get(raw_data.get("type", ""), "") indicator_data = raw_data.get("data", {}) intel_requirements: list = [] girs: list = raw_data.get("classification", {}).get("girs", []) for gir in girs: intel_requirements.append(f"GIR: {gir.get('path', '')} - {gir.get('name', '')}") value_: str = "" fields: dict = {} if type_ == FeedIndicatorType.File: value_ = indicator_data.get("file", {}).get("sha256", "") fields["md5"] = indicator_data.get("file", {}).get("md5", "") fields["sha1"] = indicator_data.get("file", {}).get("sha1", "") fields["sha256"] = indicator_data.get("file", {}).get("sha256", "") fields["ssdeep"] = indicator_data.get("file", {}).get("ssdeep", "") fields["filetype"] = indicator_data.get("file", {}).get("type", "") fields["downloadurl"] = ( f"{FEED_URL_MALWARE_FILE_VERITY471}/{indicator_data.get('file', {}).get('sha256', '')}.zip/download" ) fields["size"] = indicator_data.get("file", {}).get("size", 0) elif type_ == FeedIndicatorType.IP: value_ = indicator_data.get("ipv4", {}).get("ip_address", "") elif type_ == FeedIndicatorType.URL: value_ = indicator_data.get("url", "") elif type_ == FeedIndicatorType.Domain: value_ = indicator_data.get("domain", "") elif type_ == FeedIndicatorType.Email: value_ = indicator_data.get("email", "") elif type_ == "yara": value_ = "" fields["firstseenbysource"] = raw_data.get("activity", {}).get("first_seen_ts", "") fields["lastseenbysource"] = raw_data.get("activity", {}).get("last_seen_ts", "") fields["trafficlightprotocol"] = client.tlp_color fields["tags"] = [raw_data.get("description", "")] kill_chain_phases = raw_data.get("kill_chain_phases", []) for kill_chain_phase in kill_chain_phases: fields["tags"].append(kill_chain_phase.get("phase_name", "")) fields["tags"].extend(intel_requirements) fields["tags"].extend(client.tags) indicator_obj = { "value": value_, "type": type_, "rawJSON": raw_data, "fields": fields, "relationships": build_relationships(type_, value_, malware_family), } return indicator_obj def fetch_indicators(client: Client, save_state: bool, limit: int = -1) -> list[dict]: """Retrieves indicators from the feed. Args: client: Client object with request. save_state: save state (cursor). limit: limit the results. Returns: Indicators. """ titan_girs = [] indicators: list = [] if client.intel471_backend == "Verity471": iterator = client.build_iterator_verity471(save_state, limit) else: titan_girs = client.get_girs() iterator = client.build_iterator_titan(save_state, limit) for item in iterator: if client.intel471_backend == "Verity471": indicator_obj = build_indicator_verity471(client, item) else: indicator_obj = build_indicator_titan(client, item, titan_girs) if indicator_obj["value"]: indicators.append(indicator_obj) return indicators def get_indicators_command(client: Client, args: dict[str, str]) -> CommandResults: """Wrapper for retrieving indicators from the feed to the war-room. Args: client: Client object with request. args: demisto.args(). Returns: CommandResults object containing the indicators retrieved. """ limit = arg_to_number(demisto.args().get("limit")) or 100 indicators = fetch_indicators(client, False, limit) hr_indicators = [] for indicator in indicators: hr_indicators.append( { "Value": indicator.get("value"), "Type": indicator.get("type"), "rawJSON": indicator.get("rawJSON"), "fields": indicator.get("fields"), } ) human_readable = tableToMarkdown( "Indicators from Intel 471:", hr_indicators, headers=["Value", "Type", "rawJSON", "fields"], removeNull=True ) return CommandResults( readable_output=human_readable, outputs_prefix="Intel471Feed.Indicators", outputs_key_field="value", raw_response=indicators, ) def fetch_indicators_command(client: Client, args: dict[str, str]) -> list[dict]: """Wrapper for fetching indicators from the feed to the Indicators tab. Args: client: Client object with request. Returns: Indicators. """ indicators = fetch_indicators(client, True) return indicators def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ args = demisto.args() params = demisto.params() use_ssl = not params.get("insecure", False) tags = argToList(params.get("feedTags")) tlp_color = params.get("tlp_color") intel471_backend = params.get("intel471_backend") indicator = params.get("indicator") indicator_type = params.get("indicator_type") threat_type = THREAT_TYPE malware_family = params.get("malware_family") confidence = params.get("confidence") fetch_time = params.get("fetch_time") credentials = params.get("credentials", {}) if not credentials: raise DemistoException("Integration credentials not entered.") else: auth = (credentials.get("identifier", ""), credentials.get("password", "")) command = demisto.command() demisto.info(f"Command being called is {command}") try: client = Client( auth, use_ssl, tags, tlp_color, intel471_backend, indicator, indicator_type, threat_type, malware_family, confidence, fetch_time, ) if command == "test-module": return_results(test_module(client, params)) elif command == "intel471-indicators-get-indicators": return_results(get_indicators_command(client, args)) elif command == "fetch-indicators": indicators = fetch_indicators_command(client, args) for iter_ in batch(indicators, batch_size=2000): demisto.createIndicators(iter_) else: raise NotImplementedError(f"Command {command} is not implemented.") except Exception as err: err_msg = f"Error in {INTEGRATION_NAME} Integration. [{err}]" return_error(err_msg) if __name__ in ["__main__", "builtin", "builtins"]: main()