ACTI Indicator Query
ACTI provides intelligence regarding security threats and vulnerabilities.
Data Enrichment & Threat Intelligence · Accenture CTI v2
Details
| ID | ACTI Indicator Query |
|---|---|
| Provider | Accenture |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
ACTI provides intelligence regarding security threats and vulnerabilities.
This integration was integrated and tested with version 2.93.0 of ACTI
Configure ACTI Indicator Query in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | URL | True |
| API Token | The API Token to use for connection | True |
| Source Reliability | Reliability of the source providing the intelligence data. | True |
| 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.
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 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": "ACTI Indicator Query"
},
"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": "ACTI Indicator Query"
},
"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": "ACTI Indicator Query"
},
"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
acti-get-ioc-by-uuid
Checks reputation of a specific indicator(URL/IP/Domain) uuid.
Base Command
acti-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
!acti-get-ioc-by-uuid uuid=xxxx
Context Example
{
"DBotScore": {
"Indicator": "example.org",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "domain",
"Vendor": "ACTI Indicator Query"
},
"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
acti-get-fundamentals-by-uuid
Checks reputation of a specific Malware Family/ Threat Campaign/ Threat Group/ Threat Actor.
Base Command
acti-get-fundamentals-by-uuid
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | Unique ID of the specific Malware Family/ Threat Campaign/ Threat Group/ Threat Actor. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| ACTI_MalwareFamily.display_text | String | The display text of the Malware Family, for example, ‘Artemis’ |
| ACTI_MalwareFamily.threat_types | String | The threat type of the Malware Family. |
| ACTI_MalwareFamily.type | String | The type of fundamental i.e. an Malware Family , for example, ‘malware_family’ |
| ACTI_MalwareFamily.last_published | String | The last published date of the Malware Family, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_MalwareFamily.last_modified | String | The last modified date of the Malware Family, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_MalwareFamily.index_timestamp | String | The index timestamp of the Malware Family, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_MalwareFamily.created_on | String | The creation timestamp of the Malware Family, for example, ‘2020-03-12T22:22:25.000Z’ |
| ACTI_MalwareFamily.description | String | The description of the Malware Family |
| ACTI_MalwareFamily.analysis | String | The analysis of the Malware Family |
| ACTI_ThreatGroup.display_text | String | The display text of the Threat Group, for example, ‘Black Shadow’ |
| ACTI_ThreatGroup.threat_types | String | The threat type of the Threat Group. |
| ACTI_ThreatGroup.type | String | The type of fundamental i.e. an Threat Group, for example, ‘threat_group’ |
| ACTI_ThreatGroup.last_published | String | The last published date of the Threat Group, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatGroup.last_modified | String | The last modified date of the Threat Group, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatGroup.index_timestamp | String | The index timestamp of the Threat Group, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatGroup.created_on | String | The creation timestamp of the Threat Group, for example, ‘2020-03-12T22:22:25.000Z’ |
| ACTI_ThreatGroup.description | String | The description of the Threat Group |
| ACTI_ThreatGroup.analysis | String | The analysis of the Threat Group |
| ACTI_ThreatActor.display_text | String | The display text of the Threat Actor, for example, ‘RastaFarEye’ |
| ACTI_ThreatActor.threat_types | String | The threat type of the Threat Actor. |
| ACTI_ThreatActor.type | String | The type of fundamental i.e. an Threat Actor, for example, ‘threat_actor’ |
| ACTI_ThreatActor.last_published | String | The last published date of the Threat Actor, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatActor.last_modified | String | The last modified date of the Threat Actor, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatActor.index_timestamp | String | The index timestamp of the Threat Actor, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatActor.created_on | String | The creation timestamp of the Threat Actor, for example, ‘2020-03-12T22:22:25.000Z’ |
| ACTI_ThreatActor.description | String | The description of the Threat Actor |
| ACTI_ThreatActor.analysis | String | The analysis of the Threat Actor |
| ACTI_ThreatCampaign.display_text | String | The display text of the Threat Campaign, for example, ‘FBI Flash CU-000141-MW’ |
| ACTI_ThreatCampaign.threat_types | String | The threat type of the Threat Campaign. |
| ACTI_ThreatCampaign.type | String | The type of fundamental i.e. an Threat Campaign , for example, ‘threat_campaign’ |
| ACTI_ThreatCampaign.last_published | String | The last published date of the Threat Campaign, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatCampaign.last_modified | String | The last modified date of the Threat Campaign, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatCampaign.index_timestamp | String | The index timestamp of the Threat Campaign, for example, ‘2022-02-11T17:24:03.604Z’ |
| ACTI_ThreatCampaign.created_on | String | The creation timestamp of the Threat Campaign, for example, ‘2020-03-12T22:22:25.000Z’ |
| ACTI_ThreatCampaign.description | String | The description of the Threat Campaign |
| ACTI_ThreatCampaign.analysis | String | The analysis of the Threat Campaign |
| 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
!acti-get-fundamentals-by-uuid uuid=7q2b129s-6421-4e22-a276-22be5f76cba8
Context Example
{
"DBotScore": {
"Indicator": "7q2b129s-6421-4e22-a276-22be5f76cba8",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "ACTI Malware Family",
"Vendor": "ACTI Indicator Query"
},
"ACTI_MalwareFamily": {
"Name": "Danabot",
"DbotReputation": 2,
"ThreatTypes": "Cyber Crime",
"Type": "malware_family",
"LastPublished": "2021-04-02T04:40:19.000Z",
"LastModified": "2021-04-02T04:40:19.000Z",
"IndexTimestamp": "2021-04-02T04:40:19.000Z",
"Severity": 3,
"CreatedOn": "2021-04-02T04:40:19.000Z"
}
}
Human Readable Output
Danabot
For more insight click: https://intelgraph.idefense.com/#/node/malware_family/view/7q2b129s-6421-4e22-a276-22be5f76cba8
CreatedOn DBotReputation IndexTimestamp LastModified LastPublished Name Severity ThreatTypes Type 2021-04-02 04:40:19 2 2021-04-02 04:40:19 2021-04-02 04:40:19 2021-04-02 04:40:19 Danabot 3 Cyber Crime malware_family
acti-getThreatIntelReport
Fetches Intelligence Alerts & Intelligence Reports.
Base Command
acti-getThreatIntelReport
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | uuid of Intelligence Alert/Report (IA/IR) in the ACTI IntelGraph platform. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IAIR.abstract | String | This field is specific to Intelligence Alert and provides a summarised context, for example, ‘The worldwide COVID-19 outbreak…’ |
| IAIR.last_published | String | The last published timestamp of the IA/IR, for example, ‘2020-06-26T01:14:56.000Z’ |
| IAIR.index_timestamp | String | The index timestamp of the IA/IR, for example, ‘2022-02-11T17:24:03.604Z’ |
| IAIR.display_text | String | The display text of the IA/IR, for example, ‘SITREP Cybersecurity Risks Related to COVID-19’ |
| IAIR.value | String | The value of the IA/IR, for example, ‘8b8b48f1-92a0-411a-a073-3241f6819f8b’ |
| IAIR.last_modified | String | The last modified timestamp of the IA/IR, for example, ‘2022-02-11T17:21:48.000Z’ |
| IAIR.threat_types | String | The threat type of the IA/IR, for example, ‘- Hacktivism- Cyber Espionage- Cyber Crime- Vulnerability’. It’s formatted in such a way that it gets displayed better. |
| IAIR.created_on | String | The creation timestamp of the IA/IR, for example, ‘2020-03-12T22:22:25.000Z’ |
| IAIR.title | String | The title of the IA/IR, for example, ‘SITREP Cybersecurity Risks Related to COVID-19’ |
| IAIR.type | String | The type of report i.e. an IA/IR , for example, ‘intelligence_alert’ |
| IAIR.uuid | String | The uuid of the IA/IR, for example, ‘8b8b48f1-92a0-411a-a073-3241f6819f8b’ |
| IAIR.analysis | String | The analysis of the IA/IR, for example, ‘COVID-19 Introduces Cyberthreat Opportunities…’ |
| IAIR.attachment_links | String | Provides with the document links related to the Intelligence Alert. This field is specific to Intelligence Alert, for example, ‘https://intelgraph.idefense.com/rest/files/download/…’ |
| IAIR.severity | String | Provides severity rating. This field is specific to Intelligence Alert, for example, ‘4’ |
| IAIR.mitigation | String | Provides info on how to mitigate. This field is specific to Intelligence Alert, for example, ‘## Expert, Experienced Advice Will be CriticalTo minimize targeting opportunities…’ |
| IAIR.conclusion | String | Provides conclusion of the report. This field is specific to Intelligence Report |
| IAIR.summary | String | Provides with a summary of the report. This field is specific to Intelligence Report. |
| IAIR.dynamic_properties | String | Provides with the dynamic properties related to the intelligence alert/report. |
| IAIR.links | String | Provides details of the linked fields related to the intelligence alert/report. |
| IAIR.sources_external | String | Provides with external sources related to the intelligence alert/report. |
| 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
!acti-getThreatIntelReport uuid=8b8b48f1-92a0-411a-a073-3241f6819f8b
Context Example
{
"DBotScore": {
"Indicator": "8b8b48f1-92a0-411a-a073-3241f6819f8b",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "ACTI Intelligence Alert",
"Vendor": "ACTI Indicator Query"
},
"IAIR": {
"abstract": "The worldwide COVID-19 outbreak, which the World Health Organization (WHO) declared a pandemic......",
"last_published": "2020-06-26T01:14:56.000Z",
"index_timestamp": "2022-02-11T17:24:03.604Z",
"display_text": "SITREP: Cybersecurity Risks Related to COVID-19",
"value": "8b8b48f1-92a0-411a-a073-3241f6819f8b",
"sources_external": {},
"last_modified":"2022-02-11T17:21:48.000Z",
"dynamic_properties": {},
"threat_types": "- Hacktivism- Cyber Espionage- Cyber Crime- Vulnerability",
"created_on": "2020-03-12T22:22:25.000Z",
"title": "SITREP: Cybersecurity Risks Related to COVID-19",
"links":{},
"type": "intelligence_alert",
"uuid": "8b8b48f1-92a0-411a-a073-3241f6819f8b",
"analysis": "##COVID-19 Introduces Cyberthreat Opportunities####Exploitation of Work-from-Home.....",
"attachment_links": "- https://intelgraph.idefense.com/rest/files/download/08/f0/05/7f1f609e7659dc......",
"severity": 4,
"mitigation": "##Expert, Experienced Advice Will be CriticalTo minimize targeting opportunities...."
}
}
Human Readable Output
Report has been fetched!
UUID: 8b8b48f1-92a0-411a-a073-3241f6819f8b
Link to view report: https://intelgraph.idefense.com/#/node/intelligence_alert/view/8b8b48f1-92a0-411a-a073-3241f6819f8b
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 (6)
-
acti-get-fundamentals-by-uuidChecks reputation of a specific Malware Family/ Threat Campaign/ Threat Group/ Threat Actor.
-
acti-get-ioc-by-uuidChecks reputation of a specific indicator(URL/IP/Domain) uuid.
-
acti-getThreatIntelReportFetches Intelligence Alerts & Intelligence Reports.
-
domainChecks the reputation of the given domain.
-
ipChecks the reputation of the given IP address.
-
urlChecks the reputation of the given URL.
import requests_mock from ACTIIndicatorQuery import ( IDEFENSE_URL_TEMPLATE, Client, domain_command, url_command, ip_command, uuid_command, _calculate_dbot_score, getThreatReport_command, fix_markdown, addBaseUrlToPartialPaths, convert_inline_image_to_encoded, fundamental_uuid_command, ) # noqa: E501 from CommonServerPython import DemistoException, DBotScoreReliability from test_data.response_constants import ( URL_RES_JSON, URL_INTEL_JSON, IP_RES_JSON, IP_INTEL_JSON, DOMAIN_RES_JSON, DOMAIN_INTEL_JSON, UUID_RES_JSON, RES_JSON_IA, RES_JSON_IR, expected_output_ia, expected_output_ir, MALWARE_FAMILY_RES_JSON, expected_output_malware_family, RAW_MALWARE_FAMILY_RES_JSON, ) import demistomock as demisto import pytest API_URL = "https://test.com" DBOT_KEY = "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)" INTEGRATION_NAME = "iDefense" ENDPOINTS = {"threatindicator": "/rest/threatindicator", "document": "/rest/document", "fundamental": "/rest/fundamental"} @pytest.fixture(autouse=True) def handle_calling_context(mocker): mocker.patch.object(demisto, "callingContext", {"context": {"IntegrationBrand": INTEGRATION_NAME}}) def test_ip_command(): """ Given: - an IP When: - running ip command and validate whether the ip is malicious Then: - return command results containing indicator, dbotscore and associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/ip?key.values=0.0.0.0" doc_url = "https://test.com/rest/document/v0?links.display_text.values=0.0.0.0&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 fund_url = "https://test.com/rest/fundamental/v0/malware_family?key.values=Hive" status_code = 200 json_data = IP_RES_JSON intel_json_data = IP_INTEL_JSON malware_json_data = RAW_MALWARE_FAMILY_RES_JSON expected_output = { "IP": [{"Address": "0.0.0.0"}], "DBOTSCORE": [ {"Indicator": "0.0.0.0", "Type": "ip", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable"} ], } ip_to_check = {"ip": "0.0.0.0"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=status_code, json=intel_json_data) m.get(fund_url, status_code=status_code, json=malware_json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = ip_command(client, ip_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() output = results[0].to_context().get("EntryContext", {}) assert output.get("IP(val.Address && val.Address == obj.Address)", []) == expected_output.get("IP") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert _is_intelligence_data_present_in_command_result(context_result, intel_json_data) is True def test_ip_command_when_api_key_not_authorised_for_document_search(): """ Given: - a ip and api key not authorized for doc search When: - running ip command and validate whether the ip is malicious Then: - return command results containing indicator, dbotscore and NO associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/ip?key.values=0.0.0.0" doc_url = "https://test.com/rest/document/v0?links.display_text.values=0.0.0.0&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 fund_url = "https://test.com/rest/fundamental/v0/malware_family?key.values=Hive" status_code = 200 error_status_code = 403 json_data = IP_RES_JSON malware_family_data = RAW_MALWARE_FAMILY_RES_JSON doc_search_exception_response = { "timestamp": "2021-11-12T09:09:27.983Z", "status": 403, "error": "Forbidden", "message": "Forbidden", "path": "/rest/document/v0", } expected_output = { "IP": [{"Address": "0.0.0.0"}], "DBOTSCORE": [ {"Indicator": "0.0.0.0", "Type": "ip", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable"} ], } ip_to_check = {"ip": "0.0.0.0"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=error_status_code, json=doc_search_exception_response) m.get(fund_url, status_code=status_code, json=malware_family_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = ip_command(client, ip_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() content = context_result["HumanReadable"] output = context_result.get("EntryContext", {}) assert output.get("IP(val.Address && val.Address == obj.Address)", []) == expected_output.get("IP") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert "Intelligence Alerts" not in content assert "Intelligence Reports" not in content def test_domain_command(): """ Given: - a domain When: - running domain command and validate whether the domain is malicious Then: - return command results containing indicator, dbotscore and associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/domain?key.values=mydomain.com" doc_url = "https://test.com/rest/document/v0?links.display_text.values=mydomain.com&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 status_code = 200 json_data = DOMAIN_RES_JSON intel_json_data = DOMAIN_INTEL_JSON expected_output = { "domain": [{"Name": "mydomain.com"}], "DBOTSCORE": [ { "Indicator": "mydomain.com", "Type": "domain", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], # noqa: E501 } domain_to_check = {"domain": "mydomain.com"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=status_code, json=intel_json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = domain_command(client, domain_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() output = results[0].to_context().get("EntryContext", {}) assert output.get("Domain(val.Name && val.Name == obj.Name)", []) == expected_output.get("domain") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert _is_intelligence_data_present_in_command_result(context_result, intel_json_data) is True def test_domain_command_when_api_key_not_authorized_for_document_search(): """ Given: - a domain and api key not authorized for doc search When: - running domain command and validate whether the domain is malicious Then: - return command results containing indicator, dbotscore and NO associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/domain?key.values=mydomain.com" doc_url = "https://test.com/rest/document/v0?links.display_text.values=mydomain.com&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 status_code = 200 error_status_code = 403 json_data = DOMAIN_RES_JSON doc_search_exception_response = { "timestamp": "2021-11-12T09:09:27.983Z", "status": 403, "error": "Forbidden", "message": "Forbidden", "path": "/rest/document/v0", } expected_output = { "domain": [{"Name": "mydomain.com"}], "DBOTSCORE": [ { "Indicator": "mydomain.com", "Type": "domain", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], # noqa: E501 } domain_to_check = {"domain": "mydomain.com"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=error_status_code, json=doc_search_exception_response) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = domain_command(client, domain_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() content = context_result["HumanReadable"] output = context_result.get("EntryContext", {}) assert output.get("Domain(val.Name && val.Name == obj.Name)", []) == expected_output.get("domain") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert "Intelligence Alerts" not in content assert "Intelligence Reports" not in content def _is_intelligence_data_present_in_command_result(context_result, test_intel_json_data) -> bool: """ Function to verify whether context result includes intelligence alert and report information Args: context_result from demisto command test_intel_json_data mock response data used for document search api Returns: True if intelligence alert and report are present else False """ test_data = test_intel_json_data.get("results") alerts, reports = {}, {} for result in test_data: if result["type"] == "intelligence_alert": alerts[result["title"]] = IDEFENSE_URL_TEMPLATE.format(result["type"], result["uuid"]) if result["type"] == "intelligence_report": reports[result["title"]] = IDEFENSE_URL_TEMPLATE.format(result["type"], result["uuid"]) content = context_result["HumanReadable"] for title, url in alerts.items(): if url not in content[content.find(title) : content.find("|", content.find(title))]: return False return all(url in content[content.find(title) : content.find("|", content.find(title))] for title, url in reports.items()) def test_uuid_command(): """ Given: - a domain uuid When: - running uuid command and validate whether the domain is malicious Then: - return command results containing indicator, dbotscore and associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/461b5ba2-d4fe-4b5c-ac68-35b6636c6edf" doc_url = "https://test.com/rest/document/v0?links.display_text.values=mydomain.com&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 malware_family_url = "https://test.com/rest/fundamental/v0/malware_family?key.values=Hive" status_code = 200 json_data = UUID_RES_JSON intel_json_data = DOMAIN_INTEL_JSON malware_json_data = RAW_MALWARE_FAMILY_RES_JSON expected_output = { "domain": [{"Name": "mydomain.com"}], "DBOTSCORE": [ { "Indicator": "mydomain.com", "Type": "domain", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], # noqa: E501 } uuid_to_check = {"uuid": "461b5ba2-d4fe-4b5c-ac68-35b6636c6edf"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=status_code, json=intel_json_data) m.get(malware_family_url, status_code=status_code, json=malware_json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = uuid_command(client, uuid_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results.to_context() output = results.to_context().get("EntryContext", {}) assert output.get("Domain(val.Name && val.Name == obj.Name)", []) == expected_output.get("domain") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert _is_intelligence_data_present_in_command_result(context_result, intel_json_data) is True def test_uuid_command_when_api_key_not_authorized_for_document_search(): """ Given: - a domain uuid and api key not authorized for doc search When: - running uuid command and validate whether the domain is malicious Then: - return command results containing indicator, dbotscore and NO associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/461b5ba2-d4fe-4b5c-ac68-35b6636c6edf" doc_url = "https://test.com/rest/document/v0?links.display_text.values=mydomain.com&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 malware_family_url = "https://test.com/rest/fundamental/v0/malware_family?key.values=Hive" status_code = 200 error_status_code = 403 json_data = UUID_RES_JSON malware_json_data = RAW_MALWARE_FAMILY_RES_JSON doc_search_exception_response = { "timestamp": "2021-11-12T09:09:27.983Z", "status": 403, "error": "Forbidden", "message": "Forbidden", "path": "/rest/document/v0", } expected_output = { "domain": [{"Name": "mydomain.com"}], "DBOTSCORE": [ { "Indicator": "mydomain.com", "Type": "domain", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], # noqa: E501 } uuid_to_check = {"uuid": "461b5ba2-d4fe-4b5c-ac68-35b6636c6edf"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=error_status_code, json=doc_search_exception_response) m.get(malware_family_url, status_code=status_code, json=malware_json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = uuid_command(client, uuid_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results.to_context() content = context_result["HumanReadable"] output = context_result.get("EntryContext", {}) assert output.get("Domain(val.Name && val.Name == obj.Name)", []) == expected_output.get("domain") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert "Intelligence Alerts" not in content assert "Intelligence Reports" not in content def test_ip_not_found(): """ Given: - an IP When: - running ip command and validate whether the ip is malicious Then: - return command results with context indicate that no results were found """ url = "https://test.com/rest/threatindicator/v0/ip?key.values=1.1.1.1" status_code = 200 json_data = {"total_size": 0, "page": 1, "page_size": 25, "more": False} expected_output = "No results were found for ip 1.1.1.1" ip_to_check = {"ip": "1.1.1.1"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = ip_command(client, ip_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) output = results[0].to_context().get("HumanReadable") assert expected_output in output def test_url_not_found(): """ Given: - an URL When: - running url command and validate whether the url is malicious Then: - return command results with context indicate that no results were found """ url = "https://test.com/rest/threatindicator/v0/url?key.values=http://www.malware.com/path" status_code = 200 json_data = {"total_size": 0, "page": 1, "page_size": 25, "more": False} expected_output = "No results were found for url http://www.malware.com/path" url_to_check = {"url": "http://www.malware.com/path"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = url_command(client, url_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) output = results[0].to_context().get("HumanReadable") assert expected_output in output def test_domain_not_found(): """ Given: - an Domain When: - running domain command and validate whether the domain is malicious Then: - return command results with context indicate that no results were found """ url = "https://test.com/rest/threatindicator/v0/domain?key.values=mydomain.com" status_code = 200 json_data = {"total_size": 0, "page": 1, "page_size": 25, "more": False} expected_output = "No results were found for Domain mydomain.com" domain_to_check = {"domain": "mydomain.com"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = domain_command(client, domain_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) output = results[0].to_context().get("HumanReadable") assert expected_output in output def test_wrong_ip(): """ Given: - an IP When: - running ip command validate at first to check if the given ip is a valid ip Then: - raise error before calling http request that indicates that the given argument is not valid """ ip_to_check = {"ip": "1"} client = Client(API_URL, "api_token", True, False) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) try: ip_command(client, ip_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) except DemistoException as err: assert "Received wrong IP value" in str(err) def test_wrong_connection(): """ Given: - an api token When: - checking api access Then: - raise error if there is no access because of wrong api token """ from ACTIIndicatorQuery import test_module with requests_mock.Mocker() as m: mock_address = "https://test.com/rest/threatindicator/v0/" m.get(mock_address, status_code=401, json={}) client = Client("bad_api_key", "wrong_token", True, False) try: test_module(client) except DemistoException as err: assert "Error in API call - check the input parameters" in str(err) def test_url_command(): """ Given: - url When: - running url command and validate whether the url is malicious Then: - return command results containing indicator, dbotscore and associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/url?key.values=http://www.malware.com/path" doc_url = "https://test.com/rest/document/v0?links.display_text.values=http://www.malware.com/path&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 status_code = 200 json_data = URL_RES_JSON intel_json_data = URL_INTEL_JSON expected_output = { "URL": [{"Data": "http://www.malware.com/path"}], "DBOTSCORE": [ { "Indicator": "http://www.malware.com/path", "Type": "url", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], } url_to_check = {"url": "http://www.malware.com/path"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=status_code, json=intel_json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = url_command(client, url_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() output = results[0].to_context().get("EntryContext", {}) assert output.get("URL(val.Data && val.Data == obj.Data)", []) == expected_output.get("URL") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert _is_intelligence_data_present_in_command_result(context_result, intel_json_data) is True def test_url_command_when_api_key_not_authorized_for_document_search(): """ Given: - a url and api key not authorized for doc search When: - running url command and validate whether the url is malicious Then: - return command results containing indicator, dbotscore and NO associated intelligence alerts, reports """ url = "https://test.com/rest/threatindicator/v0/url?key.values=http://www.malware.com/path" doc_url = "https://test.com/rest/document/v0?links.display_text.values=http://www.malware.com/path&type.values=intelligence_alert&type.values=intelligence_report&links.display_text.match_all=true" # noqa: E501 status_code = 200 error_status_code = 403 json_data = URL_RES_JSON doc_search_exception_response = { "timestamp": "2021-11-12T09:09:27.983Z", "status": 403, "error": "Forbidden", "message": "Forbidden", "path": "/rest/document/v0", } expected_output = { "URL": [{"Data": "http://www.malware.com/path"}], "DBOTSCORE": [ { "Indicator": "http://www.malware.com/path", "Type": "url", "Vendor": "iDefense", "Score": 2, "Reliability": "B - Usually reliable", } ], } url_to_check = {"url": "http://www.malware.com/path"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) m.get(doc_url, status_code=error_status_code, json=doc_search_exception_response) client = Client(API_URL, "api_token", True, False, ENDPOINTS["threatindicator"]) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) fundamental_client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = url_command(client, url_to_check, DBotScoreReliability.B, doc_search_client, fundamental_client) context_result = results[0].to_context() content = context_result["HumanReadable"] output = context_result.get("EntryContext", {}) assert output.get("URL(val.Data && val.Data == obj.Data)", []) == expected_output.get("URL") assert output.get(DBOT_KEY, []) == expected_output.get("DBOTSCORE") assert "Intelligence Alerts" not in content assert "Intelligence Reports" not in content def test_calculate_dbot_score(): """ Given: - number represents severity When: - api call with indicator returns response that includes them severity score Then: - returns dbotscore according to internal conversion """ assert _calculate_dbot_score(0) == 0 assert _calculate_dbot_score(1) == 1 assert _calculate_dbot_score(2) == 1 assert _calculate_dbot_score(3) == 2 assert _calculate_dbot_score(4) == 2 assert _calculate_dbot_score(5) == 3 assert _calculate_dbot_score(6) == 3 assert _calculate_dbot_score(7) == 3 def test_fix_markdown(): text_to_update = ( "##Key Findings and Judgements\n\n* The sophisticated [cyber espionage operation](/#/node/intelligence" "_alert/view/a655306d-bd95-426d-8c93-ebeef57406e4) was selective; it used supply-chain attack techniques," " mainly a malicious update of a widely used product from IT monitoring firm SolarWinds," " but its final target list appears to number only in the hundreds. Known targets include public-" " and private-sector entities, mostly in the US, including IT vendors, US government entities, and think" " tanks (#/node/intelligence_alert/view/a655306d-bd95-426d-8c93-ebeef57406e4)." ) expected_output = ( "## Key Findings and Judgements\n\n* The sophisticated [cyber espionage operation](/#/node/" "intelligence_alert/view/a655306d-bd95-426d-8c93-ebeef57406e4) was selective; it used supply-chain attack " "techniques, mainly a malicious update of a widely used product from IT monitoring firm SolarWinds, but its" " final target list appears to number only in the hundreds. Known targets include public- and private-sector " "entities, mostly in the US, including IT vendors, US government entities, and think tanks (#/node/" "intelligence_alert/view/a655306d-bd95-426d-8c93-ebeef57406e4)." ) output = fix_markdown(text_to_update) assert expected_output == output def _test_getThreatReport_ia_command(): """ Given: - an URL When: - running ThreatReport command and fetch IA/IR Then: - return command results containing UUID, dbotscore """ url = "https://test.com/rest/document/v0/a487dfdc-08b4-4909-82ea-2d934c27d901" status_code = 200 json_res = RES_JSON_IA expected_output = expected_output_ia uuid_to_check = {"uuid": "a487dfdc-08b4-4909-82ea-2d934c27d901"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_res) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) results = getThreatReport_command(doc_search_client, uuid_to_check, DBotScoreReliability.B) output = results.to_context().get("EntryContext", {}) assert output.get("IAIR(val.value && val.value == obj.value)", []) == expected_output.get("IA") assert output.get(DBOT_KEY, []) == expected_output.get("DBot") def _test_getThreatReport_ir_command(): """ Given: - an URL When: - running ThreatReport command and fetch IA/IR Then: - return command results containing UUID, dbotscore """ url = "https://test.com/rest/document/v0/bdc9d16f-6040-4894-8544-9c98986a41fd" status_code = 200 json_res = RES_JSON_IR expected_output = expected_output_ir uuid_to_check = {"uuid": "bdc9d16f-6040-4894-8544-9c98986a41fd"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_res) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) results = getThreatReport_command(doc_search_client, uuid_to_check, DBotScoreReliability.B) output = results.to_context().get("EntryContext", {}) assert output.get("IAIR(val.value && val.value == obj.value)", []) == expected_output.get("IR") assert output.get(DBOT_KEY, []) == expected_output.get("DBot") def test_getThreatReport_not_found(): url = "https://test.com/rest/document/v0/a487dfdc-08b4-49a09-82ea-2d934c27d901" status_code = 200 json_res = None expected_output = "No report was found for UUID: a487dfdc-08b4-49a09-82ea-2d934c27d901 !!" uuid_to_check = {"uuid": "a487dfdc-08b4-49a09-82ea-2d934c27d901"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_res) doc_search_client = Client(API_URL, "api_token", True, False, ENDPOINTS["document"]) results = getThreatReport_command(doc_search_client, uuid_to_check, DBotScoreReliability.B) output = results.to_context().get("HumanReadable") assert expected_output in output def test_addBaseUrlToPartialPaths(): IA_link_in_content = ( " BELUGASTURGEON activity, including a [2020 campaign against the Cypriot" " government](#/node/intelligence_alert/view/6cc805d7-cb77-443d-afea-d052916fa602)" ) image_link_in_content = ( "as China has.\n\n " ) IA_link_expected_output = ( " BELUGASTURGEON activity, including a [2020 campaign against the Cypriot" " government](https://intelgraph.idefense.com/#/node/intelligence_alert/view/6cc805d7-cb77-443d-afea-d052916fa602)" ) image_link_expected_output = ( "as China has.\n\n " ) ialink_output = addBaseUrlToPartialPaths(IA_link_in_content) imagelink_output = addBaseUrlToPartialPaths(image_link_in_content) assert ialink_output == IA_link_expected_output assert imagelink_output == image_link_expected_output def test_convert_inline_image_to_encoded(): md_text = ( "China has.\n\n " ) url = ( "https://test.com/rest/files/download/0f/6c/6f/91de9ef8d8d38345dc270f8915d9faa496a00b5ba" "be2bff231dd195cd0/ArcticMapUWNews28288859157_5f54b9c446_c.jpg" ) status_code = 200 expected_res = ( "China has.\n\n " ) raw_res = {"content": "China has.\n\n "} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=raw_res) res = convert_inline_image_to_encoded(md_text) assert res == expected_res def test_fundamental_uuid_command(): url = "https://test.com/rest/fundamental/v0/c1b3216e-8b2e-4a9f-b0a9-2e184b7182f7" status_code = 200 json_data = MALWARE_FAMILY_RES_JSON expected_output = expected_output_malware_family uuid_to_check = {"uuid": "c1b3216e-8b2e-4a9f-b0a9-2e184b7182f7"} with requests_mock.Mocker() as m: m.get(url, status_code=status_code, json=json_data) client = Client(API_URL, "api_token", True, False, ENDPOINTS["fundamental"]) results = fundamental_uuid_command(client, uuid_to_check, DBotScoreReliability.B) output = results.to_context().get("EntryContext", {}) assert output.get("ACTI_MalwareFamily(val.value && val.value == obj.value)", []) == expected_output.get("malware_family") assert output.get(DBOT_KEY, []) == expected_output.get("dbot")