iDefense_v2 Deprecated
Deprecated. Use Accenture CTI v2 instead.
Data Enrichment & Threat Intelligence · Accenture CTI (Deprecated)
Details
| ID | iDefense_v2 |
|---|---|
| Provider | Accenture |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.10.1.25933 |
| Supported Modules | Agentix |
README
Accenture CTI provides intelligence regarding security threats and vulnerabilities.
This integration was integrated and tested with version v2.58.0 of ACTI
Configure Accenture CTI in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | URL | True |
| api_token | API Token | True |
| Source Reliability | Reliability of the source providing the intelligence data. | B - Usually reliable |
| insecure | Trust any certificate (not secure) | False |
| use_proxy | 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.
ip
Checks the reputation of the given IP address.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | IP address to check. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| IP.Address | String | The IP address that was checked. |
| IP.Malicious.Vendor | String | For malicious IP addresses, the vendor that made the decision. |
| IP.Malicious.Description | String | For malicious IP addresses, the reason the vendor made that decision. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor that was used to calculate the score. |
| DBotScore.Score | String | The actual score. |
Command Example
!ip ip=0.0.0.0
Context Example
{
"DBotScore": {
"Indicator": "0.0.0.0",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "ip",
"Vendor": "iDefense_v2"
},
"IP": {
"Address": "0.0.0.0"
}
}
Human Readable Output
Results
Confidence DbotReputation LastPublished Name ThreatTypes TypeOfUse 0 2 2018-04-25 14:20:30 0.0.0.0 Cyber Espionage MALWARE_DOWNLOAD,
MALWARE_C2
domain
Checks the reputation of the given domain.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The domain to check. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Domain.Name | String | The name of the domain that was checked. |
| Domain.Malicious.Vendor | String | For malicious domains, the vendor that made the decision. |
| Domain.Malicious.Description | String | For malicious domains, the reason the vendor made that decision. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
Command Example
!domain domain=example.org
Context Example
{
"DBotScore": {
"Indicator": "example.org",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "domain",
"Vendor": "iDefense_v2"
},
"Domain": {
"Name": "example.org"
}
}
Human Readable Output
Results
Confidence DbotReputation LastPublished Name ThreatTypes TypeOfUse 50 2 2019-09-18 15:56:49 example.org Cyber Crime MALWARE_C2
url
Checks the reputation of the given URL.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | The URL to check (must start with “http://”). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| URL.Data | String | The URL that was checked. |
| URL.Malicious.Vendor | String | For malicious URLs, the vendor that made the decision. |
| URL.Malicious.Description | String | For malicious URLs, the reason the vendor made that decision. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
Command Example
!url url=http://example.com
Context Example
{
"DBotScore": {
"Indicator": "http://example.com",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "url",
"Vendor": "iDefense_v2"
},
"URL": {
"Data": "http://example.com"
}
}
Human Readable Output
Results
Confidence DbotReputation LastPublished Name ThreatTypes TypeOfUse 50 2 2020-09-16 20:29:35 http://example.com Cyber Crime MALWARE_C2
idefense-get-ioc-by-uuid
Get specific indicator reputation
Base Command
idefense-get-ioc-by-uuid
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | Unique User ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IP.Address | String | The IP address. |
| IP.Malicious.Vendor | String | For malicious IP addresses, the vendor that made the decision. |
| IP.Malicious.Description | String | For malicious IP addresses, the reason the vendor made that decision. |
| Domain.Name | String | The domain name. |
| Domain.Malicious.Vendor | String | For malicious domains, the vendor that made the decision. |
| Domain.Malicious.Description | String | For malicious domains, the reason the vendor made that decision. |
| URL.Data | String | The URL. |
| URL.Malicious.Vendor | String | For malicious URLs, the vendor that made the decision. |
| URL.Malicious.Description | String | For malicious URLs, the reason the vendor made that decision. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
Command Example
!idefense-get-ioc-by-uuid uuid=xxxx
Context Example
{
"DBotScore": {
"Indicator": "example.org",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "domain",
"Vendor": "iDefense_v2"
},
"Domain": {
"Name": "example.org"
}
}
Human Readable Output
Results
Confidence DbotReputation LastPublished Name ThreatTypes TypeOfUse 0 2 2017-01-11 20:56:22 example.org Cyber Espionage MALWARE_C2
Configuration parameters
url— URL (required)api_token— (required)integrationReliability— Source Reliability (required)insecure— Trust any certificate (not secure)use_proxy— Use system proxy settings
Commands (4)
-
domainChecks the reputation of the given domain.
-
idefense-get-ioc-by-uuidGet specific indicator reputation
-
ipChecks the reputation of the given IP address.
-
urlChecks the reputation of the given URL.
import urllib3 from CommonServerPython import * # Disable insecure warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) '''CONSTANTS''' DATE_FORMAT = '%Y-%m-%d %H:%M:%S' IDEFENSE_URL_TEMPLATE = "https://intelgraph.idefense.com/#/node/{0}/view/{1}" ENDPOINTS = { 'threatindicator': '/rest/threatindicator', 'document': '/rest/document', 'fundamental': '/rest/fundamental/v0' } class Client(BaseClient): def __init__(self, input_url: str, api_key: str, verify_certificate: bool, proxy: bool, endpoint="/rest/threatindicator/v0"): base_url = urljoin(input_url, endpoint) headers = { "Content-Type": "application/json", 'auth-token': api_key } super(Client, self).__init__(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) def threat_indicator_search(self, url_suffix: str, data: dict = {}) -> dict: return self._http_request(method='GET', url_suffix=url_suffix, params=data) def _validate_args(indicator_type: str, values: list) -> None: """ Args: indicator_type: IP or URL values: list of values Returns: Raise error if value do not match to his corresponding regex """ for value in values: if indicator_type == 'IP': if not re.match(ipv4Regex, value): raise DemistoException("Received wrong IP value. Please check values again.") elif indicator_type == 'URL': if not re.match(urlRegex, value): raise DemistoException("Received wrong URL value. Please check values again.") def _calculate_dbot_score(severity: int) -> int: """ Calculates Dbot score according to table: Dbot Score | severity 0 | 0 1 | 1,2 2 | 3,4 3 | 5,6,7 Args: severity: value from 1 to 5, determined by iDefense threat indicator Returns: Calculated score """ dbot_score = Common.DBotScore.NONE if severity > 4: dbot_score = Common.DBotScore.BAD elif severity > 2: dbot_score = Common.DBotScore.SUSPICIOUS elif severity > 0: dbot_score = Common.DBotScore.GOOD return dbot_score def _extract_analysis_info(res: dict, dbot_score_type: str, reliability: DBotScoreReliability) -> List[dict]: """ Extract context data from http-response and create corresponding DBotScore. If response is empty, return empty context and a none for DBotScore object Args: res: response from http request indicator_value: value of indicator given as calling the command dbot_score_type: DBotScoreType Returns: analysis_info: dictionary contains the indicator details returned dbot: DBotScore regarding the specific indicator """ analysis_results = [] if res.get('total_size'): results_array = res.get('results', []) if len(results_array): for result_content in results_array: indicator_value = result_content.get('key', '') dbot_score: int = _calculate_dbot_score(result_content.get('severity', 0)) desc = 'Match found in iDefense database' dbot = Common.DBotScore(indicator_value, dbot_score_type, 'iDefense', dbot_score, desc, reliability) last_published = result_content.get('last_published', '') last_published_format = parse_date_string(last_published, DATE_FORMAT) last_seen = result_content.get('last_seen', '') last_seen_format = parse_date_string(last_seen, DATE_FORMAT) analysis_info = { 'Name': result_content.get('display_text', ''), 'DbotReputation': dbot_score, 'Confidence': result_content.get('confidence', 0), 'ThreatTypes': result_content.get('threat_types', ''), 'TypeOfUse': result_content.get('last_seen_as', ''), 'LastPublished': str(last_published_format), 'LastSeen': str(last_seen_format) } analysis_results.append({'analysis_info': analysis_info, 'dbot': dbot}) return analysis_results def _check_returned_results(res: dict) -> List[str]: """ Checks which indicator value founded on iDefense database. Args: res: api response Returns: list of indicator values that returned from api request """ returned_values = [] if res.get('total_size'): results_array = res.get('results', []) if len(results_array): for result_content in results_array: returned_values.append(result_content.get('key', '')) return returned_values def _check_no_match_values(all_inputs: list, res: list) -> List[str]: """ Args: all_inputs: all indicator values received from the user res: list of all indicator values that returned from api request Returns: Which indicator has no match on iDefense database """ complete_values = [] for val in all_inputs: if val not in res: complete_values.append(val) return complete_values def test_module(client: Client) -> str: """ Perform basic request to check if the connection to service was successful Args: client: iDefense client Returns: 'ok' if the response is ok, else will raise an error """ try: client.threat_indicator_search(url_suffix='/v0') return 'ok' except Exception as e: raise DemistoException(f"Error in API call - check the input parameters and the API Key. Error: {e}.") def ip_command(client: Client, args: dict, reliability: DBotScoreReliability, doc_search_client: Client) -> List[CommandResults]: """ Args: client: iDefense client args: arguments obtained with the command representing the indicator value to search reliability: reliability of the source Returns: CommandResults containing the indicator, the response and a readable output """ ips: list = argToList(args.get('ip')) _validate_args("IP", ips) res = client.threat_indicator_search(url_suffix='/v0/ip', data={'key.values': ips}) analysis_results = _extract_analysis_info(res, DBotScoreType.IP, reliability) returned_ips = _check_returned_results(res) no_match_values = _check_no_match_values(ips, returned_ips) command_results = [] for analysis_result in analysis_results: analysis_info: dict = analysis_result.get('analysis_info', {}) analysis_info = _enrich_analysis_result_with_intelligence(analysis_info, doc_search_client) dbot = analysis_result.get('dbot') readable_output = tableToMarkdown('Results', analysis_info) indicator = Common.IP(analysis_info.get('Name', ''), dbot) command_results.append(CommandResults(indicator=indicator, raw_response=res, readable_output=readable_output)) for val in no_match_values: desc = "No results were found on iDefense database" dbot = Common.DBotScore(val, DBotScoreType.IP, 'iDefense', 0, desc) indicator = Common.IP(val, dbot) readable_output = f"No results were found for ip {val}" command_results.append(CommandResults(indicator=indicator, readable_output=readable_output)) return command_results def url_command(client: Client, args: dict, reliability: DBotScoreReliability, doc_search_client: Client) -> List[CommandResults]: urls: list = argToList(args.get('url')) _validate_args("URL", urls) res = client.threat_indicator_search(url_suffix='/v0/url', data={'key.values': urls}) analysis_results = _extract_analysis_info(res, DBotScoreType.URL, reliability) returned_urls = _check_returned_results(res) no_match_values = _check_no_match_values(urls, returned_urls) command_results = [] for analysis_result in analysis_results: analysis_info: dict = analysis_result.get('analysis_info', {}) analysis_info = _enrich_analysis_result_with_intelligence(analysis_info, doc_search_client) dbot = analysis_result.get('dbot') readable_output = tableToMarkdown('Results', analysis_info) indicator = Common.URL(analysis_info.get('Name', ''), dbot) command_results.append(CommandResults(indicator=indicator, raw_response=res, readable_output=readable_output)) for val in no_match_values: desc = "No results were found" dbot = Common.DBotScore(val, DBotScoreType.URL, 'iDefense', 0, desc, reliability) indicator = Common.URL(val, dbot) readable_output = f"No results were found for url {val}" command_results.append(CommandResults(indicator=indicator, readable_output=readable_output)) return command_results def domain_command(client: Client, args: dict, reliability: DBotScoreReliability, doc_search_client) -> List[CommandResults]: domains: list = argToList(args.get('domain')) res = client.threat_indicator_search(url_suffix='/v0/domain', data={'key.values': domains}) analysis_results = _extract_analysis_info(res, DBotScoreType.DOMAIN, reliability) returned_domains = _check_returned_results(res) no_match_values = _check_no_match_values(domains, returned_domains) command_results = [] for analysis_result in analysis_results: analysis_info: dict = analysis_result.get('analysis_info', {}) analysis_info = _enrich_analysis_result_with_intelligence(analysis_info, doc_search_client) dbot = analysis_result.get('dbot') readable_output = tableToMarkdown('Results', analysis_info) indicator = Common.Domain(analysis_info.get('Name', ''), dbot) command_results.append(CommandResults(indicator=indicator, raw_response=res, readable_output=readable_output)) for val in no_match_values: desc = "No results were found" dbot = Common.DBotScore(val, DBotScoreType.DOMAIN, 'iDefense', 0, desc, reliability) indicator = Common.Domain(val, dbot) readable_output = f"No results were found for Domain {val}" command_results.append(CommandResults(indicator=indicator, readable_output=readable_output)) return command_results def uuid_command(client: Client, args: dict, reliability: DBotScoreReliability, doc_search_client: Client) -> CommandResults: """ Search for indicator with the given uuid. When response return, checks which indicator found. Args: client: iDefense client args: arguments obtained with the command representing the value to search Returns: CommandResults containing the indicator, the response and a readable output """ uuid: str = str(args.get('uuid')) res = {} try: res = client.threat_indicator_search(url_suffix=f'/v0/{uuid}') except Exception as e: if 'Failed to parse json object from response' in e.args[0]: return_results(CommandResults(indicator=None, raw_response={}, readable_output=f"No results were found for uuid: {uuid}")) else: raise e indicator: Optional[Union[Common.IP, Common.Domain, Common.URL]] = None analysis_info = {} if len(res): dbot_score = _calculate_dbot_score(res.get('severity', 0)) desc = 'Match found in IDefense database' indicator_value = res.get('key', '') indicator_type = res.get('type', '') # Create indicator by the uuid type returned if indicator_type.lower() == 'ip': dbot = Common.DBotScore(indicator_value, DBotScoreType.IP, 'iDefense', dbot_score, desc, reliability) indicator = Common.IP(indicator_value, dbot) elif indicator_type.lower() == 'domain': dbot = Common.DBotScore(indicator_value, DBotScoreType.DOMAIN, 'iDefense', dbot_score, desc, reliability) indicator = Common.Domain(indicator_value, dbot) elif indicator_type.lower() == 'url': dbot = Common.DBotScore(indicator_value, DBotScoreType.URL, 'iDefense', dbot_score, desc, reliability) indicator = Common.URL(indicator_value, dbot) last_published = res.get('last_published', '') last_published_format = parse_date_string(last_published, DATE_FORMAT) last_seen = res.get('last_seen', '') last_seen_format = parse_date_string(last_seen, DATE_FORMAT) analysis_info = { 'Name': res.get('display_text', ''), 'DbotReputation': dbot_score, 'Confidence': res.get('confidence', 0), 'ThreatTypes': res.get('threat_types', ''), 'TypeOfUse': res.get('last_seen_as', ''), 'LastPublished': str(last_published_format), 'LastSeen': str(last_seen_format) } analysis_info = _enrich_analysis_result_with_intelligence(analysis_info, doc_search_client) return CommandResults(indicator=indicator, raw_response=res, readable_output=tableToMarkdown('Results', analysis_info)) def _enrich_analysis_result_with_intelligence(analysis_info, doc_search_client, indicatorTypeHash: bool = False): """ Adds Intelligence reports and Intelligence alerts information to analysis result for the indicator using given doc search client # noqa: E501 Args: analysis_result obtained from _extract_analysis_info function call client: ACTI Document search contoller client Returns: analysis_result enriched with intelligence alert and intelligence report information if available for the indicator """ indicator = analysis_info['MD5'] if indicatorTypeHash else analysis_info['Name'] demisto.debug(f"getting ia for indicator {indicator}") alerts, reports = _get_ia_for_indicator(indicator, doc_search_client) if alerts is not None: analysis_info['Intelligence Alerts'] = alerts if len( alerts) > 0 else 'No Intelligence Alert has been linked to this indicator' if reports is not None: analysis_info['Intelligence Reports'] = reports if len( reports) > 0 else 'No Intelligence Report has been linked to this indicator' return analysis_info def _get_ia_for_indicator(indicator: str, doc_search_client: Client): """ Perform document controller api call with given doc search client to get Intelligence Alerts and Intelligence Reports for given indicator Args: client: ACTI Document search contoller client Returns: intelligence alert and intelligence report dictionaries if api has response else None """ res = {} intelligence_alerts, intelligence_reports = None, None try: res = doc_search_client.threat_indicator_search( url_suffix='/v0', data={'type.values': ['intelligence_alert', 'intelligence_report'], 'links.display_text.query': indicator}) # noqa: E501 alerts = {item['title']: item['uuid'] for item in res.get('results', []) if item['type'] == 'intelligence_alert'} reports = {item['title']: item['uuid'] for item in res.get('results', []) if item['type'] == 'intelligence_report'} intelligence_alerts = {title: IDEFENSE_URL_TEMPLATE.format('intelligence_alert', uuid) for title, uuid in alerts.items()} intelligence_reports = {title: IDEFENSE_URL_TEMPLATE.format( 'intelligence_report', uuid) for title, uuid in reports.items()} except Exception as e: if 'Error in API call [403]' in e.args[0]: return_results(f"Intelligence Alert & Intelligence Report enrichment (if present) is not possible! As your API token is not eligible to access Document API.\n Error: {str(e)}") # noqa: E501 demisto.debug(e.args[0]) else: raise e return intelligence_alerts, intelligence_reports def main(): params = demisto.params() api_key = params.get('api_token') if isinstance(api_key, dict): # integration version >=3.2.0 api_key = api_key.get('password') base_url = urljoin(params.get('url', '')) reliability = params.get('integrationReliability', 'B - Usually reliable') if DBotScoreReliability.is_valid_type(reliability): reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability) else: Exception("IDefense error: Please provide a valid value for the Source Reliability parameter") commands = { 'url': url_command, 'ip': ip_command, 'domain': domain_command, 'idefense-get-ioc-by-uuid': uuid_command } verify_certificate = not params.get('insecure', False) proxy = params.get('use_proxy', False) try: command = demisto.command() client = Client(base_url, api_key, verify_certificate, proxy, endpoint=ENDPOINTS['threatindicator']) document_search_client = Client(base_url, api_key, verify_certificate, proxy, endpoint=ENDPOINTS['document']) demisto.debug(f'Command being called is {command}') if command == 'test-module': return_results(test_module(client)) elif command in commands: return_results(commands[command](client, demisto.args(), reliability, document_search_client)) except Exception as e: return_error(f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}') if __name__ in ('__main__', '__builtin__', 'builtins'): main()