Mandiant
Enrich Indicators of Compromise, and fetch information about Actors, Malware Families, and Campaigns from Mandiant Advantage.
Data Enrichment & Threat Intelligence · Mandiant Advantage Threat Intelligence
Details
| ID | Mandiant |
|---|---|
| Provider | |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.6.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Mandiant Threat Intelligence Enrichment
Enrich Indicators of Compromise using Cortex XSOAR Generic Reputation commands, and create indicators for Threat Actors, Malware Families, and Campaigns from Mandiant Advantage.
Prerequisites
A Mandiant Advantage Threat Intelligence account.
Get Credentials
- Log in to
advantage.mandiant.com. - Navigate to
Settings, then scroll down toAPIv4 Access and Key. - Click
Get Key ID and Secret.
Integration Settings
| Parameter | Description | Required |
|---|---|---|
| API Key | Your API Key from Mandiant Advantage Threat Intelligence. | True |
| Secret Key | Your Secret Key from Mandiant Advantage Threat Intelligence. | True |
| Timeout | API calls timeout. | 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 enriched. | False |
| Tags | Supports CSV values. | False |
| Map Attack Pattern Relationships to Mitre ATT&CK | When enabled the integration will attempt to map Attack Pattern relationships to Attack Pattern Indicators created by the Mitre ATT&CK Integration. | False |
Commands
file
Get information about a file hash from Mandiant.
Base Command
file
Input
| Argument | Description | Required |
|---|---|---|
| file | List of files. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Score | number | The actual score calculated using the Mandiant Threat Score. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Reliability | string | The reliability definition of the vendor used to calculate the score as defined in the integration settings. |
| File.SHA1 | string | The SHA1 hash of the file. |
| File.SHA256 | string | The SHA256 hash of the file. |
| File.MD5 | string | The MD5 hash of the file. |
| File.name | string | The name of the indicator. |
| File.Campaign | string | A comma-separated list of any campaigns associated with the indicator. |
| File.TrafficLightProtocol | string | The traffic light protocol color associated with the indicator. |
| File.Malicious.description | string | A description of why the file is malicious. |
| File.Malicious.vendor | string | The vendor providing the description. |
| File.MalwareFamily | string | A comma-separated list of any Malware Families associated with the indicator. |
| File.Relationships | list | A list of relationship objects associated with the indicator. |
| File.Hashes | list | A list of hash objects associated with the indicator. |
| Mandiant.File.threat_rating.confidence_level | string | The confidence level of the indicator’s threat rating. |
| Mandiant.File.threat_rating.confidence_score | number | The confidence score of the indicator’s threat rating. |
| Mandiant.File.threat_rating.severity_level | string | The severity level of the indicator. |
| Mandiant.File.threat_rating.severity_reason | list | A list of severity reasons that contribute to the severity level of the indicator. |
| Mandiant.File.threat_rating.threat_score | number | The threat score of the indicator. |
| Mandiant.File.campaigns | list | A list of campaign objects associated with the indicator. |
| Mandiant.File.last_seen | date | The date and time that the indicator was last seen. |
| Mandiant.File.first_seen | date | The date and time that the indicator was first seen. |
| Mandiant.File.mscore | number | The confidence score of the indicator. |
| Mandiant.File.attributed_associations | list | A list of attribution objects (Threat Actors, Malware Families) associated with the indicator. |
| Mandiant.File.value | string | The value of the indicator. |
| Mandiant.File.last_updated | date | The date and time that the indicator was last updated by Mandiant. |
| Mandiant.File.associated_hashes | list | A list of file hashes associated with the indicator (MD5, SHA1, SHA256). |
| Mandiant.File.sources | list | A list of source objects associated with the indicator. |
| Mandiant.File.type | string | The indicator’s type. |
| Mandiant.File.id | string | The indicator’s Mandiant ID. |
| Mandiant.File.reports | list | A list of Mandiant reports associated with the indicator. |
ip
Get information about an IP address from Mandiant.
Base Command
ip
Input
| Argument | Description | Required |
|---|---|---|
| ip | List of IPs. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Score | number | The actual score calculated using the Mandiant Threat Score. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Reliability | string | The reliability definition of the vendor used to calculate the score as defined in the integration settings. |
| IP.Address | string | The IP address value. |
| IP.Campaign | string | A comma-separated list of any campaigns associated with the indicator. |
| IP.TrafficLightProtocol | string | The traffic light protocol color associated with the indicator. |
| IP.MalwareFamily | string | A comma-separated list of any Malware Families associated with the indicator. |
| IP.Relationships | list | A list of relationship objects associated with the indicator. |
| IP.STIXID | string | The STIX ID of the CVE. |
| IP.Publications | list | A list of report objects associated with the indicator. |
| Mandiant.IP.threat_rating.confidence_level | string | The confidence level of the indicator’s threat rating. |
| Mandiant.IP.threat_rating.confidence_score | number | The confidence score of the indicator’s threat rating. |
| Mandiant.IP.threat_rating.severity_level | string | The severity level of the indicator. |
| Mandiant.IP.threat_rating.severity_reason | list | A list of severity reasons that contribute to the severity level of the indicator. |
| Mandiant.IP.threat_rating.threat_score | number | The threat score of the indicator. |
| Mandiant.IP.campaigns | list | A list of campaign objects associated with the indicator. |
| Mandiant.IP.last_seen | date | The date and time that the indicator was last seen. |
| Mandiant.IP.first_seen | date | The date and time that the indicator was first seen. |
| Mandiant.IP.mscore | number | The confidence score of the indicator. |
| Mandiant.IP.attributed_associations | list | A list of attribution objects (Threat Actors, Malware Families) associated with the indicator. |
| Mandiant.IP.value | string | The value of the indicator. |
| Mandiant.IP.last_updated | date | The date and time that the indicator was last updated by Mandiant . |
| Mandiant.IP.sources | list | A list of source objects associated with the indicator. |
| Mandiant.IP.type | string | The indicator’s type. |
| Mandiant.IP.id | string | The indicator’s Mandiant ID. |
| Mandiant.IP.reports | list | A list of Mandiant reports associated with the indicator. |
url
Get information about a URL from Mandiant.
Base Command
url
Input
| Argument | Description | Required |
|---|---|---|
| url | List of URLs. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Score | number | The actual score calculated using the Mandiant Threat Score. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Reliability | string | The reliability definition of the vendor used to calculate the score as defined in the integration settings. |
| URL.Data | string | The URL value. |
| URL.Campaign | string | A comma-separated list of any campaigns associated with the indicator. |
| URL.TrafficLightProtocol | string | The traffic light protocol color associated with the indicator. |
| URL.MalwareFamily | string | A comma-separated list of any Malware Families associated with the indicator. |
| URL.Relationships | list | A list of relationship objects associated with the indicator. |
| URL.STIXID | string | The STIX ID of the CVE. |
| Mandiant.URL.threat_rating.confidence_level | string | The confidence level of the indicator’s threat rating. |
| Mandiant.URL.threat_rating.confidence_score | number | The confidence score of the indicator’s threat rating. |
| Mandiant.URL.threat_rating.severity_level | string | The severity level of the indicator. |
| Mandiant.URL.threat_rating.severity_reason | list | A list of severity reasons that contribute to the severity level of the indicator. |
| Mandiant.URL.threat_rating.threat_score | number | The threat score of the indicator. |
| Mandiant.URL.campaigns | list | A list of campaign objects associated with the indicator |
| Mandiant.URL.last_seen | date | The date and time that the indicator was last seen. |
| Mandiant.URL.first_seen | date | The date and time that the indicator was first seen. |
| Mandiant.URL.mscore | number | The confidence score of the indicator. |
| Mandiant.URL.attributed_associations | list | A list of attribution objects (Threat Actors, Malware Families) associated with the indicator. |
| Mandiant.URL.value | string | The value of the indicator. |
| Mandiant.URL.last_updated | date | The date and time that the indicator was last updated by Mandiant. |
| Mandiant.URL.sources | list | A list of source objects associated with the indicator. |
| Mandiant.URL.type | string | The indicator’s type. |
| Mandiant.URL.id | string | The indicator’s Mandiant ID. |
| Mandiant.URL.reports | list | A list of Mandiant reports associated with the indicator. |
domain
Get information about a domain from Mandiant.
Base Command
domain
Input
| Argument | Description | Required |
|---|---|---|
| domain | List of domains. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Score | number | The actual score calculated using the Mandiant Threat Score. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Reliability | string | The reliability definition of the vendor used to calculate the score as defined in the integration settings. |
| Domain.Name | string | The domain name. |
| Domain.Campaign | string | A comma-separated list of any campaigns associated with the indicator. |
| Domain.TrafficLightProtocol | string | The traffic light protocol color associated with the indicator. |
| Domain.MalwareFamily | string | A comma-separated list of any Malware Families associated with the indicator. |
| Domain.Relationships | list | A list of relationship objects associated with the indicator. |
| Domain.STIXID | string | The STIX ID of the CVE. |
| Mandiant.Domain.threat_rating.confidence_level | string | The confidence level of the indicator’s threat rating. |
| Mandiant.Domain.threat_rating.confidence_score | number | The confidence score of the indicator’s threat rating. |
| Mandiant.Domain.threat_rating.severity_level | string | The severity level of the indicator. |
| Mandiant.Domain.threat_rating.severity_reason | list | A list of severity reasons that contribute to the severity level of the indicator. |
| Mandiant.Domain.threat_rating.threat_score | number | The threat score of the indicator. |
| Mandiant.Domain.campaigns | list | A list of campaign objects associated with the indicator. |
| Mandiant.Domain.last_seen | date | The date and time that the indicator was last seen. |
| Mandiant.Domain.first_seen | date | The date and time that the indicator was first seen. |
| Mandiant.Domain.mscore | number | The confidence score of the indicator. |
| Mandiant.Domain.attributed_associations | list | A list of attribution objects (Threat Actors, Malware Families) associated with the indicator. |
| Mandiant.Domain.value | string | The value of the indicator. |
| Mandiant.Domain.last_updated | date | The date and time that the indicator was last updated by Mandiant. |
| Mandiant.Domain.sources | list | A list of source objects associated with the indicator. |
| Mandiant.Domain.type | string | The indicator’s type. |
| Mandiant.Domain.id | string | The indicator’s Mandiant ID. |
| Mandiant.Domain.reports | list | A list of Mandiant reports associated with the indicator. |
cve
Get information about a CVE from Mandiant.
Base Command
cve
Input
| Argument | Description | Required |
|---|---|---|
| cve | List of CVEs. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| CVE.VulnerableConfigurations | list | A list of CPE objects. |
| CVE.Publications | list | A list of reports associated with the CVE. |
| CVE.Modified | date | The date that the CVE was last modified. |
| CVE.STIXID | string | The STIX ID of the CVE. |
| CVE.VulnerableProducts | list | A list of CPE objects. |
| CVE.Published | date | The date that the CVE was last published |
| CVE.TrafficLightProtocol | string | The traffic light protocol color associated with the CVE. |
| CVE.CVSS.score | number | The CVSS score of the CVE. |
| CVE.CVSS.Vector | string | The CVSS Vector of the CVE. |
| CVE.CVSS.Version | number | The CVSS version of the CVE. |
| CVE.ID | string | The CVE ID. |
| CVE.Description | string | A description of the CVE. |
| DBotScore.Score | number | The actual score calculated using the CVSS score. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Reliability | string | The reliability definition of the vendor used to calculate the score as defined in the integration settings. |
| Mandiant.CVE.is_predicted | bool | If the risk rating was predicted (True) or set by an analyst (False). |
| Mandiant.CVE.date_of_disclosure | date | The date and time that the CVE was disclosed. |
| Mandiant.CVE.associated_reports | list | A list of reports associated with the CVE. |
| Mandiant.CVE.exploits | list | A list of exploits associated with the CVE. |
| Mandiant.CVE.cve_id | string | The CVE ID of the CVE. |
| Mandiant.CVE.workarounds_list | list | A list of workarounds associated with the CVE. |
| Mandiant.CVE.vendor_fix_references | list | A list of vendor fix references associated with the CVE. |
| Mandiant.CVE.version_history | list | A list of history objects containing links to detail about each version of the CVE. |
| Mandiant.CVE.risk_rating | list | The risk rating associated with the CVE. |
| Mandiant.CVE.first_publish_date | date | The date and time that the CVE was fist published. |
| Mandiant.CVE.exploitation_consequence | string | The exploitation consequence associated with the CVE. |
| Mandiant.CVE.vulnerable_cpes | list | A list of vulnerable CPE objects associated with the CVE. |
| Mandiant.CVE.updated_date | date | The date and time that the CVE was last updated. |
| Mandiant.CVE.workarounds | string | A summary of any workarounds associated with the CVE. |
| Mandiant.CVE.available_mitigation | list | A list of mitigations associated with the CVE. |
| Mandiant.CVE.associated_actors | list | A list of Threat Actor objects associated with the CVE. |
| Mandiant.CVE.title | string | The title of the CVE. |
| Mandiant.CVE.common_vulnerability_scores | object | An object containing common vulnerability score objects associated with the CVE. |
| Mandiant.CVE.sources | list | A list of sources associated with the CVE. |
| Mandiant.CVE.type | string | The type of indicator. |
| Mandiant.CVE.vulnerable_products | list | A summary of any vulnerable products associated with the CVE. |
| Mandiant.CVE.exploitation_vectors | list | A list of exploitation vectors associated with the CVE. |
| Mandiant.CVE.id | string | The Mandiant ID of the CVE. |
| Mandiant.CVE.last_modified_date | date | The date and time that the CVE was last modified. |
| Mandiant.CVE.observed_in_the_wild | bool | If the CVE was observed in the wild (True) of not (False). |
| Mandiant.CVE.was_zero_day | bool | If the CVE was determined to be a zero day exploit (True) of not (False). |
| Mandiant.CVE.exploitation_state | string | The current exploitation state of the CVE. |
| Mandiant.CVE.associated_malware | list | A list of Malware Family objects associated with the CVE. |
| Mandiant.CVE.description | string | A description of the CVE. |
| Mandiant.CVE.cpe_ranges | list | A list of CPE objects objects associated with the CVE. |
| Mandiant.CVE.mve_id | string | The Mandiant Vulnerability ID of the CVE. |
| Mandiant.CVE.publish_date | date | The date and time that the CVE was published. |
| Mandiant.CVE.aliases | list | A list of alias objects associated with the CVE. |
mati-get-actor
Get information about a Threat Actor from Mandiant.
Base Command
mati-get-actor
Input
| Argument | Description | Required |
|---|---|---|
| actor_name | Name of the actor to look up. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| Mandiant.Actor.associated_uncs | list | UNC Threat Actors associated with the fetched Threat Actor. |
| Mandiant.Actor.counts.aliases | number | The number of alternate names the fetched Threat Actor is known as. |
| Mandiant.Actor.counts.associated_uncs | number | The number of UNC Threat Actors associated with the fetched Threat Actor. |
| Mandiant.Actor.counts.attack_patterns | number | The number of Attack Patterns associated with the fetched Threat Actor. |
| Mandiant.Actor.counts.cve | number | The number of vulnerabilities associated with the fetched Threat Actor. |
| Mandiant.Actor.counts.industries | number | The number of industries targeted by the fetched Threat Actor. |
| Mandiant.Actor.counts.malware | number | The number of Malware Families associated with the fetched Threat Actor. |
| Mandiant.Actor.counts.reports | number | The number of finished intelligence reports associated with the fetched Threat Actor. |
| Mandiant.Actor.audience | list | A list of audience objects describing who can read the Threat Actor information. |
| Mandiant.Actor.observed | list | A list of observed objects describing when the Threat Actor was first and last seen. |
| Mandiant.Actor.name | string | The name of the Threat Actor. |
| Mandiant.Actor.value | string | The name of the Threat Actor. |
| Mandiant.Actor.last_updated | date | The date and time that the Threat Actor object was last updated by Mandiant. |
| Mandiant.Actor.cve | list | A list of vulnerability objects associated with the Threat Actor. |
| Mandiant.Actor.last_activity_time | date | The date and time that the Threat Actor object was last active. |
| Mandiant.Actor.malware | list | A list of Malware Family objects associated with the Threat Actor. |
| Mandiant.Actor.suspected_attribution | list | A list of Intel objects suspected to be associated with the Threat Actor. |
| Mandiant.Actor.type | string | The type of Cortex XSOAR indicator. |
| Mandiant.Actor.id | string | The Mandiant ID of the Threat Actor. |
| Mandiant.Actor.tools | list | A list of tool objects associated with the Threat Actor. |
| Mandiant.Actor.industries | list | A list of industry objects associated with the Threat Actor. |
| Mandiant.Actor.description | string | A description of the Threat Actor. |
| Mandiant.Actor.motivations | list | A list of motivation objects associated with the Threat Actor. |
| Mandiant.Actor.aliases | list | A list of alias objects describing alternate names associated with the Threat Actor. |
| Mandiant.Actor.locations.source | list | A list of source location objects describing the country that the Threat Actor originates from. |
| Mandiant.Actor.locations.target | list | A list of target country objects describing the countries that the Threat Actor targets. |
| Mandiant.Actor.locations.target_region | list | A list of target region objects describing the regions that the Threat Actor targets. |
| Mandiant.Actor.locations.target_sub_region | list | A list of target sub-region objects describing the sub-regions that the Threat Actor targets. |
mati-get-malware
Get information about a Malware Family from Mandiant.
Base Command
mati-get-malware
Input
| Argument | Description | Required |
|---|---|---|
| malware_name | Name of the Malware Family to look up. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| Mandiant.Malware.counts.detections | number | The number of detections associated with the Malware Family. |
| Mandiant.Malware.counts.cve | number | The number of vulnerabilities associated with the Malware Family. |
| Mandiant.Malware.counts.malware | number | The number of Malware Families associated with the Malware Family. |
| Mandiant.Malware.counts.capabilities | number | The number of capabilities associated with the Malware Family. |
| Mandiant.Malware.counts.attack_patterns | number | The number of Attack Patterns associated with the Malware Family. |
| Mandiant.Malware.counts.industries | number | The number of industries targeted by the Malware Family. |
| Mandiant.Malware.counts.actors | number | The number of Threat Actors associated with the Malware Family. |
| Mandiant.Malware.counts.aliases | number | The number of alternate names associated with the Malware Family. |
| Mandiant.Malware.counts.reports | number | The number of finished intelligence reports associated with the Malware Family. |
| Mandiant.Malware.audience | list | A list of audience objects describing who can read the Malware Family information. |
| Mandiant.Malware.operating_systems | list | A list of operating systems that the Malware Family is known to impact. |
| Mandiant.Malware.name | string | The name of the Malware Family. |
| Mandiant.Malware.detections | list | A list of detections associated with the Malware Family. |
| Mandiant.Malware.value | string | The name of the Malware Family . |
| Mandiant.Malware.last_updated | date | The date and time that the Malware Family object was last updated by Mandiant. |
| Mandiant.Malware.cve | list | A list of vulnerability objects associated with the Malware Family. |
| Mandiant.Malware.last_activity_time | date | The date and time that the Malware Family object was last active . |
| Mandiant.Malware.malware | list | A list of Malware Family objects associated with the Malware Family. |
| Mandiant.Malware.capabilities | list | A list of capability objects associated with the Malware Family. |
| Mandiant.Malware.yara | list | A list of YARA rule objects associated with the Malware Family. |
| Mandiant.Malware.industries | list | A list of industry objects targeted by the Malware Family. |
| Mandiant.Malware.roles | list | A list of roles associated with the Malware Family. |
| Mandiant.Malware.actors | list | A list of Threat Actor objects associated with the Malware Family. |
| Mandiant.Malware.aliases | list | A list of alias objects describing alternate names associated with the Malware Family. |
| Mandiant.Malware.inherently_malicious | number | If 1, the object should be considered a Malware Family, if 0 the object is a Tool. |
mati-get-campaign
Retrieve information about a Campaign from Mandiant.
Base Command
mati-get-campaign
Input
| Argument | Description | Required |
|---|---|---|
| campaign_id | ID of the campaign to lookup. | True |
Context Output
| Path | Type | Description |
|---|---|---|
| Mandiant.Campaign.counts.timeline | number | The number of events in the Campaign timeline. |
| Mandiant.Campaign.counts.campaigns | number | The number of other Campaigns associated with the Campaign. |
| Mandiant.Campaign.counts.malware | number | The number of Malware Families associated with the Campaign. |
| Mandiant.Campaign.counts.actor_collaborations | number | The number of Threat Actor Collaborations associated with the Campaign. |
| Mandiant.Campaign.counts.vulnerabilities | number | The number of Vulnerabilities associated with the Campaign. |
| Mandiant.Campaign.counts.tools | number | The number of Tools associated with the Campaign. |
| Mandiant.Campaign.counts.industries | number | The number of target industries associated with the Campaign. |
| Mandiant.Campaign.counts.actors | number | The number of Threat Actors associated with the Campaign. |
| Mandiant.Campaign.counts.reports | number | The number of finished intelligence reports associated with the Campaign. |
| Mandiant.Campaign.profile_update | date | The date and time that the profile of the Campaign was last updated. |
| Mandiant.Campaign.campaign_type | string | The type of the Campaign. |
| Mandiant.Campaign.name | string | The name of the Campaign. |
| Mandiant.Campaign.short_name | string | The short name / ID of the Campaign. |
| Mandiant.Campaign.target_locations.countries | list | A list of country objects that the Campaign targets. |
| Mandiant.Campaign.target_locations.regions | list | A list of region objects that the Campaign targets. |
| Mandiant.Campaign.target_locations.sub_regions | list | A list of sub-region objects that the Campaign targets. |
| Mandiant.Campaign.value | string | The short name / ID of the Campaign. |
| Mandiant.Campaign.last_activity_time | date | The date and time that the Campaign was last known to be active. |
| Mandiant.Campaign.malware | list | A list of Malware Family objects associated with the Campaign. |
| Mandiant.Campaign.actor_collaborations | list | A list of Actor Collaboration objects associated with the Campaign. |
| Mandiant.Campaign.vulnerabilities | list | A list of Vulnerability objects associated with the Campaign. |
| Mandiant.Campaign.type | string | The indicator type. |
| Mandiant.Campaign.tools | list | A list of tool objects associated with the Campaign. |
| Mandiant.Campaign.industries | list | A list of target industry objects associated with the Campaign. |
| Mandiant.Campaign.actors | list | A list of Threat Actor objects associated with the Campaign. |
| Mandiant.Campaign.aliases | list | A list of alias objects associated with the Campaign. |
Configuration parameters
api_key— API Key (required)secret_key— Secret Key (required)timeout— Timeoutreliability— Source Reliability (required)tlp_color— Traffic Light Protocol Colortags— Tagsmap_to_mitre_attack— Map Attack Pattern Relationships to Mitre ATT&CK.
Commands (8)
-
cveGet information about a CVE from Mandiant.
-
domainGet information about a domain from Mandiant.
-
fileGet information about a file hash from Mandiant.
-
ipGet information about an IP address from Mandiant.
-
mati-get-actorGet information about a Threat Actor from Mandiant.
-
mati-get-campaignRetrieve information about a Campaign from Mandiant.
-
mati-get-malwareGet information about a Malware Family from Mandiant.
-
urlGet information about a URL from Mandiant.
from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa from collections.abc import Callable, Generator # Disable insecure warnings requests.packages.urllib3.disable_warnings() # type:ignore API_BASE_URL = "https://api.intelligence.mandiant.com" ADV_BASE_URL = "https://advantage.mandiant.com" DEFAULT_TIMEOUT = 60 ENRICHMENT_TIMEOUT = 10 class MandiantClient(BaseClient): def __init__(self, conf: Dict): verify = not conf.get("insecure", False) proxy = conf.get("proxy", False) super().__init__(base_url=API_BASE_URL, verify=verify, proxy=proxy, ok_codes=(200,)) self.api_key = conf.get("api_key") self.secret_key = conf.get("secret_key") self.headers = {"X-App-Name": "content.xsoar.cortex.mandiant.enrichment.v1.1", "Accept": "application/json"} self.timeout = int(conf.get("timeout", DEFAULT_TIMEOUT)) if is_time_sensitive(): # For reputation commands which run during an enrichment we limit the timeout self.timeout = ENRICHMENT_TIMEOUT self.tlp_color = conf.get("tlp_color", "") self.tags = argToList(conf.get("tags", [])) self.reliability = conf.get("reliability", "") self.map_to_mitre_attack = conf.get("map_to_mitre_attack", False) def _get(self, url: str, params: Dict = {}) -> Dict: try: return self._http_request( method="GET", url_suffix=url, auth=(self.api_key, self.secret_key), headers=self.headers, timeout=self.timeout, params=params, ) except DemistoException as ex: raise DemistoException(str(ex)) def _post(self, url: str, post_body: dict) -> Dict: try: return self._http_request( method="POST", url_suffix=url, auth=(self.api_key, self.secret_key), headers=self.headers, timeout=self.timeout, json_data=post_body, ) except DemistoException as ex: raise DemistoException(str(ex)) def get_entitlements(self) -> Dict: return self._get("/v4/entitlements") def get_indicators_by_value(self, values_: List) -> List[Dict[str, Any]]: post_body = { "requests": [{"values": values_}], "include_campaigns": True, "include_threat_rating": True, "include_reports": True, "exclude_misp": True, } url = "/v4/indicator" response = self._post(url, post_body) response = response.get("indicators", []) return response def get_actor(self, actor_name: str) -> Dict: actor = self._get(f"/v4/actor/{actor_name}") return actor def get_malware(self, malware_name: str) -> Dict: return self._get(f"/v4/malware/{malware_name}") def get_associated_reports(self, intel_type: str, intel_id: str) -> Dict: return self._get(f"/v4/{intel_type}/{intel_id}/reports") def get_campaign(self, campaign_id: str) -> Dict: return self._get(f"/v4/campaign/{campaign_id}") def get_attack_patterns(self, intel_type: str, intel_id: str) -> Dict: return self._get(f"/v4/{intel_type}/{intel_id}/attack-pattern") def get_associated_campaigns(self, intel_type: str, intel_id: str) -> Dict: return self._get(f"v4/{intel_type}/{intel_id}/campaigns") def get_cve_by_cveid(self, cve_id: str) -> Dict: return self._get(f"/v4/vulnerability/{cve_id}?rating_types=analyst,predicted,unrated") def get_mitre_attack_patterns(self) -> Dict: if not self.map_to_mitre_attack: return {} response = demisto.searchIndicators( **{"query": 'type:"Attack Pattern" and sourceBrands:"MITRE ATT&CK v2"', "populateFields": "name, tags", "size": 1000} ) res_dict = {} for ioc in response.get("iocs", []): tags = ioc.get("CustomFields", {}).get("tags", "") name_ = ioc.get("CustomFields", {}).get("name", "") if not isinstance(tags, list): key_ = tags res_dict[key_] = name_ else: for t in tags: res_dict[t] = name_ return res_dict class MatiIndicator: def __init__(self, client: MandiantClient, ioc_data: Dict, ioc_type: str) -> None: self.client = client self.ioc_data = ioc_data self.ioc_type = ioc_type self.dbot_score_type: str self.indicator_object: Common.IP | Common.Domain | Common.URL | Common.File self.outputs_prefix: str self.ioc_value = self.ioc_data.get("value", "") self.threat_score = self.build_threat_score() self.sources = self.get_sources() self.relationships = self.build_relationships() def build_threat_score(self) -> int: return self.ioc_data.get("threat_rating", {}).get("threat_score", 0) def build_relationships(self) -> List: relationships: List = [] for association in self.ioc_data.get("attributed_associations", []): association_type = association.get("type", "") entity_b = association.get("name", "") if association_type == "threat-actor": relationships.append( EntityRelationship( name="uses", reverse_name="used-by", brand="Mandiant", entity_a=self.ioc_value, entity_a_type=self.ioc_type, entity_b=entity_b, entity_b_type="Threat Actor", ) ) elif association_type == "malware": relationships.append( EntityRelationship( name="indicator-of", reverse_name="indicated-by", brand="Mandiant", entity_a=self.ioc_value, entity_a_type=self.ioc_type, entity_b=entity_b, entity_b_type="Malware", ) ) return relationships def calculate_dbot_score(self) -> int: if self.threat_score is None: return Common.DBotScore.NONE if 0 <= self.threat_score <= 20: return Common.DBotScore.GOOD elif 21 <= self.threat_score <= 80: return Common.DBotScore.SUSPICIOUS elif 81 <= self.threat_score <= 100: return Common.DBotScore.BAD else: return Common.DBotScore.NONE def create_dbot_score(self) -> Common.DBotScore: return Common.DBotScore( indicator=self.ioc_value, indicator_type=self.dbot_score_type, integration_name="Mandiant", reliability=self.client.reliability, score=self.calculate_dbot_score(), ) def build_campaigns(self) -> str: campaigns_list: List[str] = [] for c in self.ioc_data.get("campaigns", []): title = c.get("title", "") campaign_id = c.get("name", "") if not title or not campaign_id: continue campaigns_list.append(f"{title} ({campaign_id})") return ", ".join(campaigns_list) if campaigns_list else "-" def build_malware_families(self) -> str: malware_list = [] for association in self.ioc_data.get("attributed_associations", []): association_type = association.get("type", "") association_name = association.get("name", "") if not association_type or not association_name: continue if association_type == "malware": malware_list.append(association_name) return ", ".join(malware_list) if malware_list else "-" def build_publications(self): publications = [] for r in self.ioc_data.get("reports", []): title = r.get("title", "") report_id = r.get("report_id", "") published = r.get("published_date") if not title or not report_id or not published: continue publications.append( Common.Publications( source="Mandiant", title=f"{title} ({report_id})", link=f"{ADV_BASE_URL}/reports/{report_id}", timestamp=published, ) ) return publications def get_stix_id(self) -> str: return self.ioc_data.get("id", "") def get_sources(self) -> List: return self.ioc_data.get("sources", []) def build_threat_types(self) -> List: threat_types = [] for source in self.sources: for c in source.get("category", []): t = Common.ThreatTypes(threat_category=c, threat_category_confidence=str(self.ioc_data.get("mscore", 0))) threat_types.append(t) return threat_types def build_source_names(self) -> List: return [s.get("source_name", "").lower() for s in self.sources] def build_indicator(self, indicator_object: Common.IP | Common.Domain | Common.URL | Common.File): indicator_object.campaign = self.build_campaigns() indicator_object.malware_family = self.build_malware_families() indicator_object.publications = self.build_publications() indicator_object.relationships = self.relationships indicator_object.stix_id = self.get_stix_id() indicator_tags = [t.threat_category for t in self.build_threat_types()] for t in self.client.tags: indicator_tags.append(t) indicator_object.tags = indicator_tags sources = self.build_source_names() indicator_object.traffic_light_protocol = "GREEN" if "mandiant" not in sources else self.client.tlp_color return indicator_object def build_markdown(self) -> str: categories = set() for t in self.build_threat_types(): categories.add(t.threat_category) reports_list: List = [r.title for r in self.build_publications()] table = { "Threat Score": self.threat_score, "Last Seen": self.ioc_data.get("last_seen"), "Malware": self.build_malware_families(), "Campaigns": self.build_campaigns(), "Categories": ", ".join(list(categories)) if categories else "-", "Reports": ", ".join(reports_list) if reports_list else "-", } return tableToMarkdown( f"Mandiant Advantage Threat Intelligence information for {self.ioc_value}\n" f"[View on Mandiant Advantage]({ADV_BASE_URL}/indicator/{self.get_stix_id()})", table, ) def build_indicator_command_result(self) -> CommandResults: return CommandResults( readable_output=self.build_markdown(), ignore_auto_extract=False, outputs_prefix=self.outputs_prefix, relationships=self.relationships, outputs=self.ioc_data, indicator=self.indicator_object, ) class MatiIpIndicator(MatiIndicator): def __init__(self, client: MandiantClient, ioc_data: Dict) -> None: super().__init__(client, ioc_data, FeedIndicatorType.IP) self.dbot_score_type = DBotScoreType.IP self.outputs_prefix = "Mandiant.IP" self.indicator_object = self.build_indicator(Common.IP(ip=self.ioc_value, dbot_score=self.create_dbot_score())) class MatiDomainIndicator(MatiIndicator): def __init__(self, client: MandiantClient, ioc_data: Dict) -> None: super().__init__(client, ioc_data, FeedIndicatorType.Domain) self.dbot_score_type = DBotScoreType.DOMAIN self.outputs_prefix = "Mandiant.Domain" self.indicator_object = self.build_indicator(Common.Domain(domain=self.ioc_value, dbot_score=self.create_dbot_score())) class MatiUrlIndicator(MatiIndicator): def __init__(self, client: MandiantClient, ioc_data: Dict) -> None: super().__init__(client, ioc_data, FeedIndicatorType.URL) self.dbot_score_type = DBotScoreType.URL self.outputs_prefix = "Mandiant.URL" self.indicator_object = self.build_indicator(Common.URL(url=self.ioc_value, dbot_score=self.create_dbot_score())) class MatiFileIndicator(MatiIndicator): def __init__(self, client: MandiantClient, ioc_data: Dict, ioc_value: str) -> None: super().__init__(client, ioc_data, FeedIndicatorType.File) self.dbot_score_type = DBotScoreType.FILE self.outputs_prefix = "Mandiant.File" self.ioc_value = ioc_value self.indicator_object = Common.File(name=self.ioc_value, dbot_score=self.create_dbot_score()) md5 = self.get_hash_value("md5") sha1 = self.get_hash_value("sha1") sha256 = self.get_hash_value("sha256") if md5: self.indicator_object.md5 = md5 if sha1: self.indicator_object.sha1 = sha1 if sha256: self.indicator_object.sha256 = sha256 self.indicator_object = self.build_indicator(self.indicator_object) def get_hash_value(self, hash_type: str) -> str: hash_value = "" for a in self.ioc_data.get("associated_hashes", []): hash_value = a.get("value", "") if a.get("type") == hash_type else "" if hash_value: break return hash_value class MatiThreatActor: def __init__(self, client: MandiantClient, actor_data: Dict) -> None: self.client = client self.actor_data = actor_data self.actor_name = self.actor_data.get("value", "") self.actor_id = self.actor_data.get("id", "") self.description = self.actor_data.get("description") self.target_industries = self.build_target_industries() self.reports_list = self.get_associated_reports() def get_associated_reports(self) -> List: reports = [] for report in self.client.get_associated_reports("actor", self.actor_id).get("reports", []): reports.append( { "source": "Mandiant", "title": report.get("title", "-"), "link": "{}/reports/{}".format(ADV_BASE_URL, report.get("report_id")), "timestamp": datetime.strptime(report.get("published_date"), "%B %d, %Y %I:%M:%S %p").timestamp(), } ) return reports def build_target_industries(self) -> List: return [i.get("name", "") for i in self.actor_data.get("industries", [])] def build_target_industries_str(self) -> str: return ", ".join(list(self.target_industries)) def build_motivations(self) -> str: return ", ".join([m.get("name") for m in self.actor_data.get("motivations", [])]) def build_target_countries(self) -> str: return ", ".join([c.get("name") for c in self.actor_data.get("locations", {}).get("target", ["Unknown"])]) def build_associated_malware(self) -> str: return ", ".join([m.get("name", "") for m in self.actor_data.get("malware", ["-"])]) def build_associated_tools(self) -> str: return ", ".join([t.get("name", "") for t in self.actor_data.get("tools", ["-"])]) def build_associated_vulnerabilities(self) -> str: return ", ".join([cve.get("cve_id", "") for cve in self.actor_data.get("cve", ["-"])]) def build_aliases(self) -> str: return ", ".join([a.get("name") for a in self.actor_data.get("aliases", [])]) def build_primary_motivation(self) -> str: motivation_map = { "Financial Gain": "Cyber Crime", "Surveillance": "Cyber Crime", "Attack / Destruction": "Cyber Crime", "Influence": "", "Espionage": "Cyber Espionage", "Hacktivism": "Hacktivism", "Unknown": "", } motivations = [m.get("name") for m in self.actor_data.get("motivations", [])] for m in motivations: if motivation_map.get(m): return motivation_map.get(m, "") return "" def get_source_country(self) -> str: return self.actor_data.get("locations", {}).get("source", [])[0].get("country", {}).get("name", "Unknown") def get_last_activity_time(self) -> str: return self.actor_data.get("last_activity_time", "Unknown") def get_last_updated(self) -> str: return self.actor_data.get("last_updated", "Unknown") def build_attribute_md(self) -> str: attribute_table = { "Link": f"{ADV_BASE_URL}/actors/{self.actor_id}", "Motivations": self.build_motivations(), "Target Industries": self.build_target_industries_str(), "Associated Malware": self.build_associated_malware(), "Associated Tools": self.build_associated_tools(), "Associated Vulnerabilities": self.build_associated_vulnerabilities(), "Last Activity Time": self.get_last_activity_time(), "Last Updated": self.get_last_updated(), } return tableToMarkdown("Threat Actor Attributes", attribute_table, url_keys=["Link"]) def build_report_md(self) -> str: earliest_report = time.time() - (86400 * 90) report_table = [ {"Title": r.get("title", ""), "Link": r.get("link", "")} for r in self.reports_list if int(r.get("timestamp", 1)) > earliest_report ] return tableToMarkdown("Recent Associated Reports", report_table, url_keys=["Link"]) def build_actor_markdown(self) -> str: return ( f"## {self.actor_name}\n\n" + f"{self.description}\n\n" + f"{self.build_attribute_md()}\n\n" + self.build_report_md() ) def build_malware_relationships(self) -> Generator: for malware in self.actor_data.get("malware", []): yield EntityRelationship( name="uses", reverse_name="used-by", brand="Mandiant", entity_a=self.actor_name, entity_a_type="Threat Actor", entity_b=malware.get("name", ""), entity_b_type="Malware", ).to_indicator() def build_vulnerbility_relationships(self) -> Generator: for vuln in self.actor_data.get("cve", []): yield EntityRelationship( name="exploits", reverse_name="used-by", brand="Mandiant", entity_a=self.actor_name, entity_a_type="Threat Actor", entity_b=vuln.get("cve_id", ""), entity_b_type="CVE", ).to_indicator() def build_unc_relationships(self) -> Generator: for unc in self.actor_data.get("associated_uncs", []): yield EntityRelationship( name="related-to", reverse_name="related-to", brand="Mandiant", entity_a=self.actor_name, entity_a_type="Threat Actor", entity_b=unc.get("name", ""), entity_b_type="Threat Actor", ).to_indicator() def build_attack_pattern_relationships(self) -> Generator: attack_patterns = self.client.get_attack_patterns("actor", self.actor_id).get("attack-patterns", {}) mitre_attack_patterns: Dict = self.client.get_mitre_attack_patterns() for ap in attack_patterns: ap_id = attack_patterns.get(ap).get("attack_pattern_identifier", "") ap_title = attack_patterns.get(ap).get("name", "") mitre_ap = mitre_attack_patterns.get(ap_id, "") entity_b = mitre_ap if mitre_ap else f"{ap_id}: {ap_title}" yield EntityRelationship( name="uses", reverse_name="used-by", brand="Mandiant", entity_a=self.actor_name, entity_a_type="Threat Actor", entity_b=entity_b, entity_b_type="Attack Pattern", ).to_indicator() def build_campaign_relationships(self) -> Generator: for c in self.client.get_associated_campaigns("actor", self.actor_id).get("campaigns", []): campaign_id = c.get("short_name", "") campaign_title = c.get("name", "") yield EntityRelationship( name="related-to", reverse_name="related-to", brand="Mandiant", entity_a=self.actor_name, entity_a_type="Threat Actor", entity_b=f"{campaign_title} ({campaign_id})", entity_b_type="Campaign", ).to_indicator() def build_actor_relationships(self) -> List: relationships = [] for malware in self.build_malware_relationships(): relationships.append(malware) for vuln in self.build_vulnerbility_relationships(): relationships.append(vuln) for unc in self.build_unc_relationships(): relationships.append(unc) for ap in self.build_attack_pattern_relationships(): relationships.append(ap) for campaign in self.build_campaign_relationships(): relationships.append(campaign) return relationships def build_indicator(self) -> Dict: return { "value": self.actor_name, "type": "Threat Actor", "rawJSON": self.actor_data, "score": ThreatIntel.ObjectsScore.THREAT_ACTOR, "fields": { "Aliases": self.build_aliases(), "STIX ID": self.actor_id, "Description": self.description, "Geo Country": self.get_source_country(), "Primary Motivation": self.build_primary_motivation(), "Tags": self.build_target_industries_str(), "Publications": self.reports_list, "Industry sectors": self.target_industries, }, "relationships": self.build_actor_relationships(), } def build_threat_actor_command_result(self): return CommandResults( outputs=self.actor_data, ignore_auto_extract=False, outputs_prefix="Mandiant.Actor", readable_output=self.build_actor_markdown(), tags=self.target_industries, ) class MatiMalware: def __init__(self, client: MandiantClient, malware_data: Dict) -> None: self.client = client self.malware_data = malware_data self.malware_name = self.malware_data.get("value", "") self.malware_id = self.malware_data.get("id", "") self.description = self.malware_data.get("description") self.target_industries = self.build_target_industries() self.reports_list = self.get_associated_reports() def build_target_industries(self) -> List: return [i.get("name", "") for i in self.malware_data.get("industries", [])] def get_associated_reports(self) -> List: reports = [] for report in self.client.get_associated_reports("malware", self.malware_id).get("reports", []): reports.append( { "source": "Mandiant", "title": report.get("title", "-"), "link": "{}/reports/{}".format(ADV_BASE_URL, report.get("report_id")), "timestamp": datetime.strptime(report.get("published_date"), "%B %d, %Y %I:%M:%S %p").timestamp(), } ) return reports def build_actor_relationships(self) -> Generator: for actor in self.malware_data.get("actors", []): yield EntityRelationship( name="used-by", reverse_name="uses", brand="Mandiant", entity_a=self.malware_name, entity_a_type="Malware", entity_b=actor.get("name", ""), entity_b_type="Threat Actor", ).to_indicator() def build_vulnerability_relationships(self) -> Generator: for vuln in self.malware_data.get("cve", []): yield EntityRelationship( name="exploits", reverse_name="used-by", brand="Mandiant", entity_a=self.malware_name, entity_a_type="Malware", entity_b=vuln.get("cve_id", ""), entity_b_type="CVE", ).to_indicator() def build_attack_pattern_relationships(self) -> Generator: attack_patterns = self.client.get_attack_patterns("malware", self.malware_id).get("attack-patterns", {}) mitre_attack_patterns: Dict = self.client.get_mitre_attack_patterns() for ap in attack_patterns: ap_id = attack_patterns.get(ap).get("attack_pattern_identifier", "") ap_title = attack_patterns.get(ap).get("name", "") mitre_ap = mitre_attack_patterns.get(ap_id, "") entity_b = mitre_ap if mitre_ap else f"{ap_id}: {ap_title}" yield EntityRelationship( name="uses", reverse_name="used-by", brand="Mandiant", entity_a=self.malware_name, entity_a_type="Malware", entity_b=entity_b, entity_b_type="Attack Pattern", ).to_indicator() def build_campaign_relationships(self) -> Generator: for c in self.client.get_associated_campaigns("malware", self.malware_id).get("campaigns", []): campaign_id = c.get("short_name", "") campaign_title = c.get("name", "") yield EntityRelationship( name="related-to", reverse_name="related-to", brand="Mandiant", entity_a=self.malware_name, entity_a_type="Malware", entity_b=f"{campaign_title} ({campaign_id})", entity_b_type="Campaign", ).to_indicator() def build_malware_relationships(self) -> List: relationships = [] for actor in self.build_actor_relationships(): relationships.append(actor) for vuln in self.build_vulnerability_relationships(): relationships.append(vuln) for ap in self.build_attack_pattern_relationships(): relationships.append(ap) for c in self.build_campaign_relationships(): relationships.append(c) return relationships def build_indicator(self) -> Dict: return { "value": self.malware_name, "type": "Malware", "rawJSON": self.malware_data, "fields": { "Tags": self.build_target_industries(), "Publications": self.reports_list, "Industry sectors": self.target_industries, }, "score": ThreatIntel.ObjectsScore.MALWARE, "relationships": self.build_malware_relationships(), } def build_roles(self) -> str: return ", ".join(self.malware_data.get("roles", [])) def build_capabilities(self) -> str: return ", ".join([c.get("name", "") for c in self.malware_data.get("capabilities", [])]) def build_detections(self) -> str: return ", ".join(self.malware_data.get("detections", [])) def build_operating_systems(self) -> str: return ", ".join(self.malware_data.get("operating_systems", [])) def build_target_indistries_str(self) -> str: return ", ".join(self.target_industries) def build_associated_actors(self) -> str: return ", ".join([a.get("name", "") for a in self.malware_data.get("actors", ["-"])]) def build_associated_vulnerabilities(self) -> str: return ", ".join([v.get("cve_id", "") for v in self.malware_data.get("cve", ["-"])]) def get_last_activity_time(self) -> str: return self.malware_data.get("last_activity_time", "Unknown") def get_last_updated(self) -> str: return self.malware_data.get("last_updated", "Unknown") def build_attribute_table_md(self) -> str: attribute_table = { "Link": f"{ADV_BASE_URL}/malware/{self.malware_id}", "Roles": self.build_roles(), "Capabilities": self.build_capabilities(), "Detections": self.build_detections(), "Operating Systems": self.build_operating_systems(), "Target Industries": self.build_target_indistries_str(), "Associated Threat Actors": self.build_associated_actors(), "Associated Vulnerabilities": self.build_associated_vulnerabilities(), "Last Activity Time": self.get_last_activity_time(), "Last Updated": self.get_last_updated(), } return tableToMarkdown("Malware Family Attributes", attribute_table, url_keys=["Link"]) def build_report_table_md(self) -> str: earliest_report = time.time() - (86400 * 90) report_table = [ {"Title": r.get("title", ""), "Link": r.get("link", "")} for r in self.reports_list if int(r.get("timestamp", 1)) > earliest_report ] return tableToMarkdown("Recent Associated Reports", report_table, url_keys=["Link"]) def build_malware_markdown(self) -> str: return ( f"## {self.malware_name}\n\n" + f"{self.description}\n\n" + f"{self.build_attribute_table_md()}\n\n" + self.build_report_table_md() ) def build_malware_command_result(self): return CommandResults( outputs=self.malware_data, ignore_auto_extract=False, outputs_prefix="Mandiant.Malware", readable_output=self.build_malware_markdown(), tags=self.target_industries, ) class MatiCve: def __init__(self, cve_data: Dict, reliability: str, tlp_color: str, tags: List) -> None: self.cve_data = cve_data self.reliability = reliability self.tlp_color = tlp_color self.tags = tags self.cve_id = self.cve_data.get("cve_id", "") self.description = self.strip_html_tags(self.cve_data.get("description", ""), True, True) self.publish_date = self.cve_data.get("publish_date", "") self.last_modified_date = self.cve_data.get("last_modified_date", "") self.risk_rating = self.cve_data.get("risk_rating", "") self.vulnerable_products = self.strip_html_tags(self.cve_data.get("vulnerable_products", ""), True, True) self.executive_summary = self.strip_html_tags(self.cve_data.get("executive_summary", ""), True, True) self.cvss_data = self.cve_data.get("common_vulnerability_scores", {}) self.cvss_version = self.calculate_cvss_version() self.cvss_score = self.get_cvss_score() self.cpe_objects = self.build_cpe_objects() self.relationships = self.build_relationships() @staticmethod def strip_html_tags(content: str, replace_line_breaks: bool, trim_result: bool) -> str: text = "" if content: text = re.sub(r"<\/?br\s?\/?>", "\n", content, flags=re.I) if replace_line_breaks else content text = re.sub(r"<.*?>", "", text) entities = { "quot": '"', "amp": "&", "apos": "'", "lt": "<", "gt": ">", "nbsp": " ", "copy": "(C)", "reg": "(R)", "tilde": "~", "ldquo": '"', "rdquo": '"', "hellip": "...", } for e in entities: text = text.replace(f"&{e};", entities[e]) if trim_result: text = re.sub(r"[ \t]{2,}", " ", text) text = re.sub(r"(\s*\r?\n){3,}", "\n\n", text) text = text.strip() return text def build_relationships(self) -> List: relationships = [] for a in self.cve_data.get("associated_actors", []): relationships.append( EntityRelationship( name="used-by", reverse_name="exploits", brand="Mandiant", entity_a=self.cve_id, entity_a_type="Indicator", entity_b=a.get("name", ""), entity_b_type="Threat Actor", ) ) for m in self.cve_data.get("associated_malware", []): relationships.append( EntityRelationship( name="used-by", reverse_name="exploits", brand="Mandiant", entity_a=self.cve_id, entity_a_type="Indicator", entity_b=m.get("name", ""), entity_b_type="Malware", ) ) return relationships def build_cpe_objects(self): return [Common.CPE(cpe.get("cpe", "")) for cpe in self.cve_data.get("vulnerable_cpes", [])] def calculate_cvss_version(self) -> str: if "v3.1" in self.cvss_data: return "v3.1" elif "v2.0" in self.cvss_data: return "v2.0" else: return "0.0" def build_exploitation_vectors(self): exploitation_vectors = self.cve_data.get("exploitation_vectors", []) if not exploitation_vectors: return "" return ", ".join(exploitation_vectors) def build_markdown(self) -> str: details_table_dict = { "Description": self.description, "Published": self.publish_date, "Last Modified": self.last_modified_date, "Risk Rating": self.risk_rating, "Exploitation Vectors": self.build_exploitation_vectors(), "Vulnerable Products": self.vulnerable_products, } markdown_sections = [f"## {self.cve_id}", self.executive_summary, tableToMarkdown("Details", details_table_dict)] return "\n\n".join(markdown_sections) def get_cvss_score(self): return str(self.cvss_data.get(self.cvss_version, {}).get("base_score", "0.0")) def get_cvss_vector(self) -> str: return self.cvss_data.get(self.cvss_version, {}).get("vector_string", "") def build_publications(self) -> List: publications = [] for r in self.cve_data.get("associated_reports", []): publications.append( Common.Publications( source="Mandiant", title=r.get("title", ""), link="{}/reports/{}".format(ADV_BASE_URL, r.get("report_id", "")), timestamp=r.get("published_date", ""), ) ) return publications def calculate_cve_dbot_score(self) -> int: try: score = float(self.cvss_score) except ValueError: return Common.DBotScore.NONE if not score: return Common.DBotScore.NONE elif score < 0 or score == 0.0: return Common.DBotScore.NONE elif 0.0 <= score <= 3.0: return Common.DBotScore.GOOD elif 4.0 <= score <= 7.0: return Common.DBotScore.SUSPICIOUS elif 8.0 <= score <= 10.0: return Common.DBotScore.BAD else: return Common.DBotScore.NONE def create_dbot_score(self) -> Common.DBotScore: return Common.DBotScore( indicator=self.cve_id, indicator_type=DBotScoreType.CVE, integration_name="Mandiant", reliability=self.reliability, score=self.calculate_cve_dbot_score(), ) def build_cve_object(self) -> Common.CVE: return Common.CVE( id=self.cve_id, cvss=self.cvss_score, published=self.publish_date, modified=self.last_modified_date, description=self.description, relationships=self.relationships, stix_id=self.cve_data.get("id", ""), cvss_version=self.cvss_version.replace("v", ""), cvss_vector=self.get_cvss_vector(), cvss_score=self.cvss_score, tags=", ".join(self.tags), traffic_light_protocol=self.tlp_color, publications=self.build_publications(), dbot_score=self.create_dbot_score(), vulnerable_products=self.cpe_objects, vulnerable_configurations=self.cpe_objects, ) def build_cve_command_result(self) -> CommandResults: return CommandResults( readable_output=self.build_markdown(), ignore_auto_extract=False, outputs_prefix="Mandiant.CVE", relationships=self.relationships, outputs=self.cve_data, indicator=self.build_cve_object(), ) class MatiCampaign: def __init__(self, client: MandiantClient, campaign_data: Dict) -> None: self.client = client self.campaign_data = campaign_data self.short_name = self.campaign_data.get("short_name", "") self.campaign_title = self.campaign_data.get("name", "") self.campaign_name = f"{self.campaign_title} ({self.short_name})" self.target_industries = self.build_target_industries() self.description = self.campaign_data.get("description", "") self.campaign_id = self.campaign_data.get("id", "") self.last_active = self.campaign_data.get("last_activity_time", "") def build_target_industries(self) -> List: return [i.get("name", "") for i in self.campaign_data.get("industries", [])] def build_markdown(self) -> str: return ( f"## {self.campaign_name}\n\n" + f"**Short Name:** {self.short_name} | **Last Active:** {self.last_active}\n\n" + f"{self.description}\n\n" + f"**Link:** {ADV_BASE_URL}/campaigns/{self.campaign_id}" ) def build_publications(self): publications = [] for r in self.client.get_associated_reports("campaign", self.campaign_id).get("reports", []): title = r.get("title", "") report_id = r.get("report_id", "") published = r.get("published_date") if not title or not report_id or not published: continue publications.append( Common.Publications( source="Mandiant", title=f"{title} ({report_id})", link=f"{ADV_BASE_URL}/reports/{report_id}", timestamp=published, ).to_context() ) return publications def build_relationships(self) -> List: relationships = [] for actor in self.campaign_data.get("actors", []): relationships.append( EntityRelationship( name="related-to", reverse_name="related-to", brand="Mandiant", entity_a=self.campaign_name, entity_a_type="Campaign", entity_b=actor.get("name"), entity_b_type="Campaign", ).to_indicator() ) for malware in self.campaign_data.get("malware", []): relationships.append( EntityRelationship( name="related-to", reverse_name="related-to", brand="Mandiant", entity_a=self.campaign_name, entity_a_type="Campaign", entity_b=malware.get("name"), entity_b_type="Campaign", ).to_indicator() ) return relationships def build_indicator(self) -> Dict: return { "value": self.campaign_name, "type": "Campaign", "rawJSON": self.campaign_data, "fields": { "Tags": self.target_industries, "Publications": self.build_publications(), "STIX ID": self.campaign_id, "Traffic Light Protocol": self.client.tlp_color, "Industry sectors": self.target_industries, }, "score": ThreatIntel.ObjectsScore.CAMPAIGN, "relationships": self.build_relationships(), } def build_campaign_command_result(self): return CommandResults( outputs=self.campaign_data, ignore_auto_extract=False, outputs_prefix="Mandiant.Campaign", readable_output=self.build_markdown(), tags=self.target_industries, ) def ip_reputation_command(client: MandiantClient, args: Dict) -> List: args = args if args else {} values_: list[str] = argToList(str(args.get("ip"))) output = [] for v in values_: api_response = client.get_indicators_by_value([v]) if not api_response: output.append(CommandResults(readable_output=f"{v} not found")) continue for i in api_response: output.append(MatiIpIndicator(client, i).build_indicator_command_result()) return output def domain_reputation_command(client: MandiantClient, args: Dict) -> List: args = args if args else {} values_: list[str] = argToList(str(args.get("domain"))) output = [] for v in values_: api_response = client.get_indicators_by_value([v]) if not api_response: output.append(CommandResults(readable_output=f"{v} not found")) continue for i in api_response: output.append(MatiDomainIndicator(client, i).build_indicator_command_result()) return output def url_reputation_command(client: MandiantClient, args: Dict) -> List: args = args if args else {} values_: list[str] = argToList(str(args.get("url"))) output = [] for v in values_: api_response = client.get_indicators_by_value([v]) if not api_response: output.append(CommandResults(readable_output=f"{v} not found")) continue for i in api_response: output.append(MatiUrlIndicator(client, i).build_indicator_command_result()) return output def file_reputation_command(client: MandiantClient, args: Dict) -> List: args = args if args else {} values_: list[str] = argToList(str(args.get("file"))) output = [] for v in values_: api_response = client.get_indicators_by_value([v]) if not api_response: output.append(CommandResults(readable_output=f"{v} not found")) continue for i in api_response: output.append(MatiFileIndicator(client, i, v).build_indicator_command_result()) return output def cve_reputation_command(client: MandiantClient, args: Dict) -> List: args = args if args else {} values_: list[str] = argToList(str(args.get("cve"))) output = [] for v in values_: cve = client.get_cve_by_cveid(v) if not cve: output.append(CommandResults(readable_output=f"{v} not found")) continue output.append(MatiCve(cve, client.reliability, client.tlp_color, client.tags).build_cve_command_result()) return output def fetch_threat_actor_command(client: MandiantClient, args: Dict) -> CommandResults: args = args if args else {} actor_name: str = args["actor_name"] actor_from_api = client.get_actor(actor_name) actor_from_api["value"] = actor_name actor_from_api["type"] = "Threat Actor" if not actor_from_api: return CommandResults(readable_output=f"{actor_name} not found") actor_client = MatiThreatActor(client, actor_from_api) demisto.createIndicators([actor_client.build_indicator()]) return actor_client.build_threat_actor_command_result() def fetch_malware_family_command(client: MandiantClient, args: Dict): args = args if args else {} malware_name: str = args["malware_name"] malware_from_api = client.get_malware(malware_name) malware_from_api["value"] = malware_name malware_from_api["type"] = "Malware" if not malware_from_api: return CommandResults(readable_output=f"{malware_name} not found") malware_client = MatiMalware(client, malware_from_api) demisto.createIndicators([malware_client.build_indicator()]) return malware_client.build_malware_command_result() def fetch_campaign_command(client: MandiantClient, args: Dict): args = args if args else {} campaign_id: str = args["campaign_id"] campaign_from_api = client.get_campaign(campaign_id) campaign_from_api["value"] = campaign_id campaign_from_api["type"] = "Campaign" if not campaign_from_api: return CommandResults(readable_output=f"{campaign_id} not found") campaign_client = MatiCampaign(client, campaign_from_api) demisto.createIndicators([campaign_client.build_indicator()]) return campaign_client.build_campaign_command_result() def module_test_command(client: MandiantClient) -> str: try: result = client.get_entitlements() if not result.get("entitlements"): raise Exception return "ok" except DemistoException as ex: raise DemistoException(str(ex)) def main() -> None: command = demisto.command() args = demisto.args() client = MandiantClient(demisto.params()) try: command_map: dict[str, Callable] = { "ip": ip_reputation_command, "domain": domain_reputation_command, "url": url_reputation_command, "file": file_reputation_command, "cve": cve_reputation_command, "mati-get-actor": fetch_threat_actor_command, "mati-get-malware": fetch_malware_family_command, "mati-get-campaign": fetch_campaign_command, } if command in command_map: return_results(command_map[command](client, args)) elif command == "test-module": return_results(module_test_command(client)) except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{str(e)}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()