From 49f8723e8829bae75072d4a70195f6f964aeb477 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Wed, 11 May 2022 14:51:58 +0300 Subject: [PATCH 01/15] ignore dependencies of packs from other MP --- Tests/Marketplace/marketplace_services.py | 8 +++++++- Tests/Marketplace/upload_packs.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index 68b21d5a1fbe..bffc8635b0c8 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -661,6 +661,8 @@ def _load_pack_dependencies_metadata(self, index_folder_path, packs_dict): Case 2: The dependency is missing from the index.zip since it is a new pack. In this case, handle missing dependency - This means we mark this pack as 'missing dependency', and once the new index.zip is created, and therefore it contains the new pack, we call this function again, and hitting case 1. + Case 3: The dependency is of a pack that is not a part of this marketplace. In this case, we ignore this + dependency. Args: index_folder_path (str): full path to download index folder. packs_dict (dict): dict of all packs relevant for current marketplace, as {pack_id: pack_object}. @@ -682,12 +684,16 @@ def _load_pack_dependencies_metadata(self, index_folder_path, packs_dict): with open(dependency_metadata_path, 'r') as metadata_file: dependency_metadata = json.load(metadata_file) dependencies_metadata_result[dependency_pack_id] = dependency_metadata - else: + elif dependency_pack_id in packs_dict: # Case 2: the dependency is not in the index since it is a new pack self._is_missing_dependencies = True logging.warning(f"{self._pack_name} pack dependency with id {dependency_pack_id} " f"was not found in index, marking it as missing dependencies - to be resolved in " f"next iteration over packs") + else: + # Case 3: the dependency is not a part of this marketplace + logging.warning(f"{self._pack_name} pack dependency with id {dependency_pack_id} " + f"is not part of this marketplace, ignoring this dependency") return dependencies_metadata_result, self._is_missing_dependencies diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 0bcfb2f500a4..2843190ae31b 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -1208,7 +1208,7 @@ def main(): pack.status = PackStatus.SUCCESS.name - logging.info(f"packs_with_missing_dependencies: {packs_with_missing_dependencies}") + logging.info(f"packs_with_missing_dependencies: {[pack.name for pack in packs_with_missing_dependencies]}") # Going over all packs that were marked as missing dependencies, # updating them with the new data for the new packs that were added to the index.zip From f1bb797203b5b742e6f1561c1787e064d805ea0b Mon Sep 17 00:00:00 2001 From: nmaimon Date: Wed, 11 May 2022 14:53:51 +0300 Subject: [PATCH 02/15] test pack --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 +- Packs/Alexa/ReleaseNotes/2_0_12.md | 3 +++ Packs/Alexa/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/Alexa/ReleaseNotes/2_0_12.md diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index c36de4f80534..74c599826601 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -5,7 +5,7 @@ import requests import traceback from typing import Dict - +# MODIFIED # Disable insecure warnings requests.packages.urllib3.disable_warnings() # pylint: disable=no-member diff --git a/Packs/Alexa/ReleaseNotes/2_0_12.md b/Packs/Alexa/ReleaseNotes/2_0_12.md new file mode 100644 index 000000000000..be549fa3a99c --- /dev/null +++ b/Packs/Alexa/ReleaseNotes/2_0_12.md @@ -0,0 +1,3 @@ +#### Integrations +##### Alexa Rank Indicator v2 +- Updated the Docker image to: *demisto/python3:3.10.4.29342*. diff --git a/Packs/Alexa/pack_metadata.json b/Packs/Alexa/pack_metadata.json index 3f88fadcca1c..0f848216062f 100644 --- a/Packs/Alexa/pack_metadata.json +++ b/Packs/Alexa/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alexa Rank Indicator", "description": "Alexa provides website ranking information that can be useful in determining if the domain in question has a strong web presence.", "support": "xsoar", - "currentVersion": "2.0.11", + "currentVersion": "2.0.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 4c3eb29d18a23a564f9e224d17b6aaf0972df8a9 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Wed, 11 May 2022 16:51:28 +0300 Subject: [PATCH 03/15] fix dependencies --- Tests/Marketplace/upload_packs.py | 76 +++++++++++++------------------ 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 2843190ae31b..33b2ead77cbe 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -930,53 +930,39 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat """ logging.info("Starting to collect pack with dependencies zips") for pack_name, pack in packs_for_current_marketplace_dict.items(): - if pack.status != PackStatus.SUCCESS.name and pack.status not in SKIPPED_STATUS_CODES: - # avoid trying to upload dependencies zip for failed packs - continue try: - logging.info(f"Collecting dependencies of {pack_name}") - pack_with_dep_path = os.path.join(pack.path, "with_dependencies") - zip_with_deps_path = os.path.join(pack.path, f"{pack_name}_with_dependencies.zip") - upload_path = os.path.join(storage_base_path, pack_name, f"{pack_name}_with_dependencies.zip") - Path(pack_with_dep_path).mkdir(parents=True, exist_ok=True) - if not (pack.zip_path and os.path.isfile(pack.zip_path)): - task_status = sign_and_zip_pack(pack, signature_key) + if pack.status not in [*SKIPPED_STATUS_CODES, PackStatus.SUCCESS.name]: + # avoid trying to upload dependencies zip for failed packs + continue + pack_and_its_dependencies = [packs_for_current_marketplace_dict.get(dep_name) for dep_name in pack.all_levels_dependencies] + [pack] + pack_or_dependency_was_uploaded = any(dep_pack.status == PackStatus.SUCCESS.name for dep_pack in pack_and_its_dependencies) + if pack_or_dependency_was_uploaded: + pack_with_dep_path = os.path.join(pack.path, "with_dependencies") + zip_with_deps_path = os.path.join(pack.path, f"{pack_name}_with_dependencies.zip") + upload_path = os.path.join(storage_base_path, pack_name, f"{pack_name}_with_dependencies.zip") + Path(pack_with_dep_path).mkdir(parents=True, exist_ok=True) + for current_pack in pack_and_its_dependencies: + logging.info(f"Starting to collect zip of pack {current_pack.name}") + # zip the pack and each of the pack's dependencies (or copy existing zip if was already zipped) + if not (current_pack.zip_path and os.path.isfile(current_pack.zip_path)): + # the zip does not exist yet, zip the current pack + task_status = sign_and_zip_pack(current_pack, signature_key) + if not task_status: + # modify the pack's status to indicate the failure was in the dependencies zip step + current_pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_SIGNING.name + logging.warning(f"Skipping uploading {pack.name} since failed zipping {current_pack.name}.") + continue + shutil.copy(current_pack.zip_path, os.path.join(pack_with_dep_path, current_pack.name + ".zip")) + logging.info(f"Zipping {pack_name} with its dependencies") + Pack.zip_folder_items(pack_with_dep_path, pack_with_dep_path, zip_with_deps_path) + shutil.rmtree(pack_with_dep_path) + logging.info(f"Uploading {pack_name} with its dependencies") + task_status, _, _ = pack.upload_to_storage(zip_with_deps_path, '', storage_bucket, True, + storage_base_path, overridden_upload_path=upload_path) + logging.info(f"{pack_name} with dependencies was{' not' if not task_status else ''} uploaded successfully") if not task_status: - # modify the pack's status to indicate the failure was in the dependencies zip step - pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_SIGNING.name - logging.warning(f"Skipping dependencies collection for {pack_name}. Failed zipping") - continue - shutil.copy(pack.zip_path, os.path.join(pack_with_dep_path, pack_name + ".zip")) - for dep_name in pack.all_levels_dependencies: - dep_pack = packs_for_current_marketplace_dict.get(dep_name) - if not (dep_pack.zip_path and os.path.isfile(dep_pack.zip_path)): - task_status = sign_and_zip_pack(dep_pack, signature_key) - if not task_status: - # modify the pack's status to indicate the failure was in the dependencies zip step - pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_SIGNING.name - logging.error(f"Skipping dependency {pack_name}. Failed zipping") - continue - shutil.copy(dep_pack.zip_path, os.path.join(pack_with_dep_path, dep_name + '.zip')) - logging.info(f"Zipping {pack_name} with dependencies") - Pack.zip_folder_items( - pack_with_dep_path, - pack_with_dep_path, - zip_with_deps_path - ) - shutil.rmtree(pack_with_dep_path) - logging.info(f"Uploading {pack_name} with dependencies") - task_status, _, _ = pack.upload_to_storage( - zip_pack_path=zip_with_deps_path, - latest_version='', - storage_bucket=storage_bucket, - override_pack=True, - storage_base_path=storage_base_path, - overridden_upload_path=upload_path - ) - logging.info(f"{pack_name} with dependencies was{' not' if not task_status else ''} uploaded successfully") - if not task_status: - pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_UPLOADING.name - pack.cleanup() + pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_UPLOADING.name + pack.cleanup() except Exception as e: logging.error(traceback.format_exc()) logging.error(f"Failed uploading packs with dependencies: {e}") From 8229abb80003cc122759912c0085d932c93cdbf0 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Thu, 12 May 2022 17:47:25 +0300 Subject: [PATCH 04/15] fix random dependencies --- Packs/CommonPlaybooks/pack_metadata.json | 4 ---- Packs/CreatePlbkDoc/pack_metadata.json | 2 +- .../pack_metadata.json | 2 +- .../GoogleChronicleBackstory/pack_metadata.json | 4 ---- .../pack_metadata.json | 2 +- Packs/PANOSPolicyOptimizer/pack_metadata.json | 4 ---- Packs/PANOStoCDLMonitoring/pack_metadata.json | 2 +- Packs/PcapAnalysis/pack_metadata.json | 4 ---- Packs/PhishingURL/pack_metadata.json | 2 +- Packs/PrismaCloud/pack_metadata.json | 16 ---------------- Packs/TIM_Processing/pack_metadata.json | 4 ---- Packs/Wiz/pack_metadata.json | 2 +- Tests/Marketplace/marketplace_services.py | 9 +++++++-- Tests/Marketplace/upload_packs.py | 2 +- 14 files changed, 14 insertions(+), 45 deletions(-) diff --git a/Packs/CommonPlaybooks/pack_metadata.json b/Packs/CommonPlaybooks/pack_metadata.json index 5ffe69aba76d..3afce6288bf3 100644 --- a/Packs/CommonPlaybooks/pack_metadata.json +++ b/Packs/CommonPlaybooks/pack_metadata.json @@ -32,10 +32,6 @@ "mandatory": false, "display_name": "McAfee ePO" }, - "McAfee ePO v2": { - "mandatory": false, - "display_name": "McAfee ePO v2" - }, "CheckpointFirewall": { "mandatory": false, "display_name": "Check Point Firewall" diff --git a/Packs/CreatePlbkDoc/pack_metadata.json b/Packs/CreatePlbkDoc/pack_metadata.json index ad10550e1f2c..6c82a91c4c19 100644 --- a/Packs/CreatePlbkDoc/pack_metadata.json +++ b/Packs/CreatePlbkDoc/pack_metadata.json @@ -15,7 +15,7 @@ "mazmat-panw" ], "dependencies": { - "Demisto REST API": { + "DemistoRESTAPI": { "mandatory": true, "display_name": "Demisto REST API" } diff --git a/Packs/ForwardXSOARAuditLogsToSplunkHEC/pack_metadata.json b/Packs/ForwardXSOARAuditLogsToSplunkHEC/pack_metadata.json index c7b9a12749cd..2520429db459 100644 --- a/Packs/ForwardXSOARAuditLogsToSplunkHEC/pack_metadata.json +++ b/Packs/ForwardXSOARAuditLogsToSplunkHEC/pack_metadata.json @@ -11,7 +11,7 @@ "mandatory": true, "display_name": "SplunkPy" }, - "Demisto REST API": { + "DemistoRESTAPI": { "mandatory": true, "display_name": "Demisto REST API" } diff --git a/Packs/GoogleChronicleBackstory/pack_metadata.json b/Packs/GoogleChronicleBackstory/pack_metadata.json index d865e09112bd..34c89a75f936 100644 --- a/Packs/GoogleChronicleBackstory/pack_metadata.json +++ b/Packs/GoogleChronicleBackstory/pack_metadata.json @@ -106,10 +106,6 @@ "mandatory": false, "display_name": "ThreatConnect" }, - "XFE": { - "mandatory": false, - "display_name": "IBM X-Force Exchange" - }, "NIST": { "mandatory": true, "display_name": "NIST" diff --git a/Packs/IntegrationsAndIncidentsHealthCheck/pack_metadata.json b/Packs/IntegrationsAndIncidentsHealthCheck/pack_metadata.json index 524edb170544..156cb4b91957 100644 --- a/Packs/IntegrationsAndIncidentsHealthCheck/pack_metadata.json +++ b/Packs/IntegrationsAndIncidentsHealthCheck/pack_metadata.json @@ -42,7 +42,7 @@ "mandatory": false, "display_name": "Mail Sender (New)" }, - "Demisto REST API": { + "DemistoRESTAPI": { "mandatory": true, "display_name": "Demisto REST API" } diff --git a/Packs/PANOSPolicyOptimizer/pack_metadata.json b/Packs/PANOSPolicyOptimizer/pack_metadata.json index 62998092102b..1a5e88e0b882 100644 --- a/Packs/PANOSPolicyOptimizer/pack_metadata.json +++ b/Packs/PANOSPolicyOptimizer/pack_metadata.json @@ -14,10 +14,6 @@ "useCases": [], "keywords": [], "dependencies": { - "Panorama": { - "mandatory": true, - "display_name": "PAN-OS" - }, "CommonScripts": { "mandatory": true, "display_name": "Common Scripts" diff --git a/Packs/PANOStoCDLMonitoring/pack_metadata.json b/Packs/PANOStoCDLMonitoring/pack_metadata.json index 1208c441482a..e37bb04e7148 100644 --- a/Packs/PANOStoCDLMonitoring/pack_metadata.json +++ b/Packs/PANOStoCDLMonitoring/pack_metadata.json @@ -21,7 +21,7 @@ "mandatory": true, "display_name": "PAN-OS" }, - "Cortex Data Lake": { + "CortexDataLake": { "mandatory": true, "display_name": "Cortex Data Lake" } diff --git a/Packs/PcapAnalysis/pack_metadata.json b/Packs/PcapAnalysis/pack_metadata.json index 5da77900acd6..c44a8db42a12 100644 --- a/Packs/PcapAnalysis/pack_metadata.json +++ b/Packs/PcapAnalysis/pack_metadata.json @@ -89,10 +89,6 @@ "mandatory": false, "display_name": "Flashpoint" }, - "XFE": { - "mandatory": false, - "display_name": "IBM X-Force Exchange" - }, "GoogleChronicleBackstory": { "mandatory": false, "display_name": "Chronicle" diff --git a/Packs/PhishingURL/pack_metadata.json b/Packs/PhishingURL/pack_metadata.json index 814897dad5fd..f61a50de9723 100644 --- a/Packs/PhishingURL/pack_metadata.json +++ b/Packs/PhishingURL/pack_metadata.json @@ -22,7 +22,7 @@ "mandatory": true, "display_name": "Rasterize" }, - "whois": { + "Whois": { "mandatory": true, "display_name": "WHOIS" } diff --git a/Packs/PrismaCloud/pack_metadata.json b/Packs/PrismaCloud/pack_metadata.json index 6773017d5956..85634933cfdf 100644 --- a/Packs/PrismaCloud/pack_metadata.json +++ b/Packs/PrismaCloud/pack_metadata.json @@ -50,22 +50,6 @@ "mandatory": false, "display_name": "AWS - IAM" }, - "Azure-AKS": { - "mandatory": false, - "display_name": "Azure - AKS" - }, - "Azure-SQL": { - "mandatory": false, - "display_name": "Azure - SQL" - }, - "Azure-Network": { - "mandatory": false, - "display_name": "Azure - Network" - }, - "Azure-Storage": { - "mandatory": false, - "display_name": "Azure - Storage" - }, "GoogleKubernetesEngine": { "mandatory": false, "display_name": "Google Kubernetes Engine" diff --git a/Packs/TIM_Processing/pack_metadata.json b/Packs/TIM_Processing/pack_metadata.json index 40f9b0c7f865..0aeb4e3e9e76 100644 --- a/Packs/TIM_Processing/pack_metadata.json +++ b/Packs/TIM_Processing/pack_metadata.json @@ -82,10 +82,6 @@ "mandatory": false, "display_name": "Palo Alto Networks WildFire" }, - "XFE": { - "mandatory": false, - "display_name": "IBM X-Force Exchange" - }, "ReversingLabs_Titanium_Cloud": { "mandatory": false, "display_name": "ReversingLabs Titanium Cloud" diff --git a/Packs/Wiz/pack_metadata.json b/Packs/Wiz/pack_metadata.json index 925bc1d0d13e..127c37fc9765 100644 --- a/Packs/Wiz/pack_metadata.json +++ b/Packs/Wiz/pack_metadata.json @@ -26,7 +26,7 @@ "mandatory": true, "name": "Base" }, - "Generic Webhook": { + "GenericWebhook": { "mandatory": true, "name": "Generic Webhook" } diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index bffc8635b0c8..6e54470a7c34 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -119,10 +119,15 @@ def __init__(self, pack_name, pack_path): @property def name(self): - """ str: pack root folder name. + """ str: pack name. """ return self._pack_name + def id(self): + """ str: pack root folder name. + """ + return self._pack_name + @property def path(self): """ str: pack folder full path. @@ -2032,7 +2037,7 @@ def format_metadata(self, index_folder_path, packs_dependencies_mapping, build_n build_number (str): circleCI build number. commit_hash (str): current commit hash. statistics_handler (StatisticsHandler): The marketplace statistics handler - packs_dict (dict): dict of all packs relevant for current marketplace, as {pack_id: pack_object}. + packs_dict (dict): dict of all packs relevant for current marketplace, as {pack_name: pack_object}. marketplace (str): Marketplace of current upload. format_dependencies_only (bool): Indicates whether the metadata formation is just for formatting the dependencies or not. diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 33b2ead77cbe..7bd1bc8ff8c8 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -1057,7 +1057,7 @@ def main(): is_bucket_upload_flow, ci_branch) # detect packs to upload - pack_names = get_packs_names(target_packs, previous_commit_hash) + pack_names = get_packs_names(target_packs, previous_commit_hash) # TODO: this is actually id extract_packs_artifacts(packs_artifacts_path, extract_destination_path) packs_list = [Pack(pack_name, os.path.join(extract_destination_path, pack_name)) for pack_name in pack_names if os.path.exists(os.path.join(extract_destination_path, pack_name))] From d83245826478b1d7089cb4e3f5a5f19301e66f70 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 11:46:48 +0300 Subject: [PATCH 05/15] debug logs --- Tests/Marketplace/upload_packs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 7bd1bc8ff8c8..7afa04310c8f 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -942,7 +942,7 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat upload_path = os.path.join(storage_base_path, pack_name, f"{pack_name}_with_dependencies.zip") Path(pack_with_dep_path).mkdir(parents=True, exist_ok=True) for current_pack in pack_and_its_dependencies: - logging.info(f"Starting to collect zip of pack {current_pack.name}") + logging.debug(f"Starting to collect zip of pack {current_pack.name}") # zip the pack and each of the pack's dependencies (or copy existing zip if was already zipped) if not (current_pack.zip_path and os.path.isfile(current_pack.zip_path)): # the zip does not exist yet, zip the current pack @@ -950,7 +950,7 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat if not task_status: # modify the pack's status to indicate the failure was in the dependencies zip step current_pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_SIGNING.name - logging.warning(f"Skipping uploading {pack.name} since failed zipping {current_pack.name}.") + logging.debug(f"Skipping uploading {pack.name} since failed zipping {current_pack.name}.") continue shutil.copy(current_pack.zip_path, os.path.join(pack_with_dep_path, current_pack.name + ".zip")) logging.info(f"Zipping {pack_name} with its dependencies") From 81ab079e41e7b8c72a78269512193dece89674e7 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 12:09:44 +0300 Subject: [PATCH 06/15] change --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 +- Packs/Alexa/pack_metadata.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index 74c599826601..c36de4f80534 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -5,7 +5,7 @@ import requests import traceback from typing import Dict -# MODIFIED + # Disable insecure warnings requests.packages.urllib3.disable_warnings() # pylint: disable=no-member diff --git a/Packs/Alexa/pack_metadata.json b/Packs/Alexa/pack_metadata.json index 0f848216062f..3f88fadcca1c 100644 --- a/Packs/Alexa/pack_metadata.json +++ b/Packs/Alexa/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alexa Rank Indicator", "description": "Alexa provides website ranking information that can be useful in determining if the domain in question has a strong web presence.", "support": "xsoar", - "currentVersion": "2.0.12", + "currentVersion": "2.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9ce74c0c4312f909d908bcbff10fe63094f43311 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 12:10:30 +0300 Subject: [PATCH 07/15] test change --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 ++ Packs/Alexa/pack_metadata.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index c36de4f80534..8488c4b2fd27 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -15,6 +15,8 @@ ''' CLIENT CLASS ''' +#CHANGE + class Client(BaseClient): def __init__(self, api_key: str, diff --git a/Packs/Alexa/pack_metadata.json b/Packs/Alexa/pack_metadata.json index 3f88fadcca1c..0f848216062f 100644 --- a/Packs/Alexa/pack_metadata.json +++ b/Packs/Alexa/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alexa Rank Indicator", "description": "Alexa provides website ranking information that can be useful in determining if the domain in question has a strong web presence.", "support": "xsoar", - "currentVersion": "2.0.11", + "currentVersion": "2.0.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 3eddfbc693205b7821b8c1280e62dab4a82f09a2 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 15:42:59 +0300 Subject: [PATCH 08/15] remove failing pack --- Packs/TrendMicroVisionOne/.pack-ignore | 0 Packs/TrendMicroVisionOne/.secrets-ignore | 8 - Packs/TrendMicroVisionOne/Author_image.png | Bin 2477 -> 0 bytes ...icro_Vision_One_XDR_-_Incoming_Mapper.json | 585 ------- ...nd_Micro_Vision_One_XDR_Account_Count.json | 29 - ...nd_Micro_Vision_One_XDR_Desktop_Count.json | 29 - ...eld-Trend_Micro_Vision_One_XDR_Detail.json | 29 - ...ro_Vision_One_XDR_Email_Address_Count.json | 29 - ...end_Micro_Vision_One_XDR_Impact_Scope.json | 29 - ...icro_Vision_One_XDR_Impacted_Entities.json | 29 - ...Vision_One_XDR_Impacted_Entities_JSON.json | 30 - ...Trend_Micro_Vision_One_XDR_Indicators.json | 29 - ..._Micro_Vision_One_XDR_Indicators_JSON.json | 30 - ...o_Vision_One_XDR_Investigation_Status.json | 29 - ...cro_Vision_One_XDR_Matched_Rules_JSON.json | 30 - ...d_Micro_Vision_One_XDR_Priority_Score.json | 29 - ...end_Micro_Vision_One_XDR_Server_Count.json | 29 - ...end_Micro_Vision_One_XDR_Workbench_ID.json | 29 - ...d_Micro_Vision_One_XDR_Workbench_Link.json | 29 - ...e-Trend_Micro_Vision_One_XDR_Incident.json | 28 - .../Integrations/TrendMicroVisionOne/Pipfile | 18 - .../TrendMicroVisionOne/Pipfile.lock | 369 ----- .../TrendMicroVisionOne/README.md | 412 ----- .../TrendMicroVisionOne.py | 1339 ----------------- .../TrendMicroVisionOne.yml | 657 -------- .../TrendMicroVisionOne_description.md | 64 - .../TrendMicroVisionOne_image.png | Bin 2477 -> 0 bytes .../TrendMicroVisionOne_test.py | 776 ---------- .../TrendMicroVisionOne/command_examples | 0 ...r-Trend_Micro_Vision_One_XDR_Incident.json | 475 ------ Packs/TrendMicroVisionOne/README.md | 26 - .../TrendMicroVisionOne/ReleaseNotes/1_0_1.md | 9 - .../TrendMicroVisionOne/ReleaseNotes/1_1_0.md | 6 - Packs/TrendMicroVisionOne/pack_metadata.json | 33 - 34 files changed, 5243 deletions(-) delete mode 100755 Packs/TrendMicroVisionOne/.pack-ignore delete mode 100755 Packs/TrendMicroVisionOne/.secrets-ignore delete mode 100644 Packs/TrendMicroVisionOne/Author_image.png delete mode 100644 Packs/TrendMicroVisionOne/Classifiers/classifier-Trend_Micro_Vision_One_XDR_-_Incoming_Mapper.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Account_Count.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Desktop_Count.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Detail.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Email_Address_Count.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impact_Scope.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impacted_Entities.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impacted_Entities_JSON.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Indicators.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Indicators_JSON.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Investigation_Status.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Matched_Rules_JSON.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Priority_Score.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Server_Count.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Workbench_ID.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Workbench_Link.json delete mode 100644 Packs/TrendMicroVisionOne/IncidentTypes/incidenttype-Trend_Micro_Vision_One_XDR_Incident.json delete mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/Pipfile delete mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/Pipfile.lock delete mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/README.md delete mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py delete mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml delete mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md delete mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png delete mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_test.py delete mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples delete mode 100644 Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json delete mode 100755 Packs/TrendMicroVisionOne/README.md delete mode 100644 Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md delete mode 100644 Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md delete mode 100755 Packs/TrendMicroVisionOne/pack_metadata.json diff --git a/Packs/TrendMicroVisionOne/.pack-ignore b/Packs/TrendMicroVisionOne/.pack-ignore deleted file mode 100755 index e69de29bb2d1..000000000000 diff --git a/Packs/TrendMicroVisionOne/.secrets-ignore b/Packs/TrendMicroVisionOne/.secrets-ignore deleted file mode 100755 index 4fdda571c45f..000000000000 --- a/Packs/TrendMicroVisionOne/.secrets-ignore +++ /dev/null @@ -1,8 +0,0 @@ -192.168.35.1 -192.168.35.254 -6.6.6.6 -https://trendmicro-fake-api.com -https://api.xdr.trendmicro.com -http:// -kjshdfjksahd@trendenablement.com -MfSqmTdAMyv9PDX3k+vQ0w@mail.gmail.com \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/Author_image.png b/Packs/TrendMicroVisionOne/Author_image.png deleted file mode 100644 index 98c959cb86c90034ee39e1d5b01c0144dba818a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2477 zcmXw4c|6ql8y|DI!o|u276KxyLciSnNimP|+kr?u`uETxDyi|fA2!#U1R?{3& z!vOSQYYNB%zZD+N#Sp>J|A{~#02jV3_0513po}4P)<(xCwDdSAEEo{~1_rutwTN6a z4iFz##{z;ZC5*74fsMifFg6MY0NA@Q9Bl$H4q(7BI2yXZTzrzl7*ZDkfloP+$JDj9 z^-U~z!NFW@eZGzXk7&%r8FAFKCidC_QWNG@E5#MPS-@dc; z_3Ic4yFN9|As7St!1zE50K?WIa!C8eO|8avTX2vBwj){e;4u%VYvO=w0RUr4NH$VO zfF_RbLi06o98KH=nlP?{8sDkG-($nk(&M7AqNl2e~RSXAf_*EkLl#%`6 z=!pqOGT+K!3QgEtS@|kj*qEK$nECYOP2XZu%gmYd>99kaYisLMf^{BG^8Cf})6T`V zc2OO3zLGvycKLHo-iMQ?h2ha$z1`Dj!URHnV_LW}I4pVjdil|lrF$I<%|E~8N@H<)y<5pP|W9*pQE+yFK_jmuSO7}DGEU|tP ze>BR=!Oj-H0|o`p2nHH1WoIQP20J1*H&;Ij|9Nx$_|Ilq3UagD!JY?qZnxB2IiD69 zN_Mf=QCpRa_O~=uU#%$0NsT#3@vVSviK7?`1H9QCe*CIRb5B#ZXuJS-I$`6rE)WMx|@YgAsWHMdCuDN>VJm~ngQbYtg zLYd)TL*Z~Z)77Vg+T{Q8$xBRAGz01V=sTy_ zcau5D{M4tX=@wD*-49Ng(Cwt)Ea_leb&DnjX; z=yrQUE?utu_2i6V-rg6&%#bvjt#?&gZPJcLr>@bRT9~gzLf*a1iBHj28}`lq+4Ji` zYwyy8wMWCZ*!Podrj3mpB`tS-J-uRyE0-%O>sim4@fj&nebTkbF*doihXs+>@w3w( zV$$a1_~QORS~uvhI5JP z7^~|or7L^U2iLS1?*si3#ZrFXfA7dnW#YL4dv6HF|ETq*ZgPf`xQCoeddK4(*G|jY zIyeJTkfl9s!kmk7^1X?dLjPNOP`paN;5+OjJy2Nk9J#Kn9RG=SmQa7Qjll}P9bC7% zWXShxdaI!|1X7FW$=rX2S%k-xs#uc!+Oo9?=;_Jcijtr%nb-kW<(2CtI6VGsw^gGb z5#aIi9MmT|ep@QO56k)n{TG5cG31t2$=gYjneYZy{MU zGNL*XxRcBH9r=@2En|d8Vjx3}f(u(oQTzFbuGl%AR+LIeQ(Dm*%HT4L9u*Vk9VwNe zeKPXbKk&I~(jNzgbUpPCy1Qc$$SywPWpjFv`*0(7^G0agG5fICV_d%RUYdem6iR~2 zq&+QaS49_HRSR?UUS+N6cN>kK_lh_-EbJF~v@uNd^!g5{KA1K1&N6I`PVs3G7aRR7 z5z0>z4r%8`Ds-zj8wYKuDDMDwRkhe$>>qNUcw1K&mdsq$pU+D28x7pj=pk9bKhn6J zMOX*@FY`t!^}ZLh{868F2H;r%8uwkNg<}oLGN?pxarnoogfnd!zI=k~C(nh9!kQwl~St3`v|BdU#dJ?dYur$Vi|~TIvKywkwYavD`>y&YYC( zEU^pRl~P~tA$_RHp~fUCEAfh}+|2`v8B6YCNt08{2{M!da{|cIAEQVVEFS9^+E89% zCM?o>HCNp}5?(Nud{|F)M7IXr{b-BTEuM`hm+oH>-7OSrBi`k2>C`>>Bux(+WTm0z?tSSWOh zX-At~>o9FyUno^ADHYhikX&}7M|FgqvpIS#IKOeIS$0Oc%RK=hHX~VHu8h0L?(W#Hyy1N1fE{Z6 zy|$vcOD>~9N~pMg@&dwT#xz8p5@&Tb=C?%4cr|uZ%m62_EfT3&qFqxJWS z@Ete}<-<%xf_#r&$)00V=x7-*%)sJxd$2q^i2mY@AxNp5M%@#FnNCF)FYc*i(yB)X zbOU!_+d&Hd7CW*Cg?mg(Pyg9TQ#g7icH$DMQB)r!ta=}`X?Vl&!jGcg9T2hjV`{%J z5^@E3h7Y62yVH&YH6CfM)gaTK2*T4dKMyr+v}m$CNSYf1VRW2QRzbMuFUfzs9zJ1- ziKDX~(=jAHtJGbo8D+JKAMZpIlv9P#OU<)~-$}^1){*=&Q>XU_TyFag50Q4 **Integrations** > **Servers & Services**. -2. Search for Trend Micro Vision One. -3. Click **Add instance** to create and configure a new integration instance. - -| **Parameter** | **Description** | **Required** | -| --- | --- | --- | -| Name | Unique name for this Trend Micro Vision One instance | True | -| Fetch Incidents | Choose if the integration should sync incidents | True | -| API URL | Base URL for Trend Micro Vision One API | True | -| API Key | API token for authentication | True | -| Incidents Fetch Interval (minutes) | How often do you want to check for new incidents | False | -| Sync On First Run (days) | How many days to go back during first sync | False | -| Max Incidents | Maximum Number of Workbenches to Retrieve | False | -4. Click **Test** to validate the URLs, token, and connection. - -## Commands -You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. - -#### Base Command - -1. `trendmicro-visionone-add-to-block-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| value_type | "file_sha1", "ip", "domain", "url" or "mailbox" | Required | -| target_value | The object you would like to add that matches the value-type | Required | -| product_id | Target product | Optional | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.BlockList.actionId | String | The action id | -| VisionOne.BlockList.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. - -2. `trendmicro-visionone-remove-from-block-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| value_type | "file_sha1", "ip", "domain", "url" or "mailbox" | Required | -| target_value | The object you would like to add that matches the value-type | Required | -| product_id | Target product | Optional | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.BlockList.actionId | String | The action id | -| VisionOne.BlockList.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. - -3. `trendmicro-visionone-quarantine-email-message` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| message_id | Email Message ID from Trend Micro Vision One message activity data | Required | -| mail_box | Email mailbox where the message will be quarantied from | Required | -| message_delivery_time | Email message's original delivery time | Required | -| product_id | Target product | Optional | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Email.actionId | String | The action id | -| VisionOne.Email.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. - -4. `trendmicro-visionone-delete-email-message` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| message_id | Email Message ID from Trend Micro Vision One message activity data | Required | -| mail_box | Email mailbox where the message will be deleted from | Required | -| message_delivery_time | Email message's original delivery time | Required | -| product_id | Target product | Optional | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Email.actionId | String | The action id | -| VisionOne.Email.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. - -5. `trendmicro-visionone-isolate-endpoint` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| endpoint | "hostname", "macaddr" or "ip" of the endpoint to isolate | Required | -| product_id | Target product: "sao" or "sds". Default: "sao". | Required | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Endpoint_Connection.actionId | String | The action id | -| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. -Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. - -6. `trendmicro-visionone-restore-endpoint-connection` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| endpoint | "hostname", "macaddr" or "ip" of the endpoint to restore connectivity | Required | -| product_id | Target product: "sao" or "sds". Default: "sao". | Required | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Endpoint_Connection.actionId | String | The action id | -| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. -Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. - -7. `trendmicro-visionone-add-objects-to-exception-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| type | The object type: "domain", "ip", "sha1", or "url" | Required | -| value | Full and partial matches supported. Domain partial match, (with a wildcard as the subdomain, example, .example.com) IP partial match, (IP range example, 192.168.35.1-192.168.35.254, cidr example, 192.168.35.1/24) URL partial match, (Supports wildcards 'http://.'', 'https://.'' at beginning, or ''' at the end. Multiple wild cards also supported, such as , https://.example.com/path1/) SHA1 only full match" | Required | -| description | Description | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Exception_List.message | String | Status message of existing task | -| VisionOne.Exception_List.status_code | String | Response code of existing task | -| VisionOne.Exception_List.total_items | String | Number of items present in the exception list. | - -8. `trendmicro-visionone-delete-objects-from-exception-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| type | The object type: "domain", "ip", "sha1", or "url" |Required| -| value | The object value | Required | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Exception_List.message | String | Status message of existing task | -| VisionOne.Exception_List.status_code | String | Response code of existing task | -| VisionOne.Exception_List.total_items | String | Number of items present in the exception list. | - -9. `trendmicro-visionone-add-objects-to-suspicious-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| type | The object type: "domain", "ip", "sha1", or "url" |Required| -| value | The object value | Required | -| description | Description | Optional | -| scan_action | The action to take if object is found. If you don't use this parameter, the scan action specified in default_settings.riskLevel.type will be used instead. "block" or "log" | Optional | -| risk_level | The Suspicious Object risk level. If you don't use this parameter, high will be used instead. "high", "medium", or "low" | Optional | -| expiry_days | The number of days to keep the object in the Suspicious Object List. If you don't use this parameter, the default_settings.expiredDay scan action will be used instead. | Optional | - - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Suspicious_List.message | String | Status message of existing task | -| VisionOne.Suspicious_List.status_code | String | Response code of existing task | -| VisionOne.Suspicious_List.total_items | String | Number of items present in the exception list. | - -10. `trendmicro-visionone-delete-objects-from-suspicious-list` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| type | The object type: "domain", "ip", "sha1", or "url" |Required| -| value | The object value | Required | - - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Suspicious_List.message | String | Status message of existing task | -| VisionOne.Suspicious_List.status_code | String | Response code of existing task | -| VisionOne.Suspicious_List.total_items | String | Number of items present in the exception list. | - -11. `trendmicro-visionone-terminate-process` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| endpoint | "hostname", "macaddr" or "ip" of the endpoint to terminate process on | Required | -| file_sha1 | SHA1 hash of the process to terminate | Required | -| product_id | Target product. Default: "sao" | Optional | -| description | Description | Optional | -| filename | Optional file name list for log | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Terminate_Process.actionId | String | The action id | -| VisionOne.Terminate_Process.taskStatus | String | Status of existing task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. -Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout is ``20 minutes``. - -12. `trendmicro-visionone-get-file-analysis-status` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| task_id | task_id from the trendmicro-visionone-submit-file-to-sandbox command output |Required| - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.File_Analysis_Status.message | String | Message status | -| VisionOne.File_Analysis_Status.code | String | Code status of the task | -| VisionOne.File_Analysis_Status.task_id | String | Task id | -| VisionOne.File_Analysis_Status.taskStatus | String | Task status | -| VisionOne.File_Analysis_Status.digest | String | Hash value of task | -| VisionOne.File_Analysis_Status.analysis_completion_time | String | Task completion time | -| VisionOne.File_Analysis_Status.risk_level | String | Risk level of task | -| VisionOne.File_Analysis_Status.description | String | Description of task | -| VisionOne.File_Analysis_Status.detection_name_list | String | List of task detected | -| VisionOne.File_Analysis_Status.threat_type_list | String | Threat type list | -| VisionOne.File_Analysis_Status.file_type | String | Type of file | -| VisionOne.File_Analysis_Status.report_id | String | Report ID of task. | - -13. `trendmicro-visionone-get-file-analysis-report` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| report_id | report_id of the sandbox submission retrieved from the trendmicro-visionone-get-file-analysis-status command |Required| -| type | Type of report to retrieve: "vaReport", "investigationPackage", or "suspiciousObject" |Required| - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.File_Analysis_Report.message | String | Message status | -| VisionOne.File_Analysis_Report.code | String | Code status of task | -| VisionOne.File_Analysis_Report.type | String | type of report | -| VisionOne.File_Analysis_Report.value | String | value of the above type | -| VisionOne.File_Analysis_Report.risk_level | String | risk level of the file | -| VisionOne.File_Analysis_Report.analysis_completion_time | String | Final analysed time of report | -| VisionOne.File_Analysis_Report.expired_time | String | Expiry time of report | -| VisionOne.File_Analysis_Report.root_file_sha1 | String | sha value of the root file | - -14. `trendmicro-visionone-collect-forensic-file` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| endpoint | "hostname", "macaddr" or "ip" of the endpoint to collect file from | Required | -| product_id | Product: "sao" "xes" "sds" |Required| -| file_path | Path of the file to collect |Required| -| os | "windows", "mac" or "linux" |Required| -| description | Description of file collected |Optional| -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Collect_Forensic_File.actionId | String | Action id of the running task | -| VisionOne.Collect_Forensic_File.taskStatus | String | Status of the running task | - -Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. -Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. - -15. `trendmicro-visionone-download-information-for-collected-forensic-file` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| actionId | actionId output from the collect command used to collect the file |Required| - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Download_Information_For_Collected_Forensic_File.url | String | URL of the collected file | -| VisionOne.Download_Information_For_Collected_Forensic_File.expires | String | URL expiration date | -| VisionOne.Download_Information_For_Collected_Forensic_File.password | String | Archive password for the protected forensic file | -| VisionOne.Download_Information_For_Collected_Forensic_File.filename | String | Name of the collected file | - -Note: The URL received from the 'trendmicro-visionone-download-information-for-collected-forensic-file' will be valid for only ``60 seconds`` - -16. `trendmicro-visionone-submit-file-to-sandbox` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| file_url | URL pointing to the location of the file to be submitted. |Required| -| filename | Name of the file to be analyzed. |Required| -| document_password | The password for decrypting the submitted document. The value must be Base64-encoded. The maximum password length is 128 bytes prior to encoding. | Optional | -| archive_password | The password for decrypting the submitted archive. The value must be Base64-encoded. The maximum password length is 128 bytes prior to encoding. | Optional | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Submit_File_to_Sandbox.message | String | Message status of the sandbox file | -| VisionOne.Submit_File_to_Sandbox.code | String | Code status of the sandbox file | -| VisionOne.Submit_File_to_Sandbox.task_id | String | Task ID of the running task | -| VisionOne.Submit_File_to_Sandbox.digest | Object | Sha value of the file | - -17. `trendmicro-visionone-check-task-status` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| polling | If the command is to run at the polling interval. | Optional | -| actionId | Action ID of the task you would like to get the status of. | Required | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Endpoint_Connection.actionId | String | The action id | -| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | - -18. `trendmicro-visionone-get-endpoint-info` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| endpoint | "hostname", "macaddr" or "ip" of the endpoint to query | Required | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Endpoint_Info.message | String | Message information from the request. | -| VisionOne.Endpoint_Info.errorCode | Integer | Error code. | -| VisionOne.Endpoint_Info.status | String | Status of the request. | -| VisionOne.Endpoint_Info.logonAccount | String | Account currently logged on to the endpoint. | -| VisionOne.Endpoint_Info.hostname | String | Hostname. | -| VisionOne.Endpoint_Info.macAddr | String | MAC address. | -| VisionOne.Endpoint_Info.ip | String | IP address. | -| VisionOne.Endpoint_Info.osName | String | Operating System name. | -| VisionOne.Endpoint_Info.osVersion | String | Operating System version. | -| VisionOne.Endpoint_Info.osDescription | String | Description of the Operating System. | -| VisionOne.Endpoint_Info.productCode | String | Product code of the Trend Micro product running on the endpoint. | ---- - -19. `trendmicro-visionone-add-note` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| workbench_id | The ID of the workbench alert that you would like to add the note to. | Required | -| content | The note content that you would like to add. | Required | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Add_Note.Workbench_Id | String | Workbench ID that the action was executed on. | -| VisionOne.Add_Note.noteId | String | Note ID. | -| VisionOne.Add_Note.response_code | String | Response code for the request. | -| VisionOne.Add_Note.response_msg | String | Response message for the request. | ---- - -20. `trendmicro-visionone-update-status` - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| workbench_id | The ID of the workbench alert that you would like to update the status for. | Required | -| status | The status to assign to the workbench alert: new, in_progress, resolved_false_positive, resolved_true_positive | Required | - -#### Context Output - -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| VisionOne.Update_Status.Workbench_Id | String | Workbench ID that the action was executed on. | -| VisionOne.Update_Status.response_code | String | Response code for the request. | -| VisionOne.Update_Status.response_msg | String | Response message for the request. | ---- -[View Integration Documentation](https://xsoar.pan.dev/docs/reference/integrations/trend-micro-vision-one) \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py deleted file mode 100644 index 6707a01e1793..000000000000 --- a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py +++ /dev/null @@ -1,1339 +0,0 @@ -'''IMPORTS''' -import demistomock as demisto # noqa: F401 -from CommonServerPython import * # noqa: F401 # pylint: disable=unused-wildcard-import -from CommonServerUserPython import * # noqa: F401 - -import base64 -import json -import requests -import re -from datetime import datetime, timezone, timedelta -from typing import Any, Dict, Union -from requests.models import HTTPError - -'''CONSTANTS''' -USER_AGENT = 'TMV1CortexXSOARApp/1.1' -URL = 'url' -POST = 'post' -GET = 'get' -PUT = 'put' -AUTHORIZATION = 'Authorization' -BEARER = 'Bearer ' -CONTENT_TYPE_JSON = 'application/json' -EMPTY_STRING = '' -ASCII = 'ascii' -API_TOKEN = 'apikey' -VALUE_TYPE = 'value_type' -TARGET_VALUE = 'target_value' -PRODUCT_ID = 'product_id' -DESCRIPTION = 'description' -MESSAGE_ID = 'message_id' -MAILBOX = 'mailbox' -MESSAGE_DELIVERY_TIME = 'message_delivery_time' -COMPUTER_ID = 'computer_id' -FIELD = 'field' -ENDPOINT = 'endpoint' -DATA = 'data' -TYPE = 'type' -VALUE = 'value' -FILESHA = 'file_sha1' -FILENAME = 'filename' -CRITERIA = 'criteria' -EXCEPTION_LIST = 'exceptionList' -SUSPICIOUS_LIST = 'suspiciousObjectList' -LAST_MODIFIED = 'lastModified' -SCAN_ACTION = 'scan_action' -RISK_LEVEL = 'risk_level' -EXPIRYDAY = 'expiry_days' -TASKID = 'task_id' -REPORT_ID = 'report_id' -OS_TYPE = 'os' -FILE_PATH = 'file_path' -FILE_URL = 'file_url' -FILE_NAME = 'filename' -DOCUMENT_PASSWORD = 'document_password' -ARCHIVE_PASSWORD = 'archive_password' -ACTION_ID = 'actionId' -WORKBENCH_ID = 'workbench_id' -CONTENT = 'content' -STATUS = 'status' -# End Points -ADD_BLOCKLIST_ENDPOINT = '/v2.0/xdr/response/block' -REMOVE_BLOCKLIST_ENDPOINT = '/v2.0/xdr/response/restoreBlock' -QUARANTINE_EMAIL_ENDPOINT = '/v2.0/xdr/response/quarantineMessage' -DELETE_EMAIL_ENDPOINT = '/v2.0/xdr/response/deleteMessage' -ISOLATE_CONNECTION_ENDPOINT = '/v2.0/xdr/response/isolate' -TERMINATE_PROCESS_ENDPOINT = '/v2.0/xdr/response/terminateProcess' -RESTORE_CONNECTION_ENDPOINT = '/v2.0/xdr/response/restoreIsolate' -ADD_OBJECT_TO_EXCEPTION_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/exceptions' -DELETE_OBJECT_FROM_EXCEPTION_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/exceptions/delete' -ADD_OBJECT_TO_SUSPICIOUS_LIST = '/v2.0/xdr/threatintel/suspiciousObjects' -DELETE_OBJECT_FROM_SUSPICIOUS_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/delete' -TASK_DETAIL_ENDPOINT = '/v2.0/xdr/response/getTask' -GET_COMPUTER_ID_ENDPOINT = '/v2.0/xdr/eiqs/query/agentInfo' -GET_ENDPOINT_INFO_ENDPOINT = '/v2.0/xdr/eiqs/query/endpointInfo' -GET_FILE_STATUS = '/v2.0/xdr/sandbox/tasks/{taskId}' -GET_FILE_REPORT = '/v2.0/xdr/sandbox/reports/{reportId}' -ADD_NOTE_ENDPOINT = '/v2.0/xdr/workbench/workbenches/{workbenchId}/notes' -UPDATE_STATUS_ENDPOINT = '/v2.0/xdr/workbench/workbenches/{workbenchId}' -COLLECT_FORENSIC_FILE = '/v2.0/xdr/response/collectFile' -DOWNLOAD_INFORMATION_COLLECTED_FILE = '/v2.0/xdr/response/downloadInfo' -SUBMIT_FILE_TO_SANDBOX = '/v2.0/xdr/sandbox/file' -WORKBENCH_HISTORIES = '/v2.0/xdr/workbench/workbenchHistories' -# Error Messages -RESPONSE_ERROR = 'Error in API call: [%d] - %s' -RETRY_ERROR = 'The max tries exceeded [%d] - %s' -COMMAND_CALLED = 'Command being called is {command}' -COMMAND_EXECUTION_ERROR = 'Failed to execute {error} command. Error' -AUTHORIZATION_ERROR = "Authorization Error: make sure URL/API Key is correctly set. Error - {error}" -PARAMETER_ISSUE = '{param} is not a valid paramter. Kindly provide valid parameter' -FILE_TYPE_ERROR = "Kindly provide valid file 'type'" -FILE_NOT_FOUND = 'No such file present in {filepath}' -# General Messages: -RAW_RESPONSE = "The raw response data - {raw_response}" -SUCCESS_RESPONSE = 'success with url {url} and response status {status}' -EXCEPTION_MESSAGE = "Successfully {task} object to exception list with response {code}, Total items in exception list - {length}" -SUCCESS_TEST = 'Successfully connected to the vision one API.' -POLLING_MESSAGE = ( - "The task has not completed, will check status again in 30 seconds" -) -# Workbench Statuses -NEW = 0 -IN_PROGRESS = 1 -RESOLVED_TRUE_POSITIVE = 2 -RESOLVED_FALSE_POSITIVE = 3 -# Table Heading -TABLE_ADD_TO_BLOCKLIST = 'Add to block list ' -TABLE_REMOVE_FROM_BLOCKLIST = 'Remove from block list ' -TABLE_QUARANTINE_EMAIL_MESSAGE = 'Quarantine email message ' -TABLE_DELETE_EMAIL_MESSAGE = 'Delete email message ' -TABLE_ISOLATE_ENDPOINT_MESSAGE = 'Isolate endpoint connection ' -TABLE_RESTORE_ENDPOINT_MESSAGE = 'Restore endpoint connection ' -TABLE_TERMINATE_PROCESS = 'Terminate process ' -TABLE_ADD_EXCEPTION_LIST = 'Add object to exception list ' -TABLE_DELETE_EXCEPTION_LIST = 'Delete object from exception list ' -TABLE_ADD_SUSPICIOUS_LIST = 'Add object to suspicious list ' -TABLE_ENDPOINT_INFO = 'Endpoint info ' -TABLE_DELETE_SUSPICIOUS_LIST = 'Delete object from suspicious list ' -TABLE_GET_FILE_ANALYSIS_STATUS = 'File analysis status ' -TABLE_GET_FILE_ANALYSIS_REPORT = 'File analysis report ' -TABLE_COLLECT_FILE = 'Collect forensic file ' -TABLE_COLLECTED_FORENSIC_FILE_DOWNLOAD_INFORMATION = 'The download information for collected forensic file ' -TABLE_SUBMIT_FILE_TO_SANDBOX = 'Submit file to sandbox ' -TABLE_ADD_NOTE = 'Add note to workbench alert ' -TABLE_UPDATE_STATUS = 'Update workbench alert status' -# COMMAND NAMES -ADD_BLOCKLIST_COMMAND = 'trendmicro-visionone-add-to-block-list' -REMOVE_BLOCKLIST_COMMAND = 'trendmicro-visionone-remove-from-block-list' -QUARANTINE_EMAIL_COMMAND = 'trendmicro-visionone-quarantine-email-message' -DELETE_EMAIL_COMMAND = 'trendmicro-visionone-delete-email-message' -ISOLATE_ENDPOINT_COMMAND = 'trendmicro-visionone-isolate-endpoint' -RESTORE_ENDPOINT_COMMAND = 'trendmicro-visionone-restore-endpoint-connection' -TERMINATE_PROCESS_COMMAND = 'trendmicro-visionone-terminate-process' -ADD_EXCEPTION_LIST_COMMAND = 'trendmicro-visionone-add-objects-to-exception-list' -DELETE_EXCEPTION_LIST_COMMAND = 'trendmicro-visionone-delete-objects-from-exception-list' -ADD_SUSPICIOUS_LIST_COMMAND = 'trendmicro-visionone-add-objects-to-suspicious-list' -DELETE_SUSPICIOUS_LIST_COMMAND = 'trendmicro-visionone-delete-objects-from-suspicious-list' -GET_FILE_ANALYSIS_STATUS = 'trendmicro-visionone-get-file-analysis-status' -GET_FILE_ANALYSIS_REPORT = 'trendmicro-visionone-get-file-analysis-report' -COLLECT_FILE = 'trendmicro-visionone-collect-forensic-file' -DOWNLOAD_COLLECTED_FILE = 'trendmicro-visionone-download-information-for-collected-forensic-file' -FILE_TO_SANDBOX = 'trendmicro-visionone-submit-file-to-sandbox' -CHECK_TASK_STATUS = 'trendmicro-visionone-check-task-status' -GET_ENDPOINT_INFO_COMMAND = 'trendmicro-visionone-get-endpoint-info' -UPDATE_STATUS = 'trendmicro-visionone-update-status' -ADD_NOTE = 'trendmicro-visionone-add-note' -FETCH_INCIDENTS = 'fetch-incidents' - -table_name = { - ADD_BLOCKLIST_COMMAND: TABLE_ADD_TO_BLOCKLIST, - REMOVE_BLOCKLIST_COMMAND: TABLE_REMOVE_FROM_BLOCKLIST, - QUARANTINE_EMAIL_COMMAND: TABLE_QUARANTINE_EMAIL_MESSAGE, - DELETE_EMAIL_COMMAND: TABLE_DELETE_EMAIL_MESSAGE, - ISOLATE_ENDPOINT_COMMAND: TABLE_ISOLATE_ENDPOINT_MESSAGE, - RESTORE_ENDPOINT_COMMAND: TABLE_RESTORE_ENDPOINT_MESSAGE, - ADD_EXCEPTION_LIST_COMMAND: TABLE_ADD_EXCEPTION_LIST, - DELETE_EXCEPTION_LIST_COMMAND: TABLE_DELETE_EXCEPTION_LIST, - ADD_SUSPICIOUS_LIST_COMMAND: TABLE_ADD_SUSPICIOUS_LIST, - GET_ENDPOINT_INFO_COMMAND: TABLE_ENDPOINT_INFO, - DELETE_SUSPICIOUS_LIST_COMMAND: TABLE_DELETE_SUSPICIOUS_LIST -} -# disable insecure warnings -requests.packages.urllib3.disable_warnings() - - -def check_datetime_aware(d): - return (d.tzinfo is not None) and (d.tzinfo.utcoffset(d) is not None) - - -class Client(BaseClient): - def __init__(self, base_url: str, api_key: str) -> None: - """ - Inherit the BaseClient class from the demistomock. - :type base_url: ``str`` - :param base_url: Base server address with suffix, for example: https://example.com/api/v2/. - :type api_key: ``str`` - :param api_key: api token to access the api data. - :type verify: ``bool`` - :param verify: Whether the request should verify the SSL certificate. - :return: returns None - :rtype: ``None`` - """ - super().__init__(base_url=base_url) - self.base_url = base_url - self.api_key = api_key - self.status = None - - def http_request(self, method: str, url_suffix: str, json_data=None, params=None, data=None) -> Any: - """ - Override http_request method from BaseClient class. This method will print an error based on status code - and exceptions. - :type method: ``str`` - :param method: The HTTP method, for example: GET, POST, and so on. - :type url_suffix: ``str`` - :param url_suffix: The API endpoint. - :type json_data: ``dict`` - :param json_data: The dictionary to send in a 'POST' request. - :type params: ``dict`` - :param params: URL parameters to specify the query. - :type data: ``dict`` - :param data: The data to send in a 'POST' request. - :return: response data - :rtype: ``dict`` or ``str`` or ``requests.Response`` - """ - header = { - "Authorization": "Bearer {token}".format(token=self.api_key), - "Content-Type": f'{CONTENT_TYPE_JSON};charset=utf-8', - "User-Agent": USER_AGENT, - } - try: - response = self._http_request(method=method, full_url=f'{self.base_url}{url_suffix}', retries=3, json_data=json_data, - params=params, headers=header, resp_type='response', - ok_codes=(200, 201), data=data) - except DemistoException as error: - demisto.error(error.message) - return_error(error.message) - if response.ok: - demisto.info(SUCCESS_RESPONSE.format(url=f'{self.base_url}{url_suffix}', status=response.status_code)) - self.status = response.status_code - content_type = response.headers.get('Content-Type', '') - if content_type.__contains__(CONTENT_TYPE_JSON): - # Handle empty response - if response.text == EMPTY_STRING: - return response - else: - return response.json() - else: - return response - - def status_check(self, data: Dict[str, Any]) -> Any: - """ - Check the status of particular task. - :type data: ``dict`` - :param method: Response data to received from the end point. - :return: task status response data. - :rtype: ``Any`` - """ - action_id = data.get(ACTION_ID) - params = {"actionId": action_id} - response = self.http_request(GET, TASK_DETAIL_ENDPOINT, params=params) - message = { - "actionId": action_id, - "taskStatus": response.get("data").get("taskStatus") - } - return CommandResults( - readable_output=tableToMarkdown("Status of task ", message, removeNull=True), - outputs_prefix=( - "VisionOne.Task_Status" - ), - outputs_key_field="actionId", - outputs=message) - - def lookup_type(self, param: Any) -> str: - - # Regex expression for validating IPv4 - regex = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|"\ - "2[0-4][0-9]|25[0-5])\\.){3}"\ - "([0-9]|[1-9][0-9]|1[0-9][0-9]|"\ - "2[0-4][0-9]|25[0-5])" - - # Regex expression for validating IPv6 - regex1 = "((([0-9a-fA-F]){1,4})\\:){7}"\ - "([0-9a-fA-F]){1,4}" - - # Regex expression for validating mac - regex2 = "([0-9A-Fa-f]{2}[:-]){5}"\ - "([0-9A-Fa-f]{2})" - - p = re.compile(regex) - p1 = re.compile(regex1) - p2 = re.compile(regex2) - - # Checking if it is a valid IPv4 addresses - if (re.search(p, param)): - return "ip" - - # Checking if it is a valid IPv6 addresses - elif (re.search(p1, param)): - return "ipv6" - - # Checking if it is a valid IPv6 addresses - elif (re.search(p2, param)): - return "macaddr" - - # Otherwise use hostname type - return "hostname" - - def get_computer_id(self, field: Any, value: Any) -> str: - """ - Fetch particular computer id using hostname, macaddress or ip. - :type field: ``str`` - :param field: type of field to search hostname, macaddress or ip. - :type value: ``str`` - :param value: value of the particular field. - :return: value of computer id. - :rtype: ``str`` - """ - body = { - CRITERIA: { - FIELD: field, - VALUE: value - } - } - response = self.http_request(POST, GET_COMPUTER_ID_ENDPOINT, data=json.dumps(body)) - - if response["status"] == 'FAIL': - return_error("kindly provide valid field value") - computer_id = response.get("result").get("computerId") - return computer_id - - def exception_list_count(self) -> int: - """ - Gets the count of object present in exception list - - :return: number of exception object. - :rtype: ``int`` - """ - response = self.http_request(GET, ADD_OBJECT_TO_EXCEPTION_LIST) - list_of_exception = response.get(DATA).get(EXCEPTION_LIST) - exception_count = len(list_of_exception) - return exception_count - - def suspicious_list_count(self) -> int: - """ - Gets the count of object present in suspicious list - :return: number of suspicious object. - :rtype: ``int`` - """ - response = self.http_request(GET, ADD_OBJECT_TO_SUSPICIOUS_LIST) - list_of_exception = response.get(DATA).get(SUSPICIOUS_LIST) - exception_count = len(list_of_exception) - return exception_count - - def get_workbench_histories(self, start, end, offset=None, size=None) -> str: - if not check_datetime_aware(start): - start = start.astimezone() - if not check_datetime_aware(end): - end = end.astimezone() - start = start.astimezone(timezone.utc) - end = end.astimezone(timezone.utc) - start = start.isoformat(timespec='milliseconds').replace('+00:00', 'Z') - end = end.isoformat(timespec='milliseconds').replace('+00:00', 'Z') - - params = dict([('startTime', start), - ('endTime', end), - ('sortBy', 'createdTime')] - + ([('offset', offset)] if offset is not None else []) - + ([('limit', size)] if size is not None else [])) - - response = self.http_request(GET, WORKBENCH_HISTORIES, params=params)['data']['workbenchRecords'] - return response - - -def run_polling_command( - args: Dict[str, Any], - cmd: str, client: Client -) -> Union[str, CommandResults]: - """ - Performs polling interval to check status of task. - :type args: ``args`` - :param client: argument required for polling. - - :type client: ``cmd`` - :param client: The command that polled for an interval. - - :type client: ``Client`` - :param client: client object to use http_request. - """ - ScheduledCommand.raise_error_if_not_supported() - interval_in_secs = int(args.get('interval_in_seconds', 30)) - command_results = client.status_check(args) - action_id = args.get("actionId") - if command_results.outputs.get( - "taskStatus") not in ( - "success", "failed", "timeout", "skipped"): - # schedule next poll - polling_args = { - 'actionId': action_id, - 'interval_in_seconds': interval_in_secs, - 'polling': True, - **args - } - scheduled_command = ScheduledCommand( - command=cmd, - next_run_in_seconds=interval_in_secs, - args=polling_args, - timeout_in_seconds=1500) # The timeout interval set for 25 minutes. - command_results = CommandResults(scheduled_command=scheduled_command) - return command_results - - -def get_task_status( - args: Dict[str, Any], - client: Client -) -> Union[str, CommandResults]: - """ - check status of task. - - :type args: ``args`` - :param client: argument required for polling. - - :type client: ``Client`` - :param client: client object to use http_request. - """ - return run_polling_command(args, CHECK_TASK_STATUS, client) - - -def test_module(client: Client) -> Any: - """ - Performs basic get request to get item samples. - :type client: ``Client`` - :param client: client object to use http_request. - """ - client.http_request('GET', '/v2.0/xdr/threatintel/suspiciousObjects/exceptions') - return 'ok' - - -def get_endpoint_info( - client: Client, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Retrieve information abouut the endpoint queried and - sends the result to demisto war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - - value = args.get(ENDPOINT) - field = client.lookup_type(value) - - computer_id = client.get_computer_id(field, value) - body = { - 'computerId': computer_id - } - response = client.http_request( - POST, GET_ENDPOINT_INFO_ENDPOINT, data=json.dumps(body) - ) - - message = { - "message": response.get("message", ""), - "errorCode": response.get("errorCodecode", ""), - "status": response.get("status", ""), - "logonAccount": response.get("result", {}) - .get("logonAccount", "") - .get("value", ""), - "hostname": response.get("result", {}) - .get("hostname", "") - .get("value", ""), - "macAddr": response.get("result", {}) - .get("macAddr", "") - .get("value", ""), - "ip": response.get("result", {}) - .get("ip", "") - .get("value", ""), - "osName": response.get("result", {}) - .get("osName", ""), - "osVersion": response.get("result", {}) - .get("osVersion", ""), - "osDescription": response.get("result", {}) - .get("osDescription", ""), - "productCode": response.get("result", {}) - .get("productCode", ""), - } - - results = CommandResults( - readable_output=tableToMarkdown( - table_name[GET_ENDPOINT_INFO_COMMAND], message, removeNull=True - ), - outputs_prefix="VisionOne.Endpoint_Info", - outputs_key_field="message", - outputs=message, - ) - return results - - -def add_delete_block_list_mapping( - data: Dict[str, Any] -) -> Dict[str, Any]: - """ - Mapping add to block list response data. - - :type data: ``dict`` - :param data: Response data to received from the end point. - - :return: mapped response data. - :rtype: ``dict`` - """ - action_id = data.get("actionId", {}) - task_status = data.get("taskStatus", {}) - return {"actionId": action_id, "taskStatus": task_status} - - -def add_or_remove_from_block_list( - client: Client, command: str, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Retrieve data from the add or remove from block list and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type command: ``str`` - :param command: type of command either - trendmicro-visionone-add-to-block-list or - trendmicro-visionone-remove-from-block-list. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - value_type = args.get(VALUE_TYPE) - target_value = args.get(TARGET_VALUE) - product_id = args.get(PRODUCT_ID) - if not product_id: - product_id = EMPTY_STRING - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - body = { - 'valueType': value_type, - 'targetValue': target_value, - 'productId': product_id, - 'description': description, - } - if command == ADD_BLOCKLIST_COMMAND: - response = client.http_request( - POST, ADD_BLOCKLIST_ENDPOINT, data=json.dumps(body) - ) - elif command == REMOVE_BLOCKLIST_COMMAND: - response = client.http_request( - POST, REMOVE_BLOCKLIST_ENDPOINT, data=json.dumps(body) - ) - - mapping_data = add_delete_block_list_mapping(response) - results = CommandResults( - readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), - outputs_prefix="VisionOne.BlockList", - outputs_key_field="actionId", - outputs=mapping_data, - ) - return results - - -def fetch_incidents(client: Client): - """ - This function do the loop to get all workbench alerts by changing - the parameters of both 'offset' and 'size'. - """ - offset = 0 - size = demisto.params().get('max_fetch') - end = datetime.now(timezone.utc) - days = int(demisto.params().get('first_fetch')) - - last_run = demisto.getLastRun() - if last_run and 'start_time' in last_run: - start = datetime.fromisoformat(last_run.get('start_time')) - else: - start = end + timedelta(days=-days) - - alerts: List[Any] = [] - alerts.extend(client.get_workbench_histories(start, end, offset, size)) - - incidents = [] - if alerts: - for record in alerts: - incident = { - 'name': record['workbenchName'], - 'occurred': record['createdTime'], - 'rawJSON': json.dumps(record) - } - incidents.append(incident) - last_event = datetime.strptime(record['createdTime'], "%Y-%m-%dT%H:%M:%SZ") - - next_search = last_event + timedelta(0, 1) - - demisto.setLastRun({ - 'start_time': next_search.isoformat() - }) - - if incidents: - demisto.incidents(incidents) - else: - demisto.incidents([]) - - return incidents - - -def quarantine_delete_email_mapping( - data: Dict[str, Any] -) -> Dict[str, Any]: - """ - Mapping quarantine email message response data. - - :type data: ``dict`` - :param method: Response data to received from the end point. - - :return: mapped response data. - :rtype: ``dict`` - """ - action_id = data.get("actionId", {}) - task_status = data.get("taskStatus", {}) - return {"actionId": action_id, "taskStatus": task_status} - - -def quarantine_or_delete_email_message( - client: Client, command: str, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Retrieve data from the quarantine or delete email message and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type command: ``str`` - :param command: type of command either - trendmicro-visionone-quarantine-email-message or - trendmicro-visionone-delete-email-message - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - message_id = args.get(MESSAGE_ID) - mailbox = args.get(MAILBOX) - message_delivery_time = args.get(MESSAGE_DELIVERY_TIME) - product_id = args.get(PRODUCT_ID) - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - body = { - 'messageId': message_id, - 'mailBox': mailbox, - 'messageDeliveryTime': message_delivery_time, - 'productId': product_id, - 'description': description - } - if command == QUARANTINE_EMAIL_COMMAND: - response = client.http_request( - POST, QUARANTINE_EMAIL_ENDPOINT, data=json.dumps(body) - ) - - elif command == DELETE_EMAIL_COMMAND: - response = client.http_request( - POST, DELETE_EMAIL_ENDPOINT, data=json.dumps(body) - ) - - mapping_data = quarantine_delete_email_mapping(response) - results = CommandResults( - readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), - outputs_prefix="VisionOne.Email", - outputs_key_field="actionId", - outputs=mapping_data, - ) - return results - - -def isolate_restore_endpoint_mapping( - data: Dict[str, Any] -) -> Dict[str, Any]: - """ - Mapping isolate endpoint and restore endpoint response data. - - :type data: ``dict`` - :param method: Response data to received from the end point. - - :return: mapped response data. - :rtype: ``dict`` - """ - action_id = data.get("actionId", {}) - task_status = data.get("taskStatus", {}) - return {"actionId": action_id, "taskStatus": task_status} - - -def isolate_or_restore_connection( - client: Client, command: str, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Retrieve data from the isolate or restore endpoint connection and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type command: ``str`` - :param command: type of command either - trendmicro-visionone-isolate-endpoint or - trendmicro-visionone-restore-endpoint-connection - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - value = args.get(ENDPOINT) - field = client.lookup_type(value) - product_id = args.get(PRODUCT_ID) - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - computer_id = client.get_computer_id(field, value) - body = { - 'computerId': computer_id, - 'productId': product_id, - 'description': description - } - if command == ISOLATE_ENDPOINT_COMMAND: - response = client.http_request( - POST, ISOLATE_CONNECTION_ENDPOINT, data=json.dumps(body) - ) - - elif command == RESTORE_ENDPOINT_COMMAND: - response = client.http_request( - POST, RESTORE_CONNECTION_ENDPOINT, data=json.dumps(body) - ) - - mapping_data = isolate_restore_endpoint_mapping( - response) - - results = CommandResults( - readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), - outputs_prefix="VisionOne.Endpoint_Connection", - outputs_key_field="actionId", - outputs=mapping_data, - ) - return results - - -def terminate_process( - client: Client, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Terminate the process running on the end point and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - file_list = [] - value = args.get(ENDPOINT) - field = client.lookup_type(value) - product_id = args.get(PRODUCT_ID) - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - computer_id = client.get_computer_id(field, value) - file_sha1 = args.get(FILESHA) - filename = args.get(FILENAME) - if filename: - file_list.append(filename) - body = { - 'computerId': computer_id, - 'fileSha1': file_sha1, - 'productId': product_id, - 'description': description, - 'filename': file_list - } - response = client.http_request( - POST, TERMINATE_PROCESS_ENDPOINT, data=json.dumps(body) - ) - - action_id = response.get("actionId", {}) - task_status = response.get("taskStatus", {}) - message = {"actionId": action_id, "taskStatus": task_status} - results = CommandResults( - readable_output=tableToMarkdown(TABLE_TERMINATE_PROCESS, message, removeNull=True), - outputs_prefix="VisionOne.Terminate_Process", - outputs_key_field="actionId", - outputs=message, - ) - return results - - -def add_or_delete_from_exception_list( - client: Client, command: str, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Add or Delete the exception object to exception list and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type command: ``str`` - :param command: type of command either - trendmicro-visionone-add-objects-to-exception-list or - trendmicro-visionone-delete-objects-from-exception-list - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - types = args.get(TYPE) - value = args.get(VALUE) - body = {DATA: [{'type': types, 'value': value}]} - if command == ADD_EXCEPTION_LIST_COMMAND: - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - body[DATA][0][DESCRIPTION] = description - client.http_request( - POST, ADD_OBJECT_TO_EXCEPTION_LIST, data=json.dumps(body) - ) - - elif command == DELETE_EXCEPTION_LIST_COMMAND: - client.http_request( - POST, DELETE_OBJECT_FROM_EXCEPTION_LIST, data=json.dumps(body) - ) - - exception_list = client.exception_list_count() - - message = { - "message": "success", - "status_code": client.status, - "total_items": exception_list, - } - results = CommandResults( - readable_output=tableToMarkdown(table_name[command], message, removeNull=True), - outputs_prefix="VisionOne.Exception_List", - outputs_key_field="message", - outputs=message, - ) - return results - - -def add_to_suspicious_list( - client: Client, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Add suspicious object to suspicious list and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - types = args.get(TYPE) - value = args.get(VALUE) - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - scan_action = args.get(SCAN_ACTION) - if scan_action and scan_action not in ("log", "block"): - return_error(PARAMETER_ISSUE.format(param=SCAN_ACTION)) - risk_level = args.get(RISK_LEVEL) - if risk_level and risk_level not in ("high", "medium", "low"): - return_error(PARAMETER_ISSUE.format(param=RISK_LEVEL)) - expiry = args.get(EXPIRYDAY) - if not expiry: - expiry = 0 - body = { - DATA: [ - { - 'type': types, - 'value': value, - 'description': description, - 'scanAction': scan_action, - 'riskLevel': risk_level, - 'expiredDay': expiry - } - ] - } - client.http_request( - POST, ADD_OBJECT_TO_SUSPICIOUS_LIST, data=json.dumps(body) - ) - suspicious_list = client.suspicious_list_count() - - message = { - "message": "success", - "status_code": client.status, - "total_items": suspicious_list, - } - results = CommandResults( - readable_output=tableToMarkdown( - table_name[ADD_SUSPICIOUS_LIST_COMMAND], message, removeNull=True - ), - outputs_prefix="VisionOne.Suspicious_List", - outputs_key_field="message", - outputs=message, - ) - return results - - -def delete_from_suspicious_list( - client: Client, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Delete the suspicious object from suspicious list and - sends the result to demist war room. - - :type client: ``Client`` - :param client: client object to use http_request. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - types = args.get(TYPE) - value = args.get(VALUE) - body = {DATA: [{'type': types, 'value': value}]} - client.http_request( - POST, DELETE_OBJECT_FROM_SUSPICIOUS_LIST, data=json.dumps(body) - ) - - exception_list = client.suspicious_list_count() - - message = { - "message": "success", - "status_code": client.status, - "total_items": exception_list, - } - results = CommandResults( - readable_output=tableToMarkdown( - table_name[DELETE_SUSPICIOUS_LIST_COMMAND], message, removeNull=True - ), - outputs_prefix="VisionOne.Suspicious_List", - outputs_key_field="message", - outputs=message, - ) - return results - - -def get_file_analysis_status( - client: Client, args: Dict[str, Any] -) -> Union[str, CommandResults]: - """ - Get the status of file based on task id and - sends the result to demist war room - - :type client: ``Client`` - :param client: client object to use http_request. - - :type args: ``dict`` - :param args: args object to fetch the argument data. - - :return: sends data to demisto war room. - :rtype: ``dict` - """ - task_id = args.get(TASKID) - response = client.http_request(GET, GET_FILE_STATUS.format(taskId=task_id)) - - message = { - "message": response.get("message", ""), - "code": response.get("code", ""), - "task_id": response.get("data", {}).get("taskId", ""), - "taskStatus": response.get("data", {}).get("taskStatus", ""), - "digest": response.get("data", {}).get("digest", ""), - "analysis_completion_time": response.get("data", {}) - .get("analysisSummary", "") - .get("analysisCompletionTime", ""), - "risk_level": response.get("data", {}) - .get("analysisSummary", "") - .get("riskLevel", ""), - "description": response.get("data", {}) - .get("analysisSummary", "") - .get("description", ""), - "detection_name_list": response.get("data", {}) - .get("analysisSummary", "") - .get("detectionNameList", ""), - "threat_type_list": response.get("data", {}) - .get("analysisSummary", "") - .get("threatTypeList", ""), - "file_type": response.get("data", {}) - .get("analysisSummary", "") - .get("trueFileType", ""), - "report_id": response.get("data", {}).get("reportId", ""), - } - results = CommandResults( - readable_output=tableToMarkdown( - TABLE_GET_FILE_ANALYSIS_STATUS, message, removeNull=True), - outputs_prefix="VisionOne.File_Analysis_Status", - outputs_key_field="message", - outputs=message, - ) - return results - - -def get_file_analysis_report(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - Get the report of file based on report id and sends the result to demist war room - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - report_id = args.get(REPORT_ID) - types = args.get(TYPE) - if types not in ('vaReport', 'investigationPackage', 'suspiciousObject'): - return_error(FILE_TYPE_ERROR) - params = { - TYPE: types - } - response = client.http_request(GET, GET_FILE_REPORT.format(reportId=report_id), params=params) - if isinstance(response, dict): - - message = { - 'message': response.get("message", ""), - 'code': response.get("code", ""), - 'data': [] - } - if len(response.get('data', [])) > 0: - for data in response.get('data', {}): - data_value = { - 'type': data.get("type", ""), - 'value': data.get("value", ""), - 'risk_level': data.get("riskLevel", ""), - 'analysis_completion_time': data.get("analysisCompletionTime", ""), - 'expired_time': data.get("expiredTime", ""), - 'root_file_sha1': data.get("rootFileSha1", "") - } - message.get('data', {}).append(data_value) - results = CommandResults( - readable_output=tableToMarkdown(TABLE_GET_FILE_ANALYSIS_REPORT, message, removeNull=True), - outputs_prefix='VisionOne.File_Analysis_Report', - outputs_key_field='message', - outputs=message - ) - elif response.headers.get('Content-Type', '') == 'binary/octet-stream': - data = response.content - if types == 'vaReport': - results = fileResult('Sandbox_Analysis_Report.pdf', data, file_type=EntryType.ENTRY_INFO_FILE) - else: - results = fileResult('Sandbox_Investigation_Package.zip', data, file_type=EntryType.ENTRY_INFO_FILE) - return results - - -def collect_file(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - Collect forensic file and sends the result to demist war room - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - value = args.get(ENDPOINT) - field = client.lookup_type(value) - product_id = args.get(PRODUCT_ID) - description = args.get(DESCRIPTION) - if not description: - description = EMPTY_STRING - computer_id = client.get_computer_id(field, value) # type: ignore - file_path = args.get(FILE_PATH) - os = args.get(OS_TYPE) - body = { - 'description': description, - 'productId': product_id, - 'computerId': computer_id, - 'filePath': file_path, - 'os': os - } - response = client.http_request(POST, COLLECT_FORENSIC_FILE, data=json.dumps(body)) - - task_status = response.get("taskStatus", {}) - action_id = response.get('actionId', {}) - message = { - 'actionId': action_id, - 'taskStatus': task_status - } - results = CommandResults( - readable_output=tableToMarkdown(TABLE_COLLECT_FILE, message, removeNull=True), - outputs_prefix='VisionOne.Collect_Forensic_File', - outputs_key_field='actionId', - outputs=message - ) - return results - - -def download_information_collected_file(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - Gets the download information for collected forensic file and sends the result to demist war room - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - action_id = args.get(ACTION_ID) - params = {'actionId': action_id} - response = client.http_request(GET, DOWNLOAD_INFORMATION_COLLECTED_FILE, params=params) - - file_url = response.get('data', '').get('url', '') - expires = response.get('data', '').get('expires', '') - password = response.get('data', '').get('password', '') - filename = response.get('data', '').get('filename', '') - message = { - 'url': file_url, - 'expires': expires, - 'password': password, - 'filename': filename - } - results = CommandResults( - readable_output=tableToMarkdown(TABLE_COLLECTED_FORENSIC_FILE_DOWNLOAD_INFORMATION, message, removeNull=True), - outputs_prefix='VisionOne.Download_Information_For_Collected_Forensic_File', - outputs_key_field='url', - outputs=message - ) - return results - - -def submit_file_to_sandbox(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - submit file to sandbox and sends the result to demist war room - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - data = {} - params: Dict[Any, Any] = {} - file_url = args.get(FILE_URL) - file_name = args.get(FILE_NAME) - document_pass = args.get(DOCUMENT_PASSWORD) - if document_pass: - data['documentPassword'] = base64.b64encode(document_pass.encode(ASCII)).decode(ASCII) - archive_pass = args.get(ARCHIVE_PASSWORD) - if archive_pass: - data['archivePassword'] = base64.b64encode(archive_pass.encode(ASCII)).decode(ASCII) - headers = {AUTHORIZATION: f'{BEARER}{client.api_key}'} - try: - file_content = requests.get(file_url, allow_redirects=True) # type: ignore - files = {'file': (file_name, file_content.content, 'application/x-zip-compressed')} - result = requests.post(f'{client.base_url}{SUBMIT_FILE_TO_SANDBOX}', params=params, - headers=headers, data=data, files=files) - result.raise_for_status() - except HTTPError as http_err: - demisto.error(http_err) - return_error(http_err) - except Exception as err: - demisto.error(err) - return_error(err) - else: - response = result.json() - - message = { - 'message': response.get("message", ""), - 'code': response.get("code", ""), - 'task_id': response.get("data", "").get("taskId", ""), - 'digest': response.get("data", "").get("digest", ""), - } - results = CommandResults( - readable_output=tableToMarkdown(TABLE_SUBMIT_FILE_TO_SANDBOX, message, removeNull=True), - outputs_prefix='VisionOne.Submit_File_to_Sandbox', - outputs_key_field='message', - outputs=message - ) - return results - - -def add_note(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - Adds a note to an existing workbench alert - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - workbench_id = args.get(WORKBENCH_ID) - content = args.get(CONTENT) - - body = { - 'content': content - } - response = client.http_request( - POST, ADD_NOTE_ENDPOINT.format(workbenchId=workbench_id), data=json.dumps(body) - ) - - note_id = response.get("data").get("id") - response_code = response.get("info").get("code") - response_msg = response.get("info").get("msg") - message = {"Workbench_Id": workbench_id, "noteId": note_id, "response_code": response_code, "response_msg": response_msg} - results = CommandResults( - readable_output=tableToMarkdown(TABLE_ADD_NOTE, message, removeNull=True), - outputs_prefix="VisionOne.Add_Note", - outputs_key_field="noteId", - outputs=message, - ) - return results - - -def update_status(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: - """ - Updates the status of an existing workbench alert - :type client: ``Client`` - :param client: client object to use http_request. - :type args: ``dict`` - :param args: args object to fetch the argument data. - :return: sends data to demisto war room. - :rtype: ``dict` - """ - workbench_id = args.get(WORKBENCH_ID) - status = args.get(STATUS) - - if status == 'new': - update_status = NEW - elif status == 'in_progress': - update_status = IN_PROGRESS - elif status == 'resolved_true_positive': - update_status = RESOLVED_TRUE_POSITIVE - elif status == 'resolved_false_positive': - update_status = RESOLVED_FALSE_POSITIVE - - body = { - 'investigationStatus': update_status - } - response = client.http_request( - PUT, UPDATE_STATUS_ENDPOINT.format(workbenchId=workbench_id), data=json.dumps(body) - ) - - response_code = response.get("info").get("code") - response_msg = response.get("info").get("msg") - message = {"Workbench_Id": workbench_id, "response_code": response_code, "response_msg": response_msg} - results = CommandResults( - readable_output=tableToMarkdown(TABLE_UPDATE_STATUS, message, removeNull=True), - outputs_prefix="VisionOne.Update_Status", - outputs_key_field="Workbench_Id", - outputs=message, - ) - return results - - -def main(): - try: - ''' GLOBAL VARS ''' - params = demisto.params() - - base_url = params.get(URL) - api_key = params.get(API_TOKEN).get('password') - - client = Client(base_url, api_key) - - command = demisto.command() - demisto.debug(COMMAND_CALLED.format(command=command)) - args = demisto.args() - - if command == 'test-module': - return_results(test_module(client)) - - elif command == 'fetch-incidents': - return_results(fetch_incidents(client)) - - elif command in (ADD_BLOCKLIST_COMMAND, REMOVE_BLOCKLIST_COMMAND): - return_results(add_or_remove_from_block_list(client, command, args)) - - elif command in (QUARANTINE_EMAIL_COMMAND, DELETE_EMAIL_COMMAND): - return_results(quarantine_or_delete_email_message(client, command, args)) - - elif command in (ISOLATE_ENDPOINT_COMMAND, RESTORE_ENDPOINT_COMMAND): - return_results(isolate_or_restore_connection(client, command, args)) - - elif command == TERMINATE_PROCESS_COMMAND: - return_results(terminate_process(client, args)) - - elif command in (ADD_EXCEPTION_LIST_COMMAND, DELETE_EXCEPTION_LIST_COMMAND): - return_results(add_or_delete_from_exception_list(client, command, args)) - - elif command == ADD_SUSPICIOUS_LIST_COMMAND: - return_results(add_to_suspicious_list(client, args)) - - elif command == DELETE_SUSPICIOUS_LIST_COMMAND: - return_results(delete_from_suspicious_list(client, args)) - - elif command == GET_FILE_ANALYSIS_STATUS: - return_results(get_file_analysis_status(client, args)) - - elif command == GET_FILE_ANALYSIS_REPORT: - return_results(get_file_analysis_report(client, args)) - - elif command == GET_ENDPOINT_INFO_COMMAND: - return_results(get_endpoint_info(client, args)) - - elif command == COLLECT_FILE: - return_results(collect_file(client, args)) - - elif command == DOWNLOAD_COLLECTED_FILE: - return_results(download_information_collected_file(client, args)) - - elif command == FILE_TO_SANDBOX: - return_results(submit_file_to_sandbox(client, args)) - - elif command == UPDATE_STATUS: - return_results(update_status(client, args)) - - elif command == ADD_NOTE: - return_results(add_note(client, args)) - - elif command == CHECK_TASK_STATUS: - if args.get("polling") == "true": - cmd_res = get_task_status(args, client) - if cmd_res is not None: - return_results(cmd_res) - else: - return_results(client.status_check(args)) - - else: - demisto.error(f'{command} command is not implemented.') - raise NotImplementedError(f'{command} command is not implemented.') - - except Exception as error: - demisto.error(COMMAND_EXECUTION_ERROR.format(error=error)) - - -if __name__ in ['__main__', 'builtin', 'builtins']: - main() diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml deleted file mode 100644 index 814337753f33..000000000000 --- a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml +++ /dev/null @@ -1,657 +0,0 @@ -category: Data Enrichment & Threat Intelligence -commonfields: - id: Trend Micro Vision One - version: -1 -configuration: -- additionalinfo: The base url for the Trend Micro Vision One API - defaultvalue: https://api.xdr.trendmicro.com - display: API URL (e.g. https://api.xdr.trendmicro.com) - name: url - required: true - type: 0 -- additionalinfo: The API token to access data - displaypassword: API Key - name: apikey - required: true - type: 9 - hiddenusername: true -- display: Fetch incidents - name: isFetch - required: false - type: 8 -- defaultvalue: "5" - display: Incidents Fetch Interval - name: incidentFetchInterval - required: false - type: 19 -- display: Incident type - name: incidentType - required: false - defaultvalue: Trend Micro Vision One XDR Incident - type: 13 -- defaultvalue: "30" - display: Sync On First Run (days) - name: first_fetch - required: false - type: 0 -- defaultvalue: "50" - display: Max Incidents - name: max_fetch - required: false - type: 0 -description: Trend Micro Vision One is a purpose-built threat defense platform that - provides added value and new benefits beyond XDR solutions, allowing you to see - more and respond faster. Providing deep and broad extended detection and response - (XDR) capabilities that collect and automatically correlate data across multiple - security layers—email, endpoints, servers, cloud workloads, and networks—Trend Micro - Vision One prevents the majority of attacks with automated protection. -display: Trend Micro Vision One -defaultmapperin: Trend Micro Vision One XDR - Incoming Mapper -name: Trend Micro Vision One -script: - commands: - - arguments: - - description: 'The type of object you would like to add to the block list: "file_sha1", - "ip", "domain", "url" or "mailbox"' - name: value_type - required: true - auto: PREDEFINED - predefined: - - file_sha1 - - domain - - ip - - url - - mailbox - - description: The object you would like to add that matches the value-type - name: target_value - required: true - - description: Target product - name: product_id - - description: Optional description for reference - name: description - description: Adds a file SHA-1, IP address, domain, or URL object to the User-Defined - Suspicious Objects List, which blocks the objects on subsequent detections - name: trendmicro-visionone-add-to-block-list - outputs: - - contextPath: VisionOne.BlockList.actionId - description: Action ID of task adding file SHA-1, IP address, domain, or URL - to the User-Defined Suspicious Objects List - type: string - - contextPath: VisionOne.BlockList.taskStatus - description: Task status of adding file SHA-1, IP address, domain, or URL object - to the User-Defined Suspicious Objects List - type: string - - arguments: - - description: 'The type of object you would like to remove from the block list: - "file_sha1", "ip", "domain", "url" or "mailbox"' - name: value_type - auto: PREDEFINED - predefined: - - file_sha1 - - domain - - ip - - url - - mailbox - required: true - - description: The object you would like to add that matches the value-type - name: target_value - required: true - - description: Target product - name: product_id - - description: Optional description for reference - name: description - description: Removes a file SHA-1, IP address, domain, or URL from the User-Defined - Suspicious Objects List - name: trendmicro-visionone-remove-from-block-list - outputs: - - contextPath: VisionOne.BlockList.actionId - description: Action ID of task removing file SHA-1, IP address, domain, or URL - object from the User-Defined Suspicious Objects List - type: string - - contextPath: VisionOne.BlockList.taskStatus - description: Task Status of removing file SHA-1, IP address, domain, or URL - object that was added to the User-Defined Suspicious Objects List from block - list - type: string - - arguments: - - description: Email Message ID from Trend Micro Vision One message activity data - name: message_id - required: true - - description: Email mailbox where the message will be quarantined from - name: mailbox - required: true - - description: Email message's original delivery time - name: message_delivery_time - required: true - - default: true - defaultValue: sca - description: Target product - name: product_id - - description: Optional description for reference - name: description - description: Moves a message from a mailbox to the quarantine folder - name: trendmicro-visionone-quarantine-email-message - outputs: - - contextPath: VisionOne.Email.actionId - description: The Action Id of moving a message from a mailbox to the quarantine - folder - type: string - - contextPath: VisionOne.Email.taskStatus - description: The status of moving a message from a mailbox to the quarantine - folder - type: string - - arguments: - - description: Email Message ID from Trend Micro Vision One message activity data - name: message_id - required: true - - description: Email mailbox where the message will be quarantined from - name: mailbox - required: true - - description: Email message's delivery time - name: message_delivery_time - required: true - - default: true - defaultValue: sca - description: Target product - name: product_id - - description: Optional description for reference - name: description - description: Deletes a message from a mailbox - name: trendmicro-visionone-delete-email-message - outputs: - - contextPath: VisionOne.Email.actionId - description: The action id of deleting a message from a mailbox - type: string - - contextPath: VisionOne.Email.taskStatus - description: The task status of deleting a message from a mailbox - type: string - - arguments: - - description: '"hostname", "macaddr" or "ip" of the endpoint to isolate' - name: endpoint - required: true - - default: true - defaultValue: sao - description: 'Target product: "sao", "sds", or "xes"' - name: product_id - auto: PREDEFINED - predefined: - - sao - - sds - - xes - required: true - - description: Description - name: description - description: Disconnects an endpoint from the network (but allows communication - with the managing Trend Micro product) - name: trendmicro-visionone-isolate-endpoint - outputs: - - contextPath: VisionOne.Endpoint_Connection.actionId - description: The action ID of isolate endpoint task - type: string - - contextPath: VisionOne.Endpoint_Connection.taskStatus - description: 'The task status of isolate endpoint ' - type: string - - arguments: - - description: '"hostname", "macaddr" or "ip" of the endpoint to restore' - name: endpoint - required: true - - default: true - defaultValue: sao - description: 'Target product: "sao", "sds", or "xes"' - name: product_id - auto: PREDEFINED - predefined: - - sao - - sds - - xes - required: true - - description: Description - name: description - description: Restores network connectivity to an endpoint that applied the "isolate - endpoint" action - name: trendmicro-visionone-restore-endpoint-connection - outputs: - - contextPath: VisionOne.Endpoint_Connection.actionId - description: The action ID of the restore endpoint connection - type: string - - contextPath: VisionOne.Endpoint_Connection.taskStatus - description: The task status of restore endpoint connection - type: string - - arguments: - - description: 'Object type: "domain", "ip", "sha1", or "url".' - name: type - auto: PREDEFINED - predefined: - - domain - - ip - - sha1 - - url - required: true - - description: The object value. Full and partial matches supported. Domain partial - match, (with a wildcard as the subdomain, example, .example.com) IP partial - match, (IP range example, 192.168.35.1-192.168.35.254, cidr example, 192.168.35.1/24) - URL Partial match, (Supports wildcards 'http://.'', 'https://.'' at beginning, - or ''' at the end. Multiple wild cards also supported, such as , https://.example.com/path1/) - SHA1 Only full match" - name: value - required: true - - description: Exception description. - name: description - description: Adds domains, file SHA-1 values, IP addresses, or URLs to the Exception - List and prevents these objects from being added to the Suspicious Object List - name: trendmicro-visionone-add-objects-to-exception-list - outputs: - - contextPath: VisionOne.Exception_List.message - description: status message success after task completion - type: string - - contextPath: VisionOne.Exception_List.status_code - description: status code of response - type: string - - contextPath: VisionOne.Exception_List.total_items - description: count of item present in exception list - type: string - - arguments: - - description: 'Object type: "domain", "ip", "sha1", or "url".' - name: type - auto: PREDEFINED - predefined: - - domain - - ip - - sha1 - - url - required: true - - description: The object value. - name: value - required: true - description: Deletes domains, file SHA-1 values, IP addresses, or URLs from the - Exception List. - name: trendmicro-visionone-delete-objects-from-exception-list - outputs: - - contextPath: VisionOne.Exception_List.message - description: status message success after task completion - type: string - - contextPath: VisionOne.Exception_List.status_code - description: status code of response - type: number - - contextPath: VisionOne.Exception_List.total_items - description: count of item present in exception list - type: string - - arguments: - - description: 'Object type: "domain", "ip", "sha1", or "url".' - name: type - auto: PREDEFINED - predefined: - - domain - - ip - - sha1 - - url - required: true - - description: The object value. - name: value - required: true - - description: Description - name: description - - description: The action to take if object is found. If you don't use this parameter, - the scan action specified in default_settings.riskLevel.type will be used - instead. "block" or "log". - name: scan_action - auto: PREDEFINED - predefined: - - block - - log - - description: The Suspicious Object risk level. If you don't use this parameter, - high will be used instead. "high", "medium" or "low". - name: risk_level - auto: PREDEFINED - predefined: - - high - - medium - - low - - description: The number of days to keep the object in the Suspicious Object - List. If you don't use this parameter, the default_settings.expiredDay scan - action will be used instead. - name: expiry_days - description: Adds domains, file SHA-1 values, IP addresses, or URLs to the Suspicious - Object List. - name: trendmicro-visionone-add-objects-to-suspicious-list - outputs: - - contextPath: VisionOne.Suspicious_List.message - description: Status message of adding item to suspicious object list - type: string - - contextPath: VisionOne.Suspicious_List.status_code - description: Response code of adding item to suspicious object list - type: number - - contextPath: VisionOne.Suspicious_List.total_items - description: Number of items present in suspicious object list - type: number - - arguments: - - description: 'Object type: "domain", "ip", "sha1", or "url".' - name: type - auto: PREDEFINED - predefined: - - domain - - ip - - sha1 - - url - required: true - - description: The object value. - name: value - required: true - description: Deletes domains, file SHA-1 values, IP addresses, or URLs from the - Suspicious Object List - name: trendmicro-visionone-delete-objects-from-suspicious-list - outputs: - - contextPath: VisionOne.Suspicious_List.message - description: Status message of removing item from suspicious object list - type: string - - contextPath: VisionOne.Suspicious_List.status_code - description: Response code of removing item from suspicious object list - type: number - - contextPath: VisionOne.Suspicious_List.total_items - description: Number of items present in suspicious object list - type: number - - arguments: - - description: '"hostname", "macaddr" or "ip" of the endpoint to query' - name: endpoint - required: true - description: Retrieves information about a specific endpoint - name: trendmicro-visionone-get-endpoint-info - outputs: - - contextPath: VisionOne.Endpoint_Info.message - description: Message information from the request - type: string - - contextPath: VisionOne.Endpoint_Info.errorCode - description: Error code - type: integer - - contextPath: VisionOne.Endpoint_Info.status - description: Status of the request - type: string - - contextPath: VisionOne.Endpoint_Info.logonAccount - description: Account currently logged on to the endpoint - type: string - - contextPath: VisionOne.Endpoint_Info.hostname - description: Hostname - type: string - - contextPath: VisionOne.Endpoint_Info.macAddr - description: MAC address - type: string - - contextPath: VisionOne.Endpoint_Info.ip - description: IP address - type: string - - contextPath: VisionOne.Endpoint_Info.osName - description: Operating System name - type: string - - contextPath: VisionOne.Endpoint_Info.osVersion - description: Operating System nersion - type: string - - contextPath: VisionOne.Endpoint_Info.osDescription - description: Description of the Operating System - type: string - - contextPath: VisionOne.Endpoint_Info.productCode - description: Product code of the Trend Micro product running on the endpoint - type: string - - arguments: - - description: '"hostname", "macaddr" or "ip" of the endpoint to terminate process on' - name: endpoint - required: true - - description: SHA1 hash of the process to terminate - name: file_sha1 - required: true - - default: true - defaultValue: sao - description: Target product - auto: PREDEFINED - predefined: - - sao - name: product_id - - description: Description - name: description - - description: Optional file name list for log - name: filename - description: Terminates a process that is running on an endpoint - name: trendmicro-visionone-terminate-process - outputs: - - contextPath: VisionOne.Terminate_Process.actionId - description: Action Id of the current running task - type: string - - contextPath: VisionOne.Terminate_Process.taskStatus - description: Status of current running task - type: string - - arguments: - - description: task_id from the trendmicro-visionone-submit-file-to-sandbox command - output - name: task_id - required: true - description: Retrieves the status of a sandbox analysis submission - name: trendmicro-visionone-get-file-analysis-status - outputs: - - contextPath: VisionOne.File_Analysis_Status.message - description: Status of the sandbox analysis - type: string - - contextPath: VisionOne.File_Analysis_Status.code - description: Response code - type: string - - contextPath: VisionOne.File_Analysis_Status.task_id - description: task_id of the task queried - type: string - - contextPath: VisionOne.File_Analysis_Status.taskStatus - description: Sandbox analysis status - type: string - - contextPath: VisionOne.File_Analysis_Status.digest - description: The hash values of file analyzed - type: string - - contextPath: VisionOne.File_Analysis_Status.analysis_completion_time - description: Sample analysis completed time. - type: string - - contextPath: VisionOne.File_Analysis_Status.risk_level - description: Risk Level of the analyzed file. - type: string - - contextPath: VisionOne.File_Analysis_Status.descritption - description: Scan result description for NotAnalyzed. - type: string - - contextPath: VisionOne.File_Analysis_Status.detection_name_list - description: Detection name of this sample, if applicable. - type: unknown - - contextPath: VisionOne.File_Analysis_Status.threat_type_list - description: Threat type of this sample. - - contextPath: VisionOne.File_Analysis_Status.file_type - description: File type of this sample. - type: string - - contextPath: VisionOne.File_Analysis_Status.report_id - description: ID used to get the report and suspicious object. Empty means no - report. - type: string - - arguments: - - description: report_id of the sandbox submission retrieved from the trendmicro-visionone-get-file-analysis-status - command - name: report_id - required: true - - description: 'Type of report to retrieve: "vaReport", "investigationPackage", - or "suspiciousObject"' - name: type - auto: PREDEFINED - predefined: - - vaReport - - investigationPackage - - suspiciousObject - required: true - description: Retrieves the analysis report, investigation package, or Suspicious - Object List of a submitted file - name: trendmicro-visionone-get-file-analysis-report - outputs: - - contextPath: VisionOne.File_Analysis_Report.message - description: Status message of file report - type: string - - contextPath: VisionOne.File_Analysis_Report.code - description: status code of file report - type: string - - contextPath: VisionOne.File_Analysis_Report.type - description: Suspicious object type - type: string - - contextPath: VisionOne.File_Analysis_Report.value - description: Suspicious object value - type: string - - contextPath: VisionOne.File_Analysis_Report.risk_level - description: Risk Level of suspicious object - type: string - - contextPath: VisionOne.File_Analysis_Report.analysis_completion_time - description: Analyze time of suspicious object - type: string - - contextPath: VisionOne.File_Analysis_Report.expired_time - description: Expire time of suspicious object - type: string - - contextPath: VisionOne.File_Analysis_Report.root_file_sha1 - description: Sample sha1 generate this suspicious object - type: string - - arguments: - - description: '"hostname", "macaddr" or "ip" of the endpoint to collect file from' - name: endpoint - required: true - - description: 'Product: "sao", "sds" or "xes"' - name: product_id - auto: PREDEFINED - predefined: - - sao - - xes - - sds - required: true - - description: Path to the file to collect. - name: file_path - required: true - - description: Type of OS. "windows", "mac" or "linux" - name: os - required: true - - description: Description of the file. - name: description - description: Compresses a file on an endpoint in a password-protected archive - and then sends the archive to the XDR service platform - name: trendmicro-visionone-collect-forensic-file - outputs: - - contextPath: VisionOne.Collect_Forensic_File.actionId - description: Action ID of the particular file. - type: string - - contextPath: VisionOne.Collect_Forensic_File.taskStatus - description: Task status of collected file - type: string - - arguments: - - description: actionId output from the collect command used to collect the file. - name: actionId - required: true - description: Retrieves a URL and other information required to download a collected - file via the trendmicro-visionone-collect-forensic-file command - name: trendmicro-visionone-download-information-for-collected-forensic-file - outputs: - - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.url - description: URL of the collected file - type: string - - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.expires - description: URL expiration date - type: string - - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.password - description: Archive password for the protected forensic file - type: string - - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.filename - description: Name of the collected file - type: string - - arguments: - - description: URL pointing to the location of the file to be submitted. - name: file_url - required: true - - description: Name of the file to be analyzed - name: filename - required: true - - description: The Base64 encoded password for decrypting the submitted document. - sample. - name: document_password - - description: The Base64 encoded password for decrypting the submitted archive. - name: archive_password - description: Submits a file to the sandbox for analysis (Note. For more information - about the supported file types, see the Trend Micro Vision One Online Help. - Submissions require credits. Does not require credits in regions where Sandbox - Analysis has not been officially released.) - name: trendmicro-visionone-submit-file-to-sandbox - outputs: - - contextPath: VisionOne.Submit_File_to_Sandbox.message - description: Status message of the file submitted to sandbox. - type: string - - contextPath: VisionOne.Submit_File_to_Sandbox.code - description: status code of the file submitted to sandbox - type: string - - contextPath: VisionOne.Submit_File_to_Sandbox.task_id - description: Task ID of the submitted file - type: string - - contextPath: VisionOne.Submit_File_to_Sandbox.digest - description: The hash value of the file - - arguments: - - name: polling - default: true - description: polling the task for 30 seconds interval. - defaultValue: "true" - - name: actionId - required: true - description: Action id of the task you would like to check. - outputs: - - contextPath: VisionOne.Task_Status.actionId - description: Action ID of the task queried. - - contextPath: VisionOne.Task_Status.taskStatus - description: Status of the task. - name: trendmicro-visionone-check-task-status - polling: true - description: Command gives the status of the running task based on the action id. - - arguments: - - description: ID of the workbench you would like to attach the note to. - name: workbench_id - required: true - - description: Contents of the note to be attached - name: content - required: true - outputs: - - contextPath: VisionOne.Add_Note.Workbench_Id - description: The ID of the workbench that the note was added to. - type: string - - contextPath: VisionOne.Add_Note.Note_Id - description: The ID of the note that was added. - type: string - - contextPath: VisionOne.Add_Note.Response_Code - description: The response code from the command - type: string - - contextPath: VisionOne.Add_Note.Response_Msg - description: The response message from the commandß - type: string - description: Attaches a note to a workbench alert - name: trendmicro-visionone-add-note - - arguments: - - description: ID of the workbench you would like to update the status for. - name: workbench_id - required: true - - description: Status to assign to the workbench alert - name: status - required: true - auto: PREDEFINED - predefined: - - new - - in_progress - - resolved_true_positive - - resolved_false_positive - outputs: - - contextPath: VisionOne.Update_Status.Workbench_Id - description: The ID of the workbench that had the status updated. - type: string - - contextPath: VisionOne.Update_Status.Response_Code - description: The response code from the command - type: string - - contextPath: VisionOne.Update_Status.Response_Msg - description: The response message from the commandß - type: string - description: Updates the status of a workbench alert - name: trendmicro-visionone-update-status - dockerimage: demisto/python3:3.10.4.29342 - isFetchSamples: true - isfetch: true - runonce: false - script: '' - subtype: python3 - type: python -fromversion: 6.2.0 -tests: -- No tests (auto formatted) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md deleted file mode 100644 index 8bafba79deb7..000000000000 --- a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md +++ /dev/null @@ -1,64 +0,0 @@ -#### Integration Author: Trend Micro -Support and maintenance for this integration are provided by the author. Please use the following contact details: -- **Email**: [integrations@trendmicro.com](mailto:integrations@trendmicro.com) -*** -Trend Micro Vision One is a purpose-built threat defense platform that provides added value and new benefits beyond XDR solutions, allowing you to see more and respond faster. Providing deep and broad extended detection and response (XDR) capabilities that collect and automatically correlate data across multiple security layers—email, endpoints, servers, cloud workloads, and networks—Trend Micro Vision One prevents the majority of attacks with automated protection. - -## Obtaining Trend Micro Vision One API Credentials -Configuring the Trend Micro Vision One integration requires API credentials generated in Trend Micro Vision One. It is recommended that a new role be created with just the permissions required for this integration. You can create a new role for this integration by following these steps in Trend Micro Vision One. - -1. Navigate to **Administration** > **User Roles** -2. Click on the **Add** button -3. Provide a name and descriptions for the role such as **Cortex XSOAR** -4. Click on the **Permissions** button and assign the following permissions to the role: - -| **Category** | **Application** | **Permission** | -| --- | --- | --- | -| Threat Intelligence | Suspicious Object Management | View, filter, and search | -| Threat Intelligence | Suspicious Object Management | Manage lists and configure settings | -| Threat Intelligence | Suspicious Object Management | View object in Sandbox Analysis | -| Threat Intelligence | Sandbox Analysis | View, filter, and search | -| Threat Intelligence | Sandbox Analysis | Submit objects | -| XDR | Workbench | Add exceptions | -| XDR | Workbench | Modify alert details | -| XDR | Workbench | View, filter, and search | -| Response Management | Response Management | View, filter, and search Task List tab | -| Response Management | Response Management | Approve/Reject Automated Response tasks | -| Response Management | Response Management | Collect file | -| Response Management | Response Management | Delete/Quarantine messages | -| Response Management | Response Management | Isolate endpoint | -| Response Management | Response Management | Terminate process | -| Response Management | Response Management | View network exceptions | -| Response Management | Response Management | Add to block list | -| Response Management | Response Management | Edit network exceptions | -| Response Management | Response Management | Submit to sandbox | - -You can then create a user account and generate an API key to be used for the Cortex XSOAR integration by following these steps in Trend Micro Vision One. - -1. Navigate to **Administration** > **User Accounts** -2. Click on the **Add Account** button -3. Fill in the **Add Account** details assigning the role you created in the previous step and choosing **APIs only** as the access level -4. Complete the account creation process by following the steps in the email sent -4. This will generate an **Authentication token** that can then be used to configure the Cortex XSOAR integration - -## Configure Trend Micro Vision One on Cortex XSOAR - -1. Navigate to **Settings** > **Integrations** > **Servers & Services**. -2. Search for Trend Micro Vision One. -3. Click **Add instance** to create and configure a new integration instance. - -| **Parameter** | **Description** | **Required** | -| --- | --- | --- | -| Name | Unique name for this Trend Micro Vision One instance | True | -| Fetch Incidents | Choose if the integration should sync incidents | True | -| Incident Type | Endsure the "Trend Micro Vision One XDR Incident" type is selected | True | -| Mapper (Incoming) | Endsure the "Trend Micro Vision One XDR - Incoming Mapper" type is selected | True | -| API URL | Base URL for Trend Micro Vision One API | True | -| API Key | API token for authentication | True | -| Incidents Fetch Interval | How often do you want to check for new incidents | False | -| Sync On First Run (days) | How many days to go back during first sync | False | -| Max Incidents | Maximum Number of Workbenches to Retrieve | False | -4. Click **Test** to validate the URLs, token, and connection. - ---- -[View Integration Documentation](https://xsoar.pan.dev/docs/reference/integrations/trend-micro-vision-one) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png deleted file mode 100644 index 98c959cb86c90034ee39e1d5b01c0144dba818a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2477 zcmXw4c|6ql8y|DI!o|u276KxyLciSnNimP|+kr?u`uETxDyi|fA2!#U1R?{3& z!vOSQYYNB%zZD+N#Sp>J|A{~#02jV3_0513po}4P)<(xCwDdSAEEo{~1_rutwTN6a z4iFz##{z;ZC5*74fsMifFg6MY0NA@Q9Bl$H4q(7BI2yXZTzrzl7*ZDkfloP+$JDj9 z^-U~z!NFW@eZGzXk7&%r8FAFKCidC_QWNG@E5#MPS-@dc; z_3Ic4yFN9|As7St!1zE50K?WIa!C8eO|8avTX2vBwj){e;4u%VYvO=w0RUr4NH$VO zfF_RbLi06o98KH=nlP?{8sDkG-($nk(&M7AqNl2e~RSXAf_*EkLl#%`6 z=!pqOGT+K!3QgEtS@|kj*qEK$nECYOP2XZu%gmYd>99kaYisLMf^{BG^8Cf})6T`V zc2OO3zLGvycKLHo-iMQ?h2ha$z1`Dj!URHnV_LW}I4pVjdil|lrF$I<%|E~8N@H<)y<5pP|W9*pQE+yFK_jmuSO7}DGEU|tP ze>BR=!Oj-H0|o`p2nHH1WoIQP20J1*H&;Ij|9Nx$_|Ilq3UagD!JY?qZnxB2IiD69 zN_Mf=QCpRa_O~=uU#%$0NsT#3@vVSviK7?`1H9QCe*CIRb5B#ZXuJS-I$`6rE)WMx|@YgAsWHMdCuDN>VJm~ngQbYtg zLYd)TL*Z~Z)77Vg+T{Q8$xBRAGz01V=sTy_ zcau5D{M4tX=@wD*-49Ng(Cwt)Ea_leb&DnjX; z=yrQUE?utu_2i6V-rg6&%#bvjt#?&gZPJcLr>@bRT9~gzLf*a1iBHj28}`lq+4Ji` zYwyy8wMWCZ*!Podrj3mpB`tS-J-uRyE0-%O>sim4@fj&nebTkbF*doihXs+>@w3w( zV$$a1_~QORS~uvhI5JP z7^~|or7L^U2iLS1?*si3#ZrFXfA7dnW#YL4dv6HF|ETq*ZgPf`xQCoeddK4(*G|jY zIyeJTkfl9s!kmk7^1X?dLjPNOP`paN;5+OjJy2Nk9J#Kn9RG=SmQa7Qjll}P9bC7% zWXShxdaI!|1X7FW$=rX2S%k-xs#uc!+Oo9?=;_Jcijtr%nb-kW<(2CtI6VGsw^gGb z5#aIi9MmT|ep@QO56k)n{TG5cG31t2$=gYjneYZy{MU zGNL*XxRcBH9r=@2En|d8Vjx3}f(u(oQTzFbuGl%AR+LIeQ(Dm*%HT4L9u*Vk9VwNe zeKPXbKk&I~(jNzgbUpPCy1Qc$$SywPWpjFv`*0(7^G0agG5fICV_d%RUYdem6iR~2 zq&+QaS49_HRSR?UUS+N6cN>kK_lh_-EbJF~v@uNd^!g5{KA1K1&N6I`PVs3G7aRR7 z5z0>z4r%8`Ds-zj8wYKuDDMDwRkhe$>>qNUcw1K&mdsq$pU+D28x7pj=pk9bKhn6J zMOX*@FY`t!^}ZLh{868F2H;r%8uwkNg<}oLGN?pxarnoogfnd!zI=k~C(nh9!kQwl~St3`v|BdU#dJ?dYur$Vi|~TIvKywkwYavD`>y&YYC( zEU^pRl~P~tA$_RHp~fUCEAfh}+|2`v8B6YCNt08{2{M!da{|cIAEQVVEFS9^+E89% zCM?o>HCNp}5?(Nud{|F)M7IXr{b-BTEuM`hm+oH>-7OSrBi`k2>C`>>Bux(+WTm0z?tSSWOh zX-At~>o9FyUno^ADHYhikX&}7M|FgqvpIS#IKOeIS$0Oc%RK=hHX~VHu8h0L?(W#Hyy1N1fE{Z6 zy|$vcOD>~9N~pMg@&dwT#xz8p5@&Tb=C?%4cr|uZ%m62_EfT3&qFqxJWS z@Ete}<-<%xf_#r&$)00V=x7-*%)sJxd$2q^i2mY@AxNp5M%@#FnNCF)FYc*i(yB)X zbOU!_+d&Hd7CW*Cg?mg(Pyg9TQ#g7icH$DMQB)r!ta=}`X?Vl&!jGcg9T2hjV`{%J z5^@E3h7Y62yVH&YH6CfM)gaTK2*T4dKMyr+v}m$CNSYf1VRW2QRzbMuFUfzs9zJ1- ziKDX~(=jAHtJGbo8D+JKAMZpIlv9P#OU<)~-$}^1){*=&Q>XU_TyFag50Q4" - ), - "mailBox": "kjshdfjksahd@trendenablement.com", - "messageDeliveryTime": "2021-12-09T14:00:12.000Z", - "productId": "sca", - "description": "quarantine info", - } - result = quarantine_or_delete_email_message( - client, "trendmicro-visionone-quarantine-email-message", args - ) - assert result.outputs["taskStatus"] == "pending" - assert isinstance(result.outputs["actionId"], str) - assert result.outputs_prefix == "VisionOne.Email" - assert result.outputs_key_field == "actionId" - - -# Test cases for delete email message -def test_delete_email_message(mocker): - """Test delete email message with positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - quarantine_delete_email_mock_response - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "messageId": ( - "" - ), - "mailBox": "kjshdfjksahd@trendenablement.com", - "messageDeliveryTime": "2021-12-09T14:00:55.000Z", - "productId": "sca", - "description": "quarantine info", - } - result = quarantine_or_delete_email_message( - client, "trendmicro-visionone-delete-email-message", args - ) - assert result.outputs["taskStatus"] == "pending" - assert isinstance(result.outputs["actionId"], str) - assert result.outputs_prefix == "VisionOne.Email" - assert result.outputs_key_field == "actionId" - - -# Mock function for isolate and restore endpoint -def isolate_restore_mock_response(*args, **kwargs): - return_value = { - "status": "string", - "actionId": "88139521", - "taskStatus": "pending", - "result": { - "computerId": "string", - }, - "data": { - "createdTime": 1589525651, - "executedTime": 1589525725, - "finishedTime": 1589525725, - "taskStatus": "success", - "error": {}, - }, - } - return return_value - - -# Test cases for isolate endpoint -def test_isolate_endpoint(mocker): - """Test isolate endpoint postive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - isolate_restore_mock_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "endpoint": "hostname", - "productId": "sao", - "description": "isolate endpoint info", - } - result = isolate_or_restore_connection( - client, "trendmicro-visionone-isolate-endpoint", args - ) - assert result.outputs["taskStatus"] == "pending" - assert result.outputs_prefix == "VisionOne.Endpoint_Connection" - assert result.outputs_key_field == "actionId" - - -# Test cases for restore endpoint -def test_restore_endpoint(mocker): - """Test restore endpoint positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - isolate_restore_mock_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "endpoint": "hostname", - "productId": "sao", - "description": "restore endpoint info", - } - result = isolate_or_restore_connection( - client, "trendmicro-visionone-restore-endpoint-connection", args - ) - assert result.outputs["taskStatus"] == "pending" - assert result.outputs_prefix == "VisionOne.Endpoint_Connection" - assert result.outputs_key_field == "actionId" - - -# Test cases for terminate process endpoint -def test_terminate_process_endpoint(mocker): - """Test terminate process positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - isolate_restore_mock_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "endpoint": "00:50:56:81:87:A8", - "fileSha1": "12a08b7a3c5a10b64700c0aca1a47941b50a4f8b", - "productId": "sao", - "description": "terminate info", - "filename": "testfile", - } - result = terminate_process(client, args) - assert result.outputs["taskStatus"] == "pending" - assert isinstance(result.outputs["actionId"], str) - assert result.outputs_prefix == "VisionOne.Terminate_Process" - assert result.outputs_key_field == "actionId" - - -# Mock function for add and delete exception list -def add_delete_exception_mock_response(*args, **kwargs): - return_value = 20 - return return_value - - -# Test cases for add exception list endpoint. -def test_add_object_to_exception_list(mocker): - """Test add to exception list with positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - add_delete_exception_mock_response) - mocker.patch( - "TrendMicroVisionOne.Client.exception_list_count", - add_delete_exception_mock_response - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "type": "domain", - "value": "1.alisiosanguera.com", - "description": "new key" - } - result = add_or_delete_from_exception_list( - client, - "trendmicro-visionone-add-objects-to-exception-list", - args - ) - assert result.outputs["status_code"] is None - assert result.outputs_prefix == "VisionOne.Exception_List" - assert isinstance(result.outputs["total_items"], int) - assert result.outputs_key_field == "message" - - -# Test cases for delete exception list. -def test_delete_object_to_exception_list(mocker): - """Test delete exception list positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - add_delete_exception_mock_response) - mocker.patch( - "TrendMicroVisionOne.Client.exception_list_count", - add_delete_exception_mock_response - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "type": "domain", - "value": "1.alisiosanguera.com.cn", - "description": "testing exception", - } - result = add_or_delete_from_exception_list( - client, "trendmicro-visionone-delete-objects-from-exception-list", args - ) - assert result.outputs["status_code"] is None - assert isinstance(result.outputs["total_items"], int) - assert result.outputs_prefix == "VisionOne.Exception_List" - assert result.outputs_key_field == "message" - - -# Mock response for add and delete suspicious list -def add_delete_suspicious_mock_response(*args, **kwargs): - return_value = 20 - return return_value - - -# Test cases for add suspicious object list -def test_add_object_to_suspicious_list(mocker): - """Test add to suspicious list with poistive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - add_delete_suspicious_mock_response) - mocker.patch( - "TrendMicroVisionOne.Client.suspicious_list_count", - add_delete_suspicious_mock_response - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "type": "domain", - "value": "1.alisiosanguera.com.cn", - "description": "Example Suspicious Object.", - "scanAction": "log", - "riskLevel": "high", - "expiredDay": 15, - } - result = add_to_suspicious_list(client, args) - assert result.outputs["status_code"] is None - assert isinstance(result.outputs["total_items"], int) - assert result.outputs_prefix == "VisionOne.Suspicious_List" - assert result.outputs_key_field == "message" - - -# Test cases for delete suspicious object list -def test_delete_object_from_suspicious_list(mocker): - """Test delete object from suspicious list.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - add_delete_suspicious_mock_response) - mocker.patch( - "TrendMicroVisionOne.Client.suspicious_list_count", - add_delete_suspicious_mock_response - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = {"type": "domain", "value": "1.alisiosanguera.com.cn"} - result = delete_from_suspicious_list(client, args) - assert result.outputs["status_code"] is None - assert isinstance(result.outputs["total_items"], int) - assert result.outputs_prefix == "VisionOne.Suspicious_List" - assert result.outputs_key_field == "message" - - -# Mock response for Get file analysis status -def mock_file_status_response(*args, **kwargs): - return_response = { - "code": "Success", - "message": "Success", - "data": { - "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", - "taskStatus": "finished", - "digest": { - "md5": "4ac174730d4143a119037d9fda81c7a9", - "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", - "sha256": ( - "65b0f656e79ab84ca17807158e3ea" - "c206bd58be6689ddeb95956a48748d138f9" - ), - }, - "analysisSummary": { - "analysisCompletionTime": "2021-05-07T03:08:40Z", - "riskLevel": "high", - "description": "", - "detectionNameList": [], - "threatTypeList": [], - "trueFileType": "exe", - }, - "reportId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", - }, - } - return return_response - - -# Test Cases for Get file analysis status -def test_get_file_status(mocker): - """Test to get status of file""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_file_status_response) - args = {"taskId": "921674d0-9735-4f79-b7de-c852e00a003d"} - client = Client("https://api.xdr.trendmicro.com", api_key) - result = get_file_analysis_status(client, args) - assert result.outputs["message"] == "Success" - assert result.outputs["code"] == "Success" - assert result.outputs["task_id"] == "012e4eac-9bd9-4e89-95db-77e02f75a6f3" - assert result.outputs["taskStatus"] == "finished" - assert result.outputs["report_id"] == ( - "012e4eac-9bd9-4e89-95db-77e02f75a6f3") - assert result.outputs_prefix == "VisionOne.File_Analysis_Status" - assert result.outputs_key_field == "message" - - -def test_get_report_id(mocker): - """Test to get status of file with report id""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_file_status_response) - args = {"taskId": "921674d0-9735-4f79-b7de-c852e00a003d"} - client = Client("https://api.xdr.trendmicro.com", api_key) - result = get_file_analysis_status(client, args) - assert result.outputs["message"] == "Success" - assert result.outputs["code"] == "Success" - assert result.outputs["report_id"] == ( - "012e4eac-9bd9-4e89-95db-77e02f75a6f3") - assert result.outputs_prefix == "VisionOne.File_Analysis_Status" - assert result.outputs_key_field == "message" - - -# Mock response for Get file analysis report -def mock_file_report_response(*args, **kwargs): - return_response = { - "code": "Success", - "message": "Success", - "data": [ - { - "type": "ip", - "value": "6.6.6.6", - "riskLevel": "high", - "analysisCompletionTime": "2021-05-07T03:08:40Z", - "expiredTime": "2021-06-07T03:08:40Z", - "rootFileSha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", - } - ], - } - return return_response - - -# Test cases for get file analysis report -def test_get_file_analysis_report(mocker): - """Test get file analysis report data.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_file_report_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "reportId": "800f908d-9578-4333-91e5-822794ed5483", - "type": "suspiciousObject", - } - result = get_file_analysis_report(client, args) - assert result.outputs["message"] == "Success" - assert result.outputs["code"] == "Success" - assert isinstance(result.outputs["data"][0]["type"], str) - assert isinstance(result.outputs["data"][0]["value"], str) - assert isinstance(result.outputs["data"][0]["risk_level"], str) - assert isinstance(result.outputs["data"][0]["analysis_completion_time"], str) - assert isinstance(result.outputs["data"][0]["expired_time"], str) - assert isinstance(result.outputs["data"][0]["root_file_sha1"], str) - - -def test_get_file_analysis_report_1(mocker): - """Test get file analysis report data.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_file_report_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "reportId": "800f908d-9578-4333-91e5-822794ed5483", - "type": "suspiciousObject", - } - result = get_file_analysis_report(client, args) - assert result.outputs["message"] == "Success" - assert result.outputs["code"] == "Success" - assert len(result.outputs["data"]) > 0 - - -# Mock function for isolate and restore endpoint -def mock_collect_file(*args, **kwargs): - return_value = { - "status": "string", - "actionId": "88139521", - "taskStatus": "pending", - "result": { - "computerId": "string", - }, - "data": { - "createdTime": 1589525651, - "executedTime": 1589525725, - "finishedTime": 1589525725, - "taskStatus": "success", - "error": {}, - } - } - return return_value - - -# Test cases for collect forensic file. -def test_collect_forensic_file(mocker): - """Test collect file with positive scenario.""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_collect_file) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "endpoint": "hostname", - "description": "collect file", - "productId": "sao", - "filePath": ( - "/file_path/sample.txt" - ), - "os": "linux", - } - result = collect_file(client, args) - assert result.outputs["taskStatus"] == "pending" - assert isinstance(result.outputs["actionId"], str) - assert result.outputs_prefix == "VisionOne.Collect_Forensic_File" - assert result.outputs_key_field == "actionId" - - -# Mock for downloaded file information -def mock_download_collected_file_info_response(*args, **kwargs): - return_response = { - "data": { - "url": "string", - "expires": "2011-10-05T14:48:00.000Z", - "password": "string", - "filename": "string", - } - } - return return_response - - -# Test Cases for Collected downloaded file information. -def test_get_forensic_file_information(mocker): - """Test endpoint to get collected file infomation based on action id""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_download_collected_file_info_response - ) - args = {"actionId": "00000700"} - client = Client("https://api.xdr.trendmicro.com", api_key) - result = download_information_collected_file(client, args) - assert isinstance(result.outputs["url"], str) - assert isinstance(result.outputs["expires"], str) - assert isinstance(result.outputs["password"], str) - assert isinstance(result.outputs["filename"], str) - - -# Mock response for submit file to sandbox. -def mock_submit_file_to_sandbox_reponse(*args, **kwargs): - return_response = { - "code": "Success", - "message": "Success", - "data": { - "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", - "digest": { - "md5": "4ac174730d4143a119037d9fda81c7a9", - "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", - "sha256": ( - "65b0f656e79ab84ca17807158e3ea" - "c206bd58be6689ddeb95956a48748d138f9" - ) - }, - }, - } - return return_response - - -# Mock response for submit file to sandbox. -def mocked_requests_get(*args, **kwargs): - class MockResponse: - def __init__(self, json_data, status_code, content): - self.json_data = json_data - self.status_code = status_code - self.content = content - - def json(self): - return self.json_data - - if args[0] == 'http://someurl.com/test.json': - return MockResponse({"key1": "value1"}, 200, "response") - elif args[0] == 'http://someotherurl.com/anothertest.json': - return MockResponse({"key2": "value2"}, 200, "response") - - return MockResponse(None, 404, None) - - -# Mock response for submit file to sandbox. -def mocked_requests_post(*args, **kwargs): - class MockResponse: - def __init__(self, json_data, status_code, content): - self.json_data = json_data - self.status_code = status_code - self.content = content - - def json(self): - return { - "code": "Success", - "message": "Success", - "data": { - "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", - "digest": { - "md5": "4ac174730d4143a119037d9fda81c7a9", - "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", - "sha256": ( - "65b0f656e79ab84ca17807158e3ea", - "c206bd58be6689ddeb95956a48748d138f9" - ) - }, - }, - } - - def raise_for_status(self): - return True - - if args[0] == 'http://someurl.com/test.json': - return MockResponse({"key1": "value1"}, 200, "response") - elif args[0] == 'http://someotherurl.com/anothertest.json': - return MockResponse({"key2": "value2"}, 200, "response") - - return MockResponse(None, 404, None) - - -def test_submit_file_to_sandbox(mocker): - mocker.patch( - "TrendMicroVisionOne.requests.get", - mocked_requests_get - ) - mocker.patch( - "TrendMicroVisionOne.requests.post", - mocked_requests_post - ) - args = { - "fileUrl": "http://adsd.com", - "fileName": "XDR_ResponseApp_CollectFile_ID00000700_20211206T134158Z.7z", - "archivePassword": "6hn467c8", - "documentPassword": "" - } - client = Client("https://api.xdr.trendmicro.com", api_key) - result = submit_file_to_sandbox(client, args) - assert result.outputs["message"] == "Success" - assert result.outputs["code"] == "Success" - - -# Mock function for check task status -def check_task_status_mock_response(*args, **kwargs): - return_value = { - "data": { - "createdTime": 1589525651, - "executedTime": 1589525725, - "finishedTime": 1589525725, - "taskStatus": "success", - "error": {} - } - } - return return_value - - -def test_check_task_status(mocker): - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - check_task_status_mock_response) - mocker.patch( - "CommonServerPython.ScheduledCommand.raise_error_if_not_supported", - lambda: None - ) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "actionId": "00001108" - } - result = get_task_status(args, client) - assert result.outputs["taskStatus"] == "success" - - -# Mock for downloaded file information -def mock_get_endpoint_info_response(*args, **kwargs): - return_response = { - "status": "SUCCESS", - "errorCode": 0, - "message": "message", - "result": { - "logonAccount": { - "value": [ - "DOMAIN\\username" - ], - "updateAt": 0 - }, - "hostname": { - "value": "hostname", - "updateAt": 0 - }, - "macAddr": { - "value": "00:11:22:33:44:55", - "updateAt": 0 - }, - "ip": { - "value": "192.168.1.1", - "updateAt": 0 - }, - "osName": "Windows", - "osVersion": "10.0.19042", - "osDescription": "Windows 10 Pro (64 bit) build 19042", - "productCode": "xes" - } - } - return return_response - - -# Test case for get endpoint information. -def test_get_endpoint_information(mocker): - """Test get information from endpoint based on computerid""" - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - mock_get_endpoint_info_response - ) - args = {"endpoint": "hostname"} - client = Client("https://api.xdr.trendmicro.com", api_key) - result = get_endpoint_info(client, args) - assert result.outputs["status"] == "SUCCESS" - assert isinstance(result.outputs["message"], str) - assert isinstance(result.outputs["hostname"], str) - assert isinstance(result.outputs["ip"], str) - assert isinstance(result.outputs["macAddr"], str) - assert isinstance(result.outputs["osDescription"], str) - assert isinstance(result.outputs["osName"], str) - assert isinstance(result.outputs["osVersion"], str) - assert isinstance(result.outputs["productCode"], str) - - -# Mock function for add note. -def add_note_mock_response(*args, **kwargs): - return_value = { - "data": { - "id": 123 - }, - "info": { - "code": 3021000, - "msg": "Alert notes added successfully." - } - } - return return_value - - -# Test case for add note -def test_add_note(mocker): - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - add_note_mock_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "workbench_id": "WB-20837-20220418-00000", - "content": "This is a new note." - } - result = add_note(client, args) - assert result.outputs["response_msg"] == "Alert notes added successfully." - assert isinstance(result.outputs["Workbench_Id"], str) - assert isinstance(result.outputs["noteId"], int) - assert isinstance(result.outputs["response_code"], int) - - -# Mock function for update alert status -def update_status_mock_response(*args, **kwargs): - return_value = { - "data": {}, - "info": { - "code": 3006000, - "msg": "Alert status changed successfully." - } - } - return return_value - - -# Test case for update alert status -def test_update_status(mocker): - mocker.patch( - "TrendMicroVisionOne.Client.http_request", - update_status_mock_response) - client = Client("https://api.xdr.trendmicro.com", api_key) - args = { - "workbench_id": "WB-20837-20220418-00000", - "status": "in_progress" - } - result = update_status(client, args) - assert result.outputs["response_msg"] == "Alert status changed successfully." - assert isinstance(result.outputs["Workbench_Id"], str) - assert isinstance(result.outputs["response_code"], int) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples deleted file mode 100755 index e69de29bb2d1..000000000000 diff --git a/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json b/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json deleted file mode 100644 index adac89f76abd..000000000000 --- a/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json +++ /dev/null @@ -1,475 +0,0 @@ -{ - "detailsV2": { - "tabs": [ - { - "id": "summary", - "name": "Legacy Summary", - "type": "summary" - }, - { - "id": "caseinfoid", - "name": "Incident Info", - "sections": [ - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "type", - "height": 22, - "id": "incident-type-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "severity", - "height": 22, - "id": "incident-severity-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "owner", - "height": 22, - "id": "incident-owner-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "sourcebrand", - "height": 22, - "id": "incident-sourceBrand-field", - "index": 3, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "sourceinstance", - "height": 22, - "id": "incident-sourceInstance-field", - "index": 4, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "playbookid", - "height": 22, - "id": "incident-playbookId-field", - "index": 5, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Case Details", - "static": false, - "w": 1, - "x": 0, - "y": 0 - }, - { - "h": 2, - "i": "caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Notes", - "static": false, - "type": "notes", - "w": 1, - "x": 2, - "y": 0 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Work Plan", - "static": false, - "type": "workplan", - "w": 1, - "x": 1, - "y": 0 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-770ec200-98b1-11e9-97d7-ed26ef9e46c8", - "isVisible": true, - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Linked Incidents", - "static": false, - "type": "linkedIncidents", - "w": 1, - "x": 2, - "y": 4 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-842632c0-98b1-11e9-97d7-ed26ef9e46c8", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Child Incidents", - "static": false, - "type": "childInv", - "w": 1, - "x": 2, - "y": 2 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-4a31afa0-98ba-11e9-a519-93a53c759fe0", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Evidence", - "static": false, - "type": "evidence", - "w": 1, - "x": 1, - "y": 2 - }, - { - "displayType": "ROW", - "h": 2, - "hideName": false, - "i": "caseinfoid-7717e580-9bed-11e9-9a3f-8b4b2158e260", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Team Members", - "static": false, - "type": "team", - "w": 1, - "x": 1, - "y": 4 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 2, - "moved": false, - "name": "Indicators", - "query": "", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 2, - "x": 0, - "y": 6 - }, - { - "displayType": "CARD", - "h": 2, - "i": "caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", - "items": [ - { - "endCol": 1, - "fieldId": "occurred", - "height": 53, - "id": "incident-occurred-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 1, - "fieldId": "dbotmodified", - "height": 53, - "id": "incident-modified-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "dbotduedate", - "height": 53, - "id": "incident-dueDate-field", - "index": 3, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "dbotcreated", - "height": 53, - "id": "incident-created-field", - "index": 1, - "sectionItemType": "field", - "startCol": 1 - }, - { - "endCol": 2, - "fieldId": "dbotclosed", - "height": 53, - "id": "incident-closed-field", - "index": 2, - "sectionItemType": "field", - "startCol": 1 - } - ], - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Timeline Information", - "static": false, - "w": 1, - "x": 0, - "y": 2 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-88e6bf70-a0b1-11e9-b27f-13ae1773d289", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "dbotclosed", - "height": 22, - "id": "incident-dbotClosed-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "closereason", - "height": 22, - "id": "incident-closeReason-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "closenotes", - "height": 22, - "id": "incident-closeNotes-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Closing Information", - "static": false, - "w": 1, - "x": 2, - "y": 6 - }, - { - "displayType": "CARD", - "h": 2, - "i": "caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "details", - "height": 22, - "id": "incident-details-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 1, - "moved": false, - "name": "Investigation Data", - "static": false, - "w": 1, - "x": 0, - "y": 4 - } - ], - "type": "custom" - }, - { - "hidden": false, - "id": "6p9vifzzk2", - "name": "Vision One", - "sections": [ - { - "displayType": "ROW", - "h": 6, - "hideName": false, - "i": "caseinfoid-6p9vifzzk2-field-changed-6p9vifzzk2-caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", - "items": [ - { - "dropEffect": "move", - "endCol": 6, - "fieldId": "trendmicrovisiononexdrworkbenchlink", - "height": 22, - "id": "ac4d8210-6dbd-11ec-9c6c-458673da1192", - "index": 0, - "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "trendmicrovisiononexdrworkbenchid", - "height": 22, - "id": "93969a90-6dbd-11ec-9c6c-458673da1192", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "occurred", - "height": 22, - "id": "b7431e70-7306-11ec-baea-bf8198da32cb", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "severity", - "height": 22, - "id": "a2951500-7306-11ec-baea-bf8198da32cb", - "index": 3, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 3, - "fieldId": "trendmicrovisiononexdrimpactscope", - "height": 44, - "id": "5f9241c0-6e37-11ec-800b-5b78fe23e766", - "index": 4, - "sectionItemType": "field", - "startCol": 0 - }, - { - "dropEffect": "move", - "endCol": 6, - "fieldId": "trendmicrovisiononexdrimpactedentities", - "height": 44, - "id": "b6888dc0-6e34-11ec-800b-5b78fe23e766", - "index": 5, - "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", - "sectionItemType": "field", - "startCol": 0 - }, - { - "dropEffect": "move", - "endCol": 6, - "fieldId": "trendmicrovisiononexdrindicators", - "height": 44, - "id": "c00db000-6e34-11ec-800b-5b78fe23e766", - "index": 6, - "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 6, - "fieldId": "alertname", - "height": 22, - "id": "41d77f90-7307-11ec-baea-bf8198da32cb", - "index": 1, - "sectionItemType": "field", - "startCol": 2 - } - ], - "maxH": null, - "maxW": 3, - "minH": 1, - "minW": 3, - "moved": false, - "name": "Vision One Alert Info", - "static": false, - "w": 3, - "x": 0, - "y": 0 - } - ], - "type": "custom" - }, - { - "id": "warRoom", - "name": "War Room", - "type": "warRoom" - }, - { - "id": "workPlan", - "name": "Work Plan", - "type": "workPlan" - }, - { - "id": "evidenceBoard", - "name": "Evidence Board", - "type": "evidenceBoard" - }, - { - "id": "relatedIncidents", - "name": "Related Incidents", - "type": "relatedIncidents" - }, - { - "id": "canvas", - "name": "Canvas", - "type": "canvas" - } - ] - }, - "group": "incident", - "id": "Trend Micro Vision One XDR Incident", - "name": "Trend Micro Vision One XDR Incident", - "system": false, - "version": -1, - "fromVersion": "6.2.0", - "description": "" -} \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/README.md b/Packs/TrendMicroVisionOne/README.md deleted file mode 100755 index 3fc116b7fb7d..000000000000 --- a/Packs/TrendMicroVisionOne/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Key Benefits of XDR with Trend Micro Vision One™ -## Prioritized view of threats across the organization - -Organizations without an XDR approach ignore nearly double the security alerts as those with XDR capabilities. XDR correlates and combines low level signals into high-fidelity alerts which tell the story of an attack. Security personnel can quickly understand where to focus efforts. -## More effective analysis - -With native integration into email, endpoints, servers, cloud environments, and networks, XDR sensors benefit from a deep understanding of data sources. This results in more effective analytics combined with continuously updated detection rules and global threat intelligence from Trend Micro Research, compared to having third-party integration through application programming interfaces (APIs). Organizations with an XDR approach suffered half as many successful attacks. -## Clearer contextual view of threats - -By viewing more contextual alerts across more threat vectors, events that seem benign on their own suddenly become meaningful indicators of compromise. This allows you to connect more dots into a single view, simplifying the steps towards achieving an attack-centric view of an entire chain of events across security layers and take response actions from one place. This enables more insightful investigations and gives you the ability to detect threats earlier. -## Stops more attacks, quicker - -The net of XDR is better protection for your organization through earlier detection and faster response. According to ESG, those with XDR are 2.2 times more likely to detect a data breach or successful attack in a few days or less, versus weeks or months for those without. -## Reduces time to detect and stop threats - -Collapses the time it takes to detect, contain, and respond to threats, minimizing the severity and scope of impact. ESG found that organizations with an XDR approach respond more completely to attacks and were 60% less likely to report that attack re-propagation had been an issue. -## Increased effectiveness and efficiency of threat investigation - -By automatically correlating threat data from multiple sources, XDR speeds up and removes manual steps involved in investigations and enables security analysts to quickly find the story of an attack. Organizations with an XDR approach stated it would take eight full time employees to replace the data correlation capabilities of XDR and also are 2.6 times less likely to report their team is overwhelmed. -## Integrated with third-party systems - -As you may have other security tools and technologies deployed in your environment, we offer a growing portfolio of open APIs and integrations to third-party systems, such as Palo Alto Networks Cortex™ XSOAR. Trend Micro Vision One™ has the ability to fit within these ecosystems and security operations workflows, acquiring meaningful data from your infrastructure to further enrich and validate your XDR capabilities. - ---- - -Why not take [Trend Micro Vision One™](https://resources.trendmicro.com/vision-one-test-drive.html?_ga=2.258269898.1102686256.1644357627-2.266528910.1607693918.1639750068-undefined) for a test drive to see how it can help you see more and respond faster to the threats your organization faces? \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md b/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md deleted file mode 100644 index 1f7cbe6771ad..000000000000 --- a/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md +++ /dev/null @@ -1,9 +0,0 @@ - -#### Incident Fields -- **Trend Micro Vision One XDR Indicators JSON** -- **Trend Micro Vision One XDR Impacted Entities JSON** -- **Trend Micro Vision One XDR Matched Rules JSON** - -#### Mappers -##### Trend Micro Vision One XDR - Incoming Mapper -- Added three incident fields to contain the impacted entities, indicators, and matched rules from the Trend Micro Vision One alert and updated the mapper to populate the new fields. diff --git a/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md b/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md deleted file mode 100644 index cbfc112d7907..000000000000 --- a/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md +++ /dev/null @@ -1,6 +0,0 @@ - -#### Integrations -##### Trend Micro Vision One -- Added the ***trendmicro-visionone-update-status*** command to modify the status of a Trend Micro Vision One workbench alert -- Added the ***trendmicro-visionone-add-note*** command to add a note to Trend Micro Vision One workbench alert -- Updated the Docker image to: *demisto/python3:3.10.4.29342*. diff --git a/Packs/TrendMicroVisionOne/pack_metadata.json b/Packs/TrendMicroVisionOne/pack_metadata.json deleted file mode 100755 index 0314072066bd..000000000000 --- a/Packs/TrendMicroVisionOne/pack_metadata.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "Trend Micro Vision One", - "description": "Trend Micro Vision One is a purpose-built threat defense platform that provides added value and new benefits beyond XDR solutions, allowing you to see more and respond faster. Providing deep and broad extended detection and response(XDR) capabilities that collect and automatically correlate data across multiple security layers\u2014email, endpoints, servers, cloud workloads, and networks\u2014Trend Micro Vision One prevents the majority of attacks with automated protection.", - "support": "partner", - "currentVersion": "1.1.0", - "serverMinVersion": "6.2.0", - "author": "Trend Micro", - "url": "https://success.trendmicro.com", - "email": "integrations@trendmicro.com", - "categories": [ - "Data Enrichment & Threat Intelligence" - ], - "tags": [ - "Alerts", - "Attack", - "Incident Handling", - "Incident Response", - "Malware", - "MITRE ATT&CK", - "Threat Intelligence" - ], - "created": "2022-01-06T09:00:00Z", - "useCases": [], - "keywords": [ - "xdr" - ], - "devEmail": [ - "integrations@trendmicro.com" - ], - "githubUser": [ - "mikedgibson" - ] -} \ No newline at end of file From e24dbbba6cee86b3a80c726fc5b750e32d860795 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 17:15:56 +0300 Subject: [PATCH 09/15] d --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index 8488c4b2fd27..dcc7e6a72323 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -15,7 +15,7 @@ ''' CLIENT CLASS ''' -#CHANGE +#MORE CHANGE class Client(BaseClient): From 02b9510190381d1dc3224af87b8ef5aab5e39a9d Mon Sep 17 00:00:00 2001 From: nmaimon Date: Sun, 15 May 2022 17:48:23 +0300 Subject: [PATCH 10/15] test change --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 +- Packs/Alexa/ReleaseNotes/2_0_13.md | 3 +++ Packs/Alexa/pack_metadata.json | 2 +- Utils/trigger_test_upload_flow.sh | 22 ++++++++++----------- 4 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 Packs/Alexa/ReleaseNotes/2_0_13.md diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index dcc7e6a72323..1882a83be19d 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -15,7 +15,7 @@ ''' CLIENT CLASS ''' -#MORE CHANGE +#MORE CHANGEעכיעיע class Client(BaseClient): diff --git a/Packs/Alexa/ReleaseNotes/2_0_13.md b/Packs/Alexa/ReleaseNotes/2_0_13.md new file mode 100644 index 000000000000..be549fa3a99c --- /dev/null +++ b/Packs/Alexa/ReleaseNotes/2_0_13.md @@ -0,0 +1,3 @@ +#### Integrations +##### Alexa Rank Indicator v2 +- Updated the Docker image to: *demisto/python3:3.10.4.29342*. diff --git a/Packs/Alexa/pack_metadata.json b/Packs/Alexa/pack_metadata.json index 0f848216062f..eec4f2b1ab92 100644 --- a/Packs/Alexa/pack_metadata.json +++ b/Packs/Alexa/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alexa Rank Indicator", "description": "Alexa provides website ranking information that can be useful in determining if the domain in question has a strong web presence.", "support": "xsoar", - "currentVersion": "2.0.12", + "currentVersion": "2.0.13", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Utils/trigger_test_upload_flow.sh b/Utils/trigger_test_upload_flow.sh index 3702f4ce4ed4..f754ae2de287 100755 --- a/Utils/trigger_test_upload_flow.sh +++ b/Utils/trigger_test_upload_flow.sh @@ -102,17 +102,17 @@ if [ -n "$_force" ] && [ -n "$_storage_base_path"]; then echo "Can not force upload while using a storage base path." exit 1 fi -#if [[ -n "$_storage_base_path" ]] && [ "$_storage_base_path" != *content ]; then -# echo "$_storage_base_path" -# echo "The given storage base path should look like upload-flow/builds/branch_name/build_number/content." -# exit 1 -#fi -# -#if [[ -n "$_storage_base_path" ]] && [ "$_storage_base_path" != upload-flow* ]; then -# echo $_storage_base_path -# echo "The given storage base path should look like upload-flow/builds/branch_name/build_number/content." -# exit 1 -#fi +if [ -n "$_storage_base_path" ] && [[ "$_storage_base_path" != *content ]]; then + echo "$_storage_base_path" + echo "The given storage base path should look like upload-flow/builds/branch_name/build_number/content.1" + exit 1 +fi + +if [ -n "$_storage_base_path" ] && [[ "$_storage_base_path" != upload-flow* ]]; then + echo $_storage_base_path + echo "The given storage base path should look like upload-flow/builds/branch_name/build_number/content.2" + exit 1 +fi if [ -n "$_gitlab" ]; then From 1c4b03b755361ccc266748c50f49ee6a98b6c47c Mon Sep 17 00:00:00 2001 From: nmaimon Date: Mon, 16 May 2022 11:47:55 +0300 Subject: [PATCH 11/15] remove testing --- Packs/Alexa/Integrations/AlexaV2/AlexaV2.py | 2 -- Packs/Alexa/pack_metadata.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py index 1882a83be19d..c36de4f80534 100644 --- a/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py +++ b/Packs/Alexa/Integrations/AlexaV2/AlexaV2.py @@ -15,8 +15,6 @@ ''' CLIENT CLASS ''' -#MORE CHANGEעכיעיע - class Client(BaseClient): def __init__(self, api_key: str, diff --git a/Packs/Alexa/pack_metadata.json b/Packs/Alexa/pack_metadata.json index eec4f2b1ab92..3f88fadcca1c 100644 --- a/Packs/Alexa/pack_metadata.json +++ b/Packs/Alexa/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alexa Rank Indicator", "description": "Alexa provides website ranking information that can be useful in determining if the domain in question has a strong web presence.", "support": "xsoar", - "currentVersion": "2.0.13", + "currentVersion": "2.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From c9b44813bbc76473ed88391bb545aa19283be8da Mon Sep 17 00:00:00 2001 From: nmaimon Date: Mon, 16 May 2022 11:49:29 +0300 Subject: [PATCH 12/15] remove testing files --- Packs/Alexa/ReleaseNotes/2_0_12.md | 3 --- Packs/Alexa/ReleaseNotes/2_0_13.md | 3 --- 2 files changed, 6 deletions(-) delete mode 100644 Packs/Alexa/ReleaseNotes/2_0_12.md delete mode 100644 Packs/Alexa/ReleaseNotes/2_0_13.md diff --git a/Packs/Alexa/ReleaseNotes/2_0_12.md b/Packs/Alexa/ReleaseNotes/2_0_12.md deleted file mode 100644 index be549fa3a99c..000000000000 --- a/Packs/Alexa/ReleaseNotes/2_0_12.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Integrations -##### Alexa Rank Indicator v2 -- Updated the Docker image to: *demisto/python3:3.10.4.29342*. diff --git a/Packs/Alexa/ReleaseNotes/2_0_13.md b/Packs/Alexa/ReleaseNotes/2_0_13.md deleted file mode 100644 index be549fa3a99c..000000000000 --- a/Packs/Alexa/ReleaseNotes/2_0_13.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Integrations -##### Alexa Rank Indicator v2 -- Updated the Docker image to: *demisto/python3:3.10.4.29342*. From fb864016eb0ff8712deeb9df8a120783092e6247 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Mon, 16 May 2022 11:58:48 +0300 Subject: [PATCH 13/15] add removed pack --- Packs/TrendMicroVisionOne/.pack-ignore | 0 Packs/TrendMicroVisionOne/.secrets-ignore | 8 ++++++++ 2 files changed, 8 insertions(+) create mode 100755 Packs/TrendMicroVisionOne/.pack-ignore create mode 100755 Packs/TrendMicroVisionOne/.secrets-ignore diff --git a/Packs/TrendMicroVisionOne/.pack-ignore b/Packs/TrendMicroVisionOne/.pack-ignore new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/Packs/TrendMicroVisionOne/.secrets-ignore b/Packs/TrendMicroVisionOne/.secrets-ignore new file mode 100755 index 000000000000..4fdda571c45f --- /dev/null +++ b/Packs/TrendMicroVisionOne/.secrets-ignore @@ -0,0 +1,8 @@ +192.168.35.1 +192.168.35.254 +6.6.6.6 +https://trendmicro-fake-api.com +https://api.xdr.trendmicro.com +http:// +kjshdfjksahd@trendenablement.com +MfSqmTdAMyv9PDX3k+vQ0w@mail.gmail.com \ No newline at end of file From 8610dceca4d9369ee28ef7218117c9f2a58d0570 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Mon, 16 May 2022 11:59:31 +0300 Subject: [PATCH 14/15] add removed pack --- Packs/TrendMicroVisionOne/Author_image.png | Bin 0 -> 2477 bytes ...icro_Vision_One_XDR_-_Incoming_Mapper.json | 585 +++++++ ...nd_Micro_Vision_One_XDR_Account_Count.json | 29 + ...nd_Micro_Vision_One_XDR_Desktop_Count.json | 29 + ...eld-Trend_Micro_Vision_One_XDR_Detail.json | 29 + ...ro_Vision_One_XDR_Email_Address_Count.json | 29 + ...end_Micro_Vision_One_XDR_Impact_Scope.json | 29 + ...icro_Vision_One_XDR_Impacted_Entities.json | 29 + ...Vision_One_XDR_Impacted_Entities_JSON.json | 30 + ...Trend_Micro_Vision_One_XDR_Indicators.json | 29 + ..._Micro_Vision_One_XDR_Indicators_JSON.json | 30 + ...o_Vision_One_XDR_Investigation_Status.json | 29 + ...cro_Vision_One_XDR_Matched_Rules_JSON.json | 30 + ...d_Micro_Vision_One_XDR_Priority_Score.json | 29 + ...end_Micro_Vision_One_XDR_Server_Count.json | 29 + ...end_Micro_Vision_One_XDR_Workbench_ID.json | 29 + ...d_Micro_Vision_One_XDR_Workbench_Link.json | 29 + ...e-Trend_Micro_Vision_One_XDR_Incident.json | 28 + .../Integrations/TrendMicroVisionOne/Pipfile | 18 + .../TrendMicroVisionOne/Pipfile.lock | 369 +++++ .../TrendMicroVisionOne/README.md | 412 +++++ .../TrendMicroVisionOne.py | 1339 +++++++++++++++++ .../TrendMicroVisionOne.yml | 657 ++++++++ .../TrendMicroVisionOne_description.md | 64 + .../TrendMicroVisionOne_image.png | Bin 0 -> 2477 bytes .../TrendMicroVisionOne_test.py | 776 ++++++++++ .../TrendMicroVisionOne/command_examples | 0 ...r-Trend_Micro_Vision_One_XDR_Incident.json | 475 ++++++ Packs/TrendMicroVisionOne/README.md | 26 + .../TrendMicroVisionOne/ReleaseNotes/1_0_1.md | 9 + .../TrendMicroVisionOne/ReleaseNotes/1_1_0.md | 6 + Packs/TrendMicroVisionOne/pack_metadata.json | 33 + 32 files changed, 5235 insertions(+) create mode 100644 Packs/TrendMicroVisionOne/Author_image.png create mode 100644 Packs/TrendMicroVisionOne/Classifiers/classifier-Trend_Micro_Vision_One_XDR_-_Incoming_Mapper.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Account_Count.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Desktop_Count.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Detail.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Email_Address_Count.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impact_Scope.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impacted_Entities.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Impacted_Entities_JSON.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Indicators.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Indicators_JSON.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Investigation_Status.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Matched_Rules_JSON.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Priority_Score.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Server_Count.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Workbench_ID.json create mode 100644 Packs/TrendMicroVisionOne/IncidentFields/incidentfield-Trend_Micro_Vision_One_XDR_Workbench_Link.json create mode 100644 Packs/TrendMicroVisionOne/IncidentTypes/incidenttype-Trend_Micro_Vision_One_XDR_Incident.json create mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/Pipfile create mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/Pipfile.lock create mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/README.md create mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py create mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml create mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md create mode 100644 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png create mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_test.py create mode 100755 Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples create mode 100644 Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json create mode 100755 Packs/TrendMicroVisionOne/README.md create mode 100644 Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md create mode 100644 Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md create mode 100755 Packs/TrendMicroVisionOne/pack_metadata.json diff --git a/Packs/TrendMicroVisionOne/Author_image.png b/Packs/TrendMicroVisionOne/Author_image.png new file mode 100644 index 0000000000000000000000000000000000000000..98c959cb86c90034ee39e1d5b01c0144dba818a0 GIT binary patch literal 2477 zcmXw4c|6ql8y|DI!o|u276KxyLciSnNimP|+kr?u`uETxDyi|fA2!#U1R?{3& z!vOSQYYNB%zZD+N#Sp>J|A{~#02jV3_0513po}4P)<(xCwDdSAEEo{~1_rutwTN6a z4iFz##{z;ZC5*74fsMifFg6MY0NA@Q9Bl$H4q(7BI2yXZTzrzl7*ZDkfloP+$JDj9 z^-U~z!NFW@eZGzXk7&%r8FAFKCidC_QWNG@E5#MPS-@dc; z_3Ic4yFN9|As7St!1zE50K?WIa!C8eO|8avTX2vBwj){e;4u%VYvO=w0RUr4NH$VO zfF_RbLi06o98KH=nlP?{8sDkG-($nk(&M7AqNl2e~RSXAf_*EkLl#%`6 z=!pqOGT+K!3QgEtS@|kj*qEK$nECYOP2XZu%gmYd>99kaYisLMf^{BG^8Cf})6T`V zc2OO3zLGvycKLHo-iMQ?h2ha$z1`Dj!URHnV_LW}I4pVjdil|lrF$I<%|E~8N@H<)y<5pP|W9*pQE+yFK_jmuSO7}DGEU|tP ze>BR=!Oj-H0|o`p2nHH1WoIQP20J1*H&;Ij|9Nx$_|Ilq3UagD!JY?qZnxB2IiD69 zN_Mf=QCpRa_O~=uU#%$0NsT#3@vVSviK7?`1H9QCe*CIRb5B#ZXuJS-I$`6rE)WMx|@YgAsWHMdCuDN>VJm~ngQbYtg zLYd)TL*Z~Z)77Vg+T{Q8$xBRAGz01V=sTy_ zcau5D{M4tX=@wD*-49Ng(Cwt)Ea_leb&DnjX; z=yrQUE?utu_2i6V-rg6&%#bvjt#?&gZPJcLr>@bRT9~gzLf*a1iBHj28}`lq+4Ji` zYwyy8wMWCZ*!Podrj3mpB`tS-J-uRyE0-%O>sim4@fj&nebTkbF*doihXs+>@w3w( zV$$a1_~QORS~uvhI5JP z7^~|or7L^U2iLS1?*si3#ZrFXfA7dnW#YL4dv6HF|ETq*ZgPf`xQCoeddK4(*G|jY zIyeJTkfl9s!kmk7^1X?dLjPNOP`paN;5+OjJy2Nk9J#Kn9RG=SmQa7Qjll}P9bC7% zWXShxdaI!|1X7FW$=rX2S%k-xs#uc!+Oo9?=;_Jcijtr%nb-kW<(2CtI6VGsw^gGb z5#aIi9MmT|ep@QO56k)n{TG5cG31t2$=gYjneYZy{MU zGNL*XxRcBH9r=@2En|d8Vjx3}f(u(oQTzFbuGl%AR+LIeQ(Dm*%HT4L9u*Vk9VwNe zeKPXbKk&I~(jNzgbUpPCy1Qc$$SywPWpjFv`*0(7^G0agG5fICV_d%RUYdem6iR~2 zq&+QaS49_HRSR?UUS+N6cN>kK_lh_-EbJF~v@uNd^!g5{KA1K1&N6I`PVs3G7aRR7 z5z0>z4r%8`Ds-zj8wYKuDDMDwRkhe$>>qNUcw1K&mdsq$pU+D28x7pj=pk9bKhn6J zMOX*@FY`t!^}ZLh{868F2H;r%8uwkNg<}oLGN?pxarnoogfnd!zI=k~C(nh9!kQwl~St3`v|BdU#dJ?dYur$Vi|~TIvKywkwYavD`>y&YYC( zEU^pRl~P~tA$_RHp~fUCEAfh}+|2`v8B6YCNt08{2{M!da{|cIAEQVVEFS9^+E89% zCM?o>HCNp}5?(Nud{|F)M7IXr{b-BTEuM`hm+oH>-7OSrBi`k2>C`>>Bux(+WTm0z?tSSWOh zX-At~>o9FyUno^ADHYhikX&}7M|FgqvpIS#IKOeIS$0Oc%RK=hHX~VHu8h0L?(W#Hyy1N1fE{Z6 zy|$vcOD>~9N~pMg@&dwT#xz8p5@&Tb=C?%4cr|uZ%m62_EfT3&qFqxJWS z@Ete}<-<%xf_#r&$)00V=x7-*%)sJxd$2q^i2mY@AxNp5M%@#FnNCF)FYc*i(yB)X zbOU!_+d&Hd7CW*Cg?mg(Pyg9TQ#g7icH$DMQB)r!ta=}`X?Vl&!jGcg9T2hjV`{%J z5^@E3h7Y62yVH&YH6CfM)gaTK2*T4dKMyr+v}m$CNSYf1VRW2QRzbMuFUfzs9zJ1- ziKDX~(=jAHtJGbo8D+JKAMZpIlv9P#OU<)~-$}^1){*=&Q>XU_TyFag50Q4 **Integrations** > **Servers & Services**. +2. Search for Trend Micro Vision One. +3. Click **Add instance** to create and configure a new integration instance. + +| **Parameter** | **Description** | **Required** | +| --- | --- | --- | +| Name | Unique name for this Trend Micro Vision One instance | True | +| Fetch Incidents | Choose if the integration should sync incidents | True | +| API URL | Base URL for Trend Micro Vision One API | True | +| API Key | API token for authentication | True | +| Incidents Fetch Interval (minutes) | How often do you want to check for new incidents | False | +| Sync On First Run (days) | How many days to go back during first sync | False | +| Max Incidents | Maximum Number of Workbenches to Retrieve | False | +4. Click **Test** to validate the URLs, token, and connection. + +## Commands +You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. + +#### Base Command + +1. `trendmicro-visionone-add-to-block-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| value_type | "file_sha1", "ip", "domain", "url" or "mailbox" | Required | +| target_value | The object you would like to add that matches the value-type | Required | +| product_id | Target product | Optional | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.BlockList.actionId | String | The action id | +| VisionOne.BlockList.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. + +2. `trendmicro-visionone-remove-from-block-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| value_type | "file_sha1", "ip", "domain", "url" or "mailbox" | Required | +| target_value | The object you would like to add that matches the value-type | Required | +| product_id | Target product | Optional | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.BlockList.actionId | String | The action id | +| VisionOne.BlockList.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. + +3. `trendmicro-visionone-quarantine-email-message` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| message_id | Email Message ID from Trend Micro Vision One message activity data | Required | +| mail_box | Email mailbox where the message will be quarantied from | Required | +| message_delivery_time | Email message's original delivery time | Required | +| product_id | Target product | Optional | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Email.actionId | String | The action id | +| VisionOne.Email.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. + +4. `trendmicro-visionone-delete-email-message` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| message_id | Email Message ID from Trend Micro Vision One message activity data | Required | +| mail_box | Email mailbox where the message will be deleted from | Required | +| message_delivery_time | Email message's original delivery time | Required | +| product_id | Target product | Optional | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Email.actionId | String | The action id | +| VisionOne.Email.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. + +5. `trendmicro-visionone-isolate-endpoint` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint | "hostname", "macaddr" or "ip" of the endpoint to isolate | Required | +| product_id | Target product: "sao" or "sds". Default: "sao". | Required | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Endpoint_Connection.actionId | String | The action id | +| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. +Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. + +6. `trendmicro-visionone-restore-endpoint-connection` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint | "hostname", "macaddr" or "ip" of the endpoint to restore connectivity | Required | +| product_id | Target product: "sao" or "sds". Default: "sao". | Required | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Endpoint_Connection.actionId | String | The action id | +| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. +Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. + +7. `trendmicro-visionone-add-objects-to-exception-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| type | The object type: "domain", "ip", "sha1", or "url" | Required | +| value | Full and partial matches supported. Domain partial match, (with a wildcard as the subdomain, example, .example.com) IP partial match, (IP range example, 192.168.35.1-192.168.35.254, cidr example, 192.168.35.1/24) URL partial match, (Supports wildcards 'http://.'', 'https://.'' at beginning, or ''' at the end. Multiple wild cards also supported, such as , https://.example.com/path1/) SHA1 only full match" | Required | +| description | Description | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Exception_List.message | String | Status message of existing task | +| VisionOne.Exception_List.status_code | String | Response code of existing task | +| VisionOne.Exception_List.total_items | String | Number of items present in the exception list. | + +8. `trendmicro-visionone-delete-objects-from-exception-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| type | The object type: "domain", "ip", "sha1", or "url" |Required| +| value | The object value | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Exception_List.message | String | Status message of existing task | +| VisionOne.Exception_List.status_code | String | Response code of existing task | +| VisionOne.Exception_List.total_items | String | Number of items present in the exception list. | + +9. `trendmicro-visionone-add-objects-to-suspicious-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| type | The object type: "domain", "ip", "sha1", or "url" |Required| +| value | The object value | Required | +| description | Description | Optional | +| scan_action | The action to take if object is found. If you don't use this parameter, the scan action specified in default_settings.riskLevel.type will be used instead. "block" or "log" | Optional | +| risk_level | The Suspicious Object risk level. If you don't use this parameter, high will be used instead. "high", "medium", or "low" | Optional | +| expiry_days | The number of days to keep the object in the Suspicious Object List. If you don't use this parameter, the default_settings.expiredDay scan action will be used instead. | Optional | + + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Suspicious_List.message | String | Status message of existing task | +| VisionOne.Suspicious_List.status_code | String | Response code of existing task | +| VisionOne.Suspicious_List.total_items | String | Number of items present in the exception list. | + +10. `trendmicro-visionone-delete-objects-from-suspicious-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| type | The object type: "domain", "ip", "sha1", or "url" |Required| +| value | The object value | Required | + + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Suspicious_List.message | String | Status message of existing task | +| VisionOne.Suspicious_List.status_code | String | Response code of existing task | +| VisionOne.Suspicious_List.total_items | String | Number of items present in the exception list. | + +11. `trendmicro-visionone-terminate-process` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint | "hostname", "macaddr" or "ip" of the endpoint to terminate process on | Required | +| file_sha1 | SHA1 hash of the process to terminate | Required | +| product_id | Target product. Default: "sao" | Optional | +| description | Description | Optional | +| filename | Optional file name list for log | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Terminate_Process.actionId | String | The action id | +| VisionOne.Terminate_Process.taskStatus | String | Status of existing task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. +Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout is ``20 minutes``. + +12. `trendmicro-visionone-get-file-analysis-status` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| task_id | task_id from the trendmicro-visionone-submit-file-to-sandbox command output |Required| + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.File_Analysis_Status.message | String | Message status | +| VisionOne.File_Analysis_Status.code | String | Code status of the task | +| VisionOne.File_Analysis_Status.task_id | String | Task id | +| VisionOne.File_Analysis_Status.taskStatus | String | Task status | +| VisionOne.File_Analysis_Status.digest | String | Hash value of task | +| VisionOne.File_Analysis_Status.analysis_completion_time | String | Task completion time | +| VisionOne.File_Analysis_Status.risk_level | String | Risk level of task | +| VisionOne.File_Analysis_Status.description | String | Description of task | +| VisionOne.File_Analysis_Status.detection_name_list | String | List of task detected | +| VisionOne.File_Analysis_Status.threat_type_list | String | Threat type list | +| VisionOne.File_Analysis_Status.file_type | String | Type of file | +| VisionOne.File_Analysis_Status.report_id | String | Report ID of task. | + +13. `trendmicro-visionone-get-file-analysis-report` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| report_id | report_id of the sandbox submission retrieved from the trendmicro-visionone-get-file-analysis-status command |Required| +| type | Type of report to retrieve: "vaReport", "investigationPackage", or "suspiciousObject" |Required| + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.File_Analysis_Report.message | String | Message status | +| VisionOne.File_Analysis_Report.code | String | Code status of task | +| VisionOne.File_Analysis_Report.type | String | type of report | +| VisionOne.File_Analysis_Report.value | String | value of the above type | +| VisionOne.File_Analysis_Report.risk_level | String | risk level of the file | +| VisionOne.File_Analysis_Report.analysis_completion_time | String | Final analysed time of report | +| VisionOne.File_Analysis_Report.expired_time | String | Expiry time of report | +| VisionOne.File_Analysis_Report.root_file_sha1 | String | sha value of the root file | + +14. `trendmicro-visionone-collect-forensic-file` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint | "hostname", "macaddr" or "ip" of the endpoint to collect file from | Required | +| product_id | Product: "sao" "xes" "sds" |Required| +| file_path | Path of the file to collect |Required| +| os | "windows", "mac" or "linux" |Required| +| description | Description of file collected |Optional| +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Collect_Forensic_File.actionId | String | Action id of the running task | +| VisionOne.Collect_Forensic_File.taskStatus | String | Status of the running task | + +Note: To get the complete task status run polling command `trendmicro-visionone-check-task-status` giving `actionId` as input parameter. +Note: The above command should be added with execution timeout in the advanced field of playbook execution. The recommended timeout be ``20 minutes``. + +15. `trendmicro-visionone-download-information-for-collected-forensic-file` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| actionId | actionId output from the collect command used to collect the file |Required| + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Download_Information_For_Collected_Forensic_File.url | String | URL of the collected file | +| VisionOne.Download_Information_For_Collected_Forensic_File.expires | String | URL expiration date | +| VisionOne.Download_Information_For_Collected_Forensic_File.password | String | Archive password for the protected forensic file | +| VisionOne.Download_Information_For_Collected_Forensic_File.filename | String | Name of the collected file | + +Note: The URL received from the 'trendmicro-visionone-download-information-for-collected-forensic-file' will be valid for only ``60 seconds`` + +16. `trendmicro-visionone-submit-file-to-sandbox` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| file_url | URL pointing to the location of the file to be submitted. |Required| +| filename | Name of the file to be analyzed. |Required| +| document_password | The password for decrypting the submitted document. The value must be Base64-encoded. The maximum password length is 128 bytes prior to encoding. | Optional | +| archive_password | The password for decrypting the submitted archive. The value must be Base64-encoded. The maximum password length is 128 bytes prior to encoding. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Submit_File_to_Sandbox.message | String | Message status of the sandbox file | +| VisionOne.Submit_File_to_Sandbox.code | String | Code status of the sandbox file | +| VisionOne.Submit_File_to_Sandbox.task_id | String | Task ID of the running task | +| VisionOne.Submit_File_to_Sandbox.digest | Object | Sha value of the file | + +17. `trendmicro-visionone-check-task-status` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| polling | If the command is to run at the polling interval. | Optional | +| actionId | Action ID of the task you would like to get the status of. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Endpoint_Connection.actionId | String | The action id | +| VisionOne.Endpoint_Connection.taskStatus | String | Status of existing task | + +18. `trendmicro-visionone-get-endpoint-info` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint | "hostname", "macaddr" or "ip" of the endpoint to query | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Endpoint_Info.message | String | Message information from the request. | +| VisionOne.Endpoint_Info.errorCode | Integer | Error code. | +| VisionOne.Endpoint_Info.status | String | Status of the request. | +| VisionOne.Endpoint_Info.logonAccount | String | Account currently logged on to the endpoint. | +| VisionOne.Endpoint_Info.hostname | String | Hostname. | +| VisionOne.Endpoint_Info.macAddr | String | MAC address. | +| VisionOne.Endpoint_Info.ip | String | IP address. | +| VisionOne.Endpoint_Info.osName | String | Operating System name. | +| VisionOne.Endpoint_Info.osVersion | String | Operating System version. | +| VisionOne.Endpoint_Info.osDescription | String | Description of the Operating System. | +| VisionOne.Endpoint_Info.productCode | String | Product code of the Trend Micro product running on the endpoint. | +--- + +19. `trendmicro-visionone-add-note` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| workbench_id | The ID of the workbench alert that you would like to add the note to. | Required | +| content | The note content that you would like to add. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Add_Note.Workbench_Id | String | Workbench ID that the action was executed on. | +| VisionOne.Add_Note.noteId | String | Note ID. | +| VisionOne.Add_Note.response_code | String | Response code for the request. | +| VisionOne.Add_Note.response_msg | String | Response message for the request. | +--- + +20. `trendmicro-visionone-update-status` + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| workbench_id | The ID of the workbench alert that you would like to update the status for. | Required | +| status | The status to assign to the workbench alert: new, in_progress, resolved_false_positive, resolved_true_positive | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| VisionOne.Update_Status.Workbench_Id | String | Workbench ID that the action was executed on. | +| VisionOne.Update_Status.response_code | String | Response code for the request. | +| VisionOne.Update_Status.response_msg | String | Response message for the request. | +--- +[View Integration Documentation](https://xsoar.pan.dev/docs/reference/integrations/trend-micro-vision-one) \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py new file mode 100644 index 000000000000..6707a01e1793 --- /dev/null +++ b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.py @@ -0,0 +1,1339 @@ +'''IMPORTS''' +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 # pylint: disable=unused-wildcard-import +from CommonServerUserPython import * # noqa: F401 + +import base64 +import json +import requests +import re +from datetime import datetime, timezone, timedelta +from typing import Any, Dict, Union +from requests.models import HTTPError + +'''CONSTANTS''' +USER_AGENT = 'TMV1CortexXSOARApp/1.1' +URL = 'url' +POST = 'post' +GET = 'get' +PUT = 'put' +AUTHORIZATION = 'Authorization' +BEARER = 'Bearer ' +CONTENT_TYPE_JSON = 'application/json' +EMPTY_STRING = '' +ASCII = 'ascii' +API_TOKEN = 'apikey' +VALUE_TYPE = 'value_type' +TARGET_VALUE = 'target_value' +PRODUCT_ID = 'product_id' +DESCRIPTION = 'description' +MESSAGE_ID = 'message_id' +MAILBOX = 'mailbox' +MESSAGE_DELIVERY_TIME = 'message_delivery_time' +COMPUTER_ID = 'computer_id' +FIELD = 'field' +ENDPOINT = 'endpoint' +DATA = 'data' +TYPE = 'type' +VALUE = 'value' +FILESHA = 'file_sha1' +FILENAME = 'filename' +CRITERIA = 'criteria' +EXCEPTION_LIST = 'exceptionList' +SUSPICIOUS_LIST = 'suspiciousObjectList' +LAST_MODIFIED = 'lastModified' +SCAN_ACTION = 'scan_action' +RISK_LEVEL = 'risk_level' +EXPIRYDAY = 'expiry_days' +TASKID = 'task_id' +REPORT_ID = 'report_id' +OS_TYPE = 'os' +FILE_PATH = 'file_path' +FILE_URL = 'file_url' +FILE_NAME = 'filename' +DOCUMENT_PASSWORD = 'document_password' +ARCHIVE_PASSWORD = 'archive_password' +ACTION_ID = 'actionId' +WORKBENCH_ID = 'workbench_id' +CONTENT = 'content' +STATUS = 'status' +# End Points +ADD_BLOCKLIST_ENDPOINT = '/v2.0/xdr/response/block' +REMOVE_BLOCKLIST_ENDPOINT = '/v2.0/xdr/response/restoreBlock' +QUARANTINE_EMAIL_ENDPOINT = '/v2.0/xdr/response/quarantineMessage' +DELETE_EMAIL_ENDPOINT = '/v2.0/xdr/response/deleteMessage' +ISOLATE_CONNECTION_ENDPOINT = '/v2.0/xdr/response/isolate' +TERMINATE_PROCESS_ENDPOINT = '/v2.0/xdr/response/terminateProcess' +RESTORE_CONNECTION_ENDPOINT = '/v2.0/xdr/response/restoreIsolate' +ADD_OBJECT_TO_EXCEPTION_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/exceptions' +DELETE_OBJECT_FROM_EXCEPTION_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/exceptions/delete' +ADD_OBJECT_TO_SUSPICIOUS_LIST = '/v2.0/xdr/threatintel/suspiciousObjects' +DELETE_OBJECT_FROM_SUSPICIOUS_LIST = '/v2.0/xdr/threatintel/suspiciousObjects/delete' +TASK_DETAIL_ENDPOINT = '/v2.0/xdr/response/getTask' +GET_COMPUTER_ID_ENDPOINT = '/v2.0/xdr/eiqs/query/agentInfo' +GET_ENDPOINT_INFO_ENDPOINT = '/v2.0/xdr/eiqs/query/endpointInfo' +GET_FILE_STATUS = '/v2.0/xdr/sandbox/tasks/{taskId}' +GET_FILE_REPORT = '/v2.0/xdr/sandbox/reports/{reportId}' +ADD_NOTE_ENDPOINT = '/v2.0/xdr/workbench/workbenches/{workbenchId}/notes' +UPDATE_STATUS_ENDPOINT = '/v2.0/xdr/workbench/workbenches/{workbenchId}' +COLLECT_FORENSIC_FILE = '/v2.0/xdr/response/collectFile' +DOWNLOAD_INFORMATION_COLLECTED_FILE = '/v2.0/xdr/response/downloadInfo' +SUBMIT_FILE_TO_SANDBOX = '/v2.0/xdr/sandbox/file' +WORKBENCH_HISTORIES = '/v2.0/xdr/workbench/workbenchHistories' +# Error Messages +RESPONSE_ERROR = 'Error in API call: [%d] - %s' +RETRY_ERROR = 'The max tries exceeded [%d] - %s' +COMMAND_CALLED = 'Command being called is {command}' +COMMAND_EXECUTION_ERROR = 'Failed to execute {error} command. Error' +AUTHORIZATION_ERROR = "Authorization Error: make sure URL/API Key is correctly set. Error - {error}" +PARAMETER_ISSUE = '{param} is not a valid paramter. Kindly provide valid parameter' +FILE_TYPE_ERROR = "Kindly provide valid file 'type'" +FILE_NOT_FOUND = 'No such file present in {filepath}' +# General Messages: +RAW_RESPONSE = "The raw response data - {raw_response}" +SUCCESS_RESPONSE = 'success with url {url} and response status {status}' +EXCEPTION_MESSAGE = "Successfully {task} object to exception list with response {code}, Total items in exception list - {length}" +SUCCESS_TEST = 'Successfully connected to the vision one API.' +POLLING_MESSAGE = ( + "The task has not completed, will check status again in 30 seconds" +) +# Workbench Statuses +NEW = 0 +IN_PROGRESS = 1 +RESOLVED_TRUE_POSITIVE = 2 +RESOLVED_FALSE_POSITIVE = 3 +# Table Heading +TABLE_ADD_TO_BLOCKLIST = 'Add to block list ' +TABLE_REMOVE_FROM_BLOCKLIST = 'Remove from block list ' +TABLE_QUARANTINE_EMAIL_MESSAGE = 'Quarantine email message ' +TABLE_DELETE_EMAIL_MESSAGE = 'Delete email message ' +TABLE_ISOLATE_ENDPOINT_MESSAGE = 'Isolate endpoint connection ' +TABLE_RESTORE_ENDPOINT_MESSAGE = 'Restore endpoint connection ' +TABLE_TERMINATE_PROCESS = 'Terminate process ' +TABLE_ADD_EXCEPTION_LIST = 'Add object to exception list ' +TABLE_DELETE_EXCEPTION_LIST = 'Delete object from exception list ' +TABLE_ADD_SUSPICIOUS_LIST = 'Add object to suspicious list ' +TABLE_ENDPOINT_INFO = 'Endpoint info ' +TABLE_DELETE_SUSPICIOUS_LIST = 'Delete object from suspicious list ' +TABLE_GET_FILE_ANALYSIS_STATUS = 'File analysis status ' +TABLE_GET_FILE_ANALYSIS_REPORT = 'File analysis report ' +TABLE_COLLECT_FILE = 'Collect forensic file ' +TABLE_COLLECTED_FORENSIC_FILE_DOWNLOAD_INFORMATION = 'The download information for collected forensic file ' +TABLE_SUBMIT_FILE_TO_SANDBOX = 'Submit file to sandbox ' +TABLE_ADD_NOTE = 'Add note to workbench alert ' +TABLE_UPDATE_STATUS = 'Update workbench alert status' +# COMMAND NAMES +ADD_BLOCKLIST_COMMAND = 'trendmicro-visionone-add-to-block-list' +REMOVE_BLOCKLIST_COMMAND = 'trendmicro-visionone-remove-from-block-list' +QUARANTINE_EMAIL_COMMAND = 'trendmicro-visionone-quarantine-email-message' +DELETE_EMAIL_COMMAND = 'trendmicro-visionone-delete-email-message' +ISOLATE_ENDPOINT_COMMAND = 'trendmicro-visionone-isolate-endpoint' +RESTORE_ENDPOINT_COMMAND = 'trendmicro-visionone-restore-endpoint-connection' +TERMINATE_PROCESS_COMMAND = 'trendmicro-visionone-terminate-process' +ADD_EXCEPTION_LIST_COMMAND = 'trendmicro-visionone-add-objects-to-exception-list' +DELETE_EXCEPTION_LIST_COMMAND = 'trendmicro-visionone-delete-objects-from-exception-list' +ADD_SUSPICIOUS_LIST_COMMAND = 'trendmicro-visionone-add-objects-to-suspicious-list' +DELETE_SUSPICIOUS_LIST_COMMAND = 'trendmicro-visionone-delete-objects-from-suspicious-list' +GET_FILE_ANALYSIS_STATUS = 'trendmicro-visionone-get-file-analysis-status' +GET_FILE_ANALYSIS_REPORT = 'trendmicro-visionone-get-file-analysis-report' +COLLECT_FILE = 'trendmicro-visionone-collect-forensic-file' +DOWNLOAD_COLLECTED_FILE = 'trendmicro-visionone-download-information-for-collected-forensic-file' +FILE_TO_SANDBOX = 'trendmicro-visionone-submit-file-to-sandbox' +CHECK_TASK_STATUS = 'trendmicro-visionone-check-task-status' +GET_ENDPOINT_INFO_COMMAND = 'trendmicro-visionone-get-endpoint-info' +UPDATE_STATUS = 'trendmicro-visionone-update-status' +ADD_NOTE = 'trendmicro-visionone-add-note' +FETCH_INCIDENTS = 'fetch-incidents' + +table_name = { + ADD_BLOCKLIST_COMMAND: TABLE_ADD_TO_BLOCKLIST, + REMOVE_BLOCKLIST_COMMAND: TABLE_REMOVE_FROM_BLOCKLIST, + QUARANTINE_EMAIL_COMMAND: TABLE_QUARANTINE_EMAIL_MESSAGE, + DELETE_EMAIL_COMMAND: TABLE_DELETE_EMAIL_MESSAGE, + ISOLATE_ENDPOINT_COMMAND: TABLE_ISOLATE_ENDPOINT_MESSAGE, + RESTORE_ENDPOINT_COMMAND: TABLE_RESTORE_ENDPOINT_MESSAGE, + ADD_EXCEPTION_LIST_COMMAND: TABLE_ADD_EXCEPTION_LIST, + DELETE_EXCEPTION_LIST_COMMAND: TABLE_DELETE_EXCEPTION_LIST, + ADD_SUSPICIOUS_LIST_COMMAND: TABLE_ADD_SUSPICIOUS_LIST, + GET_ENDPOINT_INFO_COMMAND: TABLE_ENDPOINT_INFO, + DELETE_SUSPICIOUS_LIST_COMMAND: TABLE_DELETE_SUSPICIOUS_LIST +} +# disable insecure warnings +requests.packages.urllib3.disable_warnings() + + +def check_datetime_aware(d): + return (d.tzinfo is not None) and (d.tzinfo.utcoffset(d) is not None) + + +class Client(BaseClient): + def __init__(self, base_url: str, api_key: str) -> None: + """ + Inherit the BaseClient class from the demistomock. + :type base_url: ``str`` + :param base_url: Base server address with suffix, for example: https://example.com/api/v2/. + :type api_key: ``str`` + :param api_key: api token to access the api data. + :type verify: ``bool`` + :param verify: Whether the request should verify the SSL certificate. + :return: returns None + :rtype: ``None`` + """ + super().__init__(base_url=base_url) + self.base_url = base_url + self.api_key = api_key + self.status = None + + def http_request(self, method: str, url_suffix: str, json_data=None, params=None, data=None) -> Any: + """ + Override http_request method from BaseClient class. This method will print an error based on status code + and exceptions. + :type method: ``str`` + :param method: The HTTP method, for example: GET, POST, and so on. + :type url_suffix: ``str`` + :param url_suffix: The API endpoint. + :type json_data: ``dict`` + :param json_data: The dictionary to send in a 'POST' request. + :type params: ``dict`` + :param params: URL parameters to specify the query. + :type data: ``dict`` + :param data: The data to send in a 'POST' request. + :return: response data + :rtype: ``dict`` or ``str`` or ``requests.Response`` + """ + header = { + "Authorization": "Bearer {token}".format(token=self.api_key), + "Content-Type": f'{CONTENT_TYPE_JSON};charset=utf-8', + "User-Agent": USER_AGENT, + } + try: + response = self._http_request(method=method, full_url=f'{self.base_url}{url_suffix}', retries=3, json_data=json_data, + params=params, headers=header, resp_type='response', + ok_codes=(200, 201), data=data) + except DemistoException as error: + demisto.error(error.message) + return_error(error.message) + if response.ok: + demisto.info(SUCCESS_RESPONSE.format(url=f'{self.base_url}{url_suffix}', status=response.status_code)) + self.status = response.status_code + content_type = response.headers.get('Content-Type', '') + if content_type.__contains__(CONTENT_TYPE_JSON): + # Handle empty response + if response.text == EMPTY_STRING: + return response + else: + return response.json() + else: + return response + + def status_check(self, data: Dict[str, Any]) -> Any: + """ + Check the status of particular task. + :type data: ``dict`` + :param method: Response data to received from the end point. + :return: task status response data. + :rtype: ``Any`` + """ + action_id = data.get(ACTION_ID) + params = {"actionId": action_id} + response = self.http_request(GET, TASK_DETAIL_ENDPOINT, params=params) + message = { + "actionId": action_id, + "taskStatus": response.get("data").get("taskStatus") + } + return CommandResults( + readable_output=tableToMarkdown("Status of task ", message, removeNull=True), + outputs_prefix=( + "VisionOne.Task_Status" + ), + outputs_key_field="actionId", + outputs=message) + + def lookup_type(self, param: Any) -> str: + + # Regex expression for validating IPv4 + regex = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|"\ + "2[0-4][0-9]|25[0-5])\\.){3}"\ + "([0-9]|[1-9][0-9]|1[0-9][0-9]|"\ + "2[0-4][0-9]|25[0-5])" + + # Regex expression for validating IPv6 + regex1 = "((([0-9a-fA-F]){1,4})\\:){7}"\ + "([0-9a-fA-F]){1,4}" + + # Regex expression for validating mac + regex2 = "([0-9A-Fa-f]{2}[:-]){5}"\ + "([0-9A-Fa-f]{2})" + + p = re.compile(regex) + p1 = re.compile(regex1) + p2 = re.compile(regex2) + + # Checking if it is a valid IPv4 addresses + if (re.search(p, param)): + return "ip" + + # Checking if it is a valid IPv6 addresses + elif (re.search(p1, param)): + return "ipv6" + + # Checking if it is a valid IPv6 addresses + elif (re.search(p2, param)): + return "macaddr" + + # Otherwise use hostname type + return "hostname" + + def get_computer_id(self, field: Any, value: Any) -> str: + """ + Fetch particular computer id using hostname, macaddress or ip. + :type field: ``str`` + :param field: type of field to search hostname, macaddress or ip. + :type value: ``str`` + :param value: value of the particular field. + :return: value of computer id. + :rtype: ``str`` + """ + body = { + CRITERIA: { + FIELD: field, + VALUE: value + } + } + response = self.http_request(POST, GET_COMPUTER_ID_ENDPOINT, data=json.dumps(body)) + + if response["status"] == 'FAIL': + return_error("kindly provide valid field value") + computer_id = response.get("result").get("computerId") + return computer_id + + def exception_list_count(self) -> int: + """ + Gets the count of object present in exception list + + :return: number of exception object. + :rtype: ``int`` + """ + response = self.http_request(GET, ADD_OBJECT_TO_EXCEPTION_LIST) + list_of_exception = response.get(DATA).get(EXCEPTION_LIST) + exception_count = len(list_of_exception) + return exception_count + + def suspicious_list_count(self) -> int: + """ + Gets the count of object present in suspicious list + :return: number of suspicious object. + :rtype: ``int`` + """ + response = self.http_request(GET, ADD_OBJECT_TO_SUSPICIOUS_LIST) + list_of_exception = response.get(DATA).get(SUSPICIOUS_LIST) + exception_count = len(list_of_exception) + return exception_count + + def get_workbench_histories(self, start, end, offset=None, size=None) -> str: + if not check_datetime_aware(start): + start = start.astimezone() + if not check_datetime_aware(end): + end = end.astimezone() + start = start.astimezone(timezone.utc) + end = end.astimezone(timezone.utc) + start = start.isoformat(timespec='milliseconds').replace('+00:00', 'Z') + end = end.isoformat(timespec='milliseconds').replace('+00:00', 'Z') + + params = dict([('startTime', start), + ('endTime', end), + ('sortBy', 'createdTime')] + + ([('offset', offset)] if offset is not None else []) + + ([('limit', size)] if size is not None else [])) + + response = self.http_request(GET, WORKBENCH_HISTORIES, params=params)['data']['workbenchRecords'] + return response + + +def run_polling_command( + args: Dict[str, Any], + cmd: str, client: Client +) -> Union[str, CommandResults]: + """ + Performs polling interval to check status of task. + :type args: ``args`` + :param client: argument required for polling. + + :type client: ``cmd`` + :param client: The command that polled for an interval. + + :type client: ``Client`` + :param client: client object to use http_request. + """ + ScheduledCommand.raise_error_if_not_supported() + interval_in_secs = int(args.get('interval_in_seconds', 30)) + command_results = client.status_check(args) + action_id = args.get("actionId") + if command_results.outputs.get( + "taskStatus") not in ( + "success", "failed", "timeout", "skipped"): + # schedule next poll + polling_args = { + 'actionId': action_id, + 'interval_in_seconds': interval_in_secs, + 'polling': True, + **args + } + scheduled_command = ScheduledCommand( + command=cmd, + next_run_in_seconds=interval_in_secs, + args=polling_args, + timeout_in_seconds=1500) # The timeout interval set for 25 minutes. + command_results = CommandResults(scheduled_command=scheduled_command) + return command_results + + +def get_task_status( + args: Dict[str, Any], + client: Client +) -> Union[str, CommandResults]: + """ + check status of task. + + :type args: ``args`` + :param client: argument required for polling. + + :type client: ``Client`` + :param client: client object to use http_request. + """ + return run_polling_command(args, CHECK_TASK_STATUS, client) + + +def test_module(client: Client) -> Any: + """ + Performs basic get request to get item samples. + :type client: ``Client`` + :param client: client object to use http_request. + """ + client.http_request('GET', '/v2.0/xdr/threatintel/suspiciousObjects/exceptions') + return 'ok' + + +def get_endpoint_info( + client: Client, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Retrieve information abouut the endpoint queried and + sends the result to demisto war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + + value = args.get(ENDPOINT) + field = client.lookup_type(value) + + computer_id = client.get_computer_id(field, value) + body = { + 'computerId': computer_id + } + response = client.http_request( + POST, GET_ENDPOINT_INFO_ENDPOINT, data=json.dumps(body) + ) + + message = { + "message": response.get("message", ""), + "errorCode": response.get("errorCodecode", ""), + "status": response.get("status", ""), + "logonAccount": response.get("result", {}) + .get("logonAccount", "") + .get("value", ""), + "hostname": response.get("result", {}) + .get("hostname", "") + .get("value", ""), + "macAddr": response.get("result", {}) + .get("macAddr", "") + .get("value", ""), + "ip": response.get("result", {}) + .get("ip", "") + .get("value", ""), + "osName": response.get("result", {}) + .get("osName", ""), + "osVersion": response.get("result", {}) + .get("osVersion", ""), + "osDescription": response.get("result", {}) + .get("osDescription", ""), + "productCode": response.get("result", {}) + .get("productCode", ""), + } + + results = CommandResults( + readable_output=tableToMarkdown( + table_name[GET_ENDPOINT_INFO_COMMAND], message, removeNull=True + ), + outputs_prefix="VisionOne.Endpoint_Info", + outputs_key_field="message", + outputs=message, + ) + return results + + +def add_delete_block_list_mapping( + data: Dict[str, Any] +) -> Dict[str, Any]: + """ + Mapping add to block list response data. + + :type data: ``dict`` + :param data: Response data to received from the end point. + + :return: mapped response data. + :rtype: ``dict`` + """ + action_id = data.get("actionId", {}) + task_status = data.get("taskStatus", {}) + return {"actionId": action_id, "taskStatus": task_status} + + +def add_or_remove_from_block_list( + client: Client, command: str, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Retrieve data from the add or remove from block list and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type command: ``str`` + :param command: type of command either + trendmicro-visionone-add-to-block-list or + trendmicro-visionone-remove-from-block-list. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + value_type = args.get(VALUE_TYPE) + target_value = args.get(TARGET_VALUE) + product_id = args.get(PRODUCT_ID) + if not product_id: + product_id = EMPTY_STRING + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + body = { + 'valueType': value_type, + 'targetValue': target_value, + 'productId': product_id, + 'description': description, + } + if command == ADD_BLOCKLIST_COMMAND: + response = client.http_request( + POST, ADD_BLOCKLIST_ENDPOINT, data=json.dumps(body) + ) + elif command == REMOVE_BLOCKLIST_COMMAND: + response = client.http_request( + POST, REMOVE_BLOCKLIST_ENDPOINT, data=json.dumps(body) + ) + + mapping_data = add_delete_block_list_mapping(response) + results = CommandResults( + readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), + outputs_prefix="VisionOne.BlockList", + outputs_key_field="actionId", + outputs=mapping_data, + ) + return results + + +def fetch_incidents(client: Client): + """ + This function do the loop to get all workbench alerts by changing + the parameters of both 'offset' and 'size'. + """ + offset = 0 + size = demisto.params().get('max_fetch') + end = datetime.now(timezone.utc) + days = int(demisto.params().get('first_fetch')) + + last_run = demisto.getLastRun() + if last_run and 'start_time' in last_run: + start = datetime.fromisoformat(last_run.get('start_time')) + else: + start = end + timedelta(days=-days) + + alerts: List[Any] = [] + alerts.extend(client.get_workbench_histories(start, end, offset, size)) + + incidents = [] + if alerts: + for record in alerts: + incident = { + 'name': record['workbenchName'], + 'occurred': record['createdTime'], + 'rawJSON': json.dumps(record) + } + incidents.append(incident) + last_event = datetime.strptime(record['createdTime'], "%Y-%m-%dT%H:%M:%SZ") + + next_search = last_event + timedelta(0, 1) + + demisto.setLastRun({ + 'start_time': next_search.isoformat() + }) + + if incidents: + demisto.incidents(incidents) + else: + demisto.incidents([]) + + return incidents + + +def quarantine_delete_email_mapping( + data: Dict[str, Any] +) -> Dict[str, Any]: + """ + Mapping quarantine email message response data. + + :type data: ``dict`` + :param method: Response data to received from the end point. + + :return: mapped response data. + :rtype: ``dict`` + """ + action_id = data.get("actionId", {}) + task_status = data.get("taskStatus", {}) + return {"actionId": action_id, "taskStatus": task_status} + + +def quarantine_or_delete_email_message( + client: Client, command: str, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Retrieve data from the quarantine or delete email message and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type command: ``str`` + :param command: type of command either + trendmicro-visionone-quarantine-email-message or + trendmicro-visionone-delete-email-message + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + message_id = args.get(MESSAGE_ID) + mailbox = args.get(MAILBOX) + message_delivery_time = args.get(MESSAGE_DELIVERY_TIME) + product_id = args.get(PRODUCT_ID) + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + body = { + 'messageId': message_id, + 'mailBox': mailbox, + 'messageDeliveryTime': message_delivery_time, + 'productId': product_id, + 'description': description + } + if command == QUARANTINE_EMAIL_COMMAND: + response = client.http_request( + POST, QUARANTINE_EMAIL_ENDPOINT, data=json.dumps(body) + ) + + elif command == DELETE_EMAIL_COMMAND: + response = client.http_request( + POST, DELETE_EMAIL_ENDPOINT, data=json.dumps(body) + ) + + mapping_data = quarantine_delete_email_mapping(response) + results = CommandResults( + readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), + outputs_prefix="VisionOne.Email", + outputs_key_field="actionId", + outputs=mapping_data, + ) + return results + + +def isolate_restore_endpoint_mapping( + data: Dict[str, Any] +) -> Dict[str, Any]: + """ + Mapping isolate endpoint and restore endpoint response data. + + :type data: ``dict`` + :param method: Response data to received from the end point. + + :return: mapped response data. + :rtype: ``dict`` + """ + action_id = data.get("actionId", {}) + task_status = data.get("taskStatus", {}) + return {"actionId": action_id, "taskStatus": task_status} + + +def isolate_or_restore_connection( + client: Client, command: str, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Retrieve data from the isolate or restore endpoint connection and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type command: ``str`` + :param command: type of command either + trendmicro-visionone-isolate-endpoint or + trendmicro-visionone-restore-endpoint-connection + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + value = args.get(ENDPOINT) + field = client.lookup_type(value) + product_id = args.get(PRODUCT_ID) + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + computer_id = client.get_computer_id(field, value) + body = { + 'computerId': computer_id, + 'productId': product_id, + 'description': description + } + if command == ISOLATE_ENDPOINT_COMMAND: + response = client.http_request( + POST, ISOLATE_CONNECTION_ENDPOINT, data=json.dumps(body) + ) + + elif command == RESTORE_ENDPOINT_COMMAND: + response = client.http_request( + POST, RESTORE_CONNECTION_ENDPOINT, data=json.dumps(body) + ) + + mapping_data = isolate_restore_endpoint_mapping( + response) + + results = CommandResults( + readable_output=tableToMarkdown(table_name[command], mapping_data, removeNull=True), + outputs_prefix="VisionOne.Endpoint_Connection", + outputs_key_field="actionId", + outputs=mapping_data, + ) + return results + + +def terminate_process( + client: Client, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Terminate the process running on the end point and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + file_list = [] + value = args.get(ENDPOINT) + field = client.lookup_type(value) + product_id = args.get(PRODUCT_ID) + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + computer_id = client.get_computer_id(field, value) + file_sha1 = args.get(FILESHA) + filename = args.get(FILENAME) + if filename: + file_list.append(filename) + body = { + 'computerId': computer_id, + 'fileSha1': file_sha1, + 'productId': product_id, + 'description': description, + 'filename': file_list + } + response = client.http_request( + POST, TERMINATE_PROCESS_ENDPOINT, data=json.dumps(body) + ) + + action_id = response.get("actionId", {}) + task_status = response.get("taskStatus", {}) + message = {"actionId": action_id, "taskStatus": task_status} + results = CommandResults( + readable_output=tableToMarkdown(TABLE_TERMINATE_PROCESS, message, removeNull=True), + outputs_prefix="VisionOne.Terminate_Process", + outputs_key_field="actionId", + outputs=message, + ) + return results + + +def add_or_delete_from_exception_list( + client: Client, command: str, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Add or Delete the exception object to exception list and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type command: ``str`` + :param command: type of command either + trendmicro-visionone-add-objects-to-exception-list or + trendmicro-visionone-delete-objects-from-exception-list + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + types = args.get(TYPE) + value = args.get(VALUE) + body = {DATA: [{'type': types, 'value': value}]} + if command == ADD_EXCEPTION_LIST_COMMAND: + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + body[DATA][0][DESCRIPTION] = description + client.http_request( + POST, ADD_OBJECT_TO_EXCEPTION_LIST, data=json.dumps(body) + ) + + elif command == DELETE_EXCEPTION_LIST_COMMAND: + client.http_request( + POST, DELETE_OBJECT_FROM_EXCEPTION_LIST, data=json.dumps(body) + ) + + exception_list = client.exception_list_count() + + message = { + "message": "success", + "status_code": client.status, + "total_items": exception_list, + } + results = CommandResults( + readable_output=tableToMarkdown(table_name[command], message, removeNull=True), + outputs_prefix="VisionOne.Exception_List", + outputs_key_field="message", + outputs=message, + ) + return results + + +def add_to_suspicious_list( + client: Client, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Add suspicious object to suspicious list and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + types = args.get(TYPE) + value = args.get(VALUE) + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + scan_action = args.get(SCAN_ACTION) + if scan_action and scan_action not in ("log", "block"): + return_error(PARAMETER_ISSUE.format(param=SCAN_ACTION)) + risk_level = args.get(RISK_LEVEL) + if risk_level and risk_level not in ("high", "medium", "low"): + return_error(PARAMETER_ISSUE.format(param=RISK_LEVEL)) + expiry = args.get(EXPIRYDAY) + if not expiry: + expiry = 0 + body = { + DATA: [ + { + 'type': types, + 'value': value, + 'description': description, + 'scanAction': scan_action, + 'riskLevel': risk_level, + 'expiredDay': expiry + } + ] + } + client.http_request( + POST, ADD_OBJECT_TO_SUSPICIOUS_LIST, data=json.dumps(body) + ) + suspicious_list = client.suspicious_list_count() + + message = { + "message": "success", + "status_code": client.status, + "total_items": suspicious_list, + } + results = CommandResults( + readable_output=tableToMarkdown( + table_name[ADD_SUSPICIOUS_LIST_COMMAND], message, removeNull=True + ), + outputs_prefix="VisionOne.Suspicious_List", + outputs_key_field="message", + outputs=message, + ) + return results + + +def delete_from_suspicious_list( + client: Client, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Delete the suspicious object from suspicious list and + sends the result to demist war room. + + :type client: ``Client`` + :param client: client object to use http_request. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + types = args.get(TYPE) + value = args.get(VALUE) + body = {DATA: [{'type': types, 'value': value}]} + client.http_request( + POST, DELETE_OBJECT_FROM_SUSPICIOUS_LIST, data=json.dumps(body) + ) + + exception_list = client.suspicious_list_count() + + message = { + "message": "success", + "status_code": client.status, + "total_items": exception_list, + } + results = CommandResults( + readable_output=tableToMarkdown( + table_name[DELETE_SUSPICIOUS_LIST_COMMAND], message, removeNull=True + ), + outputs_prefix="VisionOne.Suspicious_List", + outputs_key_field="message", + outputs=message, + ) + return results + + +def get_file_analysis_status( + client: Client, args: Dict[str, Any] +) -> Union[str, CommandResults]: + """ + Get the status of file based on task id and + sends the result to demist war room + + :type client: ``Client`` + :param client: client object to use http_request. + + :type args: ``dict`` + :param args: args object to fetch the argument data. + + :return: sends data to demisto war room. + :rtype: ``dict` + """ + task_id = args.get(TASKID) + response = client.http_request(GET, GET_FILE_STATUS.format(taskId=task_id)) + + message = { + "message": response.get("message", ""), + "code": response.get("code", ""), + "task_id": response.get("data", {}).get("taskId", ""), + "taskStatus": response.get("data", {}).get("taskStatus", ""), + "digest": response.get("data", {}).get("digest", ""), + "analysis_completion_time": response.get("data", {}) + .get("analysisSummary", "") + .get("analysisCompletionTime", ""), + "risk_level": response.get("data", {}) + .get("analysisSummary", "") + .get("riskLevel", ""), + "description": response.get("data", {}) + .get("analysisSummary", "") + .get("description", ""), + "detection_name_list": response.get("data", {}) + .get("analysisSummary", "") + .get("detectionNameList", ""), + "threat_type_list": response.get("data", {}) + .get("analysisSummary", "") + .get("threatTypeList", ""), + "file_type": response.get("data", {}) + .get("analysisSummary", "") + .get("trueFileType", ""), + "report_id": response.get("data", {}).get("reportId", ""), + } + results = CommandResults( + readable_output=tableToMarkdown( + TABLE_GET_FILE_ANALYSIS_STATUS, message, removeNull=True), + outputs_prefix="VisionOne.File_Analysis_Status", + outputs_key_field="message", + outputs=message, + ) + return results + + +def get_file_analysis_report(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + Get the report of file based on report id and sends the result to demist war room + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + report_id = args.get(REPORT_ID) + types = args.get(TYPE) + if types not in ('vaReport', 'investigationPackage', 'suspiciousObject'): + return_error(FILE_TYPE_ERROR) + params = { + TYPE: types + } + response = client.http_request(GET, GET_FILE_REPORT.format(reportId=report_id), params=params) + if isinstance(response, dict): + + message = { + 'message': response.get("message", ""), + 'code': response.get("code", ""), + 'data': [] + } + if len(response.get('data', [])) > 0: + for data in response.get('data', {}): + data_value = { + 'type': data.get("type", ""), + 'value': data.get("value", ""), + 'risk_level': data.get("riskLevel", ""), + 'analysis_completion_time': data.get("analysisCompletionTime", ""), + 'expired_time': data.get("expiredTime", ""), + 'root_file_sha1': data.get("rootFileSha1", "") + } + message.get('data', {}).append(data_value) + results = CommandResults( + readable_output=tableToMarkdown(TABLE_GET_FILE_ANALYSIS_REPORT, message, removeNull=True), + outputs_prefix='VisionOne.File_Analysis_Report', + outputs_key_field='message', + outputs=message + ) + elif response.headers.get('Content-Type', '') == 'binary/octet-stream': + data = response.content + if types == 'vaReport': + results = fileResult('Sandbox_Analysis_Report.pdf', data, file_type=EntryType.ENTRY_INFO_FILE) + else: + results = fileResult('Sandbox_Investigation_Package.zip', data, file_type=EntryType.ENTRY_INFO_FILE) + return results + + +def collect_file(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + Collect forensic file and sends the result to demist war room + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + value = args.get(ENDPOINT) + field = client.lookup_type(value) + product_id = args.get(PRODUCT_ID) + description = args.get(DESCRIPTION) + if not description: + description = EMPTY_STRING + computer_id = client.get_computer_id(field, value) # type: ignore + file_path = args.get(FILE_PATH) + os = args.get(OS_TYPE) + body = { + 'description': description, + 'productId': product_id, + 'computerId': computer_id, + 'filePath': file_path, + 'os': os + } + response = client.http_request(POST, COLLECT_FORENSIC_FILE, data=json.dumps(body)) + + task_status = response.get("taskStatus", {}) + action_id = response.get('actionId', {}) + message = { + 'actionId': action_id, + 'taskStatus': task_status + } + results = CommandResults( + readable_output=tableToMarkdown(TABLE_COLLECT_FILE, message, removeNull=True), + outputs_prefix='VisionOne.Collect_Forensic_File', + outputs_key_field='actionId', + outputs=message + ) + return results + + +def download_information_collected_file(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + Gets the download information for collected forensic file and sends the result to demist war room + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + action_id = args.get(ACTION_ID) + params = {'actionId': action_id} + response = client.http_request(GET, DOWNLOAD_INFORMATION_COLLECTED_FILE, params=params) + + file_url = response.get('data', '').get('url', '') + expires = response.get('data', '').get('expires', '') + password = response.get('data', '').get('password', '') + filename = response.get('data', '').get('filename', '') + message = { + 'url': file_url, + 'expires': expires, + 'password': password, + 'filename': filename + } + results = CommandResults( + readable_output=tableToMarkdown(TABLE_COLLECTED_FORENSIC_FILE_DOWNLOAD_INFORMATION, message, removeNull=True), + outputs_prefix='VisionOne.Download_Information_For_Collected_Forensic_File', + outputs_key_field='url', + outputs=message + ) + return results + + +def submit_file_to_sandbox(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + submit file to sandbox and sends the result to demist war room + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + data = {} + params: Dict[Any, Any] = {} + file_url = args.get(FILE_URL) + file_name = args.get(FILE_NAME) + document_pass = args.get(DOCUMENT_PASSWORD) + if document_pass: + data['documentPassword'] = base64.b64encode(document_pass.encode(ASCII)).decode(ASCII) + archive_pass = args.get(ARCHIVE_PASSWORD) + if archive_pass: + data['archivePassword'] = base64.b64encode(archive_pass.encode(ASCII)).decode(ASCII) + headers = {AUTHORIZATION: f'{BEARER}{client.api_key}'} + try: + file_content = requests.get(file_url, allow_redirects=True) # type: ignore + files = {'file': (file_name, file_content.content, 'application/x-zip-compressed')} + result = requests.post(f'{client.base_url}{SUBMIT_FILE_TO_SANDBOX}', params=params, + headers=headers, data=data, files=files) + result.raise_for_status() + except HTTPError as http_err: + demisto.error(http_err) + return_error(http_err) + except Exception as err: + demisto.error(err) + return_error(err) + else: + response = result.json() + + message = { + 'message': response.get("message", ""), + 'code': response.get("code", ""), + 'task_id': response.get("data", "").get("taskId", ""), + 'digest': response.get("data", "").get("digest", ""), + } + results = CommandResults( + readable_output=tableToMarkdown(TABLE_SUBMIT_FILE_TO_SANDBOX, message, removeNull=True), + outputs_prefix='VisionOne.Submit_File_to_Sandbox', + outputs_key_field='message', + outputs=message + ) + return results + + +def add_note(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + Adds a note to an existing workbench alert + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + workbench_id = args.get(WORKBENCH_ID) + content = args.get(CONTENT) + + body = { + 'content': content + } + response = client.http_request( + POST, ADD_NOTE_ENDPOINT.format(workbenchId=workbench_id), data=json.dumps(body) + ) + + note_id = response.get("data").get("id") + response_code = response.get("info").get("code") + response_msg = response.get("info").get("msg") + message = {"Workbench_Id": workbench_id, "noteId": note_id, "response_code": response_code, "response_msg": response_msg} + results = CommandResults( + readable_output=tableToMarkdown(TABLE_ADD_NOTE, message, removeNull=True), + outputs_prefix="VisionOne.Add_Note", + outputs_key_field="noteId", + outputs=message, + ) + return results + + +def update_status(client: Client, args: Dict[str, Any]) -> Union[str, CommandResults]: + """ + Updates the status of an existing workbench alert + :type client: ``Client`` + :param client: client object to use http_request. + :type args: ``dict`` + :param args: args object to fetch the argument data. + :return: sends data to demisto war room. + :rtype: ``dict` + """ + workbench_id = args.get(WORKBENCH_ID) + status = args.get(STATUS) + + if status == 'new': + update_status = NEW + elif status == 'in_progress': + update_status = IN_PROGRESS + elif status == 'resolved_true_positive': + update_status = RESOLVED_TRUE_POSITIVE + elif status == 'resolved_false_positive': + update_status = RESOLVED_FALSE_POSITIVE + + body = { + 'investigationStatus': update_status + } + response = client.http_request( + PUT, UPDATE_STATUS_ENDPOINT.format(workbenchId=workbench_id), data=json.dumps(body) + ) + + response_code = response.get("info").get("code") + response_msg = response.get("info").get("msg") + message = {"Workbench_Id": workbench_id, "response_code": response_code, "response_msg": response_msg} + results = CommandResults( + readable_output=tableToMarkdown(TABLE_UPDATE_STATUS, message, removeNull=True), + outputs_prefix="VisionOne.Update_Status", + outputs_key_field="Workbench_Id", + outputs=message, + ) + return results + + +def main(): + try: + ''' GLOBAL VARS ''' + params = demisto.params() + + base_url = params.get(URL) + api_key = params.get(API_TOKEN).get('password') + + client = Client(base_url, api_key) + + command = demisto.command() + demisto.debug(COMMAND_CALLED.format(command=command)) + args = demisto.args() + + if command == 'test-module': + return_results(test_module(client)) + + elif command == 'fetch-incidents': + return_results(fetch_incidents(client)) + + elif command in (ADD_BLOCKLIST_COMMAND, REMOVE_BLOCKLIST_COMMAND): + return_results(add_or_remove_from_block_list(client, command, args)) + + elif command in (QUARANTINE_EMAIL_COMMAND, DELETE_EMAIL_COMMAND): + return_results(quarantine_or_delete_email_message(client, command, args)) + + elif command in (ISOLATE_ENDPOINT_COMMAND, RESTORE_ENDPOINT_COMMAND): + return_results(isolate_or_restore_connection(client, command, args)) + + elif command == TERMINATE_PROCESS_COMMAND: + return_results(terminate_process(client, args)) + + elif command in (ADD_EXCEPTION_LIST_COMMAND, DELETE_EXCEPTION_LIST_COMMAND): + return_results(add_or_delete_from_exception_list(client, command, args)) + + elif command == ADD_SUSPICIOUS_LIST_COMMAND: + return_results(add_to_suspicious_list(client, args)) + + elif command == DELETE_SUSPICIOUS_LIST_COMMAND: + return_results(delete_from_suspicious_list(client, args)) + + elif command == GET_FILE_ANALYSIS_STATUS: + return_results(get_file_analysis_status(client, args)) + + elif command == GET_FILE_ANALYSIS_REPORT: + return_results(get_file_analysis_report(client, args)) + + elif command == GET_ENDPOINT_INFO_COMMAND: + return_results(get_endpoint_info(client, args)) + + elif command == COLLECT_FILE: + return_results(collect_file(client, args)) + + elif command == DOWNLOAD_COLLECTED_FILE: + return_results(download_information_collected_file(client, args)) + + elif command == FILE_TO_SANDBOX: + return_results(submit_file_to_sandbox(client, args)) + + elif command == UPDATE_STATUS: + return_results(update_status(client, args)) + + elif command == ADD_NOTE: + return_results(add_note(client, args)) + + elif command == CHECK_TASK_STATUS: + if args.get("polling") == "true": + cmd_res = get_task_status(args, client) + if cmd_res is not None: + return_results(cmd_res) + else: + return_results(client.status_check(args)) + + else: + demisto.error(f'{command} command is not implemented.') + raise NotImplementedError(f'{command} command is not implemented.') + + except Exception as error: + demisto.error(COMMAND_EXECUTION_ERROR.format(error=error)) + + +if __name__ in ['__main__', 'builtin', 'builtins']: + main() diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml new file mode 100644 index 000000000000..814337753f33 --- /dev/null +++ b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne.yml @@ -0,0 +1,657 @@ +category: Data Enrichment & Threat Intelligence +commonfields: + id: Trend Micro Vision One + version: -1 +configuration: +- additionalinfo: The base url for the Trend Micro Vision One API + defaultvalue: https://api.xdr.trendmicro.com + display: API URL (e.g. https://api.xdr.trendmicro.com) + name: url + required: true + type: 0 +- additionalinfo: The API token to access data + displaypassword: API Key + name: apikey + required: true + type: 9 + hiddenusername: true +- display: Fetch incidents + name: isFetch + required: false + type: 8 +- defaultvalue: "5" + display: Incidents Fetch Interval + name: incidentFetchInterval + required: false + type: 19 +- display: Incident type + name: incidentType + required: false + defaultvalue: Trend Micro Vision One XDR Incident + type: 13 +- defaultvalue: "30" + display: Sync On First Run (days) + name: first_fetch + required: false + type: 0 +- defaultvalue: "50" + display: Max Incidents + name: max_fetch + required: false + type: 0 +description: Trend Micro Vision One is a purpose-built threat defense platform that + provides added value and new benefits beyond XDR solutions, allowing you to see + more and respond faster. Providing deep and broad extended detection and response + (XDR) capabilities that collect and automatically correlate data across multiple + security layers—email, endpoints, servers, cloud workloads, and networks—Trend Micro + Vision One prevents the majority of attacks with automated protection. +display: Trend Micro Vision One +defaultmapperin: Trend Micro Vision One XDR - Incoming Mapper +name: Trend Micro Vision One +script: + commands: + - arguments: + - description: 'The type of object you would like to add to the block list: "file_sha1", + "ip", "domain", "url" or "mailbox"' + name: value_type + required: true + auto: PREDEFINED + predefined: + - file_sha1 + - domain + - ip + - url + - mailbox + - description: The object you would like to add that matches the value-type + name: target_value + required: true + - description: Target product + name: product_id + - description: Optional description for reference + name: description + description: Adds a file SHA-1, IP address, domain, or URL object to the User-Defined + Suspicious Objects List, which blocks the objects on subsequent detections + name: trendmicro-visionone-add-to-block-list + outputs: + - contextPath: VisionOne.BlockList.actionId + description: Action ID of task adding file SHA-1, IP address, domain, or URL + to the User-Defined Suspicious Objects List + type: string + - contextPath: VisionOne.BlockList.taskStatus + description: Task status of adding file SHA-1, IP address, domain, or URL object + to the User-Defined Suspicious Objects List + type: string + - arguments: + - description: 'The type of object you would like to remove from the block list: + "file_sha1", "ip", "domain", "url" or "mailbox"' + name: value_type + auto: PREDEFINED + predefined: + - file_sha1 + - domain + - ip + - url + - mailbox + required: true + - description: The object you would like to add that matches the value-type + name: target_value + required: true + - description: Target product + name: product_id + - description: Optional description for reference + name: description + description: Removes a file SHA-1, IP address, domain, or URL from the User-Defined + Suspicious Objects List + name: trendmicro-visionone-remove-from-block-list + outputs: + - contextPath: VisionOne.BlockList.actionId + description: Action ID of task removing file SHA-1, IP address, domain, or URL + object from the User-Defined Suspicious Objects List + type: string + - contextPath: VisionOne.BlockList.taskStatus + description: Task Status of removing file SHA-1, IP address, domain, or URL + object that was added to the User-Defined Suspicious Objects List from block + list + type: string + - arguments: + - description: Email Message ID from Trend Micro Vision One message activity data + name: message_id + required: true + - description: Email mailbox where the message will be quarantined from + name: mailbox + required: true + - description: Email message's original delivery time + name: message_delivery_time + required: true + - default: true + defaultValue: sca + description: Target product + name: product_id + - description: Optional description for reference + name: description + description: Moves a message from a mailbox to the quarantine folder + name: trendmicro-visionone-quarantine-email-message + outputs: + - contextPath: VisionOne.Email.actionId + description: The Action Id of moving a message from a mailbox to the quarantine + folder + type: string + - contextPath: VisionOne.Email.taskStatus + description: The status of moving a message from a mailbox to the quarantine + folder + type: string + - arguments: + - description: Email Message ID from Trend Micro Vision One message activity data + name: message_id + required: true + - description: Email mailbox where the message will be quarantined from + name: mailbox + required: true + - description: Email message's delivery time + name: message_delivery_time + required: true + - default: true + defaultValue: sca + description: Target product + name: product_id + - description: Optional description for reference + name: description + description: Deletes a message from a mailbox + name: trendmicro-visionone-delete-email-message + outputs: + - contextPath: VisionOne.Email.actionId + description: The action id of deleting a message from a mailbox + type: string + - contextPath: VisionOne.Email.taskStatus + description: The task status of deleting a message from a mailbox + type: string + - arguments: + - description: '"hostname", "macaddr" or "ip" of the endpoint to isolate' + name: endpoint + required: true + - default: true + defaultValue: sao + description: 'Target product: "sao", "sds", or "xes"' + name: product_id + auto: PREDEFINED + predefined: + - sao + - sds + - xes + required: true + - description: Description + name: description + description: Disconnects an endpoint from the network (but allows communication + with the managing Trend Micro product) + name: trendmicro-visionone-isolate-endpoint + outputs: + - contextPath: VisionOne.Endpoint_Connection.actionId + description: The action ID of isolate endpoint task + type: string + - contextPath: VisionOne.Endpoint_Connection.taskStatus + description: 'The task status of isolate endpoint ' + type: string + - arguments: + - description: '"hostname", "macaddr" or "ip" of the endpoint to restore' + name: endpoint + required: true + - default: true + defaultValue: sao + description: 'Target product: "sao", "sds", or "xes"' + name: product_id + auto: PREDEFINED + predefined: + - sao + - sds + - xes + required: true + - description: Description + name: description + description: Restores network connectivity to an endpoint that applied the "isolate + endpoint" action + name: trendmicro-visionone-restore-endpoint-connection + outputs: + - contextPath: VisionOne.Endpoint_Connection.actionId + description: The action ID of the restore endpoint connection + type: string + - contextPath: VisionOne.Endpoint_Connection.taskStatus + description: The task status of restore endpoint connection + type: string + - arguments: + - description: 'Object type: "domain", "ip", "sha1", or "url".' + name: type + auto: PREDEFINED + predefined: + - domain + - ip + - sha1 + - url + required: true + - description: The object value. Full and partial matches supported. Domain partial + match, (with a wildcard as the subdomain, example, .example.com) IP partial + match, (IP range example, 192.168.35.1-192.168.35.254, cidr example, 192.168.35.1/24) + URL Partial match, (Supports wildcards 'http://.'', 'https://.'' at beginning, + or ''' at the end. Multiple wild cards also supported, such as , https://.example.com/path1/) + SHA1 Only full match" + name: value + required: true + - description: Exception description. + name: description + description: Adds domains, file SHA-1 values, IP addresses, or URLs to the Exception + List and prevents these objects from being added to the Suspicious Object List + name: trendmicro-visionone-add-objects-to-exception-list + outputs: + - contextPath: VisionOne.Exception_List.message + description: status message success after task completion + type: string + - contextPath: VisionOne.Exception_List.status_code + description: status code of response + type: string + - contextPath: VisionOne.Exception_List.total_items + description: count of item present in exception list + type: string + - arguments: + - description: 'Object type: "domain", "ip", "sha1", or "url".' + name: type + auto: PREDEFINED + predefined: + - domain + - ip + - sha1 + - url + required: true + - description: The object value. + name: value + required: true + description: Deletes domains, file SHA-1 values, IP addresses, or URLs from the + Exception List. + name: trendmicro-visionone-delete-objects-from-exception-list + outputs: + - contextPath: VisionOne.Exception_List.message + description: status message success after task completion + type: string + - contextPath: VisionOne.Exception_List.status_code + description: status code of response + type: number + - contextPath: VisionOne.Exception_List.total_items + description: count of item present in exception list + type: string + - arguments: + - description: 'Object type: "domain", "ip", "sha1", or "url".' + name: type + auto: PREDEFINED + predefined: + - domain + - ip + - sha1 + - url + required: true + - description: The object value. + name: value + required: true + - description: Description + name: description + - description: The action to take if object is found. If you don't use this parameter, + the scan action specified in default_settings.riskLevel.type will be used + instead. "block" or "log". + name: scan_action + auto: PREDEFINED + predefined: + - block + - log + - description: The Suspicious Object risk level. If you don't use this parameter, + high will be used instead. "high", "medium" or "low". + name: risk_level + auto: PREDEFINED + predefined: + - high + - medium + - low + - description: The number of days to keep the object in the Suspicious Object + List. If you don't use this parameter, the default_settings.expiredDay scan + action will be used instead. + name: expiry_days + description: Adds domains, file SHA-1 values, IP addresses, or URLs to the Suspicious + Object List. + name: trendmicro-visionone-add-objects-to-suspicious-list + outputs: + - contextPath: VisionOne.Suspicious_List.message + description: Status message of adding item to suspicious object list + type: string + - contextPath: VisionOne.Suspicious_List.status_code + description: Response code of adding item to suspicious object list + type: number + - contextPath: VisionOne.Suspicious_List.total_items + description: Number of items present in suspicious object list + type: number + - arguments: + - description: 'Object type: "domain", "ip", "sha1", or "url".' + name: type + auto: PREDEFINED + predefined: + - domain + - ip + - sha1 + - url + required: true + - description: The object value. + name: value + required: true + description: Deletes domains, file SHA-1 values, IP addresses, or URLs from the + Suspicious Object List + name: trendmicro-visionone-delete-objects-from-suspicious-list + outputs: + - contextPath: VisionOne.Suspicious_List.message + description: Status message of removing item from suspicious object list + type: string + - contextPath: VisionOne.Suspicious_List.status_code + description: Response code of removing item from suspicious object list + type: number + - contextPath: VisionOne.Suspicious_List.total_items + description: Number of items present in suspicious object list + type: number + - arguments: + - description: '"hostname", "macaddr" or "ip" of the endpoint to query' + name: endpoint + required: true + description: Retrieves information about a specific endpoint + name: trendmicro-visionone-get-endpoint-info + outputs: + - contextPath: VisionOne.Endpoint_Info.message + description: Message information from the request + type: string + - contextPath: VisionOne.Endpoint_Info.errorCode + description: Error code + type: integer + - contextPath: VisionOne.Endpoint_Info.status + description: Status of the request + type: string + - contextPath: VisionOne.Endpoint_Info.logonAccount + description: Account currently logged on to the endpoint + type: string + - contextPath: VisionOne.Endpoint_Info.hostname + description: Hostname + type: string + - contextPath: VisionOne.Endpoint_Info.macAddr + description: MAC address + type: string + - contextPath: VisionOne.Endpoint_Info.ip + description: IP address + type: string + - contextPath: VisionOne.Endpoint_Info.osName + description: Operating System name + type: string + - contextPath: VisionOne.Endpoint_Info.osVersion + description: Operating System nersion + type: string + - contextPath: VisionOne.Endpoint_Info.osDescription + description: Description of the Operating System + type: string + - contextPath: VisionOne.Endpoint_Info.productCode + description: Product code of the Trend Micro product running on the endpoint + type: string + - arguments: + - description: '"hostname", "macaddr" or "ip" of the endpoint to terminate process on' + name: endpoint + required: true + - description: SHA1 hash of the process to terminate + name: file_sha1 + required: true + - default: true + defaultValue: sao + description: Target product + auto: PREDEFINED + predefined: + - sao + name: product_id + - description: Description + name: description + - description: Optional file name list for log + name: filename + description: Terminates a process that is running on an endpoint + name: trendmicro-visionone-terminate-process + outputs: + - contextPath: VisionOne.Terminate_Process.actionId + description: Action Id of the current running task + type: string + - contextPath: VisionOne.Terminate_Process.taskStatus + description: Status of current running task + type: string + - arguments: + - description: task_id from the trendmicro-visionone-submit-file-to-sandbox command + output + name: task_id + required: true + description: Retrieves the status of a sandbox analysis submission + name: trendmicro-visionone-get-file-analysis-status + outputs: + - contextPath: VisionOne.File_Analysis_Status.message + description: Status of the sandbox analysis + type: string + - contextPath: VisionOne.File_Analysis_Status.code + description: Response code + type: string + - contextPath: VisionOne.File_Analysis_Status.task_id + description: task_id of the task queried + type: string + - contextPath: VisionOne.File_Analysis_Status.taskStatus + description: Sandbox analysis status + type: string + - contextPath: VisionOne.File_Analysis_Status.digest + description: The hash values of file analyzed + type: string + - contextPath: VisionOne.File_Analysis_Status.analysis_completion_time + description: Sample analysis completed time. + type: string + - contextPath: VisionOne.File_Analysis_Status.risk_level + description: Risk Level of the analyzed file. + type: string + - contextPath: VisionOne.File_Analysis_Status.descritption + description: Scan result description for NotAnalyzed. + type: string + - contextPath: VisionOne.File_Analysis_Status.detection_name_list + description: Detection name of this sample, if applicable. + type: unknown + - contextPath: VisionOne.File_Analysis_Status.threat_type_list + description: Threat type of this sample. + - contextPath: VisionOne.File_Analysis_Status.file_type + description: File type of this sample. + type: string + - contextPath: VisionOne.File_Analysis_Status.report_id + description: ID used to get the report and suspicious object. Empty means no + report. + type: string + - arguments: + - description: report_id of the sandbox submission retrieved from the trendmicro-visionone-get-file-analysis-status + command + name: report_id + required: true + - description: 'Type of report to retrieve: "vaReport", "investigationPackage", + or "suspiciousObject"' + name: type + auto: PREDEFINED + predefined: + - vaReport + - investigationPackage + - suspiciousObject + required: true + description: Retrieves the analysis report, investigation package, or Suspicious + Object List of a submitted file + name: trendmicro-visionone-get-file-analysis-report + outputs: + - contextPath: VisionOne.File_Analysis_Report.message + description: Status message of file report + type: string + - contextPath: VisionOne.File_Analysis_Report.code + description: status code of file report + type: string + - contextPath: VisionOne.File_Analysis_Report.type + description: Suspicious object type + type: string + - contextPath: VisionOne.File_Analysis_Report.value + description: Suspicious object value + type: string + - contextPath: VisionOne.File_Analysis_Report.risk_level + description: Risk Level of suspicious object + type: string + - contextPath: VisionOne.File_Analysis_Report.analysis_completion_time + description: Analyze time of suspicious object + type: string + - contextPath: VisionOne.File_Analysis_Report.expired_time + description: Expire time of suspicious object + type: string + - contextPath: VisionOne.File_Analysis_Report.root_file_sha1 + description: Sample sha1 generate this suspicious object + type: string + - arguments: + - description: '"hostname", "macaddr" or "ip" of the endpoint to collect file from' + name: endpoint + required: true + - description: 'Product: "sao", "sds" or "xes"' + name: product_id + auto: PREDEFINED + predefined: + - sao + - xes + - sds + required: true + - description: Path to the file to collect. + name: file_path + required: true + - description: Type of OS. "windows", "mac" or "linux" + name: os + required: true + - description: Description of the file. + name: description + description: Compresses a file on an endpoint in a password-protected archive + and then sends the archive to the XDR service platform + name: trendmicro-visionone-collect-forensic-file + outputs: + - contextPath: VisionOne.Collect_Forensic_File.actionId + description: Action ID of the particular file. + type: string + - contextPath: VisionOne.Collect_Forensic_File.taskStatus + description: Task status of collected file + type: string + - arguments: + - description: actionId output from the collect command used to collect the file. + name: actionId + required: true + description: Retrieves a URL and other information required to download a collected + file via the trendmicro-visionone-collect-forensic-file command + name: trendmicro-visionone-download-information-for-collected-forensic-file + outputs: + - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.url + description: URL of the collected file + type: string + - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.expires + description: URL expiration date + type: string + - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.password + description: Archive password for the protected forensic file + type: string + - contextPath: VisionOne.Download_Information_For_Collected_Forensic_File.filename + description: Name of the collected file + type: string + - arguments: + - description: URL pointing to the location of the file to be submitted. + name: file_url + required: true + - description: Name of the file to be analyzed + name: filename + required: true + - description: The Base64 encoded password for decrypting the submitted document. + sample. + name: document_password + - description: The Base64 encoded password for decrypting the submitted archive. + name: archive_password + description: Submits a file to the sandbox for analysis (Note. For more information + about the supported file types, see the Trend Micro Vision One Online Help. + Submissions require credits. Does not require credits in regions where Sandbox + Analysis has not been officially released.) + name: trendmicro-visionone-submit-file-to-sandbox + outputs: + - contextPath: VisionOne.Submit_File_to_Sandbox.message + description: Status message of the file submitted to sandbox. + type: string + - contextPath: VisionOne.Submit_File_to_Sandbox.code + description: status code of the file submitted to sandbox + type: string + - contextPath: VisionOne.Submit_File_to_Sandbox.task_id + description: Task ID of the submitted file + type: string + - contextPath: VisionOne.Submit_File_to_Sandbox.digest + description: The hash value of the file + - arguments: + - name: polling + default: true + description: polling the task for 30 seconds interval. + defaultValue: "true" + - name: actionId + required: true + description: Action id of the task you would like to check. + outputs: + - contextPath: VisionOne.Task_Status.actionId + description: Action ID of the task queried. + - contextPath: VisionOne.Task_Status.taskStatus + description: Status of the task. + name: trendmicro-visionone-check-task-status + polling: true + description: Command gives the status of the running task based on the action id. + - arguments: + - description: ID of the workbench you would like to attach the note to. + name: workbench_id + required: true + - description: Contents of the note to be attached + name: content + required: true + outputs: + - contextPath: VisionOne.Add_Note.Workbench_Id + description: The ID of the workbench that the note was added to. + type: string + - contextPath: VisionOne.Add_Note.Note_Id + description: The ID of the note that was added. + type: string + - contextPath: VisionOne.Add_Note.Response_Code + description: The response code from the command + type: string + - contextPath: VisionOne.Add_Note.Response_Msg + description: The response message from the commandß + type: string + description: Attaches a note to a workbench alert + name: trendmicro-visionone-add-note + - arguments: + - description: ID of the workbench you would like to update the status for. + name: workbench_id + required: true + - description: Status to assign to the workbench alert + name: status + required: true + auto: PREDEFINED + predefined: + - new + - in_progress + - resolved_true_positive + - resolved_false_positive + outputs: + - contextPath: VisionOne.Update_Status.Workbench_Id + description: The ID of the workbench that had the status updated. + type: string + - contextPath: VisionOne.Update_Status.Response_Code + description: The response code from the command + type: string + - contextPath: VisionOne.Update_Status.Response_Msg + description: The response message from the commandß + type: string + description: Updates the status of a workbench alert + name: trendmicro-visionone-update-status + dockerimage: demisto/python3:3.10.4.29342 + isFetchSamples: true + isfetch: true + runonce: false + script: '' + subtype: python3 + type: python +fromversion: 6.2.0 +tests: +- No tests (auto formatted) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md new file mode 100644 index 000000000000..8bafba79deb7 --- /dev/null +++ b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_description.md @@ -0,0 +1,64 @@ +#### Integration Author: Trend Micro +Support and maintenance for this integration are provided by the author. Please use the following contact details: +- **Email**: [integrations@trendmicro.com](mailto:integrations@trendmicro.com) +*** +Trend Micro Vision One is a purpose-built threat defense platform that provides added value and new benefits beyond XDR solutions, allowing you to see more and respond faster. Providing deep and broad extended detection and response (XDR) capabilities that collect and automatically correlate data across multiple security layers—email, endpoints, servers, cloud workloads, and networks—Trend Micro Vision One prevents the majority of attacks with automated protection. + +## Obtaining Trend Micro Vision One API Credentials +Configuring the Trend Micro Vision One integration requires API credentials generated in Trend Micro Vision One. It is recommended that a new role be created with just the permissions required for this integration. You can create a new role for this integration by following these steps in Trend Micro Vision One. + +1. Navigate to **Administration** > **User Roles** +2. Click on the **Add** button +3. Provide a name and descriptions for the role such as **Cortex XSOAR** +4. Click on the **Permissions** button and assign the following permissions to the role: + +| **Category** | **Application** | **Permission** | +| --- | --- | --- | +| Threat Intelligence | Suspicious Object Management | View, filter, and search | +| Threat Intelligence | Suspicious Object Management | Manage lists and configure settings | +| Threat Intelligence | Suspicious Object Management | View object in Sandbox Analysis | +| Threat Intelligence | Sandbox Analysis | View, filter, and search | +| Threat Intelligence | Sandbox Analysis | Submit objects | +| XDR | Workbench | Add exceptions | +| XDR | Workbench | Modify alert details | +| XDR | Workbench | View, filter, and search | +| Response Management | Response Management | View, filter, and search Task List tab | +| Response Management | Response Management | Approve/Reject Automated Response tasks | +| Response Management | Response Management | Collect file | +| Response Management | Response Management | Delete/Quarantine messages | +| Response Management | Response Management | Isolate endpoint | +| Response Management | Response Management | Terminate process | +| Response Management | Response Management | View network exceptions | +| Response Management | Response Management | Add to block list | +| Response Management | Response Management | Edit network exceptions | +| Response Management | Response Management | Submit to sandbox | + +You can then create a user account and generate an API key to be used for the Cortex XSOAR integration by following these steps in Trend Micro Vision One. + +1. Navigate to **Administration** > **User Accounts** +2. Click on the **Add Account** button +3. Fill in the **Add Account** details assigning the role you created in the previous step and choosing **APIs only** as the access level +4. Complete the account creation process by following the steps in the email sent +4. This will generate an **Authentication token** that can then be used to configure the Cortex XSOAR integration + +## Configure Trend Micro Vision One on Cortex XSOAR + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for Trend Micro Vision One. +3. Click **Add instance** to create and configure a new integration instance. + +| **Parameter** | **Description** | **Required** | +| --- | --- | --- | +| Name | Unique name for this Trend Micro Vision One instance | True | +| Fetch Incidents | Choose if the integration should sync incidents | True | +| Incident Type | Endsure the "Trend Micro Vision One XDR Incident" type is selected | True | +| Mapper (Incoming) | Endsure the "Trend Micro Vision One XDR - Incoming Mapper" type is selected | True | +| API URL | Base URL for Trend Micro Vision One API | True | +| API Key | API token for authentication | True | +| Incidents Fetch Interval | How often do you want to check for new incidents | False | +| Sync On First Run (days) | How many days to go back during first sync | False | +| Max Incidents | Maximum Number of Workbenches to Retrieve | False | +4. Click **Test** to validate the URLs, token, and connection. + +--- +[View Integration Documentation](https://xsoar.pan.dev/docs/reference/integrations/trend-micro-vision-one) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/TrendMicroVisionOne_image.png new file mode 100644 index 0000000000000000000000000000000000000000..98c959cb86c90034ee39e1d5b01c0144dba818a0 GIT binary patch literal 2477 zcmXw4c|6ql8y|DI!o|u276KxyLciSnNimP|+kr?u`uETxDyi|fA2!#U1R?{3& z!vOSQYYNB%zZD+N#Sp>J|A{~#02jV3_0513po}4P)<(xCwDdSAEEo{~1_rutwTN6a z4iFz##{z;ZC5*74fsMifFg6MY0NA@Q9Bl$H4q(7BI2yXZTzrzl7*ZDkfloP+$JDj9 z^-U~z!NFW@eZGzXk7&%r8FAFKCidC_QWNG@E5#MPS-@dc; z_3Ic4yFN9|As7St!1zE50K?WIa!C8eO|8avTX2vBwj){e;4u%VYvO=w0RUr4NH$VO zfF_RbLi06o98KH=nlP?{8sDkG-($nk(&M7AqNl2e~RSXAf_*EkLl#%`6 z=!pqOGT+K!3QgEtS@|kj*qEK$nECYOP2XZu%gmYd>99kaYisLMf^{BG^8Cf})6T`V zc2OO3zLGvycKLHo-iMQ?h2ha$z1`Dj!URHnV_LW}I4pVjdil|lrF$I<%|E~8N@H<)y<5pP|W9*pQE+yFK_jmuSO7}DGEU|tP ze>BR=!Oj-H0|o`p2nHH1WoIQP20J1*H&;Ij|9Nx$_|Ilq3UagD!JY?qZnxB2IiD69 zN_Mf=QCpRa_O~=uU#%$0NsT#3@vVSviK7?`1H9QCe*CIRb5B#ZXuJS-I$`6rE)WMx|@YgAsWHMdCuDN>VJm~ngQbYtg zLYd)TL*Z~Z)77Vg+T{Q8$xBRAGz01V=sTy_ zcau5D{M4tX=@wD*-49Ng(Cwt)Ea_leb&DnjX; z=yrQUE?utu_2i6V-rg6&%#bvjt#?&gZPJcLr>@bRT9~gzLf*a1iBHj28}`lq+4Ji` zYwyy8wMWCZ*!Podrj3mpB`tS-J-uRyE0-%O>sim4@fj&nebTkbF*doihXs+>@w3w( zV$$a1_~QORS~uvhI5JP z7^~|or7L^U2iLS1?*si3#ZrFXfA7dnW#YL4dv6HF|ETq*ZgPf`xQCoeddK4(*G|jY zIyeJTkfl9s!kmk7^1X?dLjPNOP`paN;5+OjJy2Nk9J#Kn9RG=SmQa7Qjll}P9bC7% zWXShxdaI!|1X7FW$=rX2S%k-xs#uc!+Oo9?=;_Jcijtr%nb-kW<(2CtI6VGsw^gGb z5#aIi9MmT|ep@QO56k)n{TG5cG31t2$=gYjneYZy{MU zGNL*XxRcBH9r=@2En|d8Vjx3}f(u(oQTzFbuGl%AR+LIeQ(Dm*%HT4L9u*Vk9VwNe zeKPXbKk&I~(jNzgbUpPCy1Qc$$SywPWpjFv`*0(7^G0agG5fICV_d%RUYdem6iR~2 zq&+QaS49_HRSR?UUS+N6cN>kK_lh_-EbJF~v@uNd^!g5{KA1K1&N6I`PVs3G7aRR7 z5z0>z4r%8`Ds-zj8wYKuDDMDwRkhe$>>qNUcw1K&mdsq$pU+D28x7pj=pk9bKhn6J zMOX*@FY`t!^}ZLh{868F2H;r%8uwkNg<}oLGN?pxarnoogfnd!zI=k~C(nh9!kQwl~St3`v|BdU#dJ?dYur$Vi|~TIvKywkwYavD`>y&YYC( zEU^pRl~P~tA$_RHp~fUCEAfh}+|2`v8B6YCNt08{2{M!da{|cIAEQVVEFS9^+E89% zCM?o>HCNp}5?(Nud{|F)M7IXr{b-BTEuM`hm+oH>-7OSrBi`k2>C`>>Bux(+WTm0z?tSSWOh zX-At~>o9FyUno^ADHYhikX&}7M|FgqvpIS#IKOeIS$0Oc%RK=hHX~VHu8h0L?(W#Hyy1N1fE{Z6 zy|$vcOD>~9N~pMg@&dwT#xz8p5@&Tb=C?%4cr|uZ%m62_EfT3&qFqxJWS z@Ete}<-<%xf_#r&$)00V=x7-*%)sJxd$2q^i2mY@AxNp5M%@#FnNCF)FYc*i(yB)X zbOU!_+d&Hd7CW*Cg?mg(Pyg9TQ#g7icH$DMQB)r!ta=}`X?Vl&!jGcg9T2hjV`{%J z5^@E3h7Y62yVH&YH6CfM)gaTK2*T4dKMyr+v}m$CNSYf1VRW2QRzbMuFUfzs9zJ1- ziKDX~(=jAHtJGbo8D+JKAMZpIlv9P#OU<)~-$}^1){*=&Q>XU_TyFag50Q4" + ), + "mailBox": "kjshdfjksahd@trendenablement.com", + "messageDeliveryTime": "2021-12-09T14:00:12.000Z", + "productId": "sca", + "description": "quarantine info", + } + result = quarantine_or_delete_email_message( + client, "trendmicro-visionone-quarantine-email-message", args + ) + assert result.outputs["taskStatus"] == "pending" + assert isinstance(result.outputs["actionId"], str) + assert result.outputs_prefix == "VisionOne.Email" + assert result.outputs_key_field == "actionId" + + +# Test cases for delete email message +def test_delete_email_message(mocker): + """Test delete email message with positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + quarantine_delete_email_mock_response + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "messageId": ( + "" + ), + "mailBox": "kjshdfjksahd@trendenablement.com", + "messageDeliveryTime": "2021-12-09T14:00:55.000Z", + "productId": "sca", + "description": "quarantine info", + } + result = quarantine_or_delete_email_message( + client, "trendmicro-visionone-delete-email-message", args + ) + assert result.outputs["taskStatus"] == "pending" + assert isinstance(result.outputs["actionId"], str) + assert result.outputs_prefix == "VisionOne.Email" + assert result.outputs_key_field == "actionId" + + +# Mock function for isolate and restore endpoint +def isolate_restore_mock_response(*args, **kwargs): + return_value = { + "status": "string", + "actionId": "88139521", + "taskStatus": "pending", + "result": { + "computerId": "string", + }, + "data": { + "createdTime": 1589525651, + "executedTime": 1589525725, + "finishedTime": 1589525725, + "taskStatus": "success", + "error": {}, + }, + } + return return_value + + +# Test cases for isolate endpoint +def test_isolate_endpoint(mocker): + """Test isolate endpoint postive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + isolate_restore_mock_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "endpoint": "hostname", + "productId": "sao", + "description": "isolate endpoint info", + } + result = isolate_or_restore_connection( + client, "trendmicro-visionone-isolate-endpoint", args + ) + assert result.outputs["taskStatus"] == "pending" + assert result.outputs_prefix == "VisionOne.Endpoint_Connection" + assert result.outputs_key_field == "actionId" + + +# Test cases for restore endpoint +def test_restore_endpoint(mocker): + """Test restore endpoint positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + isolate_restore_mock_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "endpoint": "hostname", + "productId": "sao", + "description": "restore endpoint info", + } + result = isolate_or_restore_connection( + client, "trendmicro-visionone-restore-endpoint-connection", args + ) + assert result.outputs["taskStatus"] == "pending" + assert result.outputs_prefix == "VisionOne.Endpoint_Connection" + assert result.outputs_key_field == "actionId" + + +# Test cases for terminate process endpoint +def test_terminate_process_endpoint(mocker): + """Test terminate process positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + isolate_restore_mock_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "endpoint": "00:50:56:81:87:A8", + "fileSha1": "12a08b7a3c5a10b64700c0aca1a47941b50a4f8b", + "productId": "sao", + "description": "terminate info", + "filename": "testfile", + } + result = terminate_process(client, args) + assert result.outputs["taskStatus"] == "pending" + assert isinstance(result.outputs["actionId"], str) + assert result.outputs_prefix == "VisionOne.Terminate_Process" + assert result.outputs_key_field == "actionId" + + +# Mock function for add and delete exception list +def add_delete_exception_mock_response(*args, **kwargs): + return_value = 20 + return return_value + + +# Test cases for add exception list endpoint. +def test_add_object_to_exception_list(mocker): + """Test add to exception list with positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + add_delete_exception_mock_response) + mocker.patch( + "TrendMicroVisionOne.Client.exception_list_count", + add_delete_exception_mock_response + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "type": "domain", + "value": "1.alisiosanguera.com", + "description": "new key" + } + result = add_or_delete_from_exception_list( + client, + "trendmicro-visionone-add-objects-to-exception-list", + args + ) + assert result.outputs["status_code"] is None + assert result.outputs_prefix == "VisionOne.Exception_List" + assert isinstance(result.outputs["total_items"], int) + assert result.outputs_key_field == "message" + + +# Test cases for delete exception list. +def test_delete_object_to_exception_list(mocker): + """Test delete exception list positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + add_delete_exception_mock_response) + mocker.patch( + "TrendMicroVisionOne.Client.exception_list_count", + add_delete_exception_mock_response + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "type": "domain", + "value": "1.alisiosanguera.com.cn", + "description": "testing exception", + } + result = add_or_delete_from_exception_list( + client, "trendmicro-visionone-delete-objects-from-exception-list", args + ) + assert result.outputs["status_code"] is None + assert isinstance(result.outputs["total_items"], int) + assert result.outputs_prefix == "VisionOne.Exception_List" + assert result.outputs_key_field == "message" + + +# Mock response for add and delete suspicious list +def add_delete_suspicious_mock_response(*args, **kwargs): + return_value = 20 + return return_value + + +# Test cases for add suspicious object list +def test_add_object_to_suspicious_list(mocker): + """Test add to suspicious list with poistive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + add_delete_suspicious_mock_response) + mocker.patch( + "TrendMicroVisionOne.Client.suspicious_list_count", + add_delete_suspicious_mock_response + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "type": "domain", + "value": "1.alisiosanguera.com.cn", + "description": "Example Suspicious Object.", + "scanAction": "log", + "riskLevel": "high", + "expiredDay": 15, + } + result = add_to_suspicious_list(client, args) + assert result.outputs["status_code"] is None + assert isinstance(result.outputs["total_items"], int) + assert result.outputs_prefix == "VisionOne.Suspicious_List" + assert result.outputs_key_field == "message" + + +# Test cases for delete suspicious object list +def test_delete_object_from_suspicious_list(mocker): + """Test delete object from suspicious list.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + add_delete_suspicious_mock_response) + mocker.patch( + "TrendMicroVisionOne.Client.suspicious_list_count", + add_delete_suspicious_mock_response + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = {"type": "domain", "value": "1.alisiosanguera.com.cn"} + result = delete_from_suspicious_list(client, args) + assert result.outputs["status_code"] is None + assert isinstance(result.outputs["total_items"], int) + assert result.outputs_prefix == "VisionOne.Suspicious_List" + assert result.outputs_key_field == "message" + + +# Mock response for Get file analysis status +def mock_file_status_response(*args, **kwargs): + return_response = { + "code": "Success", + "message": "Success", + "data": { + "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", + "taskStatus": "finished", + "digest": { + "md5": "4ac174730d4143a119037d9fda81c7a9", + "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", + "sha256": ( + "65b0f656e79ab84ca17807158e3ea" + "c206bd58be6689ddeb95956a48748d138f9" + ), + }, + "analysisSummary": { + "analysisCompletionTime": "2021-05-07T03:08:40Z", + "riskLevel": "high", + "description": "", + "detectionNameList": [], + "threatTypeList": [], + "trueFileType": "exe", + }, + "reportId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", + }, + } + return return_response + + +# Test Cases for Get file analysis status +def test_get_file_status(mocker): + """Test to get status of file""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_file_status_response) + args = {"taskId": "921674d0-9735-4f79-b7de-c852e00a003d"} + client = Client("https://api.xdr.trendmicro.com", api_key) + result = get_file_analysis_status(client, args) + assert result.outputs["message"] == "Success" + assert result.outputs["code"] == "Success" + assert result.outputs["task_id"] == "012e4eac-9bd9-4e89-95db-77e02f75a6f3" + assert result.outputs["taskStatus"] == "finished" + assert result.outputs["report_id"] == ( + "012e4eac-9bd9-4e89-95db-77e02f75a6f3") + assert result.outputs_prefix == "VisionOne.File_Analysis_Status" + assert result.outputs_key_field == "message" + + +def test_get_report_id(mocker): + """Test to get status of file with report id""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_file_status_response) + args = {"taskId": "921674d0-9735-4f79-b7de-c852e00a003d"} + client = Client("https://api.xdr.trendmicro.com", api_key) + result = get_file_analysis_status(client, args) + assert result.outputs["message"] == "Success" + assert result.outputs["code"] == "Success" + assert result.outputs["report_id"] == ( + "012e4eac-9bd9-4e89-95db-77e02f75a6f3") + assert result.outputs_prefix == "VisionOne.File_Analysis_Status" + assert result.outputs_key_field == "message" + + +# Mock response for Get file analysis report +def mock_file_report_response(*args, **kwargs): + return_response = { + "code": "Success", + "message": "Success", + "data": [ + { + "type": "ip", + "value": "6.6.6.6", + "riskLevel": "high", + "analysisCompletionTime": "2021-05-07T03:08:40Z", + "expiredTime": "2021-06-07T03:08:40Z", + "rootFileSha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", + } + ], + } + return return_response + + +# Test cases for get file analysis report +def test_get_file_analysis_report(mocker): + """Test get file analysis report data.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_file_report_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "reportId": "800f908d-9578-4333-91e5-822794ed5483", + "type": "suspiciousObject", + } + result = get_file_analysis_report(client, args) + assert result.outputs["message"] == "Success" + assert result.outputs["code"] == "Success" + assert isinstance(result.outputs["data"][0]["type"], str) + assert isinstance(result.outputs["data"][0]["value"], str) + assert isinstance(result.outputs["data"][0]["risk_level"], str) + assert isinstance(result.outputs["data"][0]["analysis_completion_time"], str) + assert isinstance(result.outputs["data"][0]["expired_time"], str) + assert isinstance(result.outputs["data"][0]["root_file_sha1"], str) + + +def test_get_file_analysis_report_1(mocker): + """Test get file analysis report data.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_file_report_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "reportId": "800f908d-9578-4333-91e5-822794ed5483", + "type": "suspiciousObject", + } + result = get_file_analysis_report(client, args) + assert result.outputs["message"] == "Success" + assert result.outputs["code"] == "Success" + assert len(result.outputs["data"]) > 0 + + +# Mock function for isolate and restore endpoint +def mock_collect_file(*args, **kwargs): + return_value = { + "status": "string", + "actionId": "88139521", + "taskStatus": "pending", + "result": { + "computerId": "string", + }, + "data": { + "createdTime": 1589525651, + "executedTime": 1589525725, + "finishedTime": 1589525725, + "taskStatus": "success", + "error": {}, + } + } + return return_value + + +# Test cases for collect forensic file. +def test_collect_forensic_file(mocker): + """Test collect file with positive scenario.""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_collect_file) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "endpoint": "hostname", + "description": "collect file", + "productId": "sao", + "filePath": ( + "/file_path/sample.txt" + ), + "os": "linux", + } + result = collect_file(client, args) + assert result.outputs["taskStatus"] == "pending" + assert isinstance(result.outputs["actionId"], str) + assert result.outputs_prefix == "VisionOne.Collect_Forensic_File" + assert result.outputs_key_field == "actionId" + + +# Mock for downloaded file information +def mock_download_collected_file_info_response(*args, **kwargs): + return_response = { + "data": { + "url": "string", + "expires": "2011-10-05T14:48:00.000Z", + "password": "string", + "filename": "string", + } + } + return return_response + + +# Test Cases for Collected downloaded file information. +def test_get_forensic_file_information(mocker): + """Test endpoint to get collected file infomation based on action id""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_download_collected_file_info_response + ) + args = {"actionId": "00000700"} + client = Client("https://api.xdr.trendmicro.com", api_key) + result = download_information_collected_file(client, args) + assert isinstance(result.outputs["url"], str) + assert isinstance(result.outputs["expires"], str) + assert isinstance(result.outputs["password"], str) + assert isinstance(result.outputs["filename"], str) + + +# Mock response for submit file to sandbox. +def mock_submit_file_to_sandbox_reponse(*args, **kwargs): + return_response = { + "code": "Success", + "message": "Success", + "data": { + "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", + "digest": { + "md5": "4ac174730d4143a119037d9fda81c7a9", + "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", + "sha256": ( + "65b0f656e79ab84ca17807158e3ea" + "c206bd58be6689ddeb95956a48748d138f9" + ) + }, + }, + } + return return_response + + +# Mock response for submit file to sandbox. +def mocked_requests_get(*args, **kwargs): + class MockResponse: + def __init__(self, json_data, status_code, content): + self.json_data = json_data + self.status_code = status_code + self.content = content + + def json(self): + return self.json_data + + if args[0] == 'http://someurl.com/test.json': + return MockResponse({"key1": "value1"}, 200, "response") + elif args[0] == 'http://someotherurl.com/anothertest.json': + return MockResponse({"key2": "value2"}, 200, "response") + + return MockResponse(None, 404, None) + + +# Mock response for submit file to sandbox. +def mocked_requests_post(*args, **kwargs): + class MockResponse: + def __init__(self, json_data, status_code, content): + self.json_data = json_data + self.status_code = status_code + self.content = content + + def json(self): + return { + "code": "Success", + "message": "Success", + "data": { + "taskId": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", + "digest": { + "md5": "4ac174730d4143a119037d9fda81c7a9", + "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", + "sha256": ( + "65b0f656e79ab84ca17807158e3ea", + "c206bd58be6689ddeb95956a48748d138f9" + ) + }, + }, + } + + def raise_for_status(self): + return True + + if args[0] == 'http://someurl.com/test.json': + return MockResponse({"key1": "value1"}, 200, "response") + elif args[0] == 'http://someotherurl.com/anothertest.json': + return MockResponse({"key2": "value2"}, 200, "response") + + return MockResponse(None, 404, None) + + +def test_submit_file_to_sandbox(mocker): + mocker.patch( + "TrendMicroVisionOne.requests.get", + mocked_requests_get + ) + mocker.patch( + "TrendMicroVisionOne.requests.post", + mocked_requests_post + ) + args = { + "fileUrl": "http://adsd.com", + "fileName": "XDR_ResponseApp_CollectFile_ID00000700_20211206T134158Z.7z", + "archivePassword": "6hn467c8", + "documentPassword": "" + } + client = Client("https://api.xdr.trendmicro.com", api_key) + result = submit_file_to_sandbox(client, args) + assert result.outputs["message"] == "Success" + assert result.outputs["code"] == "Success" + + +# Mock function for check task status +def check_task_status_mock_response(*args, **kwargs): + return_value = { + "data": { + "createdTime": 1589525651, + "executedTime": 1589525725, + "finishedTime": 1589525725, + "taskStatus": "success", + "error": {} + } + } + return return_value + + +def test_check_task_status(mocker): + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + check_task_status_mock_response) + mocker.patch( + "CommonServerPython.ScheduledCommand.raise_error_if_not_supported", + lambda: None + ) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "actionId": "00001108" + } + result = get_task_status(args, client) + assert result.outputs["taskStatus"] == "success" + + +# Mock for downloaded file information +def mock_get_endpoint_info_response(*args, **kwargs): + return_response = { + "status": "SUCCESS", + "errorCode": 0, + "message": "message", + "result": { + "logonAccount": { + "value": [ + "DOMAIN\\username" + ], + "updateAt": 0 + }, + "hostname": { + "value": "hostname", + "updateAt": 0 + }, + "macAddr": { + "value": "00:11:22:33:44:55", + "updateAt": 0 + }, + "ip": { + "value": "192.168.1.1", + "updateAt": 0 + }, + "osName": "Windows", + "osVersion": "10.0.19042", + "osDescription": "Windows 10 Pro (64 bit) build 19042", + "productCode": "xes" + } + } + return return_response + + +# Test case for get endpoint information. +def test_get_endpoint_information(mocker): + """Test get information from endpoint based on computerid""" + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + mock_get_endpoint_info_response + ) + args = {"endpoint": "hostname"} + client = Client("https://api.xdr.trendmicro.com", api_key) + result = get_endpoint_info(client, args) + assert result.outputs["status"] == "SUCCESS" + assert isinstance(result.outputs["message"], str) + assert isinstance(result.outputs["hostname"], str) + assert isinstance(result.outputs["ip"], str) + assert isinstance(result.outputs["macAddr"], str) + assert isinstance(result.outputs["osDescription"], str) + assert isinstance(result.outputs["osName"], str) + assert isinstance(result.outputs["osVersion"], str) + assert isinstance(result.outputs["productCode"], str) + + +# Mock function for add note. +def add_note_mock_response(*args, **kwargs): + return_value = { + "data": { + "id": 123 + }, + "info": { + "code": 3021000, + "msg": "Alert notes added successfully." + } + } + return return_value + + +# Test case for add note +def test_add_note(mocker): + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + add_note_mock_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "workbench_id": "WB-20837-20220418-00000", + "content": "This is a new note." + } + result = add_note(client, args) + assert result.outputs["response_msg"] == "Alert notes added successfully." + assert isinstance(result.outputs["Workbench_Id"], str) + assert isinstance(result.outputs["noteId"], int) + assert isinstance(result.outputs["response_code"], int) + + +# Mock function for update alert status +def update_status_mock_response(*args, **kwargs): + return_value = { + "data": {}, + "info": { + "code": 3006000, + "msg": "Alert status changed successfully." + } + } + return return_value + + +# Test case for update alert status +def test_update_status(mocker): + mocker.patch( + "TrendMicroVisionOne.Client.http_request", + update_status_mock_response) + client = Client("https://api.xdr.trendmicro.com", api_key) + args = { + "workbench_id": "WB-20837-20220418-00000", + "status": "in_progress" + } + result = update_status(client, args) + assert result.outputs["response_msg"] == "Alert status changed successfully." + assert isinstance(result.outputs["Workbench_Id"], str) + assert isinstance(result.outputs["response_code"], int) diff --git a/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples b/Packs/TrendMicroVisionOne/Integrations/TrendMicroVisionOne/command_examples new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json b/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json new file mode 100644 index 000000000000..adac89f76abd --- /dev/null +++ b/Packs/TrendMicroVisionOne/Layouts/layoutscontainer-Trend_Micro_Vision_One_XDR_Incident.json @@ -0,0 +1,475 @@ +{ + "detailsV2": { + "tabs": [ + { + "id": "summary", + "name": "Legacy Summary", + "type": "summary" + }, + { + "id": "caseinfoid", + "name": "Incident Info", + "sections": [ + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "type", + "height": 22, + "id": "incident-type-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "severity", + "height": 22, + "id": "incident-severity-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "owner", + "height": 22, + "id": "incident-owner-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcebrand", + "height": 22, + "id": "incident-sourceBrand-field", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourceinstance", + "height": 22, + "id": "incident-sourceInstance-field", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "playbookid", + "height": 22, + "id": "incident-playbookId-field", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Case Details", + "static": false, + "w": 1, + "x": 0, + "y": 0 + }, + { + "h": 2, + "i": "caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Notes", + "static": false, + "type": "notes", + "w": 1, + "x": 2, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Work Plan", + "static": false, + "type": "workplan", + "w": 1, + "x": 1, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-770ec200-98b1-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Linked Incidents", + "static": false, + "type": "linkedIncidents", + "w": 1, + "x": 2, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-842632c0-98b1-11e9-97d7-ed26ef9e46c8", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Child Incidents", + "static": false, + "type": "childInv", + "w": 1, + "x": 2, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-4a31afa0-98ba-11e9-a519-93a53c759fe0", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Evidence", + "static": false, + "type": "evidence", + "w": 1, + "x": 1, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "caseinfoid-7717e580-9bed-11e9-9a3f-8b4b2158e260", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Team Members", + "static": false, + "type": "team", + "w": 1, + "x": 1, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 2, + "moved": false, + "name": "Indicators", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 2, + "x": 0, + "y": 6 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "items": [ + { + "endCol": 1, + "fieldId": "occurred", + "height": 53, + "id": "incident-occurred-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 1, + "fieldId": "dbotmodified", + "height": 53, + "id": "incident-modified-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotduedate", + "height": 53, + "id": "incident-dueDate-field", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotcreated", + "height": 53, + "id": "incident-created-field", + "index": 1, + "sectionItemType": "field", + "startCol": 1 + }, + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 53, + "id": "incident-closed-field", + "index": 2, + "sectionItemType": "field", + "startCol": 1 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Timeline Information", + "static": false, + "w": 1, + "x": 0, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-88e6bf70-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 22, + "id": "incident-dbotClosed-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closereason", + "height": 22, + "id": "incident-closeReason-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closenotes", + "height": 22, + "id": "incident-closeNotes-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Closing Information", + "static": false, + "w": 1, + "x": 2, + "y": 6 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "details", + "height": 22, + "id": "incident-details-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 1, + "moved": false, + "name": "Investigation Data", + "static": false, + "w": 1, + "x": 0, + "y": 4 + } + ], + "type": "custom" + }, + { + "hidden": false, + "id": "6p9vifzzk2", + "name": "Vision One", + "sections": [ + { + "displayType": "ROW", + "h": 6, + "hideName": false, + "i": "caseinfoid-6p9vifzzk2-field-changed-6p9vifzzk2-caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", + "items": [ + { + "dropEffect": "move", + "endCol": 6, + "fieldId": "trendmicrovisiononexdrworkbenchlink", + "height": 22, + "id": "ac4d8210-6dbd-11ec-9c6c-458673da1192", + "index": 0, + "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "trendmicrovisiononexdrworkbenchid", + "height": 22, + "id": "93969a90-6dbd-11ec-9c6c-458673da1192", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "occurred", + "height": 22, + "id": "b7431e70-7306-11ec-baea-bf8198da32cb", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "severity", + "height": 22, + "id": "a2951500-7306-11ec-baea-bf8198da32cb", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 3, + "fieldId": "trendmicrovisiononexdrimpactscope", + "height": 44, + "id": "5f9241c0-6e37-11ec-800b-5b78fe23e766", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 6, + "fieldId": "trendmicrovisiononexdrimpactedentities", + "height": 44, + "id": "b6888dc0-6e34-11ec-800b-5b78fe23e766", + "index": 5, + "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 6, + "fieldId": "trendmicrovisiononexdrindicators", + "height": 44, + "id": "c00db000-6e34-11ec-800b-5b78fe23e766", + "index": 6, + "listId": "caseinfoid-ea41a760-6da7-11ec-8dff-a790ce76a80f", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 6, + "fieldId": "alertname", + "height": 22, + "id": "41d77f90-7307-11ec-baea-bf8198da32cb", + "index": 1, + "sectionItemType": "field", + "startCol": 2 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 3, + "moved": false, + "name": "Vision One Alert Info", + "static": false, + "w": 3, + "x": 0, + "y": 0 + } + ], + "type": "custom" + }, + { + "id": "warRoom", + "name": "War Room", + "type": "warRoom" + }, + { + "id": "workPlan", + "name": "Work Plan", + "type": "workPlan" + }, + { + "id": "evidenceBoard", + "name": "Evidence Board", + "type": "evidenceBoard" + }, + { + "id": "relatedIncidents", + "name": "Related Incidents", + "type": "relatedIncidents" + }, + { + "id": "canvas", + "name": "Canvas", + "type": "canvas" + } + ] + }, + "group": "incident", + "id": "Trend Micro Vision One XDR Incident", + "name": "Trend Micro Vision One XDR Incident", + "system": false, + "version": -1, + "fromVersion": "6.2.0", + "description": "" +} \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/README.md b/Packs/TrendMicroVisionOne/README.md new file mode 100755 index 000000000000..3fc116b7fb7d --- /dev/null +++ b/Packs/TrendMicroVisionOne/README.md @@ -0,0 +1,26 @@ +# Key Benefits of XDR with Trend Micro Vision One™ +## Prioritized view of threats across the organization + +Organizations without an XDR approach ignore nearly double the security alerts as those with XDR capabilities. XDR correlates and combines low level signals into high-fidelity alerts which tell the story of an attack. Security personnel can quickly understand where to focus efforts. +## More effective analysis + +With native integration into email, endpoints, servers, cloud environments, and networks, XDR sensors benefit from a deep understanding of data sources. This results in more effective analytics combined with continuously updated detection rules and global threat intelligence from Trend Micro Research, compared to having third-party integration through application programming interfaces (APIs). Organizations with an XDR approach suffered half as many successful attacks. +## Clearer contextual view of threats + +By viewing more contextual alerts across more threat vectors, events that seem benign on their own suddenly become meaningful indicators of compromise. This allows you to connect more dots into a single view, simplifying the steps towards achieving an attack-centric view of an entire chain of events across security layers and take response actions from one place. This enables more insightful investigations and gives you the ability to detect threats earlier. +## Stops more attacks, quicker + +The net of XDR is better protection for your organization through earlier detection and faster response. According to ESG, those with XDR are 2.2 times more likely to detect a data breach or successful attack in a few days or less, versus weeks or months for those without. +## Reduces time to detect and stop threats + +Collapses the time it takes to detect, contain, and respond to threats, minimizing the severity and scope of impact. ESG found that organizations with an XDR approach respond more completely to attacks and were 60% less likely to report that attack re-propagation had been an issue. +## Increased effectiveness and efficiency of threat investigation + +By automatically correlating threat data from multiple sources, XDR speeds up and removes manual steps involved in investigations and enables security analysts to quickly find the story of an attack. Organizations with an XDR approach stated it would take eight full time employees to replace the data correlation capabilities of XDR and also are 2.6 times less likely to report their team is overwhelmed. +## Integrated with third-party systems + +As you may have other security tools and technologies deployed in your environment, we offer a growing portfolio of open APIs and integrations to third-party systems, such as Palo Alto Networks Cortex™ XSOAR. Trend Micro Vision One™ has the ability to fit within these ecosystems and security operations workflows, acquiring meaningful data from your infrastructure to further enrich and validate your XDR capabilities. + +--- + +Why not take [Trend Micro Vision One™](https://resources.trendmicro.com/vision-one-test-drive.html?_ga=2.258269898.1102686256.1644357627-2.266528910.1607693918.1639750068-undefined) for a test drive to see how it can help you see more and respond faster to the threats your organization faces? \ No newline at end of file diff --git a/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md b/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..1f7cbe6771ad --- /dev/null +++ b/Packs/TrendMicroVisionOne/ReleaseNotes/1_0_1.md @@ -0,0 +1,9 @@ + +#### Incident Fields +- **Trend Micro Vision One XDR Indicators JSON** +- **Trend Micro Vision One XDR Impacted Entities JSON** +- **Trend Micro Vision One XDR Matched Rules JSON** + +#### Mappers +##### Trend Micro Vision One XDR - Incoming Mapper +- Added three incident fields to contain the impacted entities, indicators, and matched rules from the Trend Micro Vision One alert and updated the mapper to populate the new fields. diff --git a/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md b/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..cbfc112d7907 --- /dev/null +++ b/Packs/TrendMicroVisionOne/ReleaseNotes/1_1_0.md @@ -0,0 +1,6 @@ + +#### Integrations +##### Trend Micro Vision One +- Added the ***trendmicro-visionone-update-status*** command to modify the status of a Trend Micro Vision One workbench alert +- Added the ***trendmicro-visionone-add-note*** command to add a note to Trend Micro Vision One workbench alert +- Updated the Docker image to: *demisto/python3:3.10.4.29342*. diff --git a/Packs/TrendMicroVisionOne/pack_metadata.json b/Packs/TrendMicroVisionOne/pack_metadata.json new file mode 100755 index 000000000000..0314072066bd --- /dev/null +++ b/Packs/TrendMicroVisionOne/pack_metadata.json @@ -0,0 +1,33 @@ +{ + "name": "Trend Micro Vision One", + "description": "Trend Micro Vision One is a purpose-built threat defense platform that provides added value and new benefits beyond XDR solutions, allowing you to see more and respond faster. Providing deep and broad extended detection and response(XDR) capabilities that collect and automatically correlate data across multiple security layers\u2014email, endpoints, servers, cloud workloads, and networks\u2014Trend Micro Vision One prevents the majority of attacks with automated protection.", + "support": "partner", + "currentVersion": "1.1.0", + "serverMinVersion": "6.2.0", + "author": "Trend Micro", + "url": "https://success.trendmicro.com", + "email": "integrations@trendmicro.com", + "categories": [ + "Data Enrichment & Threat Intelligence" + ], + "tags": [ + "Alerts", + "Attack", + "Incident Handling", + "Incident Response", + "Malware", + "MITRE ATT&CK", + "Threat Intelligence" + ], + "created": "2022-01-06T09:00:00Z", + "useCases": [], + "keywords": [ + "xdr" + ], + "devEmail": [ + "integrations@trendmicro.com" + ], + "githubUser": [ + "mikedgibson" + ] +} \ No newline at end of file From 28e01f964b6216df8b7c8d1da976df0626e25a89 Mon Sep 17 00:00:00 2001 From: nmaimon Date: Tue, 17 May 2022 13:55:37 +0300 Subject: [PATCH 15/15] lint --- Tests/Marketplace/upload_packs.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 7afa04310c8f..e4f7021e116f 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -925,7 +925,8 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat storage_base_path (str): The upload destination in the target bucket for all packs (in the format of /content/Packs). storage_bucket (google.cloud.storage.bucket.Bucket): google cloud storage bucket. - packs_for_current_marketplace_dict (dict): Dict of packs relevant for current marketplace as {pack_name: pack_object} + packs_for_current_marketplace_dict (dict): Dict of packs relevant for current marketplace as + {pack_name: pack_object} """ logging.info("Starting to collect pack with dependencies zips") @@ -934,8 +935,10 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat if pack.status not in [*SKIPPED_STATUS_CODES, PackStatus.SUCCESS.name]: # avoid trying to upload dependencies zip for failed packs continue - pack_and_its_dependencies = [packs_for_current_marketplace_dict.get(dep_name) for dep_name in pack.all_levels_dependencies] + [pack] - pack_or_dependency_was_uploaded = any(dep_pack.status == PackStatus.SUCCESS.name for dep_pack in pack_and_its_dependencies) + pack_and_its_dependencies = [packs_for_current_marketplace_dict.get(dep_name) for dep_name in + pack.all_levels_dependencies] + [pack] + pack_or_dependency_was_uploaded = any(dep_pack.status == PackStatus.SUCCESS.name for dep_pack in + pack_and_its_dependencies) if pack_or_dependency_was_uploaded: pack_with_dep_path = os.path.join(pack.path, "with_dependencies") zip_with_deps_path = os.path.join(pack.path, f"{pack_name}_with_dependencies.zip") @@ -959,7 +962,8 @@ def upload_packs_with_dependencies_zip(storage_bucket, storage_base_path, signat logging.info(f"Uploading {pack_name} with its dependencies") task_status, _, _ = pack.upload_to_storage(zip_with_deps_path, '', storage_bucket, True, storage_base_path, overridden_upload_path=upload_path) - logging.info(f"{pack_name} with dependencies was{' not' if not task_status else ''} uploaded successfully") + logging.info(f"{pack_name} with dependencies was{' not' if not task_status else ''} " + f"uploaded successfully") if not task_status: pack.status = PackStatus.FAILED_CREATING_DEPENDENCIES_ZIP_UPLOADING.name pack.cleanup() @@ -1057,7 +1061,7 @@ def main(): is_bucket_upload_flow, ci_branch) # detect packs to upload - pack_names = get_packs_names(target_packs, previous_commit_hash) # TODO: this is actually id + pack_names = get_packs_names(target_packs, previous_commit_hash) # list of the pack's ids extract_packs_artifacts(packs_artifacts_path, extract_destination_path) packs_list = [Pack(pack_name, os.path.join(extract_destination_path, pack_name)) for pack_name in pack_names if os.path.exists(os.path.join(extract_destination_path, pack_name))]