Trend Micro Vision One V3
TrendAI 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—TrendAI Vision One™ prevents the majority of attacks with automated protection.
Data Enrichment & Threat Intelligence · TrendAI Vision One™
Details
| ID | Trend Micro Vision One V3 |
|---|---|
| Provider | TrendAI™ |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.5.0 |
| Docker Image | demisto/pytmv1:0.11.0.10133006 |
| Supported Modules | Agentix XSIAM |
README
TrendAI 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—TrendAI Vision One™ prevents the majority of attacks with automated protection. V3 version of the app includes everything that the previous app had and adds more capabilities. It leverages V3 of TrendAI™ APIs and introduces further ability to manage domain accounts with addition of 4 domain account actions for enabling/disabling user account, forcing sign-out and password resets for compromised accounts. This app is in active development. We previously added 4 actions, one to fetch email activity data with count, one to fetch endpoint activity data with count and an action to restore a quarantined email message. In this release we have added 6 new custom script actions allowing the user to fetch a list of available custom scripts in XDR portal, ability to run a custom script on a specified endpoint, capacity to add, download, update and delete a custom script from XDR portal.
This integration was integrated and tested with version 3 API of TrendAI Vision One™.
Configure TrendAI Vision One™ v3 in Cortex
| Parameter | Description | Required |
|---|---|---|
| API URL (e.g. https://api.xdr.trendmicro.com) | The base url for the TrendAI Vision One™ API | True |
| API Key | The API token to access data | True |
| Fetch incidents | False | |
| Incidents Fetch Interval | False | |
| Incident type | False | |
| Sync On First Run (days) | False | |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False | |
| Source Reliability | Reliability of the source providing the intelligence data. | False |
| Severity | Severity of the incident being fetched. | False |
| Incident Mirroring Direction | Choose the direction to mirror incidents. Outgoing mirrors XSOAR changes to Vision One alerts. Cortex XSOAR only parameter. | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
trendmicro-visionone-enable-user-account
Allows the user to sign in to new application and browser sessions. Supported IAM systems -> Azure AD and Active Directory (on-premises).
Base Command
trendmicro-visionone-enable-user-account
Input
| Argument Name | Description | Required |
|---|---|---|
| account_identifiers | List of object(s) containing account_name and optional description. e.g. [{“account_name”:”some-account”,”description”:”enable”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.User_Account.status | number | Status of request to enable user account. |
| VisionOne.User_Account.task_id | string | Task ID generated after enabling user account. |
trendmicro-visionone-disable-user-account
Signs the user out of all active application and browser sessions, and prevents the user from signing in any new session. Supported IAM systems -> Azure AD and Active Directory (on-premises).
Base Command
trendmicro-visionone-disable-user-account
Input
| Argument Name | Description | Required |
|---|---|---|
| account_identifiers | List of object(s) containing account_name and optional description. e.g. [{“account_name”:”some-account”,”description”:”disable”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.User_Account.status | number | Status of request to disable user account. |
| VisionOne.User_Account.task_id | string | Task ID generated after disabling user account. |
trendmicro-visionone-force-signout
Signs the user out of all active application and browser sessions. Supported IAM systems -> Azure AD.
Base Command
trendmicro-visionone-force-signout
Input
| Argument Name | Description | Required |
|---|---|---|
| account_identifiers | List of object(s) containing account_name and optional description. e.g. [{“account_name”:”some-account”,”description”:”sign-out”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Force_Sign_Out.status | number | Status of request to sign out user. |
| VisionOne.Force_Sign_Out.task_id | string | Task ID generated after signing out user. |
trendmicro-visionone-force-password-reset
Signs the user out of all active application and browser sessions, and forces the user to create a new password during the next sign-in attempt. Supported IAM systems -> Azure AD and Active Directory (on-premises).
Base Command
trendmicro-visionone-force-password-reset
Input
| Argument Name | Description | Required |
|---|---|---|
| account_identifiers | List of object(s) containing account_name and optional description. e.g. [{“account_name”:”some-account”,”description”:”reset”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Force_Password_Reset.status | number | Status of request to reset user password. |
| VisionOne.Force_Password_Reset.task_id | string | Task ID generated after resetting user password. |
trendmicro-visionone-add-to-block-list
Adds a domain, ip, file_sha1, url, sender_mail_address to the User-Defined Suspicious Objects List, which blocks the objects on subsequent detections.
Base Command
trendmicro-visionone-add-to-block-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) made up of object_type (domain,ip,file_sha1,url,sender_mail_address), object_value and optional description. e.g. [{“object_type”:”domain”,”object_value”:”www.yahoo.com”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.BlockList.status | number | Status of adding domain, ip, file_sha1, url, sender_mail_address to the User-Defined Suspicious Objects List. |
| VisionOne.BlockList.task_id | string | Task ID generated after adding domain, ip, file_sha1, url, sender_mail_address to the User-Defined Suspicious Objects List. |
trendmicro-visionone-remove-from-block-list
Removes a domain, ip, file_sha1, url, sender_mail_address from the User-Defined Suspicious Objects List.
Base Command
trendmicro-visionone-remove-from-block-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) made up of object_type (domain,ip,file_sha1,url,sender_mail_address), object_value and optional description. e.g. [{“object_type”:”domain”,”object_value”:”www.yahoo.com”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.BlockList.status | number | Status of removing domain, ip, file_sha1, url, sender_mail_address that was added to the User-Defined Suspicious Objects List from block list. |
| VisionOne.BlockList.task_id | string | Task ID generated after removing domain, ip, file_sha1, url, sender_mail_address from the User-Defined Suspicious Objects List. |
trendmicro-visionone-quarantine-email-message
Moves a message from a mailbox to the quarantine folder.
Base Command
trendmicro-visionone-quarantine-email-message
Input
| Argument Name | Description | Required |
|---|---|---|
| email_identifiers | List of object(s) containing message_id (<mailMsgId>), mailbox (mailbox ID) and description or unique_id (msgUuid) and optional description from TrendAI Vision One™ message activity data. e.g. [{“message_id”:”xasbjAgs72912-asdjnaj”,”mailbox”:”mailbox-name”,”description”:”quarantine”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Email.status | number | Status of moving a message from a mailbox to the quarantine folder. |
| VisionOne.Email.task_id | string | Task ID generated after moving a message from a mailbox to the quarantine folder. |
trendmicro-visionone-delete-email-message
Deletes a message from a mailbox.
Base Command
trendmicro-visionone-delete-email-message
Input
| Argument Name | Description | Required |
|---|---|---|
| email_identifiers | List of object(s) containing message_id (<mailMsgId>), mailbox (mailbox ID) and description or unique_id (msgUuid) and optional description from TrendAI Vision One™ message activity data. e.g. [{“message_id”:”xasbjAgs72912-asdjnaj”,”mailbox”:”mailbox-name”,”description”:”disable”:”delete”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Email.status | number | Status of deleting a message from a mailbox. |
| VisionOne.Email.task_id | string | Task ID generated after deleting a message from a mailbox. |
trendmicro-visionone-restore-email-message
Restores a quarantined message. Deleted messages cannot be restored.
Base Command
trendmicro-visionone-restore-email-message
Input
| Argument Name | Description | Required |
|---|---|---|
| email_identifiers | List of object(s) containing message_id (<mailMsgId>), mailbox (mailbox ID) and description or unique_id (msgUuid) and optional description from TrendAI Vision One™ message activity data. e.g. [{“message_id”:”xasbjAgs72912-asdjnaj”,”mailbox”:”mailbox-name”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Email.status | number | Status of restoring a message. |
| VisionOne.Email.task_id | string | Task ID generated after restoring a message. |
trendmicro-visionone-isolate-endpoint
Disconnects an endpoint from the network (but allows communication with the managing TrendAI™ product).
Base Command
trendmicro-visionone-isolate-endpoint
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_identifiers | List of object(s) containing endpoint (hostname) and description or agent_guid and description. e.g. [{“endpoint”:”test-endpoint”,”description”:”isolate endpoint”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Endpoint_Connection.status | number | Status of isolating endpoint(s). |
| VisionOne.Endpoint_Connection.task_id | string | Task ID generated after isolating endpoint(s). |
trendmicro-visionone-restore-endpoint-connection
Restores network connectivity to an endpoint that applied the “isolate endpoint” action.
Base Command
trendmicro-visionone-restore-endpoint-connection
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_identifiers | List of object(s) containing endpoint (hostname) and description or agent_guid and description. e.g. [{“endpoint”:”test-endpoint”,”description”:”restore endpoint”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Endpoint_Connection.status | number | Status of restoring endpoint(s). |
| VisionOne.Endpoint_Connection.task_id | string | Task ID generated after restoring endpoint(s). |
trendmicro-visionone-add-objects-to-exception-list
Adds domain, ip, url, file_sha1, file_sha256, sender_mail_address to the Exception List and prevents these objects from being added to the Suspicious Object List.
Base Command
trendmicro-visionone-add-objects-to-exception-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) consisting of object_type (domain,ip,url,file_sha1,file_sha256,sender_mail_address), object_value and description. e.g. [{“object_type”:”ip”,”object_value”:”5.5.5.5”}, {“object_type”:”domain”,”object_value”:”www.yahoo.com”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Exception_List.message | string | Success or fail response message. |
| VisionOne.Exception_List.multi_response.status | number | Status of adding item(s) to exception list. |
| VisionOne.Exception_List.multi_response.task_id | string | Task ID generated after adding item(s) to exception list. |
| VisionOne.Exception_List.total_items | number | Count of total items present in exception list. |
trendmicro-visionone-delete-objects-from-exception-list
Deletes domain, ip, url, file_sha1, file_sha256, sender_mail_address from the Exception List.
Base Command
trendmicro-visionone-delete-objects-from-exception-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) consisting of object_type (domain,ip,url,file_sha1,file_sha256,sender_mail_address), object_value and description. e.g. [{“object_type”:”ip”,”object_value”:”5.5.5.5”,”description”:”exception list”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Exception_List.message | string | Success or fail response message. |
| VisionOne.Exception_List.multi_response.status | number | status code of response. |
| VisionOne.Exception_List.multi_response.task_id | string | Task ID generated after removing item(s) from exception list. |
| VisionOne.Exception_List.total_items | number | count of item present in exception list. |
trendmicro-visionone-add-objects-to-suspicious-list
Adds domain, ip, url, file_sha1, file_sha256, sender_mail_address to the Suspicious Object List.
Base Command
trendmicro-visionone-add-objects-to-suspicious-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) consisting of object_type (domain,ip,url,file_sha1,file_sha256,sender_mail_address), object_value, scan_action, risk_level, expiry_days and description. e.g. [{“object_type”:”ip”,”object_value”:”5.5.5.5”,”scan_action”:”block”,”risk_level”:”medium”,”expiry_days”:7}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Suspicious_List.message | string | Success or fail response message. |
| VisionOne.Suspicious_List.multi_response.status | number | Status of request to add item(s) to suspicious list. |
| VisionOne.Suspicious_List.multi_response.task_id | string | Task ID generated after adding item(s) to suspicious list. |
| VisionOne.Suspicious_List.total_items | number | Count of total items present in suspicious object list. |
trendmicro-visionone-delete-objects-from-suspicious-list
Deletes domain, ip, url, file_sha1, file_sha256, sender_mail_address from the Suspicious Object List.
Base Command
trendmicro-visionone-delete-objects-from-suspicious-list
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) consisting of object_type (domain,ip,url,file_sha1,file_sha256,sender_mail_address) and object_value. e.g. [{“object_type”:”ip”,”object_value”:”5.5.5.5”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Suspicious_List.message | string | Success or fail response message. |
| VisionOne.Suspicious_List.multi_response.status | number | Status of request to remove item(s) from suspicious object list. |
| VisionOne.Suspicious_List.multi_response.task_id | string | Task ID generated after removing item(s) from suspicious object list. |
| VisionOne.Suspicious_List.total_items | number | Count of total items present in suspicious object list. |
trendmicro-visionone-get-endpoint-info
Retrieves information about a specific endpoint.
Base Command
trendmicro-visionone-get-endpoint-info
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint | Filter (A dictionary object with key/value used to create a query string) for retrieving a subset of endpoint information e.g. endpoint={“endpointName”:”test-endpoint1”, “ip”:”52.72.139.96”}. Multiple endpoints can be queried but unique keys need to be supplied (e.g. endpointName, ip, etc.). For complete list of keys check (https://automation.trendmicro.com/xdr/api-v3#tag/Search/paths/~1v3.0~1eiqs~1endpoints/get). |
Required |
| query_op | Conditional operator used to build request that allows user to retrieve a subset of collected endpoint(s). Possible values: and/or. Ex. or: the results retrieved will contain information for endpoint(s) matching endpointName OR ip. and: results retrieved will contain endpoint information for endpoint matching endpointName AND ip. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Endpoint_Info.agent_guid | string | Agent Guid of the endpoint. |
| VisionOne.Endpoint_Info.login_account.value | string | Account currently logged on to the endpoint. |
| VisionOne.Endpoint_Info.endpoint_name.value | string | Hostname of the endpoint queried. |
| VisionOne.Endpoint_Info.mac_address.value | string | MAC address of the endpoint queried. |
| VisionOne.Endpoint_Info.ip.value | string | IP address of the endpoint queried. |
| VisionOne.Endpoint_Info.os_name | string | Operating System name of the endpoint queried. |
| VisionOne.Endpoint_Info.os_version | string | Operating System version of the endpoint queried. |
| VisionOne.Endpoint_Info.os_description | string | Description of the Operating System of the endpoint queried. |
| VisionOne.Endpoint_Info.product_code | string | Product code of the TrendAI™ product running on the endpoint. |
| VisionOne.Endpoint_Info.installed_product_codes | string | Product code of the TrendAI™ product installed on the endpoint. |
| VisionOne.Endpoint_Info.component_update_policy | string | The update policy for the module/pattern of the agent installed on the endpoint. |
| VisionOne.Endpoint_Info.component_update_status | string | The status of the module/pattern updates of the agent installed on the endpoint. |
| VisionOne.Endpoint_Info.component_version | string | The agent component version. |
| VisionOne.Endpoint_Info.policy_name | string | The name of a policy for an event. |
| VisionOne.Endpoint_Info.protection_manager | string | The name of your protection manager. |
trendmicro-visionone-get-endpoint-activity-data
Displays search results from the Endpoint Activity Data source that match the parameters provided.
Base Command
trendmicro-visionone-get-endpoint-activity-data
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Filter (A dictionary object with key/value used to create a query string) for retrieving a subset of endpoint activity data e.g. {“endpointName”:”sample-host”,”dpt”: 443}. Complete list of supported fields (https://automation.trendmicro.com/xdr/api-v3#tag/Search/paths/~1v3.0~1search~1endpointActivities/get). | Required |
| query_op | Conditional operator used to build request that allows user to retrieve a subset of collected endpoint activity data. Possible values: and/or. Ex. or: the results retrieved will contain activity data for endpoint(s) matching endpointName OR dpt. and: will contain activity data for endpoint matching endpointName AND dpt. Defaults to and. |
Optional |
| start | Timestamp in ISO 8601 format that indicates the start of the data retrieval range. If no value is specified, start defaults to 24 hours before the request is made. e.g. start=”2023-10-01T08:00:00Z”. | Optional |
| end | Timestamp in ISO 8601 format that indicates the end of the data retrieval time range. If no value is specified, end defaults to the time the request is made. e.g. end=”2023-12-01T08:00:00Z”. | Optional |
| top | Number of records displayed on a page. e.g. top=5. | Optional |
| select | List of fields to include in the search results. If no fields are specified, the query returns all supported fields. e.g. select=”dpt,dst,endpointHostName”. | Optional |
| fetch_max_count | Max results to be fetched by call. | Optional |
| fetch_all | Do you want to fetch all matching records or only records matching the top value. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Endpoint_Activity_Data.dpt | string | Destination port. |
| VisionOne.Endpoint_Activity_Data.dst | string | Destination IP address. |
| VisionOne.Endpoint_Activity_Data.endpoint_guid | string | endpoint GUID for identity. |
| VisionOne.Endpoint_Activity_Data.endpoint_host_name | string | Hostname of the endpoint on which the event was generated. |
| VisionOne.Endpoint_Activity_Data.endpoint_ip | string | Endpoint IP address list. |
| VisionOne.Endpoint_Activity_Data.event_id | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.event_sub_id | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.object_integrity_level | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.object_true_type | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.object_sub_true_type | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.win_event_id | string | ID corresponding to data field mapping. |
| VisionOne.Endpoint_Activity_Data.event_time | string | Log collect time utc format. |
| VisionOne.Endpoint_Activity_Data.event_time_d_t | string | Log collect time. |
| VisionOne.Endpoint_Activity_Data.host_name | string | Hostname of the endpoint on which the event was generated. |
| VisionOne.Endpoint_Activity_Data.logon_user | string | Logon user name. |
| VisionOne.Endpoint_Activity_Data.object_cmd | string | Command line entry of target process. |
| VisionOne.Endpoint_Activity_Data.object_file_hash_sha1 | string | The SHA1 hash of target process image or target file. |
| VisionOne.Endpoint_Activity_Data.object_file_path | string | File path location of target process image or target file. |
| VisionOne.Endpoint_Activity_Data.object_host_name | string | Server name where Internet event was detected. |
| VisionOne.Endpoint_Activity_Data.object_ip | string | IP address of internet event. |
| VisionOne.Endpoint_Activity_Data.object_ips | string | IP address list of internet event. |
| VisionOne.Endpoint_Activity_Data.object_port | string | The port number used by internet event. |
| VisionOne.Endpoint_Activity_Data.object_registry_data | string | The registry value data. |
| VisionOne.Endpoint_Activity_Data.object_registry_key_handle | string | The registry key. |
| VisionOne.Endpoint_Activity_Data.object_registry_value | string | Registry value name. |
| VisionOne.Endpoint_Activity_Data.object_signer | string | Certificate signer of object process or file. |
| VisionOne.Endpoint_Activity_Data.object_signer_valid | string | Validity of certificate signer. |
| VisionOne.Endpoint_Activity_Data.object_user | string | The owner name of target process / The logon user name. |
| VisionOne.Endpoint_Activity_Data.os | string | System. |
| VisionOne.Endpoint_Activity_Data.parent_cmd | string | The command line that parent process. |
| VisionOne.Endpoint_Activity_Data.parent_file_hash_sha1 | string | The SHA1 hash of parent process. |
| VisionOne.Endpoint_Activity_Data.parent_file_path | string | The file path location of parent process. |
| VisionOne.Endpoint_Activity_Data.process_cmd | string | The command line used to launch this process. |
| VisionOne.Endpoint_Activity_Data.process_file_hash_sha1 | string | The process file sha1. |
| VisionOne.Endpoint_Activity_Data.process_file_path | string | The process file path. |
| VisionOne.Endpoint_Activity_Data.request | string | Request URL (normally detected by Web Reputation Services). |
| VisionOne.Endpoint_Activity_Data.search_d_l | string | Search data lake. |
| VisionOne.Endpoint_Activity_Data.spt | string | Source port. |
| VisionOne.Endpoint_Activity_Data.src | string | Source IP address. |
| VisionOne.Endpoint_Activity_Data.src_file_hash_sha1 | string | Source file sha1. |
| VisionOne.Endpoint_Activity_Data.src_file_path | string | Source file path. |
| VisionOne.Endpoint_Activity_Data.tags | string | Detected by Security Analytics Engine filters. |
| VisionOne.Endpoint_Activity_Data.uuid | string | Log unique identity. |
trendmicro-visionone-get-endpoint-activity-data-count
Displays total count of search results from the Endpoint Activity Data source that match the parameters provided.
Base Command
trendmicro-visionone-get-endpoint-activity-data-count
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Filter (A dictionary object with key/value used to create a query string) for retrieving endpoint activity data count e.g. {“endpointName”:”sample-host”,”dpt”:443}. Complete list of supported fields (https://automation.trendmicro.com/xdr/api-v3#tag/Search/paths/~1v3.0~1search~1endpointActivities/get). | Required |
| query_op | Conditional operator used to build request that allows user to retrieve a count of collected endpoint activity. Possible values: and/or. Ex. or: the results retrieved will contain activity count for endpoint(s) matching endpointName OR dpt. and: the results retrieved will contain activity count for endpoint matching endpointName AND dpt. Defaults to and. |
Optional |
| start | Timestamp in ISO 8601 format that indicates the start of the data retrieval range. If no value is specified, start defaults to 24 hours before the request is made. e.g. start=”2023-10-01T08:00:00Z”. | Optional |
| end | Timestamp in ISO 8601 format that indicates the end of the data retrieval time range. If no value is specified, end defaults to the time the request is made. e.g. end=”2023-12-01T08:00:00Z”. | Optional |
| select | List of fields to include in the search results. If no fields are specified, the query returns all supported fields. e.g. select=”dpt,dst,endpointHostName”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Endpoint_Activity_Data_Count.endpoint_activity_count | string | Total count for endpoint activity queried. |
trendmicro-visionone-get-email-activity-data
Displays search results from the Email Activity Data source that match the parameters provided.
Base Command
trendmicro-visionone-get-email-activity-data
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Filter (A dictionary object with key/value used to create a query string) for retrieving a subset of email activity data e.g. {“mailMsgSubject”:”spam”,”mailSenderIp”:”192.169.1.1”}. Complete list of supported fields (https://automation.trendmicro.com/xdr/api-v3#tag/Search/paths/~1v3.0~1search~1emailActivities/get). | Required |
| query_op | Conditional operator used to build request that allows user to retrieve a subset of email activity data. Possible values: and/or. Ex. or: the results retrieved will contain activity data for email(s) matching mailMsgSubject OR mailSenderIp. and: the results retrieved will contain activity data for email matching mailMsgSubject AND mailSenderIp. Defaults to and. |
Optional |
| start | Timestamp in ISO 8601 format that indicates the start of the data retrieval range. If no value is specified, start defaults to 24 hours before the request is made. e.g. start=”2023-10-01T08:00:00Z”. | Optional |
| end | Timestamp in ISO 8601 format that indicates the end of the data retrieval time range. If no value is specified, end defaults to the time the request is made. e.g. end=”2023-12-01T08:00:00Z”. | Optional |
| top | Number of records displayed on a page. e.g. top=5. | Optional |
| select | List of fields to include in the search results. If no fields are specified, the query returns all supported fields. e.g. select=”mailMsgSubject,mailFromAddresses,mailToAddresses”. | Optional |
| fetch_max_count | Max results to be fetched by call. | Optional |
| fetch_all | Do you want to fetch all matching records or only records matching the top value. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Email_Activity_Data.mail_msg_subject | string | Subject of the email message. |
| VisionOne.Email_Activity_Data.mail_msg_id | string | Internet message ID of the email message. |
| VisionOne.Email_Activity_Data.msg_uuid | string | Unique ID of the email message. |
| VisionOne.Email_Activity_Data.mailbox | string | Mailbox where the email message is. |
| VisionOne.Email_Activity_Data.mail_sender_ip | string | Source IP address of the email message. |
| VisionOne.Email_Activity_Data.mail_from_addresses | string | Sender email address of the email message. |
| VisionOne.Email_Activity_Data.mail_whole_header | string | Information about the header of the email message. |
| VisionOne.Email_Activity_Data.mail_to_addresses | string | A list of recipient email addresses of the email message. |
| VisionOne.Email_Activity_Data.mail_source_domain | string | Source domain of the email message. |
| VisionOne.Email_Activity_Data.search_d_l | string | Search data lake. |
| VisionOne.Email_Activity_Data.scan_type | string | Email activity scan type. |
| VisionOne.Email_Activity_Data.event_time | string | Date and time UTC. |
| VisionOne.Email_Activity_Data.org_id | string | Unique ID used to identify an organization. |
| VisionOne.Email_Activity_Data.mail_urls_visible_link | string | Visible link in email message. |
| VisionOne.Email_Activity_Data.mail_urls_real_link | string | Real link in email message. |
trendmicro-visionone-get-email-activity-data-count
Displays search results from the Email Activity Data source that match the parameters provided.
Base Command
trendmicro-visionone-get-email-activity-data-count
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Filter (A dictionary object with key/value used to create a query string) for retrieving email activity data count e.g. {“mailMsgSubject”:”spam”,”mailSenderIp”:”192.169.1.1”}. Complete list of supported fields (https://automation.trendmicro.com/xdr/api-v3#tag/Search/paths/~1v3.0~1search~1emailActivities/get). | Required |
| query_op | Conditional operator used to build request that allows user to retrieve a count of collected email activity. Possible values: and/or. Ex. or: the results retrieved will contain activity count for email(s) matching mailMsgSubject OR mailSenderIp. and: the results retrieved will contain activity count for email matching mailMsgSubject AND mailSenderIp. Defaults to and. |
Optional |
| start | Timestamp in ISO 8601 format that indicates the start of the data retrieval range. If no value is specified, start defaults to 24 hours before the request is made. e.g. start=”2023-10-01T08:00:00Z”. | Optional |
| end | Timestamp in ISO 8601 format that indicates the end of the data retrieval time range. If no value is specified, end defaults to the time the request is made. e.g. end=”2023-12-01T08:00:00Z”. | Optional |
| select | List of fields to include in the search results. If no fields are specified, the query returns all supported fields. e.g. select=”mailMsgSubject,mailFromAddresses,mailToAddresses”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Email_Activity_Data_Count.email_activity_count | string | Total count of email activity. |
trendmicro-visionone-terminate-process
Terminates a process that is running on an endpoint.
Base Command
trendmicro-visionone-terminate-process
Input
| Argument Name | Description | Required |
|---|---|---|
| process_identifiers | List of object(s) consisting of endpoint (hostname) or agent_guid, file_sha1, filename and description. e.g. [{“endpoint”:”test-endpoint”,”file_sha1”:”fb5608fa03de204a12fe1e9e5275e4a682107471”,”filename”:”test.txt”,”description”:”terminate process”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Terminate_Process.status | number | Status of request to terminate process. |
| VisionOne.Terminate_Process.task_id | string | Task Id generated after terminating a process. |
trendmicro-visionone-get-file-analysis-status
Retrieves the status of a sandbox analysis submission.
Base Command
trendmicro-visionone-get-file-analysis-status
Input
| Argument Name | Description | Required |
|---|---|---|
| task_id | task_id from the trendmicro-visionone-submit-file-to-sandbox command output. e.g. task_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.File_Analysis_Status.id | string | Submission ID of the file submitted for sandbox analysis. |
| VisionOne.File_Analysis_Status.status | string | Response code for the action call. |
| VisionOne.File_Analysis_Status.action | string | Action performed on the submitted file. |
| VisionOne.File_Analysis_Status.error | string | Error code and message for the submission. |
| VisionOne.File_Analysis_Status.digest | string | The hash values of file analyzed. |
| VisionOne.File_Analysis_Status.created_date_time | string | Create date time for the sandbox analysis. |
| VisionOne.File_Analysis_Status.last_action_date_time | string | Date and time for last action performed on the submission. |
| VisionOne.File_Analysis_Status.resource_location | string | Location of the submitted file. |
| VisionOne.File_Analysis_Status.is_cached | string | Is the file cached or not (True or False). |
| VisionOne.File_Analysis_Status.arguments | string | Arguments for the file submitted. |
trendmicro-visionone-get-file-analysis-result
Retrieves the sandbox submission analysis result.
Base Command
trendmicro-visionone-get-file-analysis-result
Input
| Argument Name | Description | Required |
|---|---|---|
| report_id | report_id of the sandbox submission retrieved from the trendmicro-visionone-get-file-analysis-status command. e.g. report_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
| poll | If script should wait until the task is finished before returning the result, enabled by default. poll=true. Possible values are: true, false. | Optional |
| poll_time_sec | Maximum time to wait for the result to be available. e.g. poll_time_sec=45. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.File_Analysis_Result.id | string | Report ID for the submission. |
| VisionOne.File_Analysis_Result.type | string | Type of object. |
| VisionOne.File_Analysis_Result.digest | string | The hash values of file analyzed. |
| VisionOne.File_Analysis_Result.risk_level | string | Risk Level of suspicious object. |
| VisionOne.File_Analysis_Result.analysis_completion_date_time | string | Analyze time of suspicious object. |
| VisionOne.File_Analysis_Result.arguments | string | Arguments for the suspicious object. |
| VisionOne.File_Analysis_Result.detection_names | string | Detection name for the suspicious object. |
| VisionOne.File_Analysis_Result.threat_types | string | Threat type of the suspicious object. |
| VisionOne.File_Analysis_Result.true_file_type | string | File type for the suspicious object. |
| VisionOne.File_Analysis_Result.DBotScore.Score | number | The DBot score. |
| VisionOne.File_Analysis_Result.DBotScore.Vendor | string | The Vendor name. |
| VisionOne.File_Analysis_Result.DBotScore.Reliability | string | The reliability of an intelligence-data source. |
trendmicro-visionone-collect-forensic-file
Compresses a file on an endpoint in a password-protected archive and then sends the archive to the XDR service platform.
Base Command
trendmicro-visionone-collect-forensic-file
Input
| Argument Name | Description | Required |
|---|---|---|
| collect_files | List of object(s) containing endpoint (hostname) or agent_guid, file_path and description. e.g. [{“endpoint”:”test-endpoint”,”file_path”:”C:/test_dir/test.txt”,”filename”:”test.txt”,”description”:”collect file”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Collect_Forensic_File.status | number | Status of request to collect file from endpoint. |
| VisionOne.Collect_Forensic_File.task_id | string | Task ID generated after collecting file for forensic analysis. |
trendmicro-visionone-download-information-for-collected-forensic-file
Retrieves a URL and other information required to download a collected file via the trendmicro-visionone-collect-forensic-file command.
Base Command
trendmicro-visionone-download-information-for-collected-forensic-file
Input
| Argument Name | Description | Required |
|---|---|---|
| task_id | taskId output from the collect forensic file command. e.g. task_id=”00000012”. | Required |
| poll | If script should wait until the task is finished before returning the result, enabled by default. e.g. poll=true. Possible values are: true, false. | Optional |
| poll_time_sec | Maximum time to wait for the result to be available. e.g. poll_time_sec=45. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Download_Information_For_Collected_Forensic_File.status | string | Status of action performed (succeeded, running or failed). |
| VisionOne.Download_Information_For_Collected_Forensic_File.created_date_time | string | The create date time for the file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.id | string | Task ID used to query for forensic file information. |
| VisionOne.Download_Information_For_Collected_Forensic_File.last_action_date_time | string | Time and date of last action on file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.description | string | Task description. |
| VisionOne.Download_Information_For_Collected_Forensic_File.action | string | Action performed on file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.account | string | The account associated with the request. |
| VisionOne.Download_Information_For_Collected_Forensic_File.agent_guid | string | AgentGuid of the endpoint used to collect file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.endpoint_name | string | hostname of the endpoint used to collect file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.file_path | string | File path for the file that was collected. |
| VisionOne.Download_Information_For_Collected_Forensic_File.file_sha1 | string | The fileSha1 for the collected file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.file_sha256 | string | The fileSha256 for the collected file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.file_size | number | The file size of the file collected. |
| VisionOne.Download_Information_For_Collected_Forensic_File.resource_location | string | URL location of the file collected that can be used to download. |
| VisionOne.Download_Information_For_Collected_Forensic_File.expired_date_time | string | The expiration date and time of the file. |
| VisionOne.Download_Information_For_Collected_Forensic_File.password | string | The password for the file collected. |
| VisionOne.Download_Information_For_Collected_Forensic_File.error | string | Error response generated for the request. |
trendmicro-visionone-download-investigation-package
Downloads the investigation package based on submission ID.
Base Command
trendmicro-visionone-download-investigation-package
Input
| Argument Name | Description | Required |
|---|---|---|
| submission_id | The submission ID for the object submitted to sandbox for analysis. e.g. submission_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
| poll | If script should wait until the task is finished before returning the result, enabled by default. e.g. poll=true. Possible values are: true, false. | Optional |
| poll_time_sec | Maximum time to wait for the result to be available. e.g. poll_time_sec=45. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Download_Investigation_Package.submission_id | string | The submission for the file. |
| VisionOne.Download_Investigation_Package.result_code | number | Result code of making a request to download investigation package. |
| VisionOne.Download_Investigation_Package.message | number | Message notifying user that investigation package is ready for download. |
trendmicro-visionone-download-suspicious-object-list
Downloads the suspicious object list associated to the specified object. Note ~ Suspicious Object Lists are only available for objects with a high risk level.
Base Command
trendmicro-visionone-download-suspicious-object-list
Input
| Argument Name | Description | Required |
|---|---|---|
| submission_id | The submission ID for the object submitted to sandbox for analysis. e.g. submission_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
| poll | If script should wait until the task is finished before returning the result, enabled by default. e.g. poll=true. Possible values are: true, false. | Optional |
| poll_time_sec | Maximum time to wait for the result to be available. e.g. poll_time_sec=45. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Download_Suspicious_Object_list.type | string | The type of suspicious object. |
| VisionOne.Download_Suspicious_Object_list.value | string | Value of the suspicious object. |
| VisionOne.Download_Suspicious_Object_list.risk_level | string | Risk level of the analyzed object. |
| VisionOne.Download_Suspicious_Object_list.root_sha1 | string | status code for the command. |
| VisionOne.Download_Suspicious_Object_list.analysis_completion_date_time | string | The analysis completion date and time. |
| VisionOne.Download_Suspicious_Object_list.expired_date_time | string | The expiration date and time for the suspicious object. |
trendmicro-visionone-download-analysis-report
Downloads the analysis report for an object submitted to sandbox for analysis based on the submission ID.
Base Command
trendmicro-visionone-download-analysis-report
Input
| Argument Name | Description | Required |
|---|---|---|
| submission_id | The submission ID for the object submitted to sandbox for analysis. e.g. submission_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
| poll | If script should wait until the task is finished before returning the result, enabled by default. e.g. poll=true. Possible values are: true, false. | Optional |
| poll_time_sec | Maximum time to wait for the result to be available. e.g. poll_time_sec=45. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Download_Analysis_Report.submission_id | string | The submission ID for the sandbox object. |
| VisionOne.Download_Analysis_Report.result_code | string | Result code of making a request to download analysis report. |
| VisionOne.Download_Analysis_Report.message | string | Message notifying user that analysis report is ready for download. |
trendmicro-visionone-submit-file-to-sandbox
Submits a file to the sandbox for analysis (Note. For more information about the supported file types, see the TrendAI Vision One™ Online Help. Submissions require credits. Does not require credits in regions where Sandbox Analysis has not been officially released.)
Base Command
trendmicro-visionone-submit-file-to-sandbox
Input
| Argument Name | Description | Required |
|---|---|---|
| file_url | URL pointing to the location of the file to be submitted. e.g. file_url=”https://someurl.com/test.txt”. | Required |
| file_name | Name of the file (including extension) to be analyzed. e.g. file_name=”some-file.txt”. | Required |
| document_password | The Base64 encoded password for decrypting the submitted document sample. e.g. document_password=”dGVzdA==”. | Optional |
| archive_password | The Base64 encoded password for decrypting the submitted archive. e.g. archive_password=”dGVzdA==”. | Optional |
| arguments | Parameter that allows you to specify Base64-encoded command line arguments to run the submitted file. e.g. arguments=”LS10ZXN0IA==”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Submit_File_to_Sandbox.message | string | Result code of submitting file to sandbox for analysis. |
| VisionOne.Submit_File_to_Sandbox.code | string | HTTP status code of the request made to submit file to sandbox. |
| VisionOne.Submit_File_to_Sandbox.task_id | string | ID generated for submitting file to sandbox for analysis. |
| VisionOne.Submit_File_to_Sandbox.digest | string | The hash value of the file. |
| VisionOne.Submit_File_to_Sandbox.arguments | string | Command line arguments to run the submitted file. |
trendmicro-visionone-submit-file-entry-to-sandbox
Submits a file to the sandbox for analysis (Note. For more information about the supported file types, see the TrendAI Vision One™ Online Help. Submissions require credits. Does not require credits in regions where Sandbox Analysis has not been officially released.)
Base Command
trendmicro-visionone-submit-file-entry-to-sandbox
Input
| Argument Name | Description | Required |
|---|---|---|
| entry_id | Entry ID of the file to be submitted. e.g. entry_id=”104@49493d71”. | Required |
| document_password | The Base64 encoded password for decrypting the submitted document sample. e.g. document_password=”dGVzdA==”. | Optional |
| archive_password | The Base64 encoded password for decrypting the submitted archive. e.g. archive_password=”dGVzdA==”. | Optional |
| arguments | Parameter that allows you to specify Base64-encoded command line arguments to run the submitted file. e.g. arguments=”LS10ZXN0IA==”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Submit_File_Entry_to_Sandbox.message | string | Result code of submitting file entry to sandbox for analysis. |
| VisionOne.Submit_File_Entry_to_Sandbox.code | string | HTTP status code of the request made to submit file entry to sandbox. |
| VisionOne.Submit_File_Entry_to_Sandbox.task_id | string | ID of the submitted file. |
| VisionOne.Submit_File_Entry_to_Sandbox.digest | string | The hash value of the file. |
| VisionOne.Submit_File_Entry_to_Sandbox.filename | string | The name of the file submitted. |
| VisionOne.Submit_File_Entry_to_Sandbox.file_path | string | The path to the file associated to incident. |
| VisionOne.Submit_File_Entry_to_Sandbox.entry_id | string | The Entry ID for the file. |
| VisionOne.Submit_File_Entry_to_Sandbox.arguments | string | Command line arguments to run the submitted file. |
trendmicro-visionone-submit-urls-to-sandbox
Sends URL(s) to sandbox for analysis.
Base Command
trendmicro-visionone-submit-urls-to-sandbox
Input
| Argument Name | Description | Required |
|---|---|---|
| urls | List of URLs to be sent for analysis. e.g. urls=”https://test.com,https://dummydomain.com”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Submit_Urls_to_Sandbox.id | string | ID generated for the URL sent to sandbox for analysis. |
| VisionOne.Submit_Urls_to_Sandbox.url | string | URL sent to sandbox for analysis. |
| VisionOne.Submit_Urls_to_Sandbox.digest | string | Digest value generated for the URL sent to sandbox for analysis. |
| VisionOne.Submit_Urls_to_Sandbox.status | string | HTTPS status code of making the request. |
| VisionOne.Submit_Urls_to_Sandbox.task_id | string | Task ID generated for the URL sent to sandbox for analysis. |
trendmicro-visionone-get-alert-details
Fetches details for a specific alert.
Base Command
trendmicro-visionone-get-alert-details
Input
| Argument Name | Description | Required |
|---|---|---|
| workbench_id | Workbench ID for the alert to query. e.g. workbench_id=”WB-14-20190709-00003”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Alert_Details.etag | string | The ETag of the resource you want to update. |
| VisionOne.Alert_Details.alert.id | string | ID of the workbench alert. |
| VisionOne.Alert_Details.alert.model | string | Name of the detection model that triggered the alert. |
| VisionOne.Alert_Details.alert.score | number | Overall severity assigned to the alert based on the severity of the matched detection model and the impact scope. |
| VisionOne.Alert_Details.alert.severity | string | Workbench alert severity. |
| VisionOne.Alert_Details.alert.indicators | string | The indicators refer to those objects which are found by RCA or sweeping. |
| VisionOne.Alert_Details.alert.description | string | Description of the detection model that triggered the alert. |
| VisionOne.Alert_Details.alert.impact_scope | string | Affected entities information. |
| VisionOne.Alert_Details.alert.matched_rules | string | The rules are triggered. |
| VisionOne.Alert_Details.alert.alert_provider | string | Alert provider. |
| VisionOne.Alert_Details.alert.schema_version | string | The version of the JSON schema, not the version of alert trigger content. |
| VisionOne.Alert_Details.alert.workbench_link | string | Workbench URL. |
| VisionOne.Alert_Details.alert.created_date_time | string | Datetime in ISO 8601 format (yyyy-MM-ddThh:mm:ssZ in UTC) that indicates the created date time of the alert. |
| VisionOne.Alert_Details.alert.updated_date_time | string | Datetime in ISO 8601 format (yyyy-MM-ddThh:mm:ssZ in UTC) that indicates the last updated date time of the alert. |
| VisionOne.Alert_Details.alert.investigation_status | string | Workbench alert status. |
| VisionOne.Alert_Details.alert.first_investigated_date_time | string | The date and time the case status was changed to ‘In progress’ in ISO 8601 format (yyyy-MM-ddThh:mm:ssZ, UTC). |
| VisionOne.Alert_Details.alert.incident_id | string | The unique identifier of an incident. |
| VisionOne.Alert_Details.alert.case_id | string | The unique identifier of a case. |
| VisionOne.Alert_Details.alert.owner_ids | string | The owners of the Workbench alert. |
| VisionOne.Alert_Details.alert.model_id | string | ID of the detection model that triggered the alert. |
| VisionOne.Alert_Details.alert.model_type | string | Type of the detection model that triggered the alert. |
| VisionOne.Alert_Details.alert.status | string | The status of a case or investigation. |
| VisionOne.Alert_Details.alert.investigation_result | string | The findings of a case or investigation. |
trendmicro-visionone-run-sandbox-submission-polling
Runs a polling command to retrieve the status of a sandbox analysis submission.
Base Command
trendmicro-visionone-run-sandbox-submission-polling
Input
| Argument Name | Description | Required |
|---|---|---|
| polling | polling the task for 30 seconds interval. e.g. polling=true. Default is true. | Optional |
| task_id | task_id from the trendmicro-visionone-submit-file-to-sandbox or trendmicro-visionone-submit-file-entry-to-sandbox command output. e.g. task_id=”012e4eac-9bd9-4e89-95db-77e02f75a611”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Sandbox_Submission_Polling.message | string | Status of the sandbox analysis. |
| VisionOne.Sandbox_Submission_Polling.status_code | string | Status code of the request. |
| VisionOne.Sandbox_Submission_Polling.status | string | Status of action to analyze file in sandbox. |
| VisionOne.Sandbox_Submission_Polling.report_id | string | Report ID of the submission queried. |
| VisionOne.Sandbox_Submission_Polling.digest | string | The hash values of file analyzed. |
| VisionOne.Sandbox_Submission_Polling.analysis_completion_time | string | Sample analysis completed time. |
| VisionOne.Sandbox_Submission_Polling.risk_level | string | Risk Level of the analyzed file. |
| VisionOne.Sandbox_Submission_Polling.detection_name_list | string | Detection name of this sample, if applicable. |
| VisionOne.Sandbox_Submission_Polling.threat_type_list | string | Threat type of this sample. |
| VisionOne.Sandbox_Submission_Polling.file_type | string | File type of this sample. |
| VisionOne.Sandbox_Submission_Polling.type | string | Object type. |
| VisionOne.Sandbox_Submission_Polling.message | string | Error message for failed call. |
| VisionOne.Sandbox_Submission_Polling.code | string | Error code for failed call. |
| VisionOne.Sandbox_Submission_Polling.DBotScore.Score | number | The DBot score. |
| VisionOne.Sandbox_Submission_Polling.DBotScore.Vendor | string | The Vendor name. |
| VisionOne.Sandbox_Submission_Polling.DBotScore.Reliability | string | The reliability of an intelligence-data source. |
trendmicro-visionone-check-task-status
Command gives the status of the running task based on the task id.
Base Command
trendmicro-visionone-check-task-status
Input
| Argument Name | Description | Required |
|---|---|---|
| polling | polling the task for 30 seconds interval. e.g. polling=true. Default is true. | Optional |
| task_id | Task id of the task you would like to check. e.g. task_id=”00000012”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Task_Status.id | string | Task ID of the task queried. |
| VisionOne.Task_Status.status | string | Status of the task. |
| VisionOne.Task_Status.created_date_time | string | Timestamp in ISO 8601 format. |
| VisionOne.Task_Status.last_action_date_time | string | Timestamp in ISO 8601 format. |
| VisionOne.Task_Status.action | string | Action performed. |
| VisionOne.Task_Status.description | string | Description of the task. |
| VisionOne.Task_Status.account | string | Account that performed the task. |
| VisionOne.Task_Status.type | string | Value type. |
| VisionOne.Task_Status.value | string | Value that was submitted. |
| VisionOne.Task_Status.tasks | string | Task related information. |
| VisionOne.Task_Status.agent_guid | string | Agent guid of the endpoint. |
| VisionOne.Task_Status.endpoint_name | string | Endpoint name. |
trendmicro-visionone-add-note
Attaches a note to a workbench alert.
Base Command
trendmicro-visionone-add-note
Input
| Argument Name | Description | Required |
|---|---|---|
| workbench_id | ID of the workbench you would like to attach the note to. e.g. workbench_id=”WB-14-20190709-00003”. | Required |
| content | Contents of the note to be attached. e.g. content=”Some details for the workbench alert.”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Add_Note.code | string | HTTPS status code of making the request. |
| VisionOne.Add_Note.message | string | Message notifying the user of note added to workbench. |
| VisionOne.Add_Note.note_id | string | ID of the note added to workbench. |
trendmicro-visionone-update-status
Updates the status of a workbench alert.
Base Command
trendmicro-visionone-update-status
Input
| Argument Name | Description | Required |
|---|---|---|
| workbench_id | ID of the workbench you would like to update the status for. e.g. workbench_id=”WB-14-20190709-00003”. | Required |
| if_match | Target resource will be updated only if it matches ETag of the target one. Etag is one of the outputs from get_alert_details. e.g. if_match=”d41d8cd98f00b204e9800998ecf8427e”. | Required |
| status | Status to assign to the workbench alert. e.g. status=”closed”. Possible values are: open, in_progress, closed. | Optional |
| inv_status | The status of an investigation. NOTE: THIS FIELD IS DEPRECATED! e.g. inv_status=”true_positive”. Possible values are: new, in_progress, true_positive, false_positive, benign_true_positive, closed. | Optional |
| inv_result | The findings of a case or investigation. e.g. status=”noteworthy”. Possible values are: noteworthy, true_positive, false_positive, benign_true_positive, no_findings. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Update_Status.Workbench_Id | string | The ID of the workbench that had the status updated. |
| VisionOne.Update_Status.code | string | HTTP status code of updating workbench alert status. |
| VisionOne.Update_Status.message | string | Message notifying user that the alert status has been updated to user defined status. |
trendmicro-visionone-run-custom-script
Runs a custom script on the specified endpoint or agentGuid.
Base Command
trendmicro-visionone-run-custom-script
Input
| Argument Name | Description | Required |
|---|---|---|
| block_objects | List of object(s) made up of filename, endpoint or agent_guid and optional description and optional parameter. e.g. [{“filename”:”test.ps1”,”endpoint”:”test-endpoint1”,”description”:”Run custom script”,”parameter”:”some-string”}]. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Run_Custom_Script.status | number | Status of running custom script. |
| VisionOne.Run_Custom_Script.task_id | string | Task ID generated after running custom script. |
trendmicro-visionone-get-custom-script-list
Fetches a list of all available custom scripts in V1 XDR Portal.
Base Command
trendmicro-visionone-get-custom-script-list
Input
| Argument Name | Description | Required |
|---|---|---|
| filename | Name of the custom script. e.g. filename=”hello.sh”. | Optional |
| filetype | Type of script, either bash or powershell. e.g. filetype=”bash”. | Optional |
| query_op | Conditional operator used to build request that allows user to retrieve a subset of custom scripts. Possible values: and/or. Ex. or: the results retrieved will contain custom script(s) matching FileName OR FileType. and: the result retrieved will contain custom script matching FileName AND FileType. Defaults to and. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Get_Custom_Script_List.id | string | The id for custom script. |
| VisionOne.Get_Custom_Script_List.description | string | The script description. |
| VisionOne.Get_Custom_Script_List.filename | string | Name of the script. |
| VisionOne.Get_Custom_Script_List.filetype | string | File type for the script. |
trendmicro-visionone-add-custom-script
Adds a custom script to V1 portal in Response management under custom scripts.
Base Command
trendmicro-visionone-add-custom-script
Input
| Argument Name | Description | Required |
|---|---|---|
| filename | Name of the custom script. e.g. filename=”hello.sh”. | Required |
| filetype | File type of custom script. e.g. filetype=”bash”. | Required |
| script_contents | The contents of custom script to be added. script_contents=”#!/bin/sh echo ‘Custom script to do something’”. | Required |
| description | Description of the custom script. e.g. description=”This script does something.”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Add_Custom_Script.id | string | ID generated for the added custom script. |
trendmicro-visionone-download-custom-script
Downloads the contents of a custom script based on script ID.
Base Command
trendmicro-visionone-download-custom-script
Input
| Argument Name | Description | Required |
|---|---|---|
| script_id | ID for the custom script to download. e.g. script_id=”44c99cb0-8c5f-4182-af55-62135dbe32f1”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Download_Custom_Script.text | string | Contents of the custom script. |
trendmicro-visionone-delete-custom-script
Delete a custom script based on script ID.
Base Command
trendmicro-visionone-delete-custom-script
Input
| Argument Name | Description | Required |
|---|---|---|
| script_id | ID of custom script to be deleted. e.g. script_id=”44c99cb0-8c5f-4182-af55-62135dbe32f1”. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Delete_Custom_Script.status | string | Success or Failure status code. |
trendmicro-visionone-update-custom-script
Updates the contents of a custom script based on script ID.
Base Command
trendmicro-visionone-update-custom-script
Input
| Argument Name | Description | Required |
|---|---|---|
| filename | Name of the custom script. e.g. filename=”hello.sh”. | Required |
| filetype | The filetype of custom script. e.g. filetype=”bash”. | Required |
| script_id | ID of custom script to be updated. e.g. script_id=”44c99cb0-8c5f-4182-af55-62135dbe32f1”. | Required |
| script_contents | The updated contents of custom script. e.g. script_contents=”#!/bin/sh echo ‘Hello World’”. | Required |
| description | Description of the custom script. e.g. description=”Updating script to print Hello World.”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Update_Custom_Script.status | string | The Success or Error status. |
trendmicro-visionone-get-observed-attack-techniques
Displays a list of Observed Attack Techniques events that match the specified criteria.
Base Command
trendmicro-visionone-get-observed-attack-techniques
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Filter (A dictionary object with key/value used to create a query string) for retrieving a subset of the collected Observed Attack Techniques events e.g. {“endpointName”:”sample-host”,”riskLevel”:”low”}. Complete list of supported fields (https://automation.trendmicro.com/xdr/api-v3#tag/Observed-Attack-Techniques/paths/~1v3.0~1oat~1detections/get). | Required |
| query_op | Conditional operator used to build request that allows user to retrieve a subset of the collected Observed Attack Techniques events. Possible values: and/or. Ex. or: the results retrieved will contain OAT events for endpoint(s) matching endpointName OR riskLevel. and: will contain OAT events data for endpoint matching endpointName AND riskLevel. Defaults to and. Possible values are: and, or. |
Optional |
| detected_start | The start of the event detection data retrieval time range in ISO 8601 format. Default: 1 hour before the time you make the request. e.g. detected_start=”2023-10-01T08:00:00Z”. | Optional |
| detected_end | The end of the event detection data retrieval time range in ISO 8601 format. Default: The time you make the request. e.g. detected_end=”2023-12-01T08:00:00Z”. | Optional |
| ingested_start | The beginning of the data ingestion time range in ISO 8601 format. e.g. ingested_start=”2023-12-01T08:00:00Z”. | Optional |
| ingested_end | The end of the data ingestion time range in ISO 8601 format. e.g. ingested_end=”2023-12-01T08:00:00Z”. | Optional |
| top | Number of records displayed on a page. e.g. top=5. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VisionOne.Get_Observed_Attack_Techniques.id | string | Unique alphanumeric string that identifies an Observed Attack Techniques event. |
| VisionOne.Get_Observed_Attack_Techniques.source | string | The data sources associated with log types. |
| VisionOne.Get_Observed_Attack_Techniques.detail | string | Object that contains detailed information about an Observed Attack Technique event. Object may vary depending on the products purchased by the customer and the products supported in their respective regions. |
| VisionOne.Get_Observed_Attack_Techniques.filters | string | List of filters and associated information. |
| VisionOne.Get_Observed_Attack_Techniques.endpoint | string | Object that contains information about an endpoint. This field is displayed only when the detection event is related to endpoints. |
| VisionOne.Get_Observed_Attack_Techniques.entity_name | string | Name associated with an entity. |
| VisionOne.Get_Observed_Attack_Techniques.entity_type | string | Entity type associated with an event is determined by the products purchased by the customer and the products supported in their regions. |
| VisionOne.Get_Observed_Attack_Techniques.detected_date_time | string | Timestamp in ISO 8601 format that indicates when an Observed Attack Techniques event was detected. |
| VisionOne.Get_Observed_Attack_Techniques.ingested_date_time | string | Timestamp in ISO 8601 format that indicates when the pipeline ingested data related to an Observed Attack Techniques event. This field is displayed only when ingestedStartDateTime and ingestedEndDateTime are used to define the data retrieval time range. |
Configuration parameters
url— API URL (e.g. https://api.xdr.trendmicro.com) (required)apikey— (required)isFetch— Fetch incidentsincidentFetchInterval— Incidents Fetch IntervalincidentType— Incident typefirst_fetch— Sync On First Run (days)max_fetch— Max Incidentsproxy— Use system proxy settingsinsecure— Trust any certificate (not secure)integrationReliability— Source Reliabilityincident_severity— Severitymirror_direction— Incident Mirroring Direction
Commands (47)
-
get-mapping-fieldsReturns the list of fields for an incident type. This command is used for incident mirroring.
-
get-modified-remote-dataGets the list of Vision One alerts that were modified since the last update time. This command is used for incoming mirroring.
-
get-remote-dataGets remote data from Vision One for a specific alert. This method is used for incoming mirroring and debugging purposes.
-
trendmicro-visionone-add-custom-scriptAdds a custom script to V1 portal in Response management under custom scripts.
-
trendmicro-visionone-add-noteAttaches a note to a workbench alert.
-
trendmicro-visionone-add-objects-to-exception-listAdds domain, ip, url, file_sha1, file_sha256, sender_mail_address to the Exception List and prevents these objects from being added to the Suspicious Object List.
-
trendmicro-visionone-add-objects-to-suspicious-listAdds domain, ip, url, file_sha1, file_sha256, sender_mail_address to the Suspicious Object List.
-
trendmicro-visionone-add-to-block-listAdds a domain, ip, file_sha1, url, sender_mail_address to the User-Defined Suspicious Objects List, which blocks the objects on subsequent detections.
-
trendmicro-visionone-check-task-statusCommand gives the status of the running task based on the task id.
-
trendmicro-visionone-collect-forensic-fileCompresses a file on an endpoint in a password-protected archive and then sends the archive to the XDR service platform.
-
trendmicro-visionone-delete-custom-scriptDelete a custom script based on script ID.
-
trendmicro-visionone-delete-email-messageDeletes a message from a mailbox.
-
trendmicro-visionone-delete-objects-from-exception-listDeletes domain, ip, url, file_sha1, file_sha256, sender_mail_address from the Exception List.
-
trendmicro-visionone-delete-objects-from-suspicious-listDeletes domain, ip, url, file_sha1, file_sha256, sender_mail_address from the Suspicious Object List.
-
trendmicro-visionone-disable-user-accountSigns the user out of all active application and browser sessions, and prevents the user from signing in any new session. Supported IAM systems -> Azure AD and Active Directory (on-premises).
-
trendmicro-visionone-download-analysis-reportDownloads the analysis report for an object submitted to sandbox for analysis based on the submission ID.
-
trendmicro-visionone-download-custom-scriptDownloads the contents of a custom script based on script ID.
-
trendmicro-visionone-download-information-for-collected-forensic-fileRetrieves a URL and other information required to download a collected file via the trendmicro-visionone-collect-forensic-file command.
-
trendmicro-visionone-download-investigation-packageDownloads the investigation package based on submission ID.
-
trendmicro-visionone-download-suspicious-object-listDownloads the suspicious object list associated to the specified object. Note ~ Suspicious Object Lists are only available for objects with a high risk level.
-
trendmicro-visionone-enable-user-accountAllows the user to sign in to new application and browser sessions. Supported IAM systems -> Azure AD and Active Directory (on-premises).
-
trendmicro-visionone-force-password-resetSigns the user out of all active application and browser sessions, and forces the user to create a new password during the next sign-in attempt. Supported IAM systems -> Azure AD and Active Directory (on-premises).
-
trendmicro-visionone-force-signoutSigns the user out of all active application and browser sessions. Supported IAM systems -> Azure AD.
-
trendmicro-visionone-get-alert-detailsFetches details for a specific alert.
-
trendmicro-visionone-get-custom-script-listFetches a list of all available custom scripts in V1 XDR Portal.
-
trendmicro-visionone-get-email-activity-dataDisplays search results from the Email Activity Data source that match the parameters provided.
-
trendmicro-visionone-get-email-activity-data-countDisplays search results from the Email Activity Data source that match the parameters provided.
-
trendmicro-visionone-get-endpoint-activity-dataDisplays search results from the Endpoint Activity Data source that match the parameters provided.
-
trendmicro-visionone-get-endpoint-activity-data-countDisplays total count of search results from the Endpoint Activity Data source that match the parameters provided.
-
trendmicro-visionone-get-endpoint-infoRetrieves information about a specific endpoint.
-
trendmicro-visionone-get-file-analysis-resultRetrieves the sandbox submission analysis result.
-
trendmicro-visionone-get-file-analysis-statusRetrieves the status of a sandbox analysis submission.
-
trendmicro-visionone-get-observed-attack-techniquesDisplays a list of Observed Attack Techniques events that match the specified criteria.
-
trendmicro-visionone-isolate-endpointDisconnects an endpoint from the network (but allows communication with the managing TrendAI™ product).
-
trendmicro-visionone-quarantine-email-messageMoves a message from a mailbox to the quarantine folder.
-
trendmicro-visionone-remove-from-block-listRemoves a domain, ip, file_sha1, url, sender_mail_address from the User-Defined Suspicious Objects List.
-
trendmicro-visionone-restore-email-messageRestores a quarantined message. Deleted messages cannot be restored.
-
trendmicro-visionone-restore-endpoint-connectionRestores network connectivity to an endpoint that applied the "isolate endpoint" action.
-
trendmicro-visionone-run-custom-scriptRuns a custom script on the specified endpoint or agentGuid.
-
trendmicro-visionone-run-sandbox-submission-pollingRuns a polling command to retrieve the status of a sandbox analysis submission.
-
trendmicro-visionone-submit-file-entry-to-sandboxSubmits a file to the sandbox for analysis (Note. For more information about the supported file types, see [the TrendAI Vision One™Online Help](https://docs.trendmicro.com/en-us/enterprise/trend-micro-vision-one/threat-intelligence-/sandbox-analysis/sandbox-supported-fi.aspx). Submissions require credits. Does not require credits in regions where Sandbox Analysis has not been officially released.)
-
trendmicro-visionone-submit-file-to-sandboxSubmits a file to the sandbox for analysis (Note. For more information about the supported file types, see [the TrendAI Vision One™ Online Help](https://docs.trendmicro.com/en-us/enterprise/trend-micro-vision-one/threat-intelligence-/sandbox-analysis/sandbox-supported-fi.aspx). Submissions require credits. Does not require credits in regions where Sandbox Analysis has not been officially released.)
-
trendmicro-visionone-submit-urls-to-sandboxSends URL(s) to sandbox for analysis.
-
trendmicro-visionone-terminate-processTerminates a process that is running on an endpoint.
-
trendmicro-visionone-update-custom-scriptUpdates the contents of a custom script based on script ID.
-
trendmicro-visionone-update-statusUpdates the status of a workbench alert.
-
update-remote-systemPushes local XSOAR incident changes to the remote Vision One alert system. This command is used for outgoing mirroring.
import json from typing import Any # import unittest from unittest.mock import Mock import demistomock as demisto import TrendMicroVisionOneV3 from pytmv1 import ( Account, AccountTaskResp, AddAlertNoteResp, AddCustomScriptResp, BaseTaskResp, BytesResp, CollectFileTaskResp, Digest, EmailActivity, Endpoint, EndpointActivity, GetAlertResp, GetEmailActivitiesCountResp, Iam, ListCustomScriptsResp, ListEmailActivityResp, ListEndpointActivityResp, ListOatsResp, ListSandboxSuspiciousResp, MsData, MsDataUrl, MultiResp, MultiResult, MultiUrlResp, NoContentResp, OatEvent, ObjectType, OperatingSystem, ProductCode, QueryOp, Result, ResultCode, RiskLevel, SandboxAction, SandboxAnalysisResultResp, SandboxObjectType, SandboxSubmissionStatusResp, SandboxSuspiciousObject, ScriptType, Status, SubmitFileToSandboxResp, TaskAction, TextResp, Value, ValueList, ) from pytmv1.model.common import Script from TrendMicroVisionOneV3 import ( add_custom_script, add_note, add_or_delete_from_exception_list, add_or_remove_from_block_list, add_to_suspicious_list, collect_file, delete_custom_script, delete_from_suspicious_list, download_analysis_report, download_custom_script, download_information_collected_file, download_investigation_package, download_suspicious_object_list, enable_or_disable_user_account, force_password_reset, force_sign_out, get_alert_details, get_custom_script_list, get_email_activity_data, get_email_activity_data_count, get_endpoint_activity_data, get_endpoint_activity_data_count, get_endpoint_info, get_file_analysis_result, get_file_analysis_status, get_mapping_fields_command, get_modified_remote_data_command, get_observed_attack_techniques, get_remote_data_command, get_sandbox_submission_status, get_task_status, isolate_or_restore_connection, quarantine_or_delete_email_message, restore_email_message, run_custom_script, submit_file_entry_to_sandbox, submit_file_to_sandbox, submit_urls_to_sandbox, terminate_process, update_custom_script, update_remote_system_command, update_status, vision_one_status_to_xsoar, xsoar_status_to_vision_one, ) # Provide valid API KEY api_key = "test api key" proxy = True verify = True # Mock response for enabling or disabling user account def enable_user_account_mock_response(*args, **kwargs) -> MultiResult[MultiResp]: with open("./test_data/enable_user_account.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) def test_enable_user_account(mocker): """Test enable user account success response.""" client = Mock() client.account.enable = Mock(return_value=enable_user_account_mock_response()) args = { "account_identifiers": json.dumps( [ { "account_name": "ghost@trendmicro.com", "description": "Enable user account.", } ] ) } result = TrendMicroVisionOneV3.enable_or_disable_user_account(client, "trendmicro-visionone-enable-user-account", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000010" assert result.outputs_prefix == "VisionOne.User_Account" assert result.outputs_key_field == "task_id" def disable_user_account_mock_response(*args, **kwargs): with open("./test_data/disable_user_account.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) def test_disable_user_account(mocker): """Test disable user account success response.""" client = Mock() client.account.disable = Mock(return_value=disable_user_account_mock_response()) args = { "account_identifiers": json.dumps( [ { "account_name": "ghost@trendmicro.com", "description": "Disable user account.", } ] ) } result = enable_or_disable_user_account(client, "trendmicro-visionone-disable-user-account", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000009" assert result.outputs_prefix == "VisionOne.User_Account" assert result.outputs_key_field == "task_id" # Mock response for force sign out def force_signout_mock_response(*args, **kwargs): with open("./test_data/force_signout.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) def test_force_signout(mocker): """Test to force sign out user account with successful result.""" client = Mock() client.account.sign_out = Mock(return_value=force_signout_mock_response()) args = { "account_identifiers": json.dumps( [ { "account_name": "ghost@trendmicro.com", "description": "Signing out user account.", } ] ) } result = force_sign_out(client, args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000012" assert result.outputs_prefix == "VisionOne.Force_Sign_Out" assert result.outputs_key_field == "task_id" # Mock response for force password reset def force_password_reset_mock_response(*args, **kwargs): with open("./test_data/force_password_reset.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) def test_force_password_reset(mocker): """Test to force sign out user account with successful result.""" client = Mock() client.account.reset = Mock(return_value=force_password_reset_mock_response()) args = { "account_identifiers": json.dumps( [ { "account_name": "ghost@trendmicro.com", "description": "Signing out user account.", } ] ) } result = force_password_reset(client, args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000011" assert result.outputs_prefix == "VisionOne.Force_Password_Reset" assert result.outputs_key_field == "task_id" # Mock function for add to block list def add_blocklist_mock_response(*args, **kwargs): with open("./test_data/add_blocklist.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for add to block list def test_add_blocklist(mocker): """Test add to block list with positive scenario.""" client = Mock() client.object.add_block = Mock(return_value=add_blocklist_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "file_sha1", "object_value": "2de5c1125d5f991842727ed8eca8b5fda0ffa249b", "description": "Add to blocklist.", } ] ) } result = add_or_remove_from_block_list(client, "trendmicro-visionone-add-to-block-list", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000007" assert result.outputs_prefix == "VisionOne.BlockList" assert result.outputs_key_field == "task_id" # Mock function for remove from block list def remove_blocklist_mock_response(*args, **kwargs): with open("./test_data/remove_blocklist.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for remove from block list def test_remove_blocklist(mocker): """Test remove block list positive scenario.""" client = Mock() client.object.delete_block = Mock(return_value=remove_blocklist_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "domain", "object_value": "www.test.com", "description": "Remove from block list", } ] ) } result = add_or_remove_from_block_list(client, "trendmicro-visionone-remove-from-block-list", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000008" assert result.outputs_prefix == "VisionOne.BlockList" assert result.outputs_key_field == "task_id" # Mock function for quarantine and delete email message def quarantine_email_mock_response(*args, **kwargs): with open("./test_data/quarantine_email.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for quarantine email message def test_quarantine_email_message(mocker): """Test quarantine email message positive scenario.""" client = Mock() client.email.quarantine = Mock(return_value=quarantine_email_mock_response()) args = { "email_identifiers": json.dumps( [ { "message_id": ("<CANUJTKTjto9GAHTr9V=TFqMZhRXqVn=MfSqmTdAMyv9PDX3k+vQ0w@mail.gmail.com>"), "mailbox": "kjshdfjksahd@trendenablement.com", "description": "quarantine email", } ] ) } result = quarantine_or_delete_email_message(client, "trendmicro-visionone-quarantine-email-message", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000002" assert result.outputs_prefix == "VisionOne.Email" assert result.outputs_key_field == "task_id" def delete_email_mock_response(*args, **kwargs): with open("./test_data/delete_email.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for delete email message def test_delete_email_message(mocker): """Test delete email message with positive scenario.""" client = Mock() client.email.delete = Mock(return_value=delete_email_mock_response()) args = { "email_identifiers": json.dumps( [ { "unique_id": ("CANUJTKTjto9GAHTr9V=TFqMZhRXqVn=MfSqmTdAMyv9PDX3k+vQ0w@mail.gmail.com"), "description": "delete email", } ] ) } result = quarantine_or_delete_email_message(client, "trendmicro-visionone-delete-email-message", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000001" assert result.outputs_prefix == "VisionOne.Email" assert result.outputs_key_field == "task_id" # Mock response for restore email message def restore_email_mock_response(*args, **kwargs): with open("./test_data/restore_email_message.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test case for restore email def test_restore_email_message(mocker): client = Mock() client.email.restore = Mock(return_value=restore_email_mock_response()) args = { "email_identifiers": json.dumps( [ { "unique_id": "CANUJTKTjto9GAHTr9V=TFqMZhRXqVnMfSqmTdAMyv9PDX3k", "description": "Restore email.", } ] ) } result = restore_email_message(client, args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000003" assert result.outputs_prefix == "VisionOne.Email" assert result.outputs_key_field == "task_id" # Mock response for isolate endpoint def isolate_mock_response(*args, **kwargs): with open("./test_data/isolate_endpoint.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for isolate endpoint def test_isolate_endpoint(mocker): """Test isolate endpoint positive scenario.""" client = Mock() client.endpoint.isolate = Mock(return_value=isolate_mock_response()) args = { "endpoint_identifiers": json.dumps( [ { "endpoint": "client782", "description": "Add to blocklist.", } ] ) } result = isolate_or_restore_connection(client, "trendmicro-visionone-isolate-endpoint", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000004" assert result.outputs_prefix == "VisionOne.Endpoint_Connection" assert result.outputs_key_field == "task_id" # Mock response for restore endpoint def restore_endpoint_mock_response(*args, **kwargs): with open("./test_data/restore_endpoint.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for restore endpoint def test_restore_endpoint(mocker): """Test restore endpoint positive scenario.""" client = Mock() client.endpoint.restore = Mock(return_value=restore_endpoint_mock_response()) args = { "endpoint_identifiers": json.dumps( [ { "agent_guid": "cb9c8412-1f64-4fa0-a36b-76bf41a07ede", "description": "Remove from blocklist.", } ] ) } result = isolate_or_restore_connection(client, "trendmicro-visionone-restore-endpoint-connection", args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000005" assert result.outputs_prefix == "VisionOne.Endpoint_Connection" assert result.outputs_key_field == "task_id" # Mock response for terminate process def terminate_process_mock_response(*args, **kwargs): with open("./test_data/terminate_process.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for terminate process endpoint def test_terminate_process(mocker): """Test terminate process positive scenario.""" client = Mock() client.endpoint.terminate_process = Mock(return_value=terminate_process_mock_response()) args = { "process_identifiers": json.dumps( [ { "endpoint": "035f6286-2414-4cb4-8d05-e67d2d32c944", "file_sha1": "12a08b7a3c5a10b64700c0aca1a47941b50a4f8b", "description": "terminate info", "filename": "testfile.txt", } ] ) } result = terminate_process(client, args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000006" assert result.outputs_prefix == "VisionOne.Terminate_Process" assert result.outputs_key_field == "task_id" # Mock response for add to exception list def add_exception_mock_response(*args, **kwargs): with open("./test_data/add_exception.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for add exception list. def test_add_object_to_exception_list(mocker): """Test add to exception list with positive scenario.""" client = Mock() client.object.add_exception = Mock(return_value=add_exception_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "domain", "object_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["message"] == "success" assert isinstance(result.outputs["total_items"], int) assert result.outputs_prefix == "VisionOne.Exception_List" assert result.outputs_key_field == "multi_response" # Mock response for remove from exception list def delete_exception_mock_response(*args, **kwargs): with open("./test_data/remove_exception.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for delete exception list. def test_delete_object_from_exception_list(mocker): """Test delete exception list positive scenario.""" client = Mock() client.object.delete_exception = Mock(return_value=delete_exception_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "ip", "object_value": "7.7.7.7", "description": "Remove IP from exception list", } ] ) } result = add_or_delete_from_exception_list(client, "trendmicro-visionone-delete-objects-from-exception-list", args) assert result.outputs["message"] == "success" assert isinstance(result.outputs["total_items"], int) assert result.outputs_prefix == "VisionOne.Exception_List" assert result.outputs_key_field == "multi_response" # Mock response for add to suspicious list def add_suspicious_mock_response(*args, **kwargs): with open("./test_data/add_suspicious_list.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in 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.""" client = Mock() client.object.add_suspicious = Mock(return_value=add_suspicious_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "domain", "object_value": "1.alisiosanguera.com.cn", "description": "Example Suspicious Object.", "scan_action": "log", "risk_level": "high", "expiry_days": 15, } ] ) } result = add_to_suspicious_list(client, args) assert result.outputs["message"] == "success" assert isinstance(result.outputs["total_items"], int) assert result.outputs_prefix == "VisionOne.Suspicious_List" assert result.outputs_key_field == "multi_response" # Mock response for delete from suspicious list def delete_suspicious_mock_response(*args, **kwargs): with open("./test_data/delete_suspicious_list.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for delete suspicious object list def test_delete_object_from_suspicious_list(mocker): """Test delete object from suspicious list.""" client = Mock() client.object.delete_suspicious = Mock(return_value=delete_suspicious_mock_response()) args = { "block_objects": json.dumps( [ { "object_type": "domain", "object_value": "1.alisiosanguera.com.cn", "description": "Delete from suspicious list", } ] ) } result = delete_from_suspicious_list(client, args) assert result.outputs["message"] == "success" assert isinstance(result.outputs["total_items"], int) assert result.outputs_prefix == "VisionOne.Suspicious_List" assert result.outputs_key_field == "multi_response" # Mock response for Get file analysis status def mock_file_analysis_status_response(*args, **kwargs): # with open("./test_data/get_file_analysis_status.json") as f: # return_value: list[dict[str, Any]] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=SandboxSubmissionStatusResp( id="921674d0-9735-4f79-b7de-c852e00a003d", status=Status.SUCCEEDED, created_date_time="2021-11-17T12:00:00Z", last_action_date_time="2021-12-17T12:00:00Z", action=SandboxAction.ANALYZE_FILE, resource_location="https://api.xdr.trendmicro.com/...", is_cached=False, arguments="LS10ZXN0IA==", digest=Digest( md5="4ac174730d4143a119037d9fda81c7a9", sha1="fb5608fa03de204a12fe1e9e5275e4a682107471", sha256="65b0f656e79ab84ca17807158e3eac206bd58be6689ddeb95956a48748d138f9", ), ), ) # Test Cases for Get file analysis status def test_get_file_analysis_status(mocker): """Test to get status of file""" client = Mock() client.sandbox.get_submission_status = Mock(return_value=mock_file_analysis_status_response()) args = {"task_id": "921674d0-9735-4f79-b7de-c852e00a003d"} result = get_file_analysis_status(client, args) assert isinstance(result.outputs["is_cached"], bool) assert result.outputs["status"] == "succeeded" assert isinstance(result.outputs["action"], str) assert isinstance(result.outputs["arguments"], str) assert result.outputs["id"] == "921674d0-9735-4f79-b7de-c852e00a003d" assert isinstance(result.outputs["digest"], dict) assert isinstance(result.outputs["resource_location"], str) assert result.outputs_prefix == "VisionOne.File_Analysis_Status" assert result.outputs_key_field == "id" # Mock response for Get file analysis report def mock_file_result_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=SandboxAnalysisResultResp( id="800f908d-9578-4333-91e5-822794ed5483", type=SandboxObjectType.FILE, analysis_completion_date_time="2021-11-17T12:00:00Z", risk_level=RiskLevel.HIGH, true_file_type="exe", digest=Digest( md5="4ac174730d4143a119037d9fda81c7a9", sha1="fb5608fa03de204a12fe1e9e5275e4a682107471", sha256="65b0f656e79ab84ca17807158e3eac206bd58be6689ddeb95956a48748d138f9", ), arguments="LS10ZXN0IA==", detection_names=["VAN_DROPPER.UMXX"], threat_types=["Dropper"], ), ) # Test cases for get file analysis report def test_get_file_analysis_result(mocker): """Test get file analysis report data.""" client = Mock() client.sandbox.get_analysis_result = Mock(return_value=mock_file_result_response()) args = { "report_id": "800f908d-9578-4333-91e5-822794ed5483", "poll": "true", "poll_time_sec": 30, } result = get_file_analysis_result(client, args) assert result.outputs["id"] == "800f908d-9578-4333-91e5-822794ed5483" assert isinstance(result.outputs["type"], str) assert isinstance(result.outputs["digest"], dict) assert isinstance(result.outputs["arguments"], str) assert isinstance(result.outputs["analysis_completion_date_time"], str) assert result.outputs["risk_level"] == "high" assert isinstance(result.outputs["detection_names"], list) assert isinstance(result.outputs["threat_types"], list) assert isinstance(result.outputs["true_file_type"], str) assert result.outputs_key_field == "id" # Mock response for collect file def mock_collect_file_response(*args, **kwargs): with open("./test_data/collect_forensic_file.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test cases for collect forensic file. def test_collect_forensic_file(mocker): """Test collect file with positive scenario.""" client = Mock() client.endpoint.collect_file = Mock(return_value=mock_collect_file_response()) args = { "collect_files": json.dumps( [ { "endpoint": "client95c3", "file_path": "C/file_path/sample.txt", "description": "collect file", } ] ) } result = collect_file(client, args) assert result.outputs[0]["status"] == 202 assert result.outputs[0]["task_id"] == "00000003" assert result.outputs_prefix == "VisionOne.Collect_Forensic_File" assert result.outputs_key_field == "task_id" # Mock for downloaded file information def mock_download_collected_file_info_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=CollectFileTaskResp( id="00000003", status=Status.SUCCEEDED, action=TaskAction.COLLECT_FILE, created_date_time="2023-11-12T12:00:00Z", last_action_date_time="2023-11-16T12:00:00Z", description="Test", account="API", agent_guid="cb9c8412-1f64-4fa0-a36b-76bf41a07ede", endpoint_name="trend-host-1", file_path="string", file_sha1="12a08b7a3c5a10b64700c0aca1a47941b50a4f8b", file_sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", file_size=102400, resource_location="htttps://api.xdr.trendmicro.com/...", expired_date_time="2023-11-17T12:00:00Z", password="LS10ZXN0IA==", ), ) # Test Cases for Collected downloaded file information. def test_get_forensic_file_information(mocker): """Test endpoint to get collected file information based on task id""" client = Mock() client.task.get_result_class = Mock(return_value=mock_download_collected_file_info_response()) args = { "task_id": "00000003", "poll": "true", "poll_time_sec": 30, } result = download_information_collected_file(client, args) assert result.outputs["id"] == "00000003" # assert result.outputs["action"] == "collectFile" assert result.outputs["status"] == "succeeded" assert result.outputs["agent_guid"] == "cb9c8412-1f64-4fa0-a36b-76bf41a07ede" assert result.outputs["endpoint_name"] == "trend-host-1" assert result.outputs["file_sha1"] == "12a08b7a3c5a10b64700c0aca1a47941b50a4f8b" assert result.outputs["file_size"] == 102400 assert isinstance(result.outputs["file_path"], str) assert isinstance(result.outputs["resource_location"], str) assert isinstance(result.outputs["expired_date_time"], str) assert isinstance(result.outputs["created_date_time"], str) assert isinstance(result.outputs["password"], str) # Mock response for Download analysis results def mock_download_analysis_report_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=BytesResp(content=b"JVBERi0xLjQKJcCnN0cmVhbQp4nD2OywoCMQxF9=="), ) # Test Case for Download analysis report def test_download_analysis_report(mocker): """ Test to download analysis report (PDF) of file submitted to sandbox based on submission ID returned by get file analysis status. """ client = Mock() client.sandbox.download_analysis_result = Mock(return_value=mock_download_analysis_report_response()) args = { "submission_id": "8559a7ce-2b85-451b-8742-4b943ad76a22", "poll": "true", "poll_time_sec": 30, } result = download_analysis_report(client, args) assert result[1].outputs["result_code"] == "SUCCESS" assert result[1].outputs["submission_id"] == "8559a7ce-2b85-451b-8742-4b943ad76a22" assert result[1].outputs_prefix == "VisionOne.Download_Analysis_Report" assert result[1].outputs_key_field == "submission_id" # Mock response for download investigation package def mock_download_investigation_package_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=BytesResp(content=b"JVBERi0xLjQKJcCnN0cmVhbQp4nD2OywoCMQxF9=="), ) # Test case for Download analysis package def test_download_investigation_package(mocker): """ Test to download investigation package for file submitted to sandbox based on submission ID returned by get file analysis status. """ client = Mock() client.sandbox.download_investigation_package = Mock(return_value=mock_download_investigation_package_response()) args = { "submission_id": "8559a7ce-2b85-451b-8742-4b943ad76a22", "poll": "true", "poll_time_sec": 30, } result = download_investigation_package(client, args) assert result[1].outputs["result_code"] == "SUCCESS" assert result[1].outputs["submission_id"] == "8559a7ce-2b85-451b-8742-4b943ad76a22" assert result[1].outputs_prefix == "VisionOne.Download_Investigation_Package" assert result[1].outputs_key_field == "submission_id" # Mock response for download suspicious object list def mock_download_suspicious_object_list_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=ListSandboxSuspiciousResp( items=[ SandboxSuspiciousObject( risk_level=RiskLevel.HIGH, analysis_completion_date_time="2021-11-17T12:00:00Z", expired_date_time="2022-12-17T12:00:00Z", root_sha1="12a08b7a3c5a10b64700c0aca1a47941b50a4f8b", value="https://someurl.com", type=ObjectType.URL, ) ], ), ) # Test case for download suspicious object list def test_download_suspicious_object_list(mocker): """ Test to download suspicious object list based on submission ID returned by download file analysis report. Only items classified as High will be populated in the list. If no items exist, a 404 not found error will be returned. """ client = Mock() client.sandbox.list_suspicious = Mock(return_value=mock_download_suspicious_object_list_response()) args = { "submission_id": "8559a7ce-2b85-451b-8742-4b943ad76a22", "poll": "true", "poll_time_sec": 30, } result = download_suspicious_object_list(client, args) assert result.outputs[0]["risk_level"] == "high" assert isinstance(result.outputs[0]["analysis_completion_date_time"], str) assert isinstance(result.outputs[0]["expired_date_time"], str) assert isinstance(result.outputs[0]["root_sha1"], str) assert isinstance(result.outputs[0]["type"], str) assert isinstance(result.outputs[0]["value"], str) assert result.outputs_prefix == "VisionOne.Download_Suspicious_Object_list" assert result.outputs_key_field == "risk_level" # Mock response for submit file to sandbox. def mock_submit_file_to_sandbox_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=SubmitFileToSandboxResp( id="012e4eac-9bd9-4e89-95db-77e02f75a6f3", digest=Digest( md5="4ac174730d4143a119037d9fda81c7a9", sha1="fb5608fa03de204a12fe1e9e5275e4a682107471", sha256="65b0f656e79ab84ca17807158e3eac206bd58be6689ddeb95956a48748d138f9", ), arguments="LS10ZXN0IA==", ), ) # 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 { "id": "012e4eac-9bd9-4e89-95db-77e02f75a6f3", "digest": { "md5": "4ac174730d4143a119037d9fda81c7a9", "sha1": "fb5608fa03de204a12fe1e9e5275e4a682107471", "sha256": "65b0f656e79ab84ca17807158e3eac206bd58be6689ddeb95956a48748d138f9", }, "arguments": "LS10ZXN0IA==", } 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): client = Mock() client.sandbox.submit_file = Mock(return_value=mock_submit_file_to_sandbox_response()) args = { "file_path": "https://someurl.com/test.json", "filename": "dummy.pdf", "archive_password": "6hn467c8", "document_password": "", "arguments": "LS10ZXN0IA==", } mocker.patch("TrendMicroVisionOneV3.requests.get", mocked_requests_get) result = submit_file_to_sandbox(client, args) assert isinstance(result.outputs["task_id"], str) assert isinstance(result.outputs["digest"], dict) assert result.outputs["code"] == 202 assert isinstance(result.outputs["arguments"], str) assert result.outputs["message"] == "SUCCESS" assert result.outputs_key_field == "task_id" def test_submit_file_entry_to_sandbox(mocker): mocker.patch.object( demisto, "getFilePath", return_value={"id": id, "path": "README.md", "name": "test.txt"}, ) client = Mock() client.sandbox.submit_file = Mock(return_value=mock_submit_file_to_sandbox_response()) mocker.patch("TrendMicroVisionOneV3.requests.get", mocked_requests_get) mocker.patch("TrendMicroVisionOneV3.requests.post", mocked_requests_post) args = { "entry_id": "12@1221", "archive_password": "6hn467c8", "document_password": "", "arguments": "LS10ZXN0IA==", } result = submit_file_entry_to_sandbox(client, args) assert result.outputs["entry_id"] == "12@1221" assert isinstance(result.outputs["task_id"], str) assert isinstance(result.outputs["digest"], dict) assert result.outputs_key_field == "entry_id" # Mock response for submit urls to sandbox def mock_urls_to_sandbox_response(*args, **kwargs): with open("./test_data/submit_urls_sandbox.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiUrlResp(items=[MsDataUrl(**data) for data in return_value]), ) # Test case for submit urls to sandbox def test_submit_urls_to_sandbox(mocker): client = Mock() client.sandbox.submit_url = Mock(return_value=mock_urls_to_sandbox_response()) args = { "urls": json.dumps( [ "http://www.shadywebsite.com", "http://www.virus2.com", "https://testurl.com", ] ) } result = submit_urls_to_sandbox(client, args) assert isinstance(result.outputs[0]["url"], str) assert isinstance(result.outputs[0]["id"], str) assert isinstance(result.outputs[0]["digest"], dict) assert result.outputs_key_field == "id" def test_sandbox_submission_polling(mocker): """Test sandbox submission polling.""" client = Mock() client.sandbox.get_submission_status = Mock(return_value=mock_file_analysis_status_response()) client.sandbox.get_analysis_result = Mock(return_value=mock_file_result_response()) mocker.patch.object( demisto, "demistoVersion", return_value={"version": "6.2.0", "buildNumber": "12345"}, ) mocker.patch("CommonServerPython.ScheduledCommand.raise_error_if_not_supported", lambda: None) args = {"task_id": "800f908d-9578-4333-91e5-822794ed5483"} result = get_sandbox_submission_status(args, client) assert result.outputs["report_id"] == "800f908d-9578-4333-91e5-822794ed5483" assert isinstance(result.outputs["type"], str) assert isinstance(result.outputs["digest"], dict) assert isinstance(result.outputs["arguments"], str) assert isinstance(result.outputs["analysis_completion_time"], str) assert isinstance(result.outputs["risk_level"], str) assert isinstance(result.outputs["detection_name_list"], list) assert isinstance(result.outputs["threat_type_list"], list) assert isinstance(result.outputs["file_type"], str) # Mock function for check task status def get_base_task_result_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=BaseTaskResp( id="00000004", status=Status.SUCCEEDED, created_date_time="2021-11-17T12:00:00Z", last_action_date_time="2021-12-17T12:00:00Z", action=TaskAction.ENABLE_ACCOUNT, description="something", account="API", ), ) # Mock function for check task status def check_task_status_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=AccountTaskResp( id="00000004", status=Status.SUCCEEDED, created_date_time="2021-11-17T12:00:00Z", last_action_date_time="2021-12-17T12:00:00Z", action=TaskAction.ENABLE_ACCOUNT, description="something", account="API", tasks=[ Account( iam=Iam.AAD, account_name="jdoe@trendenablement.com", status=Status.SUCCEEDED, last_action_date_time="2023-11-16T21:51:19Z", ) ], ), ) def test_check_task_status(mocker): client = Mock() client.task.get_result = Mock(return_value=get_base_task_result_mock_response()) client.task.get_result_class = Mock(return_value=check_task_status_mock_response()) mocker.patch("CommonServerPython.ScheduledCommand.raise_error_if_not_supported", lambda: None) args = { "task_id": "00000004", "poll": "true", "poll_time_sec": 30, } result = get_task_status(args, client) assert result.outputs["id"] == "00000004" assert result.outputs["status"] == "succeeded" assert isinstance(result.outputs["action"], str) assert isinstance(result.outputs["created_date_time"], str) assert isinstance(result.outputs["description"], str) assert isinstance(result.outputs["last_action_date_time"], str) # Mock for downloaded file information def mock_get_endpoint_info_response(*args, **kwargs): return Endpoint( agent_guid="35fa11da-a24e-40cf-8b56-baf8828cc151", login_account=ValueList( value=["MSEDGEWIN10\\\\IEUser"], updated_date_time="2020-06-01T02:12:56Z", ), endpoint_name=Value(value="MSEDGEWIN10", updated_date_time="2020-06-01T02:12:56Z"), mac_address=ValueList( updated_date_time="2020-06-01T02:12:56Z", value=["00:1c:42:be:22:5f"], ), ip=ValueList(value=["10.211.55.36"], updated_date_time="2020-06-01T02:12:56Z"), os_name=OperatingSystem.WINDOWS, os_version="10.0 (Build 19045)", os_description="Windows 10 10.0 (Build 19045)", product_code=ProductCode.SAO, installed_product_codes=[ProductCode.SAO, ProductCode.XES], ) def side_effect(lambda_func, *args2, **args3): lambda_func(mock_get_endpoint_info_response()) # Test case for get endpoint information. def test_get_endpoint_information(mocker): """Test get information from endpoint based on endpointName or agentGuid""" args = { "query_op": "and", "endpoint": json.dumps({"dpt": "443", "endpointName": "MSEDGEWIN10"}), } client = Mock() my_list = [] client.endpoint.consume_data = Mock(side_effect=side_effect) client.endpoint.consume_data(lambda cons: my_list.append(cons), QueryOp.AND, **json.loads(args["endpoint"])) result = get_endpoint_info(client, args) assert isinstance(result.outputs[0]["agent_guid"], str) assert isinstance(result.outputs[0]["login_account"], dict) assert isinstance(result.outputs[0]["endpoint_name"], dict) assert isinstance(result.outputs[0]["mac_address"], dict) assert isinstance(result.outputs[0]["ip"], dict) assert isinstance(result.outputs[0]["os_name"], str) assert isinstance(result.outputs[0]["os_version"], str) assert isinstance(result.outputs[0]["os_description"], str) assert isinstance(result.outputs[0]["product_code"], str) assert isinstance(result.outputs[0]["installed_product_codes"], list) assert result.outputs_key_field == "endpoint_name" # Mock response for get endpoint activity data def get_endpoint_activity_data_mock_response(*args, **kwargs): with open("./test_data/get_endpoint_activity_data.json") as f: endpoint_activity: dict[str, Any] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=ListEndpointActivityResp( next_link="https://somelink.com", items=[EndpointActivity(**endpoint_activity)], progress_rate=30, ), ) # Test case for get alert details def test_get_endpoint_activity_data(mocker): client = Mock() client.endpoint.get_activity_count = Mock(return_value=get_endpoint_activity_data_count_mock_response()) client.endpoint.list_activity = Mock(return_value=get_endpoint_activity_data_mock_response()) args = { "start": "2022-10-04T08:22:37Z", "end": "2023-10-04T08:22:37Z", "top": 500, "query_op": "or", "select": "dpt,dst,endpointHostName", "get_activity_data_count": "true", "fetch_all": "false", "fetch_max_count": "50", "fields": json.dumps({"dpt": "443", "endpointHostName": "MSEDGEWIN10"}), } result = get_endpoint_activity_data(client, args) assert isinstance(result.outputs[0]["endpoint_host_name"], str) assert result.outputs_key_field == "endpoint_host_name" # Mock response for get endpoint activity data count def get_endpoint_activity_data_count_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=GetEmailActivitiesCountResp(total_count=10), ) # Test case for get alert details def test_get_endpoint_activity_data_count(mocker): client = Mock() client.endpoint.get_activity_count = Mock(return_value=get_endpoint_activity_data_count_mock_response()) args = { "start": "2022-10-04T08:22:37Z", "end": "2023-10-04T08:22:37Z", "query_op": "or", "select": "dpt,dst,endpointHostName", "get_activity_data_count": "true", "fields": json.dumps({"dpt": "443", "endpointHostName": "MSEDGEWIN10"}), } result = get_endpoint_activity_data_count(client, args) assert isinstance(result.outputs["endpoint_activity_count"], int) assert result.outputs_key_field == "endpoint_activity_count" # Mock response for get endpoint activity data def get_email_activity_data_mock_response(*args, **kwargs): with open("./test_data/get_email_activity_data.json") as f: email_activity: dict[str, Any] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=ListEmailActivityResp( next_link="https://somelink.com", items=[EmailActivity(**email_activity)], progress_rate=30, ), ) # Test case for get alert details def test_get_email_activity_data(mocker): client = Mock() client.email.get_activity_count = Mock(return_value=get_email_activity_data_count_mock_response()) client.email.list_activity = Mock(return_value=get_email_activity_data_mock_response()) args = { "start": "2022-10-04T08:22:37Z", "end": "2023-10-04T08:22:37Z", "top": 50, "query_op": "or", "select": "mailFromAddresses,mailToAddresses", "fetch_all": "false", "fetch_max_count": "50", "fields": json.dumps({"mailToAddresses": "testemail@gmail.com", "mailMsgSubject": "spam"}), } result = get_email_activity_data(client, args) assert isinstance(result.outputs[0]["mail_msg_id"], str) assert result.outputs_key_field == "mail_to_addresses" # Mock response for get email activity data count def get_email_activity_data_count_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=GetEmailActivitiesCountResp(total_count=10), ) # Test case for get email activity data count def test_get_email_activity_data_count(mocker): client = Mock() client.email.get_activity_count = Mock(return_value=get_email_activity_data_count_mock_response()) args = { "start": "2022-10-04T08:22:37Z", "end": "2023-10-04T08:22:37Z", "query_op": "or", "select": "mailFromAddresses,mailToAddresses", "fields": json.dumps({"mailToAddresses": "testemail@gmail.com", "mailMsgSubject": "spam"}), } result = get_email_activity_data_count(client, args) assert isinstance(result.outputs["email_activity_count"], int) assert result.outputs_key_field == "email_activity_count" # Mock response for get alert details def get_alert_details_mock_response(*args, **kwargs): with open("./test_data/get_alert_details.json") as f: alert = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=GetAlertResp(etag="33a64df551425fcc55e4d42a148795d9f25f89d4", data=alert), ) # Test case for get alert details def test_get_alert_details(mocker): client = Mock() client.alert.get = Mock(return_value=get_alert_details_mock_response()) args = {"workbench_id": "WB-9002-20220909-00111"} result = get_alert_details(client, args) assert result.outputs["etag"] == "33a64df551425fcc55e4d42a148795d9f25f89d4" assert isinstance(result.outputs["alert"], dict) assert result.outputs_key_field == "etag" # Mock response for add note. def add_note_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=AddAlertNoteResp(note_id="1"), ) # Test case for add note def test_add_note(mocker): client = Mock() client.note.create = Mock(return_value=add_note_mock_response()) args = {"workbench_id": "WB-14-20190709-00003", "content": "This is a new note."} result = add_note(client, args) assert isinstance(result.outputs["message"], str) assert isinstance(result.outputs["code"], int) assert result.outputs["note_id"] == "1" assert result.outputs_key_field == "note_id" # Mock function for update alert status def update_status_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=NoContentResp(), ) # Test case for update alert status def test_update_status(mocker): client = Mock() client.alert.update_status = Mock(return_value=update_status_mock_response()) args = { "workbench_id": "WB-20837-20220418-00000", "if_match": "d41d8cd98f00b204e9800998ecf8427e", "status": "in_progress", "inv_result": "no_findings", } result = update_status(client, args) assert result.outputs["code"] == 204 assert isinstance(result.outputs["message"], str) assert result.outputs["Workbench_Id"] == "WB-20837-20220418-00000" # Mock function for run custom script def run_custom_script_mock_response(*args, **kwargs): with open("./test_data/run_custom_script.json") as f: return_value: list[dict[str, Any]] = json.load(f) return MultiResult( result_code=ResultCode.SUCCESS, response=MultiResp(items=[MsData(**data) for data in return_value]), ) # Test case to run a custom script def test_run_custom_script(mocker): """ Given: - block_objects -> A dictionary object containing endpoint or agent_guid, optional description and optional parameter. When: - Execute run_custom_script command Then: - validate a success response and a task_id is generated """ client = Mock() client.script.run = Mock(return_value=run_custom_script_mock_response()) args = { "block_objects": json.dumps( [ { "filename": "test.ps1", "endpoint": "custom-endpoint1", "parameter": "string", "description": "Run custom script.", } ] ) } result = run_custom_script(client, args) assert result.outputs[0]["status"] == 202 assert isinstance(result.outputs[0]["task_id"], str) assert result.outputs_prefix == "VisionOne.Run_Custom_Script" assert result.outputs_key_field == "task_id" # Mock function to get custom script list def get_custom_script_list_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=ListCustomScriptsResp( items=[ Script( id="cb044c99-8fc5-2418-f5a5-2f15dbe62133", file_name="string", file_type=ScriptType.BASH, description="Script to update some values", ), Script( id="44c99cb0-8c5f-4182-af55-62135dbe32f1", file_name="string", file_type=ScriptType.POWERSHELL, description="Script to delete duplicate values", ), ] ), ) # Test case to fetch custom script list def test_get_custom_script_list(mocker): """ Given: - fields -> A dictionary object containing fileName and/or fileType - query_op -> Operator used to build the query string, possible values are and/or When: - Execute get_custom_script_list command Then: - validate an id, filename and filetype are returned """ client = Mock() client.script.list = Mock(return_value=get_custom_script_list_mock_response()) args = {"filename": "test-script.sh", "filetype": "bash", "query_op": "or"} result = get_custom_script_list(client, args) assert isinstance(result.outputs[0]["id"], str) assert isinstance(result.outputs[0]["filename"], str) assert isinstance(result.outputs[0]["filetype"], str) assert result.outputs_prefix == "VisionOne.Get_Custom_Script_List" assert result.outputs_key_field == "id" # Mock function to download custom script def download_custom_script_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=TextResp(text="#!/bin/sh echo 'Download script'"), ) # Test case to download a custom script def test_download_custom_script(mocker): """ Given: - script_id -> The ID for a custom script to download When: - Execute download_custom_script command Then: - validate text response for downloaded script """ client = Mock() client.script.download = Mock(return_value=download_custom_script_mock_response()) args = {"script_id": "44c99cb0-8c5f-4182-af55-62135dbe32f1"} result = download_custom_script(client, args) assert result.outputs["text"] == "#!/bin/sh echo 'Download script'" assert result.outputs_prefix == "VisionOne.Download_Custom_Script" assert result.outputs_key_field == "text" # Mock function to delete custom script def delete_custom_script_mock_response(*args, **kwargs): with open("./test_data/delete_custom_script.json") as f: return_value: dict[str, str] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=NoContentResp(**return_value), ) # Test case to delete a custom script def test_delete_custom_script(mocker): """ Given: - script_id -> The ID of a custom script to delete When: - Execute delete_custom_script command Then: - validate a success response """ client = Mock() client.script.delete = Mock(return_value=delete_custom_script_mock_response()) args = {"script_id": "44c99cb0-8c5f-4182-af55-62135dbe32f1"} result = delete_custom_script(client, args) assert isinstance(result.outputs["status"], str) assert result.outputs_prefix == "VisionOne.Delete_Custom_Script" assert result.outputs_key_field == "status" # Mock function to add custom script def add_custom_script_mock_response(*args, **kwargs): return Result( result_code=ResultCode.SUCCESS, response=AddCustomScriptResp(script_id="44c99cb0-8c5f-4182-af55-62135dbe32f1"), ) # Test case to add a custom script def test_add_custom_script(mocker): """ Given: - filename -> Name of the custom script - filetype -> Filetype of the custom script - description -> Optional description for the custom script - script_contents -> Contents of the custom script When: - Execute add_custom_script command Then: - validate an ID is returned after successful action completion """ client = Mock() client.script.create = Mock(return_value=add_custom_script_mock_response()) args = { "file_url": "http://someurl.com/testscript.sh", "filename": "test_script.sh", "filetype": "bash", "description": "Script to delete duplicates.", } mocker.patch("TrendMicroVisionOneV3.requests.get", mocked_requests_get) mocker.patch("TrendMicroVisionOneV3.requests.post", mocked_requests_post) result = add_custom_script(client, args) assert result.outputs["id"] == "44c99cb0-8c5f-4182-af55-62135dbe32f1" assert result.outputs_prefix == "VisionOne.Add_Custom_Script" assert result.outputs_key_field == "id" # Mock function to update custom script def update_custom_script_mock_response(*args, **kwargs): with open("./test_data/update_custom_script.json") as f: return_value: dict[str, str] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=NoContentResp(**return_value), ) # Test case to update a custom script def test_update_custom_script(mocker): """ Given: - filename -> Name of the custom script - filetype -> Filetype of the custom script - script_id -> ID of the custom script to update - script_contents -> New contents of the custom script - description -> Optional description for the custom script When: - Execute update_custom_script command Then: - validate a success response """ client = Mock() client.script.update = Mock(return_value=update_custom_script_mock_response()) mocker.patch("TrendMicroVisionOneV3.requests.get", mocked_requests_get) mocker.patch("TrendMicroVisionOneV3.requests.post", mocked_requests_post) args = { "filetype": "bash", "filename": "test_script.sh", "script_id": "44c99cb0-8c5f-4182-af55-62135dbe32f1", "file_url": "http://someurl.com/test1script.sh", "description": "Script to update values.", } result = update_custom_script(client, args) assert result.outputs["status"] == "SUCCESS" assert result.outputs_prefix == "VisionOne.Update_Custom_Script" assert result.outputs_key_field == "status" # Mock response for get observed attack techniques events def get_observed_attack_techniques_mock_response(*args, **kwargs): with open("./test_data/get_observed_attack_techniques.json") as f: attack_techniques: dict[str, Any] = json.load(f) return Result( result_code=ResultCode.SUCCESS, response=ListOatsResp( next_link="https://somelink.com", items=[OatEvent(**attack_techniques)], total_count=30, count=10, ), ) # Test case for fetching observed attack techniques def test_get_observed_attack_techniques(mocker): """ Given: - detected_start -> Detection start date time - detected_end -> Detection end date time - ingested_start -> Ingestion start date time - ingested_end -> Ingestion end date time - top -> Number of records displayed on a page. - query_op -> Conditional operator used to build request that allows user to retrieve a subset of the collected Observed Attack Techniques events - fields -> Required filter (A dictionary object with key/value used to create a query string) for retrieving a subset of the collected Observed Attack Techniques events When: - Execute get_observed_attack_techniques command Then: - validate a string id response """ client = Mock() client.oat.list = Mock(return_value=get_observed_attack_techniques_mock_response()) args = { "detected_start": "2024-01-15T10:00:00Z", "detected_end": "2024-05-15T10:00:00Z", "ingested_start": "2024-01-15T10:00:00Z", "ingested_end": "2024-05-15T10:00:00Z", "top": 10, "query_op": "or", "fields": json.dumps({"endpointName": "sample-host", "riskLevel": "low"}), } result = get_observed_attack_techniques(client, args) assert isinstance(result.outputs[0]["id"], str) assert result.outputs_prefix == "VisionOne.Get_Observed_Attack_Techniques" assert result.outputs_key_field == "id" def test_xsoar_status_to_vision_one(): """ Test the xsoar_status_to_vision_one helper function that maps XSOAR incident statuses to Vision One alert statuses. Given: - incident_status: XSOAR IncidentStatus value (0=Pending, 1=Active, 2=Closed, or unknown) When: - Execute xsoar_status_to_vision_one function Then: - Validate correct mapping to Vision One status """ # Test Pending (0) -> "open" status = xsoar_status_to_vision_one(0) assert status == "open" # Test Active (1) -> "in_progress" status = xsoar_status_to_vision_one(1) assert status == "in_progress" # Test Closed (2) -> "closed" status = xsoar_status_to_vision_one(2) assert status == "closed" # Test Unknown status (999) -> defaults to "open" status = xsoar_status_to_vision_one(999) assert status == "open" # ========== Outgoing Mirroring Tests (update-remote-system) ========== def test_update_remote_system_no_remote_id(mocker): """ Test update_remote_system when no remote ID is provided. Given: - No remote incident ID (empty string) When: - Execute update_remote_system command Then: - Should return empty string without making API calls """ client = Mock() mocker.patch.object(demisto, "error") args = { "remoteId": "", "data": {"status": 2}, "entries": [], "incidentChanged": True, } result = update_remote_system_command(client, args) # Should return empty string without any API calls assert result == "" client.alert.get.assert_not_called() def test_update_remote_system_incident_not_changed(mocker): """ Test update_remote_system when incident has not changed. Given: - Remote incident ID - incidentChanged is False When: - Execute update_remote_system command Then: - Should return remote ID without making API calls """ client = Mock() mocker.patch.object(demisto, "error") args = { "remoteId": "WB-14-20190709-00003", "data": {"status": 1}, "entries": [], "incidentChanged": False, } result = update_remote_system_command(client, args) # Should return remote ID without calling API assert result == "WB-14-20190709-00003" client.alert.get.assert_not_called() def test_update_remote_system_status_update_success(mocker): """ Test update_remote_system when incident status changes successfully. Given: - Incident status changed to Closed (2) - Close reason "Resolved" When: - Execute update_remote_system command Then: - Should retrieve alert to get ETag - Should update Vision One alert status to "closed" with investigation result TRUE_POSITIVE """ from pytmv1 import AlertStatus, InvestigationResult, GetAlertResp, Result, ResultCode, MultiResp client = Mock() mocker.patch.object(demisto, "error") # Mock alert.get() response - return success with etag mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.etag = "test-etag-123" mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result # Mock alert.update_status() response - return success mock_update_result = Mock(spec=MultiResp) mock_update_result.result_code = ResultCode.SUCCESS mock_update_result.error = None client.alert.update_status.return_value = mock_update_result args = { "remoteId": "WB-14-20190709-00003", "data": {"status": 2, "closeReason": "Resolved"}, "entries": [], "incidentChanged": True, } result = update_remote_system_command(client, args) # Should return remote ID assert result == "WB-14-20190709-00003" # Verify alert.get was called client.alert.get.assert_called_once_with(alert_id="WB-14-20190709-00003") # Verify alert.update_status was called with correct parameters client.alert.update_status.assert_called_once() call_args = client.alert.update_status.call_args assert call_args.kwargs["alert_id"] == "WB-14-20190709-00003" assert call_args.kwargs["status"] == AlertStatus.CLOSED assert call_args.kwargs["etag"] == "test-etag-123" assert call_args.kwargs["inv_result"] == InvestigationResult.TRUE_POSITIVE def test_update_remote_system_with_close_notes(mocker): """ Test update_remote_system when incident is closed with close notes. Given: - Incident closed with closeNotes When: - Execute update_remote_system command Then: - Should update status - Should add closing note to Vision One alert """ from pytmv1 import GetAlertResp, Result, ResultCode, MultiResp client = Mock() mocker.patch.object(demisto, "error") # Mock alert.get() response mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.etag = "test-etag-456" mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result # Mock alert.update_status() response mock_update_result = Mock(spec=MultiResp) mock_update_result.result_code = ResultCode.SUCCESS mock_update_result.error = None client.alert.update_status.return_value = mock_update_result # Mock note.create() response mock_note_result = Mock(spec=Result) mock_note_result.result_code = ResultCode.SUCCESS mock_note_result.error = None client.note.create.return_value = mock_note_result args = { "remoteId": "WB-14-20190709-00003", "data": { "status": 2, "closeReason": "Resolved", "closeNotes": "Confirmed false positive after investigation", "closingUserId": "analyst@example.com", "id": "12345", }, "entries": [], "incidentChanged": True, } result = update_remote_system_command(client, args) # Should return remote ID assert result == "WB-14-20190709-00003" # Verify note.create was called client.note.create.assert_called_once() call_args = client.note.create.call_args assert call_args.kwargs["alert_id"] == "WB-14-20190709-00003" assert "XSOAR Incident ID: 12345" in call_args.kwargs["note_content"] assert "Close Reason: Resolved" in call_args.kwargs["note_content"] assert "analyst@example.com" in call_args.kwargs["note_content"] assert "Confirmed false positive after investigation" in call_args.kwargs["note_content"] def test_update_remote_system_close_reason_mapping(mocker): """ Test update_remote_system close reason to investigation result mapping. Given: - Incident closed with different close reasons When: - Execute update_remote_system command Then: - Should map close reasons correctly to investigation results """ from pytmv1 import InvestigationResult, GetAlertResp, Result, ResultCode, MultiResp client = Mock() mocker.patch.object(demisto, "error") # Mock responses mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.etag = "test-etag" mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result mock_update_result = Mock(spec=MultiResp) mock_update_result.result_code = ResultCode.SUCCESS mock_update_result.error = None client.alert.update_status.return_value = mock_update_result # Test case 1: "False Positive" -> FALSE_POSITIVE args_fp = { "remoteId": "WB-TEST", "data": {"status": 2, "closeReason": "False Positive"}, "entries": [], "incidentChanged": True, } update_remote_system_command(client, args_fp) call_args = client.alert.update_status.call_args assert call_args.kwargs["inv_result"] == InvestigationResult.FALSE_POSITIVE # Reset mock client.alert.update_status.reset_mock() # Test case 2: "Resolved" -> TRUE_POSITIVE args_resolved = { "remoteId": "WB-TEST", "data": {"status": 2, "closeReason": "Resolved"}, "entries": [], "incidentChanged": True, } update_remote_system_command(client, args_resolved) call_args = client.alert.update_status.call_args assert call_args.kwargs["inv_result"] == InvestigationResult.TRUE_POSITIVE # Reset mock client.alert.update_status.reset_mock() # Test case 3: "Duplicate" -> NO_FINDINGS args_duplicate = { "remoteId": "WB-TEST", "data": {"status": 2, "closeReason": "Duplicate"}, "entries": [], "incidentChanged": True, } update_remote_system_command(client, args_duplicate) call_args = client.alert.update_status.call_args assert call_args.kwargs["inv_result"] == InvestigationResult.NO_FINDINGS # Reset mock client.alert.update_status.reset_mock() # Test case 4: "Other" -> NOTEWORTHY args_other = { "remoteId": "WB-TEST", "data": {"status": 2, "closeReason": "Other"}, "entries": [], "incidentChanged": True, } update_remote_system_command(client, args_other) call_args = client.alert.update_status.call_args assert call_args.kwargs["inv_result"] == InvestigationResult.NOTEWORTHY def test_update_remote_system_api_error(mocker): """ Test update_remote_system when API returns an error. Given: - Vision One API returns error when getting alert When: - Execute update_remote_system command Then: - Should log error and return remote ID without updating """ from pytmv1 import Result, ResultCode, Error client = Mock() mock_error_logger = mocker.patch.object(demisto, "error") # Mock alert.get() to return error mock_error = Mock(spec=Error) mock_error.message = "Alert not found" mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.ERROR mock_get_result.response = None mock_get_result.error = mock_error client.alert.get.return_value = mock_get_result args = { "remoteId": "WB-INVALID", "data": {"status": 2}, "entries": [], "incidentChanged": True, } result = update_remote_system_command(client, args) # Should return remote ID even on error assert result == "WB-INVALID" # Should have logged error assert mock_error_logger.called error_msg = mock_error_logger.call_args[0][0] assert "Error fetching alert" in error_msg assert "WB-INVALID" in error_msg # Should not call update_status client.alert.update_status.assert_not_called() # ========== Incoming Mirroring Tests (get-modified-remote-data) ========== def test_vision_one_status_to_xsoar(): """ Test the vision_one_status_to_xsoar helper function that maps Vision One alert statuses to XSOAR incident statuses. Given: - v1_status: Vision One alert status string When: - Execute vision_one_status_to_xsoar function Then: - Validate correct mapping to XSOAR IncidentStatus values """ # Test "Open" -> 0 (Pending) - Vision One API format status = vision_one_status_to_xsoar("Open") assert status == 0 # Test "In Progress" -> 1 (Active) - Vision One API format status = vision_one_status_to_xsoar("In Progress") assert status == 1 # Test "Closed" -> 2 (Closed) - Vision One API format status = vision_one_status_to_xsoar("Closed") assert status == 2 # Test unknown status -> defaults to 0 (Pending) status = vision_one_status_to_xsoar("unknown_status") assert status == 0 def test_get_modified_remote_data_success(mocker): """ Test get_modified_remote_data returns modified alert IDs. Given: - last_update timestamp When: - Execute get_modified_remote_data command - Vision One returns alerts updated since last_update Then: - Should return list of modified alert IDs """ from pytmv1 import SaeAlert client = Mock() mocker.patch.object(demisto, "error") # Mock alert.consume to call callback with test alerts def mock_consume(callback, **kwargs): # Create mock alerts alert1 = Mock(spec=SaeAlert) alert1.id = "WB-ALERT-001" alert2 = Mock(spec=SaeAlert) alert2.id = "WB-ALERT-002" # Call the callback for each alert callback(alert1) callback(alert2) client.alert.consume = mock_consume args = { "lastUpdate": "2025-01-01T00:00:00Z", } result = get_modified_remote_data_command(client, args) # Should return list of modified alert IDs assert len(result.modified_incident_ids) == 2 assert "WB-ALERT-001" in result.modified_incident_ids assert "WB-ALERT-002" in result.modified_incident_ids def test_get_modified_remote_data_no_last_update(mocker): """ Test get_modified_remote_data when no last_update provided. Given: - No last_update timestamp When: - Execute get_modified_remote_data command Then: - Should default to 1 hour ago - Should return 0 modified alerts """ from pytmv1 import SaeAlert client = Mock() mocker.patch.object(demisto, "error") # Mock alert.consume def mock_consume(callback, **kwargs): alert = Mock(spec=SaeAlert) alert.id = "WB-ALERT-003" callback(alert) client.alert.consume = mock_consume args = {} result = get_modified_remote_data_command(client, args) # Should return results even without last_update assert len(result.modified_incident_ids) == 0 def test_get_modified_remote_data_invalid_timestamp(mocker): """ Test get_modified_remote_data with invalid timestamp format. Given: - Invalid last_update timestamp format When: - Execute get_modified_remote_data command Then: - Should log error - Should default to 1 hour ago - Should still return results """ from pytmv1 import SaeAlert client = Mock() mock_error_logger = mocker.patch.object(demisto, "error") # Mock alert.consume def mock_consume(callback, **kwargs): alert = Mock(spec=SaeAlert) alert.id = "WB-ALERT-004" callback(alert) client.alert.consume = mock_consume args = { "lastUpdate": "invalid-timestamp-format", } result = get_modified_remote_data_command(client, args) # Should log error about invalid format assert mock_error_logger.called error_msg = mock_error_logger.call_args[0][0] assert "Invalid last_update format" in error_msg # Should still return results assert len(result.modified_incident_ids) == 1 def test_get_modified_remote_data_api_error(mocker): """ Test get_modified_remote_data when API throws exception. Given: - Vision One API throws exception When: - Execute get_modified_remote_data command Then: - Should log error - Should return empty list """ client = Mock() mock_error_logger = mocker.patch.object(demisto, "error") # Mock alert.consume to raise exception client.alert.consume.side_effect = Exception("API connection error") args = { "lastUpdate": "2025-01-01T00:00:00Z", } result = get_modified_remote_data_command(client, args) # Should log error assert mock_error_logger.called # Should return empty list assert len(result.modified_incident_ids) == 0 # ========== Incoming Mirroring Tests (get-remote-data) ========== def test_get_remote_data_no_alert_id(mocker): """ Test get_remote_data when no alert ID is provided. Given: - Empty or missing alert ID When: - Execute get_remote_data command Then: - Should return empty response """ client = Mock() mocker.patch.object(demisto, "error") args = { "id": "", "lastUpdate": "2025-01-01T00:00:00Z", } result = get_remote_data_command(client, args) # Should return empty response assert result.mirrored_object == {} assert len(result.entries) == 0 # Should not call API client.alert.get.assert_not_called() def test_get_remote_data_alert_not_modified(mocker): """ Test get_remote_data when alert was not modified since last_update. Given: - Alert updated time is before last_update When: - Execute get_remote_data command Then: - Should return empty response (optimization) """ from pytmv1 import GetAlertResp, Result, ResultCode client = Mock() mocker.patch.object(demisto, "error") # Mock alert.get() to return alert with old update time mock_alert_data = Mock() mock_alert_data.model_dump.return_value = { "id": "WB-ALERT-OLD", "status": "Open", "severity": "medium", "updated_date_time": "2025-01-01T00:00:00Z", # Before last_update } mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.data = mock_alert_data mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result args = { "id": "WB-ALERT-OLD", "lastUpdate": "2025-01-02T00:00:00Z", # After alert update time } result = get_remote_data_command(client, args) # Should return empty response (not modified) assert result.mirrored_object == {} assert len(result.entries) == 0 def test_get_remote_data_success_closed_alert(mocker): """ Test get_remote_data when alert status is closed. Given: - Alert with status "Closed" (realistic Vision One data structure) When: - Execute get_remote_data command Then: - Should return incident data with status 2 (Closed) - Should add close entry - Should preserve impact_scope and indicators fields """ from pytmv1 import GetAlertResp, Result, ResultCode client = Mock() mocker.patch.object(demisto, "error") # Mock alert.get() to return closed alert with realistic Vision One structure mock_alert_data = Mock() mock_alert_data.model_dump.return_value = { "schema_version": "1.12", "id": "WB-ALERT-CLOSED", "status": "Closed", "severity": "high", "investigation_status": "Closed", "investigation_result": "True Positive", "updated_date_time": "2025-01-03T00:00:00Z", "created_date_time": "2025-01-01T00:00:00Z", "model": "Privilege Escalation via UAC Bypass", "score": 64, "workbench_link": "test/...", "impact_scope": { "desktop_count": 1, "server_count": 0, "account_count": 1, "entities": [ { "entity_type": "account", "entity_value": "domain\\user", "entity_id": "domain\\user", "related_entities": ["HOST-GUID"], "provenance": ["Alert"], }, { "entity_type": "host", "entity_value": {"guid": "HOST-GUID", "name": "test-host", "ips": ["10.0.0.1"]}, "entity_id": "HOST-GUID", "related_entities": ["domain\\user"], "related_indicator_ids": [1, 2], "provenance": ["Alert"], }, ], }, "indicators": [ { "id": 1, "type": "command_line", "field": "processCmd", "value": "powershell.exe -enc ...", "related_entities": ["HOST-GUID"], "provenance": ["Alert"], }, { "id": 2, "type": "registry_key", "field": "objectRegistryKeyHandle", "value": "hkcr\\ms-settings\\shell\\open\\command", "related_entities": ["HOST-GUID"], "provenance": ["Alert"], }, ], "matched_rules": [{"id": "rule-id", "name": "UAC Bypass Rule", "matched_filters": []}], } mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.data = mock_alert_data mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result args = { "id": "WB-ALERT-CLOSED", "lastUpdate": "2025-01-01T00:00:00Z", } result = get_remote_data_command(client, args) # Should return incident data with closed status assert result.mirrored_object["id"] == "WB-ALERT-CLOSED" assert result.mirrored_object["status"] == "Closed" # Closed # Should have close entry assert len(result.entries) == 1 close_entry = result.entries[0] assert close_entry["Type"] == 1 # Note def test_get_remote_data_success_open_alert(mocker): """ Test get_remote_data when alert status is open or in progress. Given: - Alert with status "In Progress" (realistic Vision One data structure) When: - Execute get_remote_data command Then: - Should return incident data with status 1 (Active) - Should not add any entries (XSOAR handles status update automatically) - Should preserve impact_scope and indicators fields """ from pytmv1 import GetAlertResp, Result, ResultCode client = Mock() mocker.patch.object(demisto, "error") # Mock alert.get() to return in-progress alert with realistic Vision One structure mock_alert_data = Mock() mock_alert_data.model_dump.return_value = { "schema_version": "1.12", "id": "WB-ALERT-ACTIVE", "status": "In Progress", "severity": "medium", "investigation_status": "In Progress", "updated_date_time": "2025-01-03T00:00:00Z", "created_date_time": "2025-01-01T00:00:00Z", "model": "Suspicious Network Activity", "score": 45, "workbench_link": "test/...", "impact_scope": { "desktop_count": 1, "server_count": 0, "account_count": 1, "entities": [ { "entity_type": "host", "entity_value": {"guid": "HOST-GUID-123", "name": "workstation-01", "ips": ["192.168.1.100"]}, "entity_id": "HOST-GUID-123", "related_entities": ["user@domain.com"], "related_indicator_ids": [1], "provenance": ["Alert"], } ], }, "indicators": [ { "id": 1, "type": "ip", "field": "dst", "value": "test value", "related_entities": ["HOST-GUID-123"], "provenance": ["Alert"], } ], "matched_rules": [{"id": "rule-id-456", "name": "Outbound Connection to Known Bad IP", "matched_filters": []}], } mock_alert_resp = Mock(spec=GetAlertResp) mock_alert_resp.data = mock_alert_data mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.SUCCESS mock_get_result.response = mock_alert_resp mock_get_result.error = None client.alert.get.return_value = mock_get_result args = { "id": "WB-ALERT-ACTIVE", "lastUpdate": "2025-01-01T00:00:00Z", } result = get_remote_data_command(client, args) # Should return incident data with active status assert result.mirrored_object["id"] == "WB-ALERT-ACTIVE" assert result.mirrored_object["status"] == "In Progress" # Active assert len(result.entries) == 1 def test_get_remote_data_alert_not_found(mocker): """ Test get_remote_data when alert is not found. Given: - Vision One API returns error (alert not found) When: - Execute get_remote_data command Then: - Should log error - Should return empty response """ from pytmv1 import Result, ResultCode, Error client = Mock() mock_error_logger = mocker.patch.object(demisto, "error") # Mock alert.get() to return error mock_error = Mock(spec=Error) mock_error.message = "Alert not found" mock_get_result = Mock(spec=Result) mock_get_result.result_code = ResultCode.ERROR mock_get_result.response = None mock_get_result.error = mock_error client.alert.get.return_value = mock_get_result args = { "id": "WB-NONEXISTENT", "lastUpdate": "2025-01-01T00:00:00Z", } result = get_remote_data_command(client, args) # Should log error assert mock_error_logger.called error_msg = mock_error_logger.call_args[0][0] assert "Error fetching alert" in error_msg # Should return empty response assert result.mirrored_object == {} assert len(result.entries) == 0 # ========== Mapping Fields Tests ========== def test_get_mapping_fields(mocker): """ Test get_mapping_fields returns correct field mappings. Given: - No arguments (function takes no parameters) When: - Execute get_mapping_fields command Then: - Should return GetMappingFieldsResponse with SchemeTypeMapping - Should include mirrored Vision One alert fields """ mocker.patch.object(demisto, "error") # get_mapping_fields() takes no parameters result = get_mapping_fields_command() # Should return GetMappingFieldsResponse assert result is not None assert len(result.scheme_types_mappings) > 0 # Verify incident type name scheme_type = result.scheme_types_mappings[0] assert scheme_type.type_name == "Trend Micro Vision One XDR Incident" fields: dict = scheme_type.fields # Verify mirrored fields are present field_names = [field_key for field_key, _ in fields.items()] assert "status" in field_names assert "severity" in field_names assert "investigation_result" in field_names