MicrosoftDefenderThreatIntelligence
Use the Microsoft Defender Threat Intelligence integration to query enriched threat intelligence data such as articles, threat actor profiles, WHOIS records, and host-related infrastructure.
Data Enrichment & Threat Intelligence · MicrosoftDefenderThreatIntelligence
Details
| ID | MicrosoftDefenderThreatIntelligence |
|---|---|
| Provider | Microsoft |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.1.0 |
| Docker Image | demisto/crypto:1.0.0.10120494 |
| Supported Modules | Agentix XSIAM |
README
This integration requires Defender Threat Intelligence—premium version
Use the Microsoft Defender Threat Intelligence integration to query enriched threat intelligence data such as articles, threat actor profiles, WHOIS records, and host-related infrastructure.
Configure MicrosoftDefenderThreatIntelligence in Cortex
| Parameter | Description | Required |
|---|---|---|
| Application ID (Client ID for Client credentials mode) | False | |
| Tenant ID (required for Client Credentials mode) | False | |
| Client Secret (required for Client Credentials mode) | Client Secret. Required for Client Credentials mode) | False |
| Certificate Thumbprint | Used for certificate authentication. As appears in the “Certificates & secrets” page of the app. | False |
| Private Key | False | |
| Use Azure Managed Identities | Relevant only if the integration is running on Azure VM. If selected, authenticates based on the value provided for the Azure Managed Identities Client ID field. If no value is provided for the Azure Managed Identities Client ID field, authenticates based on the System Assigned Managed Identity. For additional information, see the Help tab. | False |
| Azure Managed Identities Client ID | The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. | False |
| Azure AD endpoint | Azure AD endpoint associated with a national cloud. | False |
| Incident type | False | |
| Use Client Credentials Authorization Flow | Use a self-deployed Azure application and authenticate using the Client Credentials flow. | False |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
msg-defender-threat-intel-auth-start
Run this command to start the authorization process and follow the instructions in the command results.
Base Command
msg-defender-threat-intel-auth-start
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
msg-defender-threat-intel-auth-complete
Run this command to complete the authorization process.\nShould be used after running the msg-defender-threat-intel-auth-start command.
Base Command
msg-defender-threat-intel-auth-complete
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
msg-defender-threat-intel-auth-test
Run this command to test if the authorization process is successful.
Base Command
msg-defender-threat-intel-auth-test
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
msg-defender-threat-intel-auth-reset
Run this command to reset the authorization process.
Base Command
msg-defender-threat-intel-auth-reset
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
msg-defender-threat-intel-article-list
Get articles including their properties and relationships.
Base Command
msg-defender-threat-intel-article-list
Input
| Argument Name | Description | Required |
|---|---|---|
| article_id | Article ID to retrieve specific article details. | Optional |
| limit | Number of incidents in the list. | Optional |
| odata | Use “odata” query to customize the response | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.Article.id | String | The unique identifier of the threat intelligence article. |
| MSGDefenderThreatIntel.Article.title | String | The title of the Microsoft Defender Threat Intelligence article. |
msg-defender-threat-intel-article-indicators-list
Get indicators of threat or compromise related to the contents of an article.
Base Command
msg-defender-threat-intel-article-indicators-list
Input
| Argument Name | Description | Required |
|---|---|---|
| article_id | The unique identifier of the article. | Optional |
| article_indicator_id | The unique identifier of a specific indicator within the article. | Optional |
| limit | Number of incidents in the list. | Optional |
| odata | Use “odata” query to customize the response | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.ArticleIndicator.id | String | The unique identifier of the indicator associated with the article. |
| MSGDefenderThreatIntel.ArticleIndicator.artifact.id | String | The unique identifier of the artifact (e.g., file, domain, IP) related to the indicator. |
msg-defender-threat-intel-profile-list
Get Intelligence Profiles including their properties and relationships.
Base Command
msg-defender-threat-intel-profile-list
Input
| Argument Name | Description | Required |
|---|---|---|
| intel_profile_id | The unique identifier of the intelligence profile. | Optional |
| limit | Number of incidents in the list. | Optional |
| odata | Use “odata” query to customize the response | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.Profile.id | unknown | The unique identifier of the threat actor profile. |
| MSGDefenderThreatIntel.Profile.title | String | The title or name of the threat actor profile. |
msg-defender-threat-intel-profile-indicators-list
Get Intelligence Profiles Indicators and their properties.
Base Command
msg-defender-threat-intel-profile-indicators-list
Input
| Argument Name | Description | Required |
|---|---|---|
| intel_profile_id | The unique identifier of the intelligence profile. | Optional |
| intel_profile_indicator_id | The unique identifier of a specific indicator related to an intelligence profile. | Optional |
| limit | Number of incidents in the list. | Optional |
| odata | Use “odata” query to customize the response | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.ProfileIndicator.id | unknown | The unique identifier of the indicator associated with the threat actor profile. |
| MSGDefenderThreatIntel.ProfileIndicator.artifact.id | String | The unique identifier of the artifact (e.g., IP address, domain, file hash) linked to the indicator. |
msg-defender-threat-intel-host
Read the properties and relationships of a host object.
Base Command
msg-defender-threat-intel-host
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | The unique identifier of the host. | Required |
| odata | Use “odata” query to customize the response | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.Host.id | unknown | The unique identifier of the host object in Microsoft Defender Threat Intelligence. |
| MSGDefenderThreatIntel.Host.registrar | String | The name of the domain registrar responsible for registering the host. |
| MSGDefenderThreatIntel.Host.registrant | String | The entity (person or organization) that registered the host domain. |
msg-defender-threat-intel-host-whois
Get the specified whoisRecord resource.
Base Command
msg-defender-threat-intel-host-whois
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | hostname or IP address. | Optional |
| whois_record_id | The unique identifier of a specific WHOIS record. | Optional |
| odata | Use “odata” query to customize the response. | Optional |
| limit | Number of records in the list. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.Whois.id | unknown | The unique identifier of the WHOIS record in Microsoft Defender Threat Intelligence. |
| MSGDefenderThreatIntel.Whois.whoisServer | String | The WHOIS server that provided the domain registration information. |
| MSGDefenderThreatIntel.Whois.domainStatus | String | The current status of the domain (e.g., active, clientHold, expired) as reported in the WHOIS record. |
msg-defender-threat-intel-host-whois-history
Get the history for a whoisRecord, as represented by a collection of whoisHistoryRecord resources.
Base Command
msg-defender-threat-intel-host-whois-history
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | hostname or IP address. | Optional |
| whois_record_id | The unique identifier of the WHOIS record whose history you want to retrieve. | Optional |
| odata | Use “odata” query to customize the response. | Optional |
| limit | Number of records in the list. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.WhoisHistory.id | unknown | The unique identifier of the historical WHOIS record. |
| MSGDefenderThreatIntel.WhoisHistory.whoisServer | String | The WHOIS server that provided the historical domain registration data. |
| MSGDefenderThreatIntel.WhoisHistory.domainStatus | String | The domain’s status at the time of the historical WHOIS record (e.g., clientTransferProhibited, inactive). |
msg-defender-threat-intel-host
Read the properties and relationships of a host object.
Base Command
msg-defender-threat-intel-host-reputation
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | The unique identifier of the host. | Required |
| odata | Use “odata” query to customize the response. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGDefenderThreatIntel.HostReputation.id | unknown | The unique identifier of the host object in Microsoft Defender Threat Intelligence. |
| MSGDefenderThreatIntel.HostReputation.classification | String | The reputation classification of the host (e.g., Malicious, Suspicious, Unknown). |
| MSGDefenderThreatIntel.HostReputation.score | String | TA numerical score representing the confidence or severity of the host’s reputation. |
Configuration parameters
app_id— Application ID (Client ID for Client Credentials mode)tenant_id— Tenant ID (required for Client Credentials mode)credentials—creds_certificate— Certificate Thumbprintuse_managed_identities— Use Azure Managed Identitiesmanaged_identities_client_id—azure_ad_endpoint— Azure AD endpointclient_credentials— Use Client Credentials Authorization Flowinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (12)
-
msg-defender-threat-intel-article-indicators-listGet indicators of threat or compromise related to the contents of an article.
-
msg-defender-threat-intel-article-listGet articles including their properties and relationships.
-
msg-defender-threat-intel-auth-completeCompletes the authorization process. Should be used after running the msg-defender-threat-intel-auth-start command.
-
msg-defender-threat-intel-auth-resetReruns the authentication process.
-
msg-defender-threat-intel-auth-startStarts the authorization process. Follow the instructions in the command results.
-
msg-defender-threat-intel-auth-testTests connectivity to Microsoft.
-
msg-defender-threat-intel-hostRead the properties and relationships of a host object.
-
msg-defender-threat-intel-host-reputationRetrieves the reputation details, properties, and related information for a specified host.
-
msg-defender-threat-intel-host-whoisGet the specified whoisRecord resource.
-
msg-defender-threat-intel-host-whois-historyGet the history for a whoisRecord, as represented by a collection of whoisHistoryRecord resources.
-
msg-defender-threat-intel-profile-indicators-listGet Intelligence Profiles Indicators and their properties.
-
msg-defender-threat-intel-profile-listGet Intelligence Profiles including their properties and relationships.
from typing import Any import demistomock as demisto import urllib3 from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import # from CommonServerUserPython import * # noqa from MicrosoftApiModule import * # noqa: E402 # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # ISO8601 format with UTC, default in XSOAR REQUIRED_PERMISSIONS = ( "offline_access", # allows device-flow login "ThreatIntelligence.Read.All", # Threat Intelligence specific permission ) """ CLIENT CLASS """ class Client: def __init__( self, app_id: str, verify: bool, proxy: bool, azure_ad_endpoint: str = "https://login.microsoftonline.com", client_credentials: bool = False, tenant_id: str = None, enc_key: str = None, managed_identities_client_id: Optional[str] = None, private_key: Optional[str] = None, certificate_thumbprint: Optional[str] = None, ): if app_id and "@" in app_id: app_id, refresh_token = app_id.split("@") integration_context = get_integration_context() integration_context["current_refresh_token"] = refresh_token set_integration_context(integration_context) elif client_credentials and (not enc_key and not (certificate_thumbprint and private_key)): raise DemistoException( "Either enc_key or (Certificate Thumbprint and Private Key) must be provided. For further " "information see " "https://xsoar.pan.dev/docs/reference/articles/microsoft-integrations---authentication" ) args = { "azure_ad_endpoint": azure_ad_endpoint, "self_deployed": True, "auth_id": app_id, "grant_type": CLIENT_CREDENTIALS if client_credentials else DEVICE_CODE, "base_url": "https://graph.microsoft.com", "verify": verify, "proxy": proxy, "tenant_id": tenant_id, "enc_key": enc_key, "managed_identities_client_id": managed_identities_client_id, "managed_identities_resource_uri": Resources.graph, "certificate_thumbprint": certificate_thumbprint, "private_key": private_key, "command_prefix": "msg-defender-threat-intel", } if not client_credentials: args["scope"] = " ".join(REQUIRED_PERMISSIONS) args["token_retrieval_url"] = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" self.ms_client = MicrosoftClient(**args) # type: ignore def article_list(self, article_id: str, odata: str, limit: int) -> list: """ Retrieve threat intelligence articles from Microsoft Defender. Docs: https://learn.microsoft.com/en-us/graph/api/security-threatintelligence-list-articles?view=graph-rest-1.0&tabs=http https://learn.microsoft.com/en-us/graph/api/security-article-get?view=graph-rest-1.0&tabs=http Args: article_id (str): Specific article ID to retrieve. If empty, retrieves all articles. odata (str): Additional OData query parameters for filtering and sorting. limit (int): Maximum number of articles to return. Returns: list: List of article objects. If article_id is provided, returns a single article in a list format. If article_id is empty, returns multiple articles from the 'value' field of the response. """ odata_query = "" if not article_id: odata_query = f"?$top={limit}&{odata}" response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/articles{odata_query}", ) return response.get("value", []) if odata: odata_query += f"?{odata}" return [ self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/articles/{article_id}{odata_query}", ) ] def article_indicator_list(self, article_id: str, article_indicator_id: str, odata: str, limit: int) -> list: """ Retrieve threat intelligence indicators from Microsoft Defender. Docs: https://learn.microsoft.com/en-us/graph/api/security-articleindicator-get?view=graph-rest-1.0&tabs=http https://learn.microsoft.com/en-us/graph/api/security-article-list-indicators?view=graph-rest-1.0&tabs=http Args: article_id (str): The ID of the article to retrieve indicators from. article_indicator_id (str): The specific indicator ID to retrieve. odata (str): Additional OData query parameters for filtering and sorting. limit (int): Maximum number of indicators to return. Returns: list: List of article indicator objects from the 'value' field of the response. """ odata_query = "" if not article_id: if odata: odata_query += f"?{odata}" return [ self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/articleIndicators/{article_indicator_id}{odata_query}", ) ] odata_query = f"?$top={limit}&{odata}" response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/articles/{article_id}/indicators{odata_query}", ) return response.get("value", []) def profile_list(self, intel_profile_id: str, odata: str, limit: int) -> list: """ Retrieve threat intelligence profiles from Microsoft Defender. Docs: https://learn.microsoft.com/en-us/graph/api/security-threatintelligence-list-intelprofiles?view=graph-rest-1.0&tabs=http https://learn.microsoft.com/en-us/graph/api/security-intelligenceprofile-get?view=graph-rest-1.0&tabs=http Args: intel_profile_id (str): The ID of the specific intelligence profile to retrieve. odata (str): Additional OData query parameters for filtering and sorting. limit (int): Maximum number of profiles to return. Returns: list: List of intelligence profile objects from the 'value' field of the response. """ odata_query = "" if intel_profile_id: if odata: odata_query += f"?{odata}" return [ self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/intelProfiles/{intel_profile_id}{odata_query}", ) ] odata_query = f"?$top={limit}&{odata}" response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/intelProfiles{odata_query}", ) return response.get("value", []) def profile_indicators_list(self, intel_profile_id: str, intel_profile_indicator_id: str, odata: str, limit: int) -> list: """ Retrieve intelligence profile indicators. Docs: https://learn.microsoft.com/en-us/graph/api/security-intelligenceprofileindicator-get?view=graph-rest-1.0&tabs=http https://learn.microsoft.com/en-us/graph/api/security-intelligenceprofile-list-indicators?view=graph-rest-1.0&tabs=http Args: intel_profile_id (str): The ID of the intelligence profile. intel_profile_indicator_id (str): The ID of a specific intelligence profile indicator. odata (str): OData query parameters for filtering and formatting the response. limit (int): Maximum number of indicators to return. Returns: list: A list of intelligence profile indicators, each containing information such as ID, source, first/last seen timestamps, and associated artifacts. """ odata_query = "" if not intel_profile_indicator_id: odata_query = f"?$top={limit}&{odata}" response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/intelProfiles/{intel_profile_id}/indicators{odata_query}", ) return response.get("value", []) if odata: odata_query += f"?{odata}" return [ self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/intelligenceProfileIndicators/{intel_profile_indicator_id}{odata_query}", ) ] def host(self, host_id: str, odata: str) -> dict: """ Retrieve host information by host ID. Docs: https://learn.microsoft.com/en-us/graph/api/security-host-get?view=graph-rest-1.0&tabs=http Args: host_id (str): The ID (host name or ip address) of the host to retrieve information for. odata (str): OData query parameters for filtering and formatting the response. Returns: dict: A dictionary containing host information including ID, first/last seen timestamps, registrar, and registrant details. """ odata_query = f"?{odata}" if odata else "" return self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/hosts/{host_id}{odata_query}", ) def host_whois(self, host_id: str, whois_record_id: str, odata: str) -> dict: """ Retrieve WHOIS record information for a host or specific WHOIS record. Docs: https://learn.microsoft.com/en-us/graph/api/security-whoisrecord-get?view=graph-rest-1.0&tabs=http Args: host_id (str): The ID (host name or ip address) of the host to retrieve WHOIS information for. whois_record_id (str): The specific WHOIS record ID to retrieve. odata (str): OData query parameters for filtering and formatting the response. Returns: dict: A dictionary containing WHOIS record information including registration details, contact information (admin, technical, registrant), nameservers, and timestamps. """ odata_query = f"?{odata}" if odata else "" if host_id: return self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/hosts/{host_id}/whois{odata_query}", ) return self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/whoisRecords/{whois_record_id}{odata_query}", ) def host_whois_history(self, host_id: str, whois_record_id: str, odata: str, limit: str) -> list: """ Retrieves WHOIS history records for a host or specific WHOIS record. Docs: https://learn.microsoft.com/en-us/graph/api/security-whoisrecord-list-history?view=graph-rest-1.0&tabs=http https://learn.microsoft.com/en-us/graph/api/security-whoishistoryrecord-get?view=graph-rest-1.0 Args: host_id (str): The ID (host name or ip address) of the host to get WHOIS history for. whois_record_id (str): The ID of a specific WHOIS record to get history for. odata (str): OData query parameters for filtering and formatting results. limit (str): Maximum number of records to return (used when whois_history_record_id is not provided). Returns: list: A list of WHOIS history records containing registration details, contact information, nameservers, and other domain registration data. """ odata_query = f"?$top={limit}&{odata}" if host_id: response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/hosts/{host_id}/whois/history{odata_query}", ) return response.get("value", []) response = self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/whoisRecords/{whois_record_id}/history{odata_query}", ) return response.get("value", []) def host_reputation(self, host_id: str, odata: str) -> dict: """ Retrieve host reputation information by host ID. Docs: https://learn.microsoft.com/en-us/graph/api/security-host-get-reputation?view=graph-rest-1.0&tabs=http Args: host_id (str): The ID (host name or ip address) of the host to retrieve reputation information for. odata (str): OData query parameters for filtering and formatting the response. Returns: dict: A dictionary containing host reputation information including reputation score, classification, rules, and other reputation-related details. """ odata_query = f"?{odata}" if odata else "" return self.ms_client.http_request( method="GET", url_suffix=f"v1.0/security/threatIntelligence/hosts/{host_id}/reputation{odata_query}", ) """ HELPER FUNCTIONS """ def ensure_only_one_argument_provided(**kwargs): """ Ensures that exactly one of the provided keyword arguments has a non-empty value. Raises: ValueError: If none or more than one arguments are provided. """ provided_keys = [key for key, value in kwargs.items() if value] total_provided = len(provided_keys) allowed_keys = ", ".join(kwargs.keys()) if total_provided == 0: raise ValueError(f"You must provide one of the following arguments: {allowed_keys}.\nNone were provided.") elif total_provided > 1: raise ValueError( f"Only one of the following arguments should be provided: {allowed_keys}.\n" f"Currently provided: {', '.join(provided_keys)}." ) """ COMMAND FUNCTIONS """ def start_auth(client: Client) -> CommandResults: # pragma: no cover """ Initiates the authentication process for Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for authentication. Returns: CommandResults: Command results containing the authentication start response. """ result = client.ms_client.start_auth("!msg-defender-threat-intel-auth-complete") return CommandResults(readable_output=result) def complete_auth(client: Client) -> str: # pragma: no cover """ Completes the authentication process for Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for authentication. Returns: str: Success message indicating that authorization was completed successfully. """ client.ms_client.get_access_token() return "✅ Authorization completed successfully." def test_connection(client: Client) -> str: # pragma: no cover """ Tests the connection to Microsoft Defender Threat Intelligence by attempting to retrieve an access token. Args: client (Client): The client instance used for connection testing. Returns: str: Success message indicating that the connection test passed. """ client.ms_client.get_access_token() return "✅ Success!" def article_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves a list of articles from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - article_id (str, optional): Specific article ID to retrieve. - odata (str, optional): OData query parameters for filtering. - limit (int, optional): Maximum number of articles to return. Defaults to 50. Returns: CommandResults: Command results containing the list of articles with ID and title information. """ article_id = args.get("article_id", "") odata = args.get("odata", "") limit = args.get("limit", 50) response = client.article_list(article_id, odata, limit) if len(response) == 0: return CommandResults(readable_output="No articles were found.") display_data = [{"Article Id": article.get("id"), "Title": article.get("title")} for article in response] return CommandResults( "MSGDefenderThreatIntel.Article", "id", outputs=response, readable_output=tableToMarkdown( "Articles:", display_data, removeNull=True, ), ) def article_indicators_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves a list of indicators associated with articles from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - article_id (str, optional): Specific article ID to retrieve indicators for. - article_indicator_id (str, optional): Specific article indicator ID to retrieve. - odata (str, optional): OData query parameters for filtering. - limit (int, optional): Maximum number of indicators to return. Defaults to 50. Returns: CommandResults: Command results containing the list of article indicators with ID and artifact ID information. """ article_id = args.get("article_id", "") article_indicator_id = args.get("article_indicator_id", "") odata = args.get("odata", "") limit = args.get("limit", 50) ensure_only_one_argument_provided(article_id=article_id, article_indicator_id=article_indicator_id) response = client.article_indicator_list(article_id, article_indicator_id, odata, limit) if len(response) == 0: return CommandResults(readable_output="No article indicators were found.") display_data = [ { "ID": indicator.get("id"), "Artifact Id": indicator.get("artifact").get("id") if isinstance(indicator.get("artifact"), dict) else None, } for indicator in response ] return CommandResults( "MSGDefenderThreatIntel.ArticleIndicator", "id", outputs=response, readable_output=tableToMarkdown( "Indicators:", display_data, removeNull=True, ), ) def profile_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves a list of intelligence profiles from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - intel_profile_id (str, optional): Specific intelligence profile ID to retrieve. - odata (str, optional): OData query parameters for filtering. - limit (int, optional): Maximum number of profiles to return. Defaults to 50. Returns: CommandResults: Command results containing the list of intelligence profiles with ID and title information. """ intel_profile_id = args.get("intel_profile_id", "") odata = args.get("odata", "") limit = args.get("limit", 50) response = client.profile_list(intel_profile_id, odata, limit) if len(response) == 0: return CommandResults(readable_output="No profiles were found.") display_data = [{"Profile ID": profile.get("id"), "Title": profile.get("title")} for profile in response] return CommandResults( "MSGDefenderThreatIntel.Profile", "id", outputs=response, readable_output=tableToMarkdown( "Profiles:", display_data, removeNull=True, ), ) def profile_indicators_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves a list of intelligence profile indicators from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - intel_profile_id (str, optional): Specific intelligence profile ID to retrieve indicators for. - intel_profile_indicator_id (str, optional): Specific intelligence profile indicator ID to retrieve. - odata (str, optional): OData query parameters for filtering. - limit (int, optional): Maximum number of profile indicators to return. Defaults to 50. Returns: CommandResults: Command results containing the list of intelligence profile indicators with ID and artifact ID information. """ intel_profile_id = args.get("intel_profile_id", "") intel_profile_indicator_id = args.get("intel_profile_indicator_id", "") odata = args.get("odata", "") limit = args.get("limit", 50) ensure_only_one_argument_provided(intel_profile_id=intel_profile_id, intel_profile_indicator_id=intel_profile_indicator_id) response = client.profile_indicators_list(intel_profile_id, intel_profile_indicator_id, odata, limit) if len(response) == 0: return CommandResults(readable_output="No profile indicators were found.") display_data = [ { "ID": profileIndicator.get("id"), "Artifact Id": profileIndicator.get("artifact").get("id") if isinstance(profileIndicator.get("artifact"), dict) else None, } for profileIndicator in response ] return CommandResults( "MSGDefenderThreatIntel.ProfileIndicator", "id", outputs=response, readable_output=tableToMarkdown( "Profiles Indicators:", display_data, removeNull=True, ), ) def host_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves host information from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - host_id (str, required): Specific host ID to retrieve information for. - odata (str, optional): OData query parameters for filtering. Returns: CommandResults: Command results containing the host information with ID, registrar, and registrant details. """ host_id = args.get("host_id", "") odata = args.get("odata", "") response = client.host(host_id, odata) display_data = [ { "Host Id": response.get("id"), "Host Registrar": response.get("registrar"), "Host Registrant": response.get("registrant"), } ] return CommandResults( "MSGDefenderThreatIntel.Host", "id", outputs=response, readable_output=tableToMarkdown( "Host:", display_data, removeNull=True, ), ) def host_whois_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves WHOIS record information for a host from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - host_id (str, optional): Specific host ID to retrieve WHOIS information for. - whois_record_id (str, optional): Specific WHOIS record ID to retrieve. - odata (str, optional): OData query parameters for filtering. Returns: CommandResults: Command results containing the WHOIS record information with ID, WHOIS server, and domain status details. """ host_id = args.get("host_id", "") whois_record_id = args.get("whois_record_id", "") odata = args.get("odata", "") ensure_only_one_argument_provided(host_id=host_id, whois_record_id=whois_record_id) response = client.host_whois(host_id, whois_record_id, odata) display_data = [ {"Id": response.get("id"), "Whois Server": response.get("whoisServer"), "Domain Status": response.get("domainStatus")} ] return CommandResults( "MSGDefenderThreatIntel.Whois", "id", outputs=response, readable_output=tableToMarkdown( "Whois:", display_data, removeNull=True, ), ) def host_whois_history_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves WHOIS history records for a host from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - host_id (str, optional): Specific host ID to retrieve WHOIS history for. - whois_record_id (str, optional): Specific WHOIS record ID to retrieve history for. - odata (str, optional): OData query parameters for filtering. - limit (int, optional): Maximum number of records to return. Defaults to 50. Returns: CommandResults: Command results containing the WHOIS history records with ID, WHOIS server, and domain status details. """ host_id = args.get("host_id", "") whois_record_id = args.get("whois_record_id", "") odata = args.get("odata", "") limit = args.get("limit", 50) ensure_only_one_argument_provided(host_id=host_id, whois_record_id=whois_record_id) response = client.host_whois_history(host_id, whois_record_id, odata, limit) if len(response) == 0: return CommandResults(readable_output="No WHOIS history records found.") display_data = [ { "Id": whois_record.get("id"), "Whois Server": whois_record.get("whoisServer"), "Domain Status": whois_record.get("domainStatus"), } for whois_record in response ] return CommandResults( "MSGDefenderThreatIntel.WhoisHistory", "id", outputs=response, readable_output=tableToMarkdown( "Whois:", display_data, removeNull=True, ), ) def host_reputation_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Retrieves host reputation information from Microsoft Defender Threat Intelligence. Args: client (Client): The client instance used for API communication. args (dict[str, Any]): Command arguments containing: - host_id (str, required): Specific host ID to retrieve reputation information for. - odata (str, optional): OData query parameters for filtering. Returns: CommandResults: Command results containing the host reputation information with ID, classification, and score details. """ host_id = args.get("host_id", "") odata = args.get("odata", "") response = client.host_reputation(host_id, odata) display_data = [ { "Host Id": response.get("id"), "Host Classification": response.get("classification"), "Host Score": response.get("score"), } ] return CommandResults( "MSGDefenderThreatIntel.HostReputation", "id", outputs=response, readable_output=tableToMarkdown( "Host Reputation:", display_data, removeNull=True, ), ) def main(): command = demisto.command() demisto.debug(f"Command being called is {command}") try: params = demisto.params() args = demisto.args() handle_proxy() client = Client( app_id=params.get("app_id"), verify=not params.get("insecure", False), proxy=params.get("proxy", False), azure_ad_endpoint=params.get("azure_ad_endpoint", "https://login.microsoftonline.com") or "https://login.microsoftonline.com", tenant_id=params.get("tenant_id"), client_credentials=params.get("client_credentials", False), enc_key=(params.get("credentials") or {}).get("password"), managed_identities_client_id=get_azure_managed_identities_client_id(params), certificate_thumbprint=params.get("creds_certificate", {}).get("identifier"), private_key=(replace_spaces_in_credential(params.get("creds_certificate", {}).get("password"))), ) if command == "test-module": if client.ms_client.managed_identities_client_id or client.ms_client.grant_type == CLIENT_CREDENTIALS: test_connection(client=client) return_results("ok") else: return_results("The test module is not functional, run the msg-defender-threat-intel-auth-start command instead.") elif command == "msg-defender-threat-intel-auth-start": return_results(start_auth(client)) elif command == "msg-defender-threat-intel-auth-complete": return_results(complete_auth(client)) elif command == "msg-defender-threat-intel-auth-test": return_results(test_connection(client)) elif command == "msg-defender-threat-intel-auth-reset": return_results(reset_auth()) elif command == "msg-defender-threat-intel-article-list": return_results(article_list_command(client, args)) elif command == "msg-defender-threat-intel-article-indicators-list": return_results(article_indicators_list_command(client, args)) elif command == "msg-defender-threat-intel-profile-list": return_results(profile_list_command(client, args)) elif command == "msg-defender-threat-intel-profile-indicators-list": return_results(profile_indicators_list_command(client, args)) elif command == "msg-defender-threat-intel-host": return_results(host_command(client, args)) elif command == "msg-defender-threat-intel-host-whois": return_results(host_whois_command(client, args)) elif command == "msg-defender-threat-intel-host-whois-history": return_results(host_whois_history_command(client, args)) elif command == "msg-defender-threat-intel-host-reputation": return_results(host_reputation_command(client, args)) else: raise NotImplementedError(f"Command {command} is not implemented") except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{str(e)}") if __name__ in ("__main__", "__builtin__", "builtins"): # pragma: no cover main()