diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py index 21197c8ea5ea..997ad6a138ca 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py @@ -745,12 +745,13 @@ def batch_refresh_session(batch_id: str) -> None: demisto.debug('Finished session refresh') -def run_batch_read_cmd(batch_id: str, command_type: str, full_command: str) -> Dict: +def run_batch_read_cmd(batch_id: str, command_type: str, full_command: str, timeout: int = 30) -> Dict: """ Sends RTR command scope with read access :param batch_id: Batch ID to execute the command on. :param command_type: Read-only command type we are going to execute, for example: ls or cd. :param full_command: Full command string for the command. + :param timeout: The timeout for the request. :return: Response JSON which contains errors (if exist) and retrieved resources """ endpoint_url = '/real-time-response/combined/batch-command/v1' @@ -760,17 +761,22 @@ def run_batch_read_cmd(batch_id: str, command_type: str, full_command: str) -> D 'batch_id': batch_id, 'command_string': full_command }) - response = http_request('POST', endpoint_url, data=body) + params = { + 'timeout': timeout + } + response = http_request('POST', endpoint_url, data=body, params=params, timeout=timeout) return response -def run_batch_write_cmd(batch_id: str, command_type: str, full_command: str, optional_hosts: list | None = None) -> Dict: +def run_batch_write_cmd(batch_id: str, command_type: str, full_command: str, optional_hosts: list | None = None, + timeout: int = 30) -> Dict: """ Sends RTR command scope with write access :param batch_id: Batch ID to execute the command on. :param command_type: Read-only command type we are going to execute, for example: ls or cd. :param full_command: Full command string for the command. :param optional_hosts: The hosts ids to run the command on. + :param timeout: The timeout for the request. :return: Response JSON which contains errors (if exist) and retrieved resources """ endpoint_url = '/real-time-response/combined/batch-active-responder-command/v1' @@ -780,11 +786,14 @@ def run_batch_write_cmd(batch_id: str, command_type: str, full_command: str, opt 'batch_id': batch_id, 'command_string': full_command } + params = { + 'timeout': timeout + } if optional_hosts: default_body['optional_hosts'] = optional_hosts # type:ignore body = json.dumps(default_body) - response = http_request('POST', endpoint_url, data=body) + response = http_request('POST', endpoint_url, data=body, timeout=timeout, params=params) return response @@ -814,7 +823,7 @@ def run_batch_admin_cmd(batch_id: str, command_type: str, full_command: str, tim default_body['optional_hosts'] = optional_hosts # type:ignore body = json.dumps(default_body) - response = http_request('POST', endpoint_url, data=body, params=params) + response = http_request('POST', endpoint_url, data=body, params=params, timeout=timeout) return response @@ -858,12 +867,15 @@ def status_get_cmd(request_id: str, timeout: int | None = None, timeout_duration return response -def run_single_read_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool) -> Dict: +def run_single_read_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool, + timeout: int = 30) -> Dict: """ Sends RTR command scope with read access :param host_id: Host agent ID to run RTR command on. :param command_type: Active-Responder command type we are going to execute, for example: get or cp. :param full_command: Full command string for the command. + :param queue_offline: Whether the command will run against an offline-queued session and be queued for execution when the host comes online. # noqa: E501 + :param timeout: The timeout for the request. :return: Response JSON which contains errors (if exist) and retrieved resources """ endpoint_url = '/real-time-response/entities/command/v1' @@ -874,16 +886,22 @@ def run_single_read_cmd(host_id: str, command_type: str, full_command: str, queu 'command_string': full_command, 'session_id': session_id }) - response = http_request('POST', endpoint_url, data=body) + params = { + 'timeout': timeout + } + response = http_request('POST', endpoint_url, data=body, timeout=timeout, params=params) return response -def run_single_write_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool) -> Dict: +def run_single_write_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool, + timeout: int = 30) -> Dict: """ Sends RTR command scope with write access :param host_id: Host agent ID to run RTR command on. :param command_type: Active-Responder command type we are going to execute, for example: get or cp. :param full_command: Full command string for the command. + :param queue_offline: Whether the command will run against an offline-queued session and be queued for execution when the host comes online. # noqa: E501 + :param timeout: The timeout for the request. :return: Response JSON which contains errors (if exist) and retrieved resources """ endpoint_url = '/real-time-response/entities/active-responder-command/v1' @@ -893,16 +911,22 @@ def run_single_write_cmd(host_id: str, command_type: str, full_command: str, que 'command_string': full_command, 'session_id': session_id }) - response = http_request('POST', endpoint_url, data=body) + params = { + 'timeout': timeout + } + response = http_request('POST', endpoint_url, data=body, timeout=timeout, params=params) return response -def run_single_admin_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool) -> Dict: +def run_single_admin_cmd(host_id: str, command_type: str, full_command: str, queue_offline: bool, + timeout: int = 30) -> Dict: """ Sends RTR command scope with admin access :param host_id: Host agent ID to run RTR command on. :param command_type: Active-Responder command type we are going to execute, for example: get or cp. :param full_command: Full command string for the command. + :param queue_offline: Whether the command will run against an offline-queued session and be queued for execution when the host comes online. # noqa: E501 + :param timeout: The timeout for the request. :return: Response JSON which contains errors (if exist) and retrieved resources """ endpoint_url = '/real-time-response/entities/admin-command/v1' @@ -913,7 +937,10 @@ def run_single_admin_cmd(host_id: str, command_type: str, full_command: str, que 'command_string': full_command, 'session_id': session_id }) - response = http_request('POST', endpoint_url, data=body) + params = { + 'timeout': timeout + } + response = http_request('POST', endpoint_url, data=body, timeout=timeout, params=params) return response @@ -3020,6 +3047,7 @@ def run_command(): full_command = args.get('full_command') scope = args.get('scope', 'read') target = args.get('target', 'batch') + timeout = int(args.get('timeout', 180)) offline = argToBoolean(args.get('queue_offline', False)) @@ -3031,11 +3059,11 @@ def run_command(): timer.start() try: if scope == 'read': - response = run_batch_read_cmd(batch_id, command_type, full_command) + response = run_batch_read_cmd(batch_id, command_type, full_command, timeout=timeout) elif scope == 'write': - response = run_batch_write_cmd(batch_id, command_type, full_command) + response = run_batch_write_cmd(batch_id, command_type, full_command, timeout=timeout) else: # scope = admin - response = run_batch_admin_cmd(batch_id, command_type, full_command) + response = run_batch_admin_cmd(batch_id, command_type, full_command, timeout=timeout) finally: timer.cancel() @@ -3068,11 +3096,11 @@ def run_command(): responses = [] for host_id in host_ids: if scope == 'read': - response1 = run_single_read_cmd(host_id, command_type, full_command, offline) + response1 = run_single_read_cmd(host_id, command_type, full_command, offline, timeout=timeout) elif scope == 'write': - response1 = run_single_write_cmd(host_id, command_type, full_command, offline) + response1 = run_single_write_cmd(host_id, command_type, full_command, offline, timeout=timeout) else: # scope = admin - response1 = run_single_admin_cmd(host_id, command_type, full_command, offline) + response1 = run_single_admin_cmd(host_id, command_type, full_command, offline, timeout=timeout) responses.append(response1) for resource in response1.get('resources', []): diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml index 2fb6e67143d5..3fdaa28eac69 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml @@ -404,6 +404,10 @@ script: - read - write - admin + - name: timeout + description: The amount of time (in seconds) that a request will wait for a client to establish a connection to a remote machine before a timeout occurs. + defaultValue: "180" + type: unknown - auto: PREDEFINED defaultValue: batch description: 'The target to run the command for. Possible values are: "single" and "batch".' diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md index f4293a986b02..c89413edd036 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md @@ -516,6 +516,7 @@ Sends commands to hosts. | scope | The scope for which to run the command. Possible values are: "read", "write", and "admin". Default is "read". (NOTE: In order to run the CrowdStrike RTR `put` command, it is necessary to pass `scope=admin`.) | Optional | | target | The target for which to run the command. Possible values are: "single" and "batch". Default is "batch". | Optional | | queue_offline | Any commands run against an offline-queued session will be queued up and executed when the host comes online. | Optional | +| timeout | The amount of time (in seconds) that a request will wait for a client to establish a connection to a remote machine before a timeout occurs. | Optional | #### Context Output @@ -3681,6 +3682,7 @@ Uploads a batch of indicators. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | | multiple_indicators_json | A JSON object with list of CS Falcon indicators to upload. | Required | +| timeout | The amount of time (in seconds) that a request will wait for a client to establish a connection to a remote machine before a timeout occurs. | Optional | #### Context Output diff --git a/Packs/CrowdStrikeFalcon/ReleaseNotes/1_10_31.md b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_10_31.md new file mode 100644 index 000000000000..2f54732d7d51 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_10_31.md @@ -0,0 +1,5 @@ +#### Integrations + +##### CrowdStrike Falcon + +- Added the timeout argument to **cs-falcon-run-command** command. \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/pack_metadata.json b/Packs/CrowdStrikeFalcon/pack_metadata.json index 53428f1b85ea..86ab156f3d71 100644 --- a/Packs/CrowdStrikeFalcon/pack_metadata.json +++ b/Packs/CrowdStrikeFalcon/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CrowdStrike Falcon", "description": "The CrowdStrike Falcon OAuth 2 API (formerly the Falcon Firehose API), enables fetching and resolving detections, searching devices, getting behaviors by ID, containing hosts, and lifting host containment.", "support": "xsoar", - "currentVersion": "1.10.30", + "currentVersion": "1.10.31", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "",